[
  {
    "path": ".dockerignore",
    "content": "assets/\nbuild/\nbin/\ndocs/\nnetworks/\nproto/\ntools/\nkurtosis/\ntesting/\n.github/\n.git/\n.vscode/\n*.md\ncontracts/\ndocs/\nscripts/\n"
  },
  {
    "path": ".gitattributes",
    "content": "docs/** linguist-vendored"
  },
  {
    "path": ".github/workflows/berachain_release.asc",
    "content": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmDMEaIky1hYJKwYBBAHaRw8BAQdAnxP3mNWC+miF0OKvOg4+BzzswbrTWLbluSJU\n+NBib3q0H2NhbGJlcmEgPGNhbGJlcmFAYmVyYWNoYWluLmNvbT6ImQQTFgoAQQIb\nAwULCQgHAgIiAgYVCgkICwIEFgIDAQIeBwIXgBYhBPzFjSePGuMIYGS4P/GUiPGD\n4kvxBQJpr+YaBQkBnVpEAAoJEPGUiPGD4kvxil4A/jJqgaUlW7Yk1G4joQnAE7FS\n1RotqI2olJa2f7Vt33VEAP99Bi4TkSUwQpx6pKHRggrJ0aBEJg2eZXQd7AeTPWmL\nALg4BGiJMtYSCisGAQQBl1UBBQEBB0A6onCspxjhXI7X13LHlUYQxYVyzUDamgVP\nhXYTLZ1QEAMBCAeIfgQYFgoAJhYhBPzFjSePGuMIYGS4P/GUiPGD4kvxBQJoiTLW\nAhsMBQkAdqcAAAoJEPGUiPGD4kvxWOAA/0IedfbPuCJU/IWo+gxCZMl9Fb7oVA4L\nv9lMBtnspGsxAQDRX3fFP/Bv96wHlUWQHg01TSaWNyTQa5dTpjEcLxnXCQ==\n=EVlI\n-----END PGP PUBLIC KEY BLOCK-----\n"
  },
  {
    "path": ".github/workflows/docker-nightly-preconf.yml",
    "content": "# SPDX-License-Identifier: MIT\n#\n# Copyright (c) 2025 Berachain Foundation\n#\n# Permission is hereby granted, free of charge, to any person\n# obtaining a copy of this software and associated documentation\n# files (the \"Software\"), to deal in the Software without\n# restriction, including without limitation the rights to use,\n# copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the\n# Software is furnished to do so, subject to the following\n# conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n# OTHER DEALINGS IN THE SOFTWARE.\n\nname: Docker Nightly Preconf\n\non:\n  schedule:\n    - cron: \"0 1 * * *\"\n  workflow_dispatch:\n\nenv:\n  GHCR_REGISTRY: ghcr.io\n  VERSION: nightly-preconf\n\njobs:\n  build-and-push:\n    runs-on:\n      labels: ubuntu-24.04-beacon-kit\n    permissions:\n      id-token: write\n      contents: read\n      packages: write\n      attestations: write\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n        with:\n          ref: preconf-dev\n\n      - name: Build Docker image\n        run: |\n          make build-docker VERSION=${{ env.VERSION }}\n\n      - name: Authenticate to GitHub Container Registry\n        uses: docker/login-action@v3\n        with:\n          registry: ${{ env.GHCR_REGISTRY }}\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Push Docker image\n        run: |\n          make push-docker-github VERSION=${{ env.VERSION }}\n"
  },
  {
    "path": ".github/workflows/pipeline.yml",
    "content": "# SPDX-License-Identifier: MIT\n#\n# Copyright (c) 2025 Berachain Foundation\n#\n# Permission is hereby granted, free of charge, to any person\n# obtaining a copy of this software and associated documentation\n# files (the \"Software\"), to deal in the Software without\n# restriction, including without limitation the rights to use,\n# copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the\n# Software is furnished to do so, subject to the following\n# conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n# OTHER DEALINGS IN THE SOFTWARE.\n\nname: pipeline\n\non:\n  push:\n    branches:\n      - main\n      - preconf-dev\n    tags:\n      - \"v*\"\n  pull_request:\n  merge_group:\n\nconcurrency:\n  group: ci-${{ github.ref }}-tests\n  # We don't want to cancel in progress on main. This is to allow\n  # us to debug main if a bad commit is pushed.\n  # Case 1: The base branch is main and the event triggered via merge group => we DO NOT want to cancel in progress\n  # Case 2: The reference branch is not main => we want to cancel in progress\n  cancel-in-progress: ${{ !(github.base_ref == 'refs/heads/main' && github.event_name == 'merge_group') || github.ref != 'refs/heads/main' }}\n\nenv:\n  GHCR_REGISTRY: ghcr.io\n  PUSH_DOCKER_IMAGE: ${{ (github.base_ref == github.head_ref && github.event_name == 'push') || github.ref == 'refs/tags/v*'}}\n  VERSION: ${{ github.ref_name }}\n\njobs:\n  # -------------------------------------------------------------------------- #\n  #                                Main Pipeline                               #\n  # -------------------------------------------------------------------------- #\n\n  ci:\n    strategy:\n      matrix:\n        args:\n          - \"build\"\n          - \"lint\"\n          - \"slither\"\n          - \"gosec\"\n          - \"nilaway\"\n          - \"vulncheck\"\n          - \"markdownlint\"\n          - \"generate-check\"\n          - \"tidy-sync-check\"\n          - \"test-unit-cover\"\n          - \"test-unit-bench\"\n          - \"test-unit-fuzz\"\n          - \"test-forge-cover\"\n          - \"test-forge-fuzz\"\n        os:\n          - ubuntu-24.04-beacon-kit\n    name: ${{ matrix.args }}\n    runs-on:\n      labels: ${{ matrix.os }}\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n        with:\n          submodules: recursive\n\n      - name: Install Foundry\n        uses: foundry-rs/foundry-toolchain@v1\n        with:\n          version: v1.3.1\n        if: ${{ matrix.args == 'lint' || matrix.args == 'generate-check' || matrix.args == 'test-forge-cover' || matrix.args == 'test-forge-fuzz' }}\n\n      - name: Setup Golang\n        uses: actions/setup-go@v5\n        with:\n          go-version-file: go.mod\n          check-latest: true\n          cache-dependency-path: \"**/*.sum\"\n        if: ${{ !(matrix.args == 'test-forge-cover' || matrix.args == 'test-forge-fuzz') }}\n\n      - name: Run ${{ matrix.args }}\n        run: |\n          make ${{ matrix.args }}\n        env:\n          GOPATH: /home/runner/go\n\n      # If running unit test coverage, merge the two coverage files\n      - name: Merge Coverage Reports for Unit Tests\n        if: ${{ matrix.args == 'test-unit-cover' }}\n        run: |\n          # Install gocovmerge\n          go install github.com/wadey/gocovmerge@latest\n          # Merge the two coverage files\n          gocovmerge test-unit-cover.txt test-simulated.txt > coverage-merged.txt\n\n      # Upload merged coverage for unit tests\n      - name: Upload Unit Test Coverage to Codecov\n        if: ${{ matrix.args == 'test-unit-cover' }}\n        uses: codecov/codecov-action@v2\n        with:\n          token: ${{ secrets.CODECOV_TOKEN }}\n          files: coverage-merged.txt\n\n  # -------------------------------------------------------------------------- #\n  #                                 E2E Testing                                #\n  # -------------------------------------------------------------------------- #\n\n  ci-e2e:\n    strategy:\n      fail-fast: false\n      matrix:\n        args:\n          - \"test-e2e-standard\"\n        os:\n          - ubuntu-24.04-e2e\n    name: ${{ matrix.args }}\n    runs-on:\n      labels: ${{ matrix.os }}\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n        with:\n          submodules: recursive\n      - name: Check if Docker Hub credentials exist\n        id: check-docker-credentials\n        run: |\n          if [ \"${{ secrets.DOCKERHUB_USERNAME }}\" != \"\" ] && [ \"${{ secrets.DOCKERHUB_TOKEN }}\" != \"\" ]; then\n            echo \"has_credentials=true\" >> $GITHUB_OUTPUT\n          fi\n        shell: bash\n      - name: Login to Docker Hub\n        uses: docker/login-action@v3.4.0\n        if: steps.check-docker-credentials.outputs.has_credentials == 'true'\n        with:\n          username: ${{ secrets.DOCKERHUB_USERNAME }}\n          password: ${{ secrets.DOCKERHUB_TOKEN }}\n      - name: Login to GHCR\n        uses: docker/login-action@v3.4.0\n        with:\n          registry: ghcr.io\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n      - name: Setup Golang\n        uses: actions/setup-go@v5\n        with:\n          go-version-file: go.mod\n          check-latest: true\n          cache-dependency-path: \"**/*.sum\"\n      - name: Set up QEMU\n        uses: docker/setup-qemu-action@v1\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@v1\n      - name: Install Kurtosis\n        run: |\n          KURTOSIS_VERSION=$(go list -m -f '{{.Version}}' github.com/kurtosis-tech/kurtosis/api/golang | sed 's/^v//')\n          echo \"Installing kurtosis-cli ${KURTOSIS_VERSION}\"\n          curl -sL \"https://github.com/kurtosis-tech/kurtosis-cli-release-artifacts/releases/download/${KURTOSIS_VERSION}/kurtosis-cli_${KURTOSIS_VERSION}_linux_amd64.tar.gz\" | tar xz -C /tmp\n          sudo mv /tmp/kurtosis /usr/local/bin/kurtosis\n          kurtosis version\n          docker info\n          for img in kurtosistech/engine:1.4.3 timberio/vector:0.31.0-debian traefik:2.10.6 alpine:3.17; do\n            docker pull $img\n          done\n          kurtosis engine start\n      - name: Run ${{ matrix.args }}\n        run: |\n          make ${{ matrix.args }}\n        env:\n          GOPATH: /home/runner/go\n\n  # -------------------------------------------------------------------------- #\n  #                       Docker Container Build and Push                      #\n  # -------------------------------------------------------------------------- #\n\n  build-and-push-container:\n    runs-on:\n      labels: ubuntu-24.04-beacon-kit\n    permissions:\n      id-token: write\n      contents: read\n      packages: write\n      attestations: write\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n\n      - name: Echo GitHub Context Variables\n        env:\n          GITHUB_ACTOR: ${{ github.actor }}\n          GITHUB_REPOSITORY: ${{ github.repository }}\n          GITHUB_EVENT_NAME: ${{ github.event_name }}\n          GITHUB_SHA: ${{ github.sha }}\n          GITHUB_REF: ${{ github.ref }}\n          GITHUB_WORKFLOW: ${{ github.workflow }}\n          GITHUB_ACTION: ${{ github.action }}\n          GITHUB_RUN_ID: ${{ github.run_id }}\n          GITHUB_RUN_NUMBER: ${{ github.run_number }}\n          GITHUB_JOB: ${{ github.job }}\n          GITHUB_SERVER_URL: ${{ github.server_url }}\n          GITHUB_API_URL: ${{ github.api_url }}\n          GITHUB_GRAPHQL_URL: ${{ github.graphql_url }}\n          GITHUB_HEAD_REF: ${{ github.head_ref }}\n          GITHUB_BASE_REF: ${{ github.base_ref }}\n          PUSH_DOCKER_IMAGE: ${{ env.PUSH_DOCKER_IMAGE }}\n          VERSION: ${{ env.VERSION }}\n        run: |\n          echo \"GitHub Actor: \\\"$GITHUB_ACTOR\\\"\"\n          echo \"GitHub Repository: \\\"$GITHUB_REPOSITORY\\\"\"\n          echo \"GitHub Event Name: \\\"$GITHUB_EVENT_NAME\\\"\"\n          echo \"GitHub SHA: \\\"$GITHUB_SHA\\\"\"\n          echo \"GitHub Ref: \\\"$GITHUB_REF\\\"\"\n          echo \"GitHub Workflow: \\\"$GITHUB_WORKFLOW\\\"\"\n          echo \"GitHub Action: \\\"$GITHUB_ACTION\\\"\"\n          echo \"GitHub Run ID: \\\"$GITHUB_RUN_ID\\\"\"\n          echo \"GitHub Run Number: \\\"$GITHUB_RUN_NUMBER\\\"\"\n          echo \"GitHub Job: \\\"$GITHUB_JOB\\\"\"\n          echo \"GitHub Server URL: \\\"$GITHUB_SERVER_URL\\\"\"\n          echo \"GitHub API URL: \\\"$GITHUB_API_URL\\\"\"\n          echo \"GitHub GraphQL URL: \\\"$GITHUB_GRAPHQL_URL\\\"\"\n          echo \"GitHub Head Ref: \\\"$GITHUB_HEAD_REF\\\"\"\n          echo \"GitHub Base Ref: \\\"$GITHUB_BASE_REF\\\"\"\n          echo \"PUSH_DOCKER_IMAGE: \\\"$PUSH_DOCKER_IMAGE\\\"\"\n          echo \"VERSION: \\\"$VERSION\\\"\"\n      - name: Build Docker image\n        run: |\n          make build-docker\n\n      - if: ${{ env.PUSH_DOCKER_IMAGE == 'true' }}\n        name: Authenticate to GitHub Container Registry\n        uses: docker/login-action@v3\n        with:\n          registry: ${{ env.GHCR_REGISTRY }}\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      - if: ${{ env.PUSH_DOCKER_IMAGE == 'true' }}\n        name: Push Docker image\n        run: |\n          make push-docker-github\n"
  },
  {
    "path": ".github/workflows/release.yaml",
    "content": "# SPDX-License-Identifier: MIT\n#\n# Copyright (c) 2025 Berachain Foundation\n#\n# Permission is hereby granted, free of charge, to any person\n# obtaining a copy of this software and associated documentation\n# files (the \"Software\"), to deal in the Software without\n# restriction, including without limitation the rights to use,\n# copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the\n# Software is furnished to do so, subject to the following\n# conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n# OTHER DEALINGS IN THE SOFTWARE.\n\nname: release\n\non:\n  push:\n    tags:\n      - \"v*\" \n\nenv:\n  REPO_NAME: ${{ github.repository }} \n  IMAGE_NAME: ${{ github.repository }}\n  GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\njobs:\n  # Job to extract version\n  extract-version:\n    name: extract version\n    runs-on: ubuntu-latest\n    steps:\n      - name: Extract version\n        run: echo \"VERSION=$(echo ${GITHUB_REF#refs/tags/})\" >> $GITHUB_OUTPUT\n        id: extract_version\n    outputs:\n      VERSION: ${{ steps.extract_version.outputs.VERSION }}\n  \n  # Job to build release\n  build:\n    name: build release\n    needs: extract-version\n    strategy:\n      matrix:\n        configs:\n          - arch: arm64\n            target-os: linux\n            runs-on: ubuntu-24.04-arm\n          - arch: amd64\n            target-os: linux\n            runs-on: ubuntu-latest\n          - arch: arm64\n            target-os: darwin\n            runs-on: macos-14\n        build:\n          - binary: beacond\n    runs-on: ${{ matrix.configs.runs-on }}\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-go@v5\n        with:\n          go-version-file: go.mod\n        env:\n          GOOS: ${{ matrix.configs.target-os }}\n          GOARCH: ${{ matrix.configs.arch }}\n\n      - name: Import GPG key\n        run: |\n          mkdir -p ~/.gnupg\n          chmod 700 ~/.gnupg\n          echo \"allow-loopback-pinentry\" >> ~/.gnupg/gpg-agent.conf\n          echo \"$GPG_KEY\" | gpg --batch --import\n          gpg-connect-agent reloadagent /bye || true\n        env:\n          GPG_KEY: ${{ secrets.GPG_KEY }}\n\n      - name: Build ${{ matrix.build.binary }}\n        run: |\n          make build-${{ matrix.configs.target-os }}-${{ matrix.configs.arch }}-${{ needs.extract-version.outputs.VERSION }}\n          tar -czvf ${{ matrix.build.binary }}-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.configs.target-os }}-${{ matrix.configs.arch }}.tar.gz -C build/bin .\n\n      - name: Sign binary archive\n        run: gpg --batch --yes --pinentry-mode=loopback --passphrase \"$GPG_KEY_PASSPHRASE\" --detach-sign ${{ matrix.build.binary }}-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.configs.target-os }}-${{ matrix.configs.arch }}.tar.gz\n        env:\n          GPG_KEY_PASSPHRASE: ${{ secrets.GPG_KEY_PASSPHRASE }}\n      \n      # Upload archives and signatures\n      - name: Upload archive\n        uses: actions/upload-artifact@v4\n        with:\n          name: ${{ matrix.build.binary }}-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.configs.target-os }}-${{ matrix.configs.arch }}.tar.gz\n          path: |\n            ${{ matrix.build.binary }}-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.configs.target-os }}-${{ matrix.configs.arch }}.tar.gz\n      - name: Upload archive signature\n        uses: actions/upload-artifact@v4\n        with:\n          name: ${{ matrix.build.binary }}-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.configs.target-os }}-${{ matrix.configs.arch }}.tar.gz.sig\n          path: |\n            ${{ matrix.build.binary }}-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.configs.target-os }}-${{ matrix.configs.arch }}.tar.gz.sig\n\n  # Job to draft release\n  draft-release:\n    name: draft release\n    needs: [build, extract-version]\n    runs-on: ubuntu-latest\n    env:\n      VERSION: ${{ needs.extract-version.outputs.VERSION }}\n    permissions:\n      contents: write # Required to post the release\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          fetch-depth: 0 # This is necessary for generating the changelog. It has to come before \"Download Artifacts\" or else it deletes the artifacts.\n      - name: Download artifacts\n        uses: actions/download-artifact@v4\n      - name: Generate full changelog\n        id: changelog\n        run: |\n          echo \"CHANGELOG<<EOF\" >> $GITHUB_OUTPUT\n          echo \"$(git log --pretty=format:\"- %s\" $(git describe --tags --abbrev=0 ${{ env.VERSION }}^)..${{ env.VERSION }})\" >> $GITHUB_OUTPUT\n          echo \"EOF\" >> $GITHUB_OUTPUT\n      - name: Create release draft\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        # The formatting here is borrowed from Reth (which is borrowed from Lighthouse (which is borrowed from OpenEthereum)):\n        # https://github.com/openethereum/openethereum/blob/6c2d392d867b058ff867c4373e40850ca3f96969/.github/workflows/build.yml\n        run: |\n          body=$(cat <<- \"ENDBODY\"\n          ![image](https://res.cloudinary.com/duv0g402y/image/upload/v1718034312/BeaconKitBanner.png)\n          ## Testing Checklist (DELETE ME)\n\n          - [ ] Run on testnet for 1-3 days.\n          - [ ] Resync a mainnet node.\n          - [ ] Ensure all CI checks pass.\n\n          ## Release Checklist (DELETE ME)\n\n          - [ ] Ensure all crates have had their versions bumped.\n          - [ ] Write the summary.\n          - [ ] Fill out the update priority.\n          - [ ] Ensure all binaries have been added.\n          - [ ] Prepare release posts (Twitter, ...).\n\n          ## Summary\n\n          Add a summary, including:\n\n          - Critical bug fixes\n          - New features\n          - Any breaking changes (and what to expect)\n\n          ## Update Priority\n\n          This table provides priorities for which classes of users should update particular components.\n\n          | User Class           | Priority        |\n          |----------------------|-----------------|\n          | Payload Builders     | <TODO>          |\n          | Non-Payload Builders | <TODO>          |\n\n          ## All Changes\n\n          ${{ steps.changelog.outputs.CHANGELOG }}\n\n          ## Binaries\n\n          | System | Architecture | Binary | PGP Signature |\n          |:---:|:---:|:---:|:---|\n          | <img src=\"https://simpleicons.org/icons/linux.svg\" style=\"width: 32px;\"/> | amd64 | [beacond-${{ env.VERSION }}-linux-amd64](https://github.com/${{ env.REPO_NAME }}/releases/download/${{ env.VERSION }}/beacond-${{ env.VERSION }}-linux-amd64.tar.gz) | [Signature](https://github.com/${{ env.REPO_NAME }}/releases/download/${{ env.VERSION }}/beacond-${{ env.VERSION }}-linux-amd64.tar.gz.sig) |\n          | <img src=\"https://simpleicons.org/icons/linux.svg\" style=\"width: 32px;\"/> | arm64 | [beacond-${{ env.VERSION }}-linux-arm64](https://github.com/${{ env.REPO_NAME }}/releases/download/${{ env.VERSION }}/beacond-${{ env.VERSION }}-linux-arm64.tar.gz) | [Signature](https://github.com/${{ env.REPO_NAME }}/releases/download/${{ env.VERSION }}/beacond-${{ env.VERSION }}-linux-arm64.tar.gz.sig) |\n          | <img src=\"https://simpleicons.org/icons/apple.svg\" style=\"width: 32px;\"/> | arm64 | [beacond-${{ env.VERSION }}-darwin-arm64](https://github.com/${{ env.REPO_NAME }}/releases/download/${{ env.VERSION }}/beacond-${{ env.VERSION }}-darwin-arm64.tar.gz) | [Signature](https://github.com/${{ env.REPO_NAME }}/releases/download/${{ env.VERSION }}/beacond-${{ env.VERSION }}-darwin-arm64.tar.gz.sig) |          \n          | **System** | **Option** | - | **Resource** |\n          | <img src=\"https://simpleicons.org/icons/docker.svg\" style=\"width: 32px;\"/> | Docker | | [${{ env.IMAGE_NAME }}](https://ghcr.io/berachain/beacon-kit) |\n          \n          ### Verifying signatures\n          Use gpg to verify the signature on these binary archives. This is important to make sure that the content you\\'ve downloaded is legitimate. gpg can be installed with most package managers. For example:\n          - `brew install gpg` on mac\n          - `apt install gpg` on Ubuntu/Debian\n\n          Once gpg is installed, import our public key into its database and verify:\n          - [Download signing public key from here](https://raw.githubusercontent.com/${{ github.repository }}/${{ github.ref_name }}/.github/workflows/berachain_release.asc).\n          - Run `gpg --import berachain_release.asc`\n          - Verify with `gpg --verify {signature}.sig {binary}.tar.gz`\n          - This message is expected: `WARNING: This key is not certified with a trusted signature!`\n          - To resolve the warning, trust the key by signing with your own keypair. `gpg --lsign-key <keyid>`\n\n          ENDBODY\n          )\n          assets=()\n          for asset in ./*beacond-*.tar.gz*; do\n              assets+=(\"$asset/$asset\")\n          done\n          tag_name=\"${{ env.VERSION }}\"\n          echo \"$body\" | gh release create --draft -t \"BeaconKit $tag_name\" -F \"-\" \"$tag_name\" \"${assets[@]}\"\n"
  },
  {
    "path": ".github/workflows/vuln-and-dep-check.yml",
    "content": "# SPDX-License-Identifier: MIT\n#\n# Copyright (c) 2025 Berachain Foundation\n#\n# Permission is hereby granted, free of charge, to any person\n# obtaining a copy of this software and associated documentation\n# files (the \"Software\"), to deal in the Software without\n# restriction, including without limitation the rights to use,\n# copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the\n# Software is furnished to do so, subject to the following\n# conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n# OTHER DEALINGS IN THE SOFTWARE.\n\nname: deps\n\non:\n  schedule:\n    - cron: '0 8 * * *' # daily at 08:00 UTC\n  workflow_dispatch:\n\n# Cancel any in-progress run if a new one starts on the same branch.\nconcurrency:\n  group: vuln-and-dep-check-${{ github.ref }}\n  cancel-in-progress: true\n\npermissions:\n  contents: read\n\njobs:\n  # Catch newly published vulnerabilities in dependencies via symbol-level analysis.\n  govulncheck:\n    runs-on:\n      labels: ubuntu-24.04-beacon-kit\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          submodules: recursive\n      - uses: actions/setup-go@v5\n        with:\n          go-version-file: go.mod\n          check-latest: true\n          cache-dependency-path: \"**/*.sum\"\n      - run: make vulncheck\n\n  # Run tests with locked and latest deps to catch breakage from both.\n  test-deps:\n    runs-on:\n      labels: ubuntu-24.04-beacon-kit\n    strategy:\n      fail-fast: false # Always run both variants so one failure doesn't hide the other.\n      matrix:\n        deps: [locked, latest]\n    name: test-${{ matrix.deps }}-deps\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          submodules: recursive\n      - uses: actions/setup-go@v5\n        with:\n          go-version-file: go.mod\n          check-latest: true\n          cache-dependency-path: \"**/*.sum\"\n      - if: matrix.deps == 'latest'\n        name: Update dependencies to latest (skip replace-pinned modules)\n        run: |\n          go list -m -f '{{if not .Indirect}}{{.Path}}{{end}}' all \\\n            | grep -vE 'berachain/beacon-kit|cosmossdk\\.io/|cosmos/cosmos-sdk|cometbft/|karalabe/ssz|kurtosis-tech/' \\\n            | xargs go get -u -t\n          go mod tidy\n      - run: make test-unit\n        env:\n          GOPATH: /home/runner/go\n"
  },
  {
    "path": ".gitignore",
    "content": "###########\n# Project #\n###########\n\n# Outputs\nbin/\n./out/\ndata/\nsite/\ncontracts/cache\ncontracts/out\ntmp/\ncscope.files\n\n##########\n# Golang #\n##########\n\n# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\n*.info\n\n# Test binary, built with `go test -c`\n*.test\n\n# Output of the go coverage tool, specifically when used with LiteIDE\n*.out\n\n# Dependency directories (remove the comment below to include it)\ngo.work.sum\n\n##########\n# Linux  #\n##########\n\n*~\n\n# temporary files which can be created if a process still has a handle open of a deleted file\n.fuse_hidden*\n\n# KDE directory preferences\n.directory\n\n# Linux trash folder which might appear on any partition or disk\n.Trash-*\n\n# .nfs files are created when an open file is removed but is still being accessed\n.nfs*\n\n# Version files created during code generation\nv*.*.*\n\n###########\n# Windows #\n###########\n\n# Windows thumbnail cache files\nThumbs.db\nThumbs.db:encryptable\nehthumbs.db\nehthumbs_vista.db\n\n# Dump file\n*.stackdump\n\n# Folder config file\n[Dd]esktop.ini\n\n# Recycle Bin used on file shares\n$RECYCLE.BIN/\n\n# Windows Installer files\n*.cab\n*.msi\n*.msix\n*.msm\n*.msp\n\n# Windows shortcuts\n*.lnk\n\n#########\n# macOS #\n#########\n\n# General\n.DS_Store\n.AppleDouble\n.LSOverride\n\n# Icon must end with two \\r\nIcon\n\n# Thumbnails\n._*\n\n# Files that might appear in the root of a volume\n.DocumentRevisions-V100\n.fseventsd\n.Spotlight-V100\n.TemporaryItems\n.Trashes\n.VolumeIcon.icns\n.com.apple.timemachine.donotpresent\n\n# Directories potentially created on remote AFP share\n.AppleDB\n.AppleDesktop\nNetwork Trash Folder\nTemporary Items\n.apdisk\n\n##########\n# VSCODE #\n##########\n\n.vscode/*\n!.vscode/tasks.json\n!.vscode/launch.json\n!.vscode/extensions.json\n*.code-workspace\n\n# Local History for Visual Studio Code\n.history/\n\n#############\n# JetBrains #\n#############\n\n.idea\n# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider\n# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839\n\n# User-specific stuff\n.idea/**/workspace.xml\n.idea/**/tasks.xml\n.idea/**/usage.statistics.xml\n.idea/**/dictionaries\n.idea/**/shelf\n\n# AWS User-specific\n.idea/**/aws.xml\n\n# Generated files\n.idea/**/contentModel.xml\n\n# Sensitive or high-churn files\n.idea/**/dataSources/\n.idea/**/dataSources.ids\n.idea/**/dataSources.local.xml\n.idea/**/sqlDataSources.xml\n.idea/**/dynamic.xml\n.idea/**/uiDesigner.xml\n.idea/**/dbnavigator.xml\n\n# Mongo Explorer plugin\n.idea/**/mongoSettings.xml\n\n# File-based project format\n*.iws\n\n# mpeltonen/sbt-idea plugin\n.idea_modules/\n\n# JIRA plugin\natlassian-ide-plugin.xml\n\n# Cursive Clojure plugin\n.idea/replstate.xml\n\n# Crashlytics plugin (for Android Studio and IntelliJ)\ncom_crashlytics_export_strings.xml\ncrashlytics.properties\ncrashlytics-build.properties\nfabric.properties\n\n# Editor-based Rest Client\n.idea/httpRequests\n\n# general\nvue/node_modules\nvue/dist\nrelease/\n.idea/\ndata/\n.DS_Store\n*.pyc\n.vscode/*.log\n\n# upgrades\npkg/**/.*.yaml\n*/**/.tmp/\n.tmp/\n/tmp\n\n# forge\n*/**/solidity-files-cache.json\ncontracts/out/\n*/**/broadcast\ncontracts/out/**/*.bin\n\n# e2e\ne2e/**/*.txt\n\n# hive\n!e2e/hive/**/*.json\n\n# geth\n*.rlp\n\n# cosmos\n.testnets/\n*.dot\n*.log\n\n# xml\n*.xml\n\n#next\nnode_modules\n.next\nnext-env.d.ts\n.env\nout\n\n# docker test\n**/temp/\n\n# testing coverage\ncoverage-test-unit-cover.txt\ncoverage-merged.txt\ntest-simulated.txt\ntest-unit-cover.txt\ntemp-test-simulated.txt\ntemp-test-unit-cover.txt\n.vercel\n\n# server dev env for Air\n.air.toml\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"contracts/lib/solady\"]\n\tpath = contracts/lib/solady\n\turl = https://github.com/Vectorized/solady\n[submodule \"contracts/lib/forge-std\"]\n\tpath = contracts/lib/forge-std\n\turl = https://github.com/foundry-rs/forge-std\n"
  },
  {
    "path": ".golangci.yaml",
    "content": "# This code is licensed under the terms of the MIT license https://opensource.org/license/mit\n# Copyright (c) 2021 Marat Reymers\n\n## Golden config for golangci-lint v1.58.2\n#\n# This is the best config for golangci-lint based on my experience and opinion.\n# It is very strict, but not extremely strict.\n# Feel free to adapt and change it for your needs.\n\nrun:\n  # Timeout for analysis, e.g. 30s, 5m.\n  # Default: 1m\n  timeout: 3m\n  build-tags: [\"test\"]\n\n\n# This file contains only configs which differ from defaults.\n# All possible options can be found here https://github.com/golangci/golangci-lint/blob/master/.golangci.reference.yml\nlinters-settings:\n  cyclop:\n    # The maximal code complexity to report.\n    # Default: 10\n    max-complexity: 30\n    # The maximal average package complexity.\n    # If it's higher than 0.0 (float) the check is enabled\n    # Default: 0.0\n    package-average: 10.0\n\n  errcheck:\n    # Report about not checking of errors in type assertions: `a := b.(MyStruct)`.\n    # Such cases aren't reported by default.\n    # Default: false\n    check-type-assertions: true\n\n  paralleltest:\n    # Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.\n    # Default: false\n    ignore-missing: false\n    # Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are\n    # still required to have `t.Parallel`, but subtests are allowed to skip it.\n    # Default: false\n    ignore-missing-subtests: true\n\n  exhaustive:\n    # Program elements to check for exhaustiveness.\n    # Default: [ switch ]\n    check:\n      - switch\n      - map\n    # Presence of \"default\" case in switch statements satisfies exhaustiveness,\n    # even if all enum members are not listed.\n    # Default: false\n    default-signifies-exhaustive: true\n\n  exhaustruct:\n    # List of regular expressions to exclude struct packages and their names from checks.\n    # Regular expressions must match complete canonical struct package/name/structname.\n    # Default: []\n    exclude:\n      # std libs\n      - \"^net/http.Client$\"\n      - \"^net/http.Cookie$\"\n      - \"^net/http.Request$\"\n      - \"^net/http.Response$\"\n      - \"^net/http.Server$\"\n      - \"^net/http.Transport$\"\n      - \"^net/url.URL$\"\n      - \"^os/exec.Cmd$\"\n      - \"^reflect.StructField$\"\n      # public libs\n      - \"^github.com/Shopify/sarama.Config$\"\n      - \"^github.com/Shopify/sarama.ProducerMessage$\"\n      - \"^github.com/mitchellh/mapstructure.DecoderConfig$\"\n      - \"^github.com/prometheus/client_golang/.+Opts$\"\n      - \"^github.com/spf13/cobra.Command$\"\n      - \"^github.com/spf13/cobra.CompletionOptions$\"\n      - \"^github.com/stretchr/testify/mock.Mock$\"\n      - \"^github.com/testcontainers/testcontainers-go.+Request$\"\n      - \"^github.com/testcontainers/testcontainers-go.FromDockerfile$\"\n      - \"^golang.org/x/tools/go/analysis.Analyzer$\"\n      - \"^google.golang.org/protobuf/.+Options$\"\n      - \"^gopkg.in/yaml.v3.Node$\"\n\n  funlen:\n    # Checks the number of lines in a function.\n    # If lower than 0, disable the check.\n    # Default: 60\n    lines: 100\n    # Checks the number of statements in a function.\n    # If lower than 0, disable the check.\n    # Default: 40\n    statements: 50\n    # Ignore comments when counting lines.\n    # Default false\n    ignore-comments: true\n\n  gocognit:\n    # Minimal code complexity to report.\n    # Default: 30 (but we recommend 10-20)\n    min-complexity: 20\n\n  gocritic:\n    # Settings passed to gocritic.\n    # The settings key is the name of a supported gocritic checker.\n    # The list of supported checkers can be find in https://go-critic.github.io/overview.\n    settings:\n      captLocal:\n        # Whether to restrict checker to params only.\n        # Default: true\n        paramsOnly: false\n      underef:\n        # Whether to skip (*x).method() calls where x is a pointer receiver.\n        # Default: true\n        skipRecvDeref: false\n\n  gomodguard:\n    blocked:\n      # List of blocked modules.\n      # Default: []\n      modules:\n        - github.com/golang/protobuf:\n            recommendations:\n              - google.golang.org/protobuf\n            reason: \"see https://developers.google.com/protocol-buffers/docs/reference/go/faq#modules\"\n        - github.com/satori/go.uuid:\n            recommendations:\n              - github.com/google/uuid\n            reason: \"satori's package is not maintained\"\n        - github.com/gofrs/uuid:\n            recommendations:\n              - github.com/gofrs/uuid/v5\n            reason: \"gofrs' package was not go module before v5\"\n\n\n  govet:\n    # Enable all analyzers.\n    # Default: false\n    enable-all: true\n    # Disable analyzers by name.\n    # Run `go tool vet help` to see all analyzers.\n    # Default: []\n    disable:\n      - fieldalignment # too strict\n    # Settings per analyzer.\n    settings:\n      shadow:\n        # Whether to be strict about shadowing; can be noisy.\n        # Default: false\n        strict: true\n\n  inamedparam:\n    # Skips check for interface methods with only a single parameter.\n    # Default: false\n    skip-single-param: true\n\n  lll:\n    # Max line length, lines longer will be reported.\n    # '\\t' is counted as 1 character by default, and can be changed with the tab-width option.\n    # Default: 120.\n    line-length: 140\n    # Tab width in spaces.\n    # Default: 1\n    tab-width: 1\n\n  mnd:\n    # List of function patterns to exclude from analysis.\n    # Values always ignored: `time.Date`,\n    # `strconv.FormatInt`, `strconv.FormatUint`, `strconv.FormatFloat`,\n    # `strconv.ParseInt`, `strconv.ParseUint`, `strconv.ParseFloat`.\n    # Default: []\n    ignored-functions:\n      - args.Error\n      - flag.Arg\n      - flag.Duration.*\n      - flag.Float.*\n      - flag.Int.*\n      - flag.Uint.*\n      - os.Chmod\n      - os.Mkdir.*\n      - os.OpenFile\n      - os.WriteFile\n      - prometheus.ExponentialBuckets.*\n      - prometheus.LinearBuckets\n\n  nakedret:\n    # Make an issue if func has more lines of code than this setting, and it has naked returns.\n    # Default: 30\n    max-func-lines: 0\n\n  nolintlint:\n    # Exclude following linters from requiring an explanation.\n    # Default: []\n    allow-no-explanation: [ funlen, gocognit, lll ]\n    # Enable to require an explanation of nonzero length after each nolint directive.\n    # Default: false\n    require-explanation: true\n    # Enable to require nolint directives to mention the specific linter being suppressed.\n    # Default: false\n    require-specific: true\n\n  perfsprint:\n    # Optimizes into strings concatenation.\n    # Default: true\n    strconcat: true\n\n  rowserrcheck:\n    # database/sql is always checked\n    # Default: []\n    packages:\n      - github.com/jmoiron/sqlx\n\n  sloglint:\n    # Enforce not using global loggers.\n    # Values:\n    # - \"\": disabled\n    # - \"all\": report all global loggers\n    # - \"default\": report only the default slog logger\n    # Default: \"\"\n    no-global: \"all\"\n    # Enforce using methods that accept a context.\n    # Values:\n    # - \"\": disabled\n    # - \"all\": report all contextless calls\n    # - \"scope\": report only if a context exists in the scope of the outermost function\n    # Default: \"\"\n    context: \"scope\"\n\n  tenv:\n    # The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.\n    # Otherwise, only methods that take `*testing.T`, `*testing.B`, and `testing.TB` as arguments are checked.\n    # Default: false\n    all: true\n\n\nlinters:\n  disable-all: true\n  enable:\n    ## enabled by default\n    - errcheck # checking for unchecked errors, these unchecked errors can be critical bugs in some cases\n    - gosimple # specializes in simplifying a code\n    - govet # reports suspicious constructs, such as Printf calls whose arguments do not align with the format string\n    - ineffassign # detects when assignments to existing variables are not used\n    - staticcheck # is a go vet on steroids, applying a ton of static analysis checks\n    - typecheck # like the front-end of a Go compiler, parses and type-checks Go code\n    - unused # checks for unused constants, variables, functions and types\n    ## disabled by default\n    - asasalint # checks for pass []any as any in variadic func(...any)\n    - asciicheck # checks that your code does not contain non-ASCII identifiers\n    - bidichk # checks for dangerous unicode character sequences\n    - bodyclose # checks whether HTTP response body is closed successfully\n    - canonicalheader # checks whether net/http.Header uses canonical header\n    - cyclop # checks function and package cyclomatic complexity\n    - dupl # tool for code clone detection\n    - durationcheck # checks for two durations multiplied together\n    - errname # checks that sentinel errors are prefixed with the Err and error types are suffixed with the Error\n    - errorlint # finds code that will cause problems with the error wrapping scheme introduced in Go 1.13\n    - exhaustive # checks exhaustiveness of enum switch statements\n    - fatcontext # detects nested contexts in loops\n    - forbidigo # forbids identifiers\n    - funlen # tool for detection of long functions\n    - gocheckcompilerdirectives # validates go compiler directive comments (//go:)\n    - gochecknoglobals # checks that no global variables exist\n    - gochecknoinits # checks that no init functions are present in Go code\n    - gochecksumtype # checks exhaustiveness on Go \"sum types\"\n    - gocognit # computes and checks the cognitive complexity of functions\n    - goconst # finds repeated strings that could be replaced by a constant\n    - gocritic # provides diagnostics that check for bugs, performance and style issues\n    - gocyclo # computes and checks the cyclomatic complexity of functions\n    - goimports # in addition to fixing imports, goimports also formats your code in the same style as gofmt\n    # - gomoddirectives # manages the use of 'replace', 'retract', and 'excludes' directives in go.mod\n    - gomodguard # allow and block lists linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations\n    - goprintffuncname # checks that printf-like functions are named with f at the end\n    - gosec # inspects source code for security problems\n    - intrange # finds places where for loops could make use of an integer range\n    - lll # reports long lines\n    - loggercheck # checks key value pairs for common logger libraries (kitlog,klog,logr,zap)\n    - makezero # finds slice declarations with non-zero initial length\n    - mirror # reports wrong mirror patterns of bytes/strings usage\n    - mnd # detects magic numbers\n    - musttag # enforces field tags in (un)marshaled structs\n    - nakedret # finds naked returns in functions greater than a specified function length\n    - nestif # reports deeply nested if statements\n    - nilerr # finds the code that returns nil even if it checks that the error is not nil\n    - nilnil # checks that there is no simultaneous return of nil error and an invalid value\n    - noctx # finds sending http request without context.Context\n    - nolintlint # reports ill-formed or insufficient nolint directives\n    - nonamedreturns # reports all named returns\n    - nosprintfhostport # checks for misuse of Sprintf to construct a host with port in a URL\n    - perfsprint # checks that fmt.Sprintf can be replaced with a faster alternative\n    - predeclared # finds code that shadows one of Go's predeclared identifiers\n    - promlinter # checks Prometheus metrics naming via promlint\n    - protogetter # reports direct reads from proto message fields when getters should be used\n    - reassign # checks that package variables are not reassigned\n    - revive # fast, configurable, extensible, flexible, and beautiful linter for Go, drop-in replacement of golint\n    - rowserrcheck # checks whether Err of rows is checked successfully\n    - sloglint # ensure consistent code style when using log/slog\n    - spancheck # checks for mistakes with OpenTelemetry/Census spans\n    - sqlclosecheck # checks that sql.Rows and sql.Stmt are closed\n    - stylecheck # is a replacement for golint\n    - testableexamples # checks if examples are testable (have an expected output)\n    - usetesting # detects using os.Setenv instead of t.Setenv since Go1.17 (replaces deprecated tenv)\n    - testifylint # checks usage of github.com/stretchr/testify\n    - testpackage # makes you use a separate _test package\n#    - tparallel # detects inappropriate usage of t.Parallel() method in your Go test codes. Replaced with paralleltest\n    - unconvert # removes unnecessary type conversions\n    - unparam # reports unused function parameters\n    - usestdlibvars # detects the possibility to use variables/constants from the Go standard library\n    - wastedassign # finds wasted assignment statements\n    - whitespace # detects leading and trailing whitespace\n\n    ## you may want to enable\n    - decorder # checks declaration order and count of types, constants, variables and functions\n    #- exhaustruct # [highly recommend to enable] checks if all structure fields are initialized\n    - gci # controls golang package import order and makes it always deterministic\n    #- ginkgolinter # [if you use ginkgo/gomega] enforces standards of using ginkgo and gomega\n    #- godox # detects FIXME, TODO and other comment keywords\n    - goheader # checks is file header matches to pattern\n    #- inamedparam # [great idea, but too strict, need to ignore a lot of cases by default] reports interfaces with unnamed method parameters\n    #- interfacebloat # checks the number of methods inside an interface\n    #- ireturn # accept interfaces, return concrete types\n    - prealloc # [premature optimization, but can be used in some cases] finds slice declarations that could potentially be preallocated\n    #- tagalign # checks that struct tags are well aligned\n    #- varnamelen # [great idea, but too many false positives] checks that the length of a variable's name matches its scope\n    #- wrapcheck # checks that errors returned from external packages are wrapped\n    - zerologlint # detects the wrong usage of zerolog that a user forgets to dispatch zerolog.Event\n\n    ## disabled\n    #- containedctx # detects struct contained context.Context field\n    - contextcheck # [too many false positives] checks the function whether use a non-inherited context\n    #- depguard # [replaced by gomodguard] checks if package imports are in a list of acceptable packages\n    - dogsled # checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())\n    #- dupword # [useless without config] checks for duplicate words in the source code\n    #- err113 # [too strict] checks the errors handling expressions\n    #- errchkjson # [don't see profit + I'm against of omitting errors like in the first example https://github.com/breml/errchkjson] checks types passed to the json encoding functions. Reports unsupported types and optionally reports occasions, where the check for the returned error can be omitted\n    #- execinquery # [deprecated] checks query string in Query function which reads your Go src files and warning it finds\n    #- forcetypeassert # [replaced by errcheck] finds forced type assertions\n    #- gofmt # [replaced by goimports] checks whether code was gofmt-ed\n    #- gofumpt # [replaced by goimports, gofumports is not available yet] checks whether code was gofumpt-ed\n    - gosmopolitan # reports certain i18n/l10n anti-patterns in your Go codebase\n    - grouper # analyzes expression groups\n    - importas # enforces consistent import aliases\n    - maintidx # measures the maintainability index of each function\n    - misspell # [useless] finds commonly misspelled English words in comments\n    #- nlreturn # [too strict and mostly code is not more readable] checks for a new line before return and branch statements to increase code clarity\n    - paralleltest # detects missing usage of t.Parallel() method in your Go test\n    # - tagliatelle # checks the struct tags\n    - thelper # detects golang test helpers without t.Helper() call and checks the consistency of test helpers\n    #- wsl # [too strict and mostly code is not more readable] whitespace linter forces you to use empty lines\n\n\nissues:\n  # Maximum count of issues with the same text.\n  # Set to 0 to disable.\n  # Default: 3\n  max-same-issues: 50\n\n  exclude-rules:\n    - source: \"//noinspection\"\n      linters: [ gocritic ]\n    - path: \"_test\\\\.go\"\n      linters:\n        - bodyclose\n        - dupl\n        - funlen\n        - goconst\n        - gosec\n        - noctx\n        - wrapcheck\n        - gochecknoglobals\n    # We exclude thelper for consensus types due to the usage of runForAllSupportedVersions where thelper falsely misses the usage of t.Helper()\n    - path: \"^consensus-types/types/.*\\\\.go$\"\n      linters:\n        - thelper\n  exclude-files:\n    - \"pkg/cometbft/cli/.*\\\\.go\"\n    - \"pkg/cometbft/service/server/.*\\\\.go\"\n    # Copied/adapted from go-ethereum (geth); not worth linting.\n    - \"geth-primitives/types/.*\\\\.go\""
  },
  {
    "path": ".mockery.yaml",
    "content": "# SPDX-License-Identifier: MIT\n#\n# Copyright (c) 2025 Berachain Foundation\n#\n# Permission is hereby granted, free of charge, to any person\n# obtaining a copy of this software and associated documentation\n# files (the \"Software\"), to deal in the Software without\n# restriction, including without limitation the rights to use,\n# copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the\n# Software is furnished to do so, subject to the following\n# conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n# OTHER DEALINGS IN THE SOFTWARE.\n\ndir: \"{{.InterfaceDir}}/mocks\"\nmockname: \"{{.InterfaceNameCamel}}\"\nfilename: \"{{.InterfaceNameSnake}}.mock.go\"\noutpkg: \"mocks\"\nresolve-type-alias: False # see https://vektra.github.io/mockery/latest/deprecations/#resolve-type-alias\nissue-845-fix: True # see https://vektra.github.io/mockery/latest/deprecations/#issue-845-fix\npackages:\n  github.com/berachain/beacon-kit/execution/client/ethclient:\n    config:\n      recursive: True\n      with-expecter: true\n      include-regex: GethRPCClient\n  github.com/berachain/beacon-kit/node-core/services/registry:\n    config:\n      recursive: True\n      with-expecter: true\n      all: True\n  github.com/berachain/beacon-kit/storage/interfaces:\n    config:\n      recursive: False\n      with-expecter: true\n      all: True\n  github.com/berachain/beacon-kit/consensus-types/types:\n    config:\n      recursive: False\n      with-expecter: true\n      all: True\n  github.com/berachain/beacon-kit/storage/pruner:\n    config:\n      recursive: False\n      with-expecter: true\n      all: True\n  github.com/berachain/beacon-kit/primitives/crypto:\n    config:\n      recursive: False\n      with-expecter: true\n      all: True\n  github.com/berachain/beacon-kit/engine-primitives/engine-primitives:\n    config:\n      recursive: False\n      with-expecter: true\n      all: True\n  github.com/berachain/beacon-kit/state-transition/core:\n    config:\n      recursive: False\n      with-expecter: true\n      include-regex: ExecutionEngine\n  github.com/berachain/beacon-kit/beacon/blockchain:\n    config:\n      recursive: False\n      with-expecter: true\n      include-regex: LocalBuilder|StorageBackend\n  github.com/berachain/beacon-kit/node-api/handlers/beacon:\n    config:\n      recursive: False\n      with-expecter: true\n      include-regex: ^Backend$\n  github.com/berachain/beacon-kit/node-api/handlers/node:\n    config:\n      recursive: False\n      with-expecter: true\n      include-regex: ^Backend$\n  github.com/berachain/beacon-kit/node-api/backend:\n    config:\n      recursive: False\n      with-expecter: true\n      include-regex: GenesisStateProcessor\n  github.com/berachain/beacon-kit/node-core/types:\n    config:\n      recursive: False\n      with-expecter: true\n      include-regex: ConsensusService\n"
  },
  {
    "path": ".vscode/launch.json",
    "content": "{\n    \"version\": \"0.2.0\",\n    \"configurations\": [\n        {\n            \"name\": \"Init local devnet\",\n            \"type\": \"go\",\n            \"request\": \"launch\",\n            \"preLaunchTask\": \"build\",\n            \"mode\": \"exec\",\n            \"program\": \"${workspaceFolder}/build/bin/beacond\",\n            \"args\": [\n                \"init\",\n                \"localtestnet\",\n                \"--beacon-kit.chain-spec=devnet\",\n                \"--chain-id=beacond-2061\",\n                \"--home=${workspaceFolder}/.tmp/beacond\",\n            ],\n            \"internalConsoleOptions\": \"openOnSessionStart\",\n            \"presentation\": {\n                \"group\": \"initialize\",\n                \"order\": 1\n            },\n        },\n        {\n            \"name\": \"Add premined deposit\",\n            \"type\": \"go\",\n            \"request\": \"launch\",\n            \"mode\": \"exec\",\n            \"program\": \"${workspaceFolder}/build/bin/beacond\",\n            \"preLaunchTask\": \"build\",\n            \"args\": [\n                \"genesis\",\n                \"add-premined-deposit\",\n                \"32000000000\",\n                \"0x20f33ce90a13a4b5e7697e3544c3083b8f8a51d4\",\n                \"--beacon-kit.chain-spec=devnet\",\n                \"--home=${workspaceFolder}/.tmp/beacond\",\n            ],\n            \"internalConsoleOptions\": \"openOnSessionStart\",\n            \"presentation\": {\n                \"group\": \"initialize\",\n                \"order\": 2\n            },\n        },\n        {\n            \"name\": \"Collect premined deposit\",\n            \"type\": \"go\",\n            \"request\": \"launch\",\n            \"preLaunchTask\": \"build\",\n            \"mode\": \"exec\",\n            \"program\": \"${workspaceFolder}/build/bin/beacond\",\n            \"args\": [\n                \"genesis\",\n                \"collect-premined-deposits\",\n                \"--beacon-kit.chain-spec=devnet\",\n                \"--home=${workspaceFolder}/.tmp/beacond\",\n            ],\n            \"internalConsoleOptions\": \"openOnSessionStart\",\n            \"presentation\": {\n                \"group\": \"initialize\",\n                \"order\": 3\n            },\n        },\n        {\n            \"name\": \"Set deposit storage\",\n            \"type\": \"go\",\n            \"request\": \"launch\",\n            \"preLaunchTask\": \"build\",\n            \"mode\": \"exec\",\n            \"program\": \"${workspaceFolder}/build/bin/beacond\",\n            \"args\": [\n                \"genesis\",\n                \"set-deposit-storage\",\n                \"${workspaceFolder}/testing/files/eth-genesis.json\",\n                \"--beacon-kit.chain-spec=devnet\",\n                \"--home=${workspaceFolder}/.tmp/beacond\",\n            ],\n            \"internalConsoleOptions\": \"openOnSessionStart\",\n            \"presentation\": {\n                \"group\": \"initialize\",\n                \"order\": 4\n            },\n        },\n        {\n            \"name\": \"Genesis execution payload\",\n            \"type\": \"go\",\n            \"request\": \"launch\",\n            \"preLaunchTask\": \"build\",\n            \"mode\": \"exec\",\n            \"program\": \"${workspaceFolder}/build/bin/beacond\",\n            \"args\": [\n                \"genesis\",\n                \"execution-payload\",\n                \"${workspaceFolder}/.tmp/beacond/eth-genesis.json\",\n                \"--beacon-kit.chain-spec=devnet\",\n                \"--home=${workspaceFolder}/.tmp/beacond\",\n            ],\n            \"internalConsoleOptions\": \"openOnSessionStart\",\n            \"presentation\": {\n                \"group\": \"initialize\",\n                \"order\": 5\n            },\n        },\n        {\n            \"name\": \"Start beacond (mainnet)\",\n            \"type\": \"go\",\n            \"request\": \"launch\",\n            \"preLaunchTask\": \"build\",\n            \"mode\": \"exec\",\n            \"program\": \"${workspaceFolder}/build/bin/beacond\",\n            \"args\": [\n                \"start\",\n                \"--pruning=nothing\",\n                \"--beacon-kit.chain-spec=mainnet\",\n                \"--beacon-kit.logger.log-level=info\",\n                \"--home=${workspaceFolder}/.tmp/beacond\",\n                \"--beacon-kit.engine.jwt-secret-path=${workspaceFolder}/testing/files/jwt.hex\",\n                \"--beacon-kit.node-api.enabled\",\n                \"--beacon-kit.node-api.logging\",\n            ],\n            \"internalConsoleOptions\": \"openOnSessionStart\",\n            \"presentation\": {\n                \"group\": \"run\",\n                \"order\": 1\n            },\n            \"suppressMultipleSessionWarning\": true,\n        },\n        {\n            \"name\": \"Start beacond (devnet)\",\n            \"type\": \"go\",\n            \"request\": \"launch\",\n            \"preLaunchTask\": \"build\",\n            \"mode\": \"exec\",\n            \"program\": \"${workspaceFolder}/build/bin/beacond\",\n            \"args\": [\n                \"start\",\n                \"--pruning=nothing\",\n                \"--beacon-kit.chain-spec=devnet\",\n                \"--beacon-kit.logger.log-level=info\",\n                \"--home=${workspaceFolder}/.tmp/beacond\",\n                \"--beacon-kit.engine.jwt-secret-path=${workspaceFolder}/testing/files/jwt.hex\",\n                \"--beacon-kit.node-api.enabled\",\n                \"--beacon-kit.node-api.logging\",\n            ],\n            \"internalConsoleOptions\": \"openOnSessionStart\",\n            \"presentation\": {\n                \"group\": \"run\",\n                \"order\": 2\n            },\n            \"suppressMultipleSessionWarning\": true,\n        }\n    ]\n}"
  },
  {
    "path": ".vscode/tasks.json",
    "content": "{\n    \"version\": \"2.0.0\",\n    \"tasks\": [\n        {\n            \"label\": \"build\",\n            \"type\": \"shell\",\n            \"command\": \"make build COSMOS_BUILD_OPTIONS=nostrip\",\n            \"presentation\": {\n                \"close\": true\n            }\n        }\n    ]\n}"
  },
  {
    "path": "CLAUDE.md",
    "content": "# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Introduction & Overview\n\nBeaconKit is a modular consensus client implementation that uses a modified CometBFT (Tendermint) for consensus instead of the standard Ethereum beacon chain consensus. It implements the Ethereum consensus layer specification while supporting all major Ethereum execution clients through the Engine API.\n\n### Key Differences from Standard Ethereum\n- **Consensus**: Uses CometBFT's Tendermint consensus instead of Ethereum's LMD-GHOST + Casper FFG\n- **Block Timing**: No fixed 12-second slots; uses timeout-based rounds\n- **Validator Set**: Custom validator set cap implementation\n- **Block Heights**: Sequential without gaps (CometBFT height = beacon slot)\n- **No Missed Slots**: Every height produces a block eventually through round-based consensus\n\n## Project Structure\n\n### Key Directories\n- `/beacon/` - Core beacon chain logic (blockchain service, validator service, payload coordination)\n- `/chain/` - Chain specifications and helpers (spec interfaces, network configs, genesis generation)\n- `/cli/` - CLI commands and configuration (all beacond commands, flag definitions)\n- `/config/` - Configuration management (TOML templates, default configs)\n- `/consensus-types/` - Consensus layer types (blocks, states, validators, SSZ serialization)\n- `/contracts/` - Solidity contracts (deposit contract, staking, Go bindings)\n- `/da/` - Data availability layer (blob management, KZG commitments, proofs)\n- `/engine-primitives/` - Execution engine types (Engine API types, payloads, withdrawals)\n- `/execution/` - Execution client integration (Engine API client, deposit syncing)\n- `/node-api/` - REST API implementation (beacon API handlers, server setup)\n- `/node-core/` - Core node infrastructure (DI components, service registry, node builder)\n- `/primitives/` - Basic types and constants (Slot, Gwei, ValidatorIndex, crypto primitives)\n- `/state-transition/` - State transition logic (state machine, fork transitions, operations)\n- `/storage/` - Database and storage backends (beacon DB, block store, blob store, pruning)\n- `/testing/` - Test utilities and networks (e2e tests, simulations, test fixtures)\n\n### Configuration Files\n- Home directory: `~/.beacond` (or `.tmp/beacond` for local testing)\n- Config files: `config.toml`, `app.toml`, `client.toml`, `genesis.json`\n- Configuration sections in `config.toml`:\n  - `beacon-kit.engine` - Execution client settings\n  - `beacon-kit.logger` - Logging configuration\n  - `beacon-kit.kzg` - KZG trusted setup\n  - `beacon-kit.payload-builder` - Block building\n  - `beacon-kit.validator` - Validator settings\n  - `beacon-kit.block-store-service` - Block storage\n  - `beacon-kit.node-api` - API server settings\n\n## Development Commands\n\n### Building\n```bash\nmake build                    # Build beacond binary to build/bin/beacond\nmake build-docker            # Build Docker image\nmake install                 # Install beacond to $GOPATH/bin\n```\n\n### Running\n```bash\nmake start                   # Start ephemeral devnet node (chain ID: 80087)\nmake start-custom <spec>     # Start with custom chain spec TOML file\nmake start-<client>          # Start execution client (reth/geth/nethermind/besu/erigon/ethereumjs)\n```\nNote: Always start the beacon node before the execution client, as it generates the required genesis configuration.\n\n### Testing\n```bash\nmake test                    # Run all tests (unit + forge)\nmake test-unit               # Run unit tests with coverage\nmake test-unit-no-coverage   # Run unit tests without coverage\nmake test-unit-bench         # Run benchmarks\nmake test-unit-fuzz          # Run Go fuzz tests\nmake test-simulated          # Run simulation tests (chaos, forks)\nmake test-e2e                # Run e2e tests (builds Docker first)\nmake test-forge-cover        # Run Solidity tests with coverage\n```\n\n### Linting & Formatting\n```bash\nmake lint                    # Run all linters\nmake format                  # Run all formatters\nmake golangci-fix            # Auto-fix linting issues\nmake gosec                   # Run security scanner\nmake nilaway                 # Run nil pointer checker\n```\n\n### Code Generation\n```bash\nmake generate                # Run all code generation\nmake proto                   # Generate protobuf code\nmake generate-check          # Verify generated code is up to date\n```\n\n## Environment Variables\n\nBeaconKit uses Viper for configuration management, which supports environment variables with automatic binding.\n\n### Environment Variable Configuration\n- **Prefix**: Configured per application (e.g., `BEACOND_` for the main beacon daemon)\n- **Key Mapping**: Configuration keys are transformed for environment variables:\n  - Dots (`.`) are replaced with underscores (`_`)\n  - Hyphens (`-`) are replaced with underscores (`_`)\n  - All keys are uppercased\n- **Auto-binding**: Environment variables are automatically bound using `viper.AutomaticEnv()`\n\n### Configuration Precedence\nThe configuration system follows this precedence order (highest to lowest):\n1. **CLI flags** - Command-line arguments override everything\n2. **Environment variables** - Override config file values\n3. **Config file** - Values from `config.toml`, `app.toml`, etc.\n4. **Default values** - Hardcoded defaults in the application\n\n### Implementation Details\n\nThe environment variable system is initialized in `cli/commands/server/cmd/execute.go`:\n\n```go\nviper.SetEnvPrefix(envPrefix)\nviper.SetEnvKeyReplacer(strings.NewReplacer(\".\", \"_\", \"-\", \"_\"))\nviper.AutomaticEnv()\n```\n\nThis setup ensures that:\n- All environment variables with the configured prefix are automatically recognized\n- Configuration keys are properly mapped to environment variable names\n- Values from environment variables override configuration file values\n\n## CLI Usage\n\n### beacond Commands\n```bash\nbeacond init                                    # Initialize a new node\nbeacond start                                   # Start the beacon node\nbeacond rollback                                # Rollback blockchain state\nbeacond genesis add-premined-deposit            # Add premined deposits to genesis\nbeacond genesis collect-premined-deposits       # Collect premined deposits\nbeacond genesis set-deposit-storage             # Set deposit contract storage\nbeacond genesis execution-payload               # Generate execution payload\nbeacond deposit create-validator                # Create validator deposit\n```\n\n### Key Flags\n```bash\n--beacon-kit.chain-spec <spec>                  # Chain spec: devnet/testnet/mainnet\n--beacon-kit.chain-spec-file <path>             # Custom chain spec TOML file\n--beacon-kit.engine.jwt-secret-path <path>      # JWT secret for EL auth\n--beacon-kit.engine.rpc-dial-url <url>          # Execution client RPC URL\n--beacon-kit.kzg.trusted-setup-path <path>      # KZG trusted setup file\n--beacon-kit.node-api.enabled                   # Enable REST API\n--home <path>                                   # Node home directory (default: ~/.beacond)\n```\n\n## Network Specifications\n\n### Supported Networks\n- **Devnet** - Chain ID: 80087 (local development)\n- **Testnet/Bepolia** - Chain ID: 80069 (public testnet)\n- **Mainnet** - Chain ID: 80094 (production)\n\nNetwork configurations are in `testing/networks/<chain-id>/`\n\n## Architecture Overview\n\nBeaconKit implements a modular EVM consensus client using a modified CometBFT for consensus and supporting all major Ethereum execution clients through the Engine API.\n\n### System Architecture\n\n```\n┌───────────────────────────────────────────────────────────────┐\n│                      Service Registry                         │\n│              (Lifecycle orchestrator for all services)        │\n│  Startup Order:                                               │\n│  1. ShutdownService → 2. ValidatorService → 3. NodeAPIServer  │\n│  4. ReportingService → 5. TelemetryService → 6. EngineClient  │\n│  7. ChainService → 8. CometBFTService                         │\n└──────────────────────────────┬────────────────────────────────┘\n                               │ manages lifecycle\n                               ▼\n                ┌─────────────────────────────────────┐\n                │         CometBFT Service            │\n                │  (Consensus orchestrator via P2P)   │\n                │  ┌─────────────────────────────┐    │\n                │  │ ABCI++ Interface:           │    │\n                │  │ • Info                      │    │\n                │  │ • InitChain                 │    │\n                │  │ • PrepareProposal           │    │\n                │  │ • ProcessProposal           │    │\n                │  │ • FinalizeBlock             │    │\n                │  │ • Commit                    │    │\n                │  └─────────────────────────────┘    │\n                └───────────────┬─────────────────────┘\n                                │\n            PrepareProposal     │    ProcessProposal/FinalizeBlock\n                    ┌───────────┴─────────┐\n                    ▼                     ▼\n        ┌─────────────────────┐ ┌────────────────────┐\n        │  Validator Service  │ │ Blockchain Service │\n        │  (Block builder)    │ │ (Block processor)  │\n        │ ┌─────────────────┐ │ │ ┌────────────────┐ │\n        │ │ • StateProcessor│ │ │ │• StateProcessor│ │\n        │ │ • BlobFactory   │ │ │ │• BlobProcessor │ │\n        │ │ • PayloadBuilder│ │ │ │• LocalBuilder  │ │\n        │ │ • Signer        │ │ │ │• DepositFetcher│ │\n        │ └─────────────────┘ │ │ └────────────────┘ │\n        └──────────┬──────────┘ └────────┬───────────┘\n                   │                     │\n                   │ both use            │ both use\n                   ▼                     ▼\n        ┌────────────────────────────────────────┐\n        │         Execution Engine               │\n        │   (Engine API client wrapper)          │\n        │  • forkchoiceUpdate                    │\n        │  • newPayload / getPayload             │\n        └──────────────┬─────────────────────────┘\n                       │ communicates with\n                       ▼\n                External EL Client\n                (Geth/Reth/etc.)\n\n┌───────────────────────────────────────────────────────────────┐\n│                      Storage Backend                          │\n│                 (Shared data layer - DI injected)             │\n│  ┌────────────┐ ┌───────────┐ ┌─────────────────┐ ┌────────┐  │\n│  │ BlockStore │ │ BeaconDB  │ │AvailabilityStore│ │Deposit │  │\n│  │            │ │ (StateDB) │ │ (Blob storage)  │ │Store   │  │\n│  └────────────┘ └───────────┘ └─────────────────┘ └────────┘  │\n└────────────────────────┬──────────────────────────────────────┘\n                         │ accessed by\n     ┌───────────────────┼───────────────────┐\n     │                   │                   │\n     ▼                   ▼                   ▼\n┌─────────────┐ ┌─────────────────┐ ┌───────────────┐\n│ Node API    │ │ Validator       │ │ Blockchain    │\n│ Server      │ │ Service         │ │ Service       │\n│(REST/HTTP)  │ │                 │ │               │\n└─────────────┘ └─────────────────┘ └───────────────┘\n\nAsync Background Process:\n┌────────────────────────────────────────────────────┐\n│            Deposit Monitoring Flow                 │\n│  Execution Layer → Deposit Contract → DepositStore │\n└────────────────────────────────────────────────────┘\n```\n\n**System Flow:**\n1. **Service Registry** manages the lifecycle of all services in dependency order\n2. **CometBFT Service** drives the entire system through ABCI callbacks\n3. **Block Building**: CometBFT → PrepareProposal → Validator Service\n4. **Block Processing**: CometBFT → ProcessProposal/FinalizeBlock → Blockchain Service\n5. **State Updates**: Blockchain Service → State Processor → Storage Backend\n6. **External Queries**: Node API → Storage Backend (independent of consensus flow)\n\n**Key Facts:**\n- Service Registry orchestrates startup/shutdown in correct order\n- CometBFT is the consensus driver, not a middle layer\n- Storage Backend is a passive resource, not an active service\n- Node API runs independently, only queries storage\n- Execution Engine communicates with external EL clients\n- Services must wait for dependencies (e.g., EngineClient blocks until EL is ready)\n\n### Core Components\n\n**beacon/** - Consensus layer implementation\n- `blockchain/`: Core service handling block processing, state transitions, fork choice\n  - Integrates with execution engine via Engine API\n  - Manages block and blob storage\n  - Handles deposit processing from execution layer\n- `validator/`: Block building and validation\n  - Payload building coordination with execution client\n  - Blob sidecar creation and bundling\n  - Block proposal generation for CometBFT\n\n**state-transition/** - Beacon chain state transitions\n- Core state machine implementing Ethereum consensus specs\n- Handles validator lifecycle: activation, exits, slashing\n- Processes operations: deposits, withdrawals, attestations\n- Fork transition logic (Deneb → Electra)\n- Custom modifications: validator set cap, churn rules\n\n**node-core/** - Infrastructure and dependency injection\n- `components/`: All service providers for DI\n  - Each component has a `Provide*` function\n  - Dependencies declared via struct tags\n- `services/registry/`: Service lifecycle management\n  - Start/stop ordering based on dependencies\n  - Graceful shutdown handling\n- `builder/`: Node assembly and configuration\n\n**execution/** - Execution client integration\n- `client/`: Engine API implementation\n  - JWT authenticated HTTP client\n  - Retry logic with exponential backoff\n  - Error classification (fatal vs retryable)\n- `deposit/`: Deposit contract monitoring\n  - Syncs deposits from execution layer\n  - Manages deposit Merkle tree\n- Supports all major EL clients via standard Engine API\n\n**storage/** - Multi-layered persistence\n- `beacondb/`: State storage with context management\n  - Fork-aware state queries\n  - Validator and balance lookups\n- `blockstore/`: KV store for beacon blocks\n  - Indexed by slot number\n  - Range query support\n- `availabilitystore/`: Blob sidecar storage\n  - TTL-based pruning (availability window)\n  - Indexed by block root and index\n- `depositstore/`: Deposit event tracking\n  - Synced from execution layer logs\n\n**consensus-types/** - Core type definitions\n- Beacon chain types: blocks, states, validators\n- Fork-specific types with version handling\n- SSZ serialization for all consensus types\n- Generic interfaces for fork compatibility\n\n**da/** - Data availability layer\n- `blob/`: Blob and sidecar management\n  - KZG commitment verification\n  - Blob to sidecar transformation\n- `kzg/`: KZG ceremony integration\n  - Trusted setup loading\n  - Proof generation and verification\n\n### Data Flow Patterns\n\n#### Block Production Flow\n1. CometBFT calls `PrepareProposal` when node is proposer\n2. Validator service initiates payload building:\n   - Checks for cached FCU response first\n   - If no cache: sends FCU with payload attributes to execution engine\n   - Receives payload ID for tracking\n3. Block assembly:\n   - Waits briefly then calls `getPayload` to retrieve execution payload\n   - Creates blob sidecars from blob transactions\n   - Assembles beacon block with payload\n4. Returns complete block to CometBFT for proposal\n\n#### Block Processing Flow\n1. CometBFT calls `ProcessProposal` with new block\n2. Blockchain service validates block structure\n3. Blob processor verifies:\n   - KZG proofs for all blobs\n   - Blob count within limits\n4. State processor performs validation\n5. Execution engine validates via `newPayload`\n6. Vote to accept/reject returned to CometBFT\n\n#### State Finalization Flow\n1. CometBFT calls `FinalizeBlock` after consensus\n2. State processor executes full state transition:\n   - Process slots up to block slot\n   - Apply block operations\n   - Update validator balances\n3. Storage backends persist:\n   - Updated beacon state\n   - Block and sidecars\n   - State root mappings\n4. Post-block FCU updates execution engine head\n\n### Critical Paths\n\n**Block Production (must complete in ~1s):**\n1. Initiate payload building immediately\n2. Parallel assembly of beacon block components\n3. Timeout handling for slow execution clients\n\n**Block Validation (must complete quickly):**\n1. Structural validation first (fail fast)\n2. Parallel blob verification\n3. Execution payload validation last\n\n**State Transitions (deterministic execution):**\n1. Slot processing (RANDAO, proposer selection)\n2. Block processing (operations in order)\n3. Epoch processing (validator updates)\n\n## Key Types and Interfaces\n\n### Core Interfaces\n- `ChainSpec` - Chain specification interface\n- `BeaconState` - Beacon chain state\n- `ExecutionPayload` - Execution layer payload\n- `AvailabilityStore` - Blob storage interface\n- `DepositStore` - Deposit storage interface\n- `BlockStore` - Block storage interface\n- `StateProcessor` - State transition processor\n\n### Important Types\n- `types.BeaconBlock` - Beacon block structure\n- `types.Validator` - Validator information\n- `types.Deposit` - Deposit data\n- `engine.ExecutionEngine` - Execution engine client\n- `payload.PayloadBuilder` - Local payload builder\n\n### Key Abstractions\n\n**StorageBackend Interface:**\n```go\ntype StorageBackend interface {\n    AvailabilityStore() AvailabilityStore\n    BlockStore() BlockStore\n    DepositStore() DepositStore\n    StateFromContext(ctx context.Context) BeaconState\n}\n```\n\n**StateProcessor Interface:**\n```go\ntype StateProcessor interface {\n    ProcessSlot(BeaconState) (TransitionResult, error)\n    ProcessBlock(BeaconState, BeaconBlock) (BeaconState, error)\n    ProcessEpoch(BeaconState) (TransitionResult, error)\n}\n```\n\n**ExecutionEngine Interface:**\n```go\ntype ExecutionEngine interface {\n    NewPayload(ctx, payload, versionedHashes) (PayloadStatus, error)\n    ForkchoiceUpdate(ctx, state, attrs) (ForkchoiceResponse, error)\n    GetPayload(ctx, payloadID) (ExecutionPayload, error)\n}\n```\n\n## Integration Patterns\n\n### CometBFT Integration (ABCI++)\n\nBeaconKit integrates with CometBFT through ABCI++ hooks:\n\n```go\n// Key integration points in beacon/blockchain/service.go\nPrepareProposal(ctx, req) (*ProposalResponse, error)  // Build blocks\nProcessProposal(ctx, req) (*ProcessResponse, error)   // Validate blocks\nFinalizeBlock(ctx, req) (*BlockResponse, error)      // Execute state transition\n```\n\n**Important:** BeaconKit maps 1 beacon slot = 1 CometBFT height (no missed slots)\n\n### Execution Engine Integration\n\nCommunication with execution clients via Engine API:\n\n```go\n// Engine API flow for block production\n1. forkchoiceUpdate(head, safe, finalized, payloadAttributes) → payloadId\n2. getPayload(payloadId) → executionPayload + blobsBundle\n3. newPayload(executionPayload) → status\n4. forkchoiceUpdate(newHead, safe, finalized) → status\n```\n\n**Key Files:**\n- `execution/client/client.go` - Main Engine API client\n- `execution/client/errors.go` - Error handling and retries\n- `execution/pkg/engine/helpers.go` - Request/response helpers\n\n### State Management Integration\n\nState transitions follow a specific pattern:\n\n```go\n// State transition pipeline\nctx := state.Context()\nstate = processSlots(state, targetSlot)\nif isEpochEnd(slot) {\n    state = processEpoch(state)\n}\nstate = processBlock(state, block)\n// Changes are cached and only flushed to disk on Finalize/Commit\nstorage.SetState(ctx, state)\n```\n\n**Context Usage:** All state queries use context for fork-awareness\n\n### Storage Layer Integration\n\nMulti-backend storage with clear interfaces:\n\n```go\n// Storage access pattern\nbackend := node.StorageBackend()\nstate := backend.StateFromContext(ctx)\nblock := backend.BlockStore().GetBySlot(slot)\nblobs := backend.AvailabilityStore().Get(blockRoot)\ndeposits := backend.DepositStore().GetAll()\n```\n\n### Service Lifecycle Integration\n\nServices follow a strict lifecycle pattern:\n\n```go\ntype Service interface {\n    Start(context.Context) error\n    Stop() error\n    Name() string\n}\n```\n\n**Startup Order:**\n1. Storage backends initialized\n2. Core services created via DI\n3. Services started in dependency order\n4. CometBFT node started last\n\n**Shutdown:** Reverse order with graceful termination\n\n### Configuration Integration\n\nConfiguration flows through the system:\n\n```toml\n# config.toml structure\n[beacon-kit]\n  [beacon-kit.engine]\n    jwt-secret-path = \"path/to/jwt.hex\"\n    rpc-dial-url = \"http://localhost:8551\"\n\n  [beacon-kit.payload-builder]\n    enabled = true\n```\n\n**Environment Overrides:** CLI flags > env vars > config file > defaults\n\n## Block Height Lifecycle\n\nThis section describes how BeaconKit processes blocks using CometBFT's Tendermint consensus algorithm.\n\n### Key Differences from Ethereum\n- **Timeout-Based Timing**: No fixed slot duration; block time depends on consensus timeouts and network conditions\n- **Sequential Heights**: CometBFT maintains sequential block heights without gaps (unlike Ethereum's slot system)\n- **Round-Based Consensus**: Multiple proposers per height if rounds fail\n- **Height = Slot**: CometBFT height maps 1:1 to beacon slot number\n\n### Consensus Timing Configuration\nBeaconKit configures timeout values for CometBFT consensus:\n- **TimeoutCommit**: 500ms minimum - Post-commit wait time (enforced minimum)\n- **TimeoutPropose**: 2000ms maximum - Initial proposal timeout (enforced maximum)\n- **TimeoutPrevote**: 2000ms maximum - Prevote collection timeout (enforced maximum)\n- **TimeoutPrecommit**: 2000ms maximum - Precommit collection timeout (enforced maximum)\n\n**Note**: Only TimeoutCommit has an enforced minimum. The other timeouts have enforced maximums. Actual block times depend on:\n- Network latency and message propagation\n- Number of consensus rounds needed (failed rounds extend time)\n- Execution client response times\n- Validator participation and vote collection speed\n\n### CometBFT Round-Based Consensus\n\n**Key Concept**: CometBFT uses rounds within each height. If consensus fails, it increments the round (not the height) and selects a new proposer.\n\n```\nHeight N, Round 0: Proposer A fails/times out\nHeight N, Round 1: Proposer B tries\nHeight N, Round 2: Proposer C succeeds → Height N+1\n```\n\n### ABCI Method Flow\n\n#### 1. Block Proposal (PrepareProposal)\n**When**: Node is selected as proposer for current height/round\n**Called on**: Proposer node only\n**Can be called**: Multiple times per height (once per round if timeouts occur)\n\n**Steps**:\n1. CometBFT calls `PrepareProposal` with height and round info\n2. State is reset if this is a subsequent round (handles timeouts)\n3. `ValidatorService.BuildBlockAndSidecars()` executes:\n   - Sends `forkchoiceUpdate` with attributes to execution client\n   - Receives payload ID\n   - Calls `getPayload()` to retrieve execution payload\n   - `BlobFactory` creates blob sidecars\n4. Returns proposed block to CometBFT\n\n#### 2. Block Validation (ProcessProposal)\n**When**: Any node (including proposer) receives a proposed block\n**Called on**: ALL nodes\n**Purpose**: Validate proposal before voting\n\n**Steps**:\n1. CometBFT calls `ProcessProposal` with proposed block\n2. Resets `finalizeBlockState` in preparation\n3. Blockchain Service validates:\n   - Block structure and signatures\n   - `BlobProcessor` verifies KZG proofs\n   - Execution engine validates via `newPayload` (but doesn't commit)\n4. Returns ACCEPT or REJECT to CometBFT\n\n#### 3. Consensus Voting Rounds\n**After ProcessProposal returns ACCEPT**:\n\n1. **Prevote Phase**:\n   - Validators broadcast prevotes for the proposal\n   - Wait up to TimeoutPrevote for 2/3+ prevotes\n\n2. **Precommit Phase**:\n   - If 2/3+ prevotes received, broadcast precommit\n   - Wait up to TimeoutPrecommit for 2/3+ precommits\n\n3. **Commit Decision**:\n   - If 2/3+ precommits received, block is decided\n   - Wait TimeoutCommit before moving to next height\n\nIf any phase fails/times out → new round at same height\n\n#### 4. Block Finalization (FinalizeBlock)\n**When**: After consensus achieved (2/3+ precommits)\n**Called on**: ALL nodes\n**Called**: Exactly once per height (not per round)\n\n**Steps**:\n1. CometBFT calls `FinalizeBlock` with decided block\n2. State Processor executes state transition:\n   - Applies all block operations\n   - Updates validator balances and registry\n   - Processes epoch transitions if applicable\n3. Commits to storage:\n   - Beacon state → BeaconDB\n   - Block → BlockStore\n   - Blob sidecars → AvailabilityStore\n4. Sends post-finalization `forkchoiceUpdate` to execution client\n5. CometBFT advances to next height\n\n### Important Characteristics\n\n**Height Progression**:\n- Heights only increment after successful FinalizeBlock\n- Multiple rounds can occur at the same height\n- Each round gets a new proposer (deterministic selection)\n\n**State Management**:\n- ProcessProposal validates but doesn't commit\n- FinalizeBlock performs actual state mutations\n- State can be reset between rounds at same height\n\n**Sequential Block Heights**:\n- BeaconKit's `ProcessSlots` called for every sequential height\n- No gaps in block heights (unlike Ethereum's slot system)\n- Failed proposals trigger new rounds at same height, not height skips\n\n### Failure Scenarios\n\n- **Proposer Timeout**: New round with different proposer at same height\n- **Invalid Proposal**: Rejected in ProcessProposal, new round begins\n- **Insufficient Votes**: Timeout triggers new round\n- **Network Partition**: Consensus halts until 2/3+ validators connected\n- **Execution Client Issues**: Proposal fails, new round attempted\n\nThis architecture ensures continuous block production through CometBFT's robust round-based consensus, maintaining Byzantine fault tolerance with up to 1/3 malicious validators.\n\n### Critical Integration Points\n\n1. **Block Production Timing:**\n   - Must complete within slot duration\n   - Timeout handling for slow execution clients\n   - Parallel preparation of components\n\n2. **State Consistency:**\n   - CometBFT app hash = beacon state root\n   - Execution payload state root verification\n   - Fork choice alignment with execution client\n\n3. **Deposit Bridge:**\n   - Monitors execution layer deposit events\n   - Maintains deposit Merkle tree\n   - Synchronizes with beacon state\n\n4. **Blob Handling:**\n   - KZG verification in consensus layer\n   - Blob propagation separate from blocks\n   - Pruning after availability window\n\n### Component Dependencies\n\nThe system uses `cosmossdk.io/depinject` for dependency injection:\n\n```go\n// Example component provider\nfunc ProvideBlockchainService(\n    in struct {\n        depinject.In\n        ChainSpec    chain.ChainSpec\n        ExecutionEngine ExecutionEngine\n        LocalBuilder    LocalBuilder\n        StateProcessor  StateProcessor\n        StorageBackend  StorageBackend\n        TelemetrySink   TelemetrySink\n    },\n) *Service {\n    // Component initialization\n}\n```\n\n**Dependency Graph:**\n- Node → CometBFT Service → Blockchain Service\n- Blockchain → State Processor, Execution Engine, Storage\n- State Processor → Chain Spec, Execution Engine\n- All components → Logger, Metrics, Config\n\n## Storage Architecture\n\n**Multi-Backend Approach:**\n1. **CometBFT State**: Application state via IAVL trees\n2. **BeaconDB**: Beacon state indexed by StateRoot\n3. **BlockStore**: Blocks indexed by slot\n4. **AvailabilityStore**: Blobs with pruning\n5. **FileDB**: Generic KV store implementation\n\n**State Management:**\n- StateDB provides high-level API\n- Context-based forking for speculation\n- Lazy loading for performance\n- Cache layers for hot data\n\n## Error Handling\n\n- Custom error wrapper in `errors/mod.go`\n- Fatal vs non-fatal errors with `IsFatal()` checks\n- Consistent error wrapping with context\n- Detailed error types for different failure modes\n\n## Build Requirements\n\n### Dependencies\n- Go\n- Docker (for running EL clients)\n- Foundry (for Solidity contracts)\n- Make (GNU Make)\n\n### Build Tags\n- `bls12381` - BLS cryptography\n- `test` - Testing utilities\n- `e2e` - End-to-end tests\n- `simulated` - Simulation tests\n\n### Key Constants\n- `RootLength = 32` - Hash tree root length\n- Default RPC timeout: 30s\n- Default shutdown timeout: 5 minutes\n- Block store availability window: configurable via chain spec\n\n## Development Considerations\n\n### Key Design Patterns\n\n1. **Interface Segregation**: Small, focused interfaces for each concern\n2. **Dependency Injection**: All wiring via DI container, no global state\n3. **Context Propagation**: Request-scoped values and cancellation\n4. **Error Wrapping**: Detailed context preservation with error chains\n5. **Metrics-First**: Every operation instrumented with Prometheus\n6. **Defensive Validation**: Validate early, validate often\n7. **Fork Abstraction**: Generic types handle fork differences\n\n### Testing Approach\n\n- Unit tests alongside code files (`*_test.go`)\n- Simulated tests for chaos/fork scenarios in `testing/`\n- E2E tests with real execution clients in `testing/e2e/`\n- Kurtosis for multi-node testing scenarios\n"
  },
  {
    "path": "CODEOWNERS",
    "content": "*     @berachain/core-admin\n"
  },
  {
    "path": "Dockerfile",
    "content": "# syntax=docker/dockerfile:1\n#\n# Copyright (C) 2022, Berachain Foundation. All rights reserved.\n# See the file LICENSE for licensing terms.\n#\n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n#######################################################\n###           Stage 0 - Build Arguments             ###\n#######################################################\n\nARG GO_VERSION\nARG RUNNER_IMAGE=alpine:3.20\nARG BUILD_TAGS=\"netgo,muslc,blst,bls12381,pebbledb\"\nARG NAME=beacond\nARG APP_NAME=beacond\nARG DB_BACKEND=pebbledb\nARG CMD_PATH=./cmd/beacond\n\n#######################################################\n###         Stage 1 - Cache Go Modules              ###\n#######################################################\n\nFROM golang:${GO_VERSION}-alpine AS mod-cache\n\nWORKDIR /workdir\n\nRUN apk add --no-cache git\n\n# Download Go modules\nCOPY ./go.mod ./go.sum ./\nRUN --mount=type=cache,target=/root/.cache/go-build \\\n    --mount=type=cache,target=/root/go/pkg/mod \\\n    go mod download\n\n#######################################################\n###         Stage 2 - Build the Application         ###\n#######################################################\n\nFROM golang:${GO_VERSION}-alpine AS builder\n\nARG GIT_VERSION\nARG GIT_COMMIT\nARG BUILD_TAGS\n\n# Set the working directory\nWORKDIR /workdir\n\n# Consolidate RUN commands to reduce layers\nRUN apk add --no-cache --update \\\n    ca-certificates \\\n    build-base\n\n# Copy the dependencies from the cache stage\nCOPY --from=mod-cache /go/pkg /go/pkg\n\n# Copy all the source code (this will ignore files/dirs in .dockerignore)\nCOPY ./ ./\n\n# Build args\nARG NAME\nARG APP_NAME\nARG DB_BACKEND\nARG CMD_PATH\n\n# Build beacond\nRUN --mount=type=cache,target=/root/.cache/go-build \\\n    --mount=type=cache,target=/root/go/pkg/mod \\\n    env NAME=${NAME} DB_BACKEND=${DB_BACKEND} APP_NAME=${APP_NAME} CGO_ENABLED=1 && \\\n    go build \\\n    -mod=readonly \\\n    -tags ${BUILD_TAGS} \\\n    -ldflags \"-X github.com/cosmos/cosmos-sdk/version.Name=${NAME} \\\n    -X github.com/cosmos/cosmos-sdk/version.AppName=${APP_NAME} \\\n    -X github.com/cosmos/cosmos-sdk/version.Version=${GIT_VERSION} \\\n    -X github.com/cosmos/cosmos-sdk/version.Commit=${GIT_COMMIT} \\\n    -X github.com/cosmos/cosmos-sdk/version.BuildTags=${BUILD_TAGS} \\\n    -X github.com/cosmos/cosmos-sdk/types.DBBackend=$DB_BACKEND \\\n    -w -s -linkmode=external -extldflags '-Wl,-z,muldefs -static'\" \\\n    -trimpath \\\n    -o /workdir/build/bin/beacond \\\n    ${CMD_PATH}\n\n#######################################################\n###        Stage 3 - Prepare the Final Image        ###\n#######################################################\n\nFROM ${RUNNER_IMAGE}\n\n# Build args\nARG APP_NAME\n\n# Copy over built executable into a fresh container\nCOPY --from=builder /workdir/build/bin/${APP_NAME} /usr/bin/${APP_NAME}\n\n# TODO: We should un hood this part, its very specific\n# to our kurtosis setup.\nRUN mkdir -p /root/jwt /root/kzg && \\\n    apk add --no-cache bash sed curl jq\n\nEXPOSE 26656\nEXPOSE 26657\n\nENTRYPOINT [ \"beacond\" ]"
  },
  {
    "path": "LICENSE",
    "content": "Business Source License 1.1\n\nLicense text copyright © 2023 MariaDB plc, All Rights Reserved.\n“Business Source License” is a trademark of MariaDB plc.\n\n-----------------------------------------------------------------------------\n\nParameters\n\nLicensor:             Berachain Foundation\n\nLicensed Work:        BeaconKit\n                      The Licensed Work is (c) 2025 Berachain Foundation\n\nAdditional Use Grant: Please contact founders@berachain.com\n\nChange Date:          2026-01-31\n\nChange License:       MIT License\n\nFor information about alternative licensing arrangements for the Software,\nplease contact Berachain: https://berachain.com\n\n-----------------------------------------------------------------------------\n\nTerms\n\nThe Licensor hereby grants you the right to copy, modify, create derivative\nworks, redistribute, and make non-production use of the Licensed Work. The\nLicensor may make an Additional Use Grant, above, permitting limited\nproduction use.\n\nEffective on the Change Date, or the fourth anniversary of the first publicly\navailable distribution of a specific version of the Licensed Work under this\nLicense, whichever comes first, the Licensor hereby grants you rights under\nthe terms of the Change License, and the rights granted in the paragraph\nabove terminate.\n\nIf your use of the Licensed Work does not comply with the requirements\ncurrently in effect as described in this License, you must purchase a\ncommercial license from the Licensor, its affiliated entities, or authorized\nresellers, or you must refrain from using the Licensed Work.\n\nAll copies of the original and modified Licensed Work, and derivative works\nof the Licensed Work, are subject to this License. This License applies\nseparately for each version of the Licensed Work and the Change Date may vary\nfor each version of the Licensed Work released by Licensor.\n\nYou must conspicuously display this License on each original or modified copy\nof the Licensed Work. If you receive the Licensed Work in original or\nmodified form from a third party, the terms and conditions set forth in this\nLicense apply to your use of that work.\n\nAny use of the Licensed Work in violation of this License will automatically\nterminate your rights under this License for the current and all other\nversions of the Licensed Work.\n\nThis License does not grant you any right in any trademark or logo of\nLicensor or its affiliates (provided that you may use a trademark or logo of\nLicensor as expressly required by this License).\n\nTO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\nAN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\nEXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\nTITLE.\n\nMariaDB hereby grants you permission to use this License’s text to license\nyour works, and to refer to it using the trademark “Business Source License”,\nas long as you comply with the Covenants of Licensor below.\n\n-----------------------------------------------------------------------------\n\nCovenants of Licensor\n\nIn consideration of the right to use this License’s text and the “Business\nSource License” name and trademark, Licensor covenants to MariaDB, and to all\nother recipients of the licensed work to be provided by Licensor:\n\n1. To specify as the Change License the GPL Version 2.0 or any later version,\n   or a license that is compatible with GPL Version 2.0 or a later version,\n   where “compatible” means that software provided under the Change License can\n   be included in a program with software provided under GPL Version 2.0 or a\n   later version. Licensor may specify additional Change Licenses without\n   limitation.\n\n2. To either: (a) specify an additional grant of rights to use that does not\n   impose any additional restriction on the right granted in this License, as\n   the Additional Use Grant; or (b) insert the text “None”.\n\n3. To specify a Change Date.\n\n4. Not to modify this License in any other way.\n\n-----------------------------------------------------------------------------\n\nNotice\n\nThe Business Source License (this document, or the “License”) is not an Open \nSource license. However, the Licensed Work will eventually be made available \nunder an Open Source License, as stated in this License.\n\nFor more information on the use of the Business Source License for MariaDB\nproducts, please visit the MariaDB Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-mariadb.\n\nFor more information on the use of the Business Source License generally,\nplease visit the Adopting and Developing Business Source License FAQ at\nhttps://mariadb.com/bsl-faq-adopting."
  },
  {
    "path": "LICENSE.header",
    "content": "SPDX-License-Identifier: BUSL-1.1\n\nCopyright (C) 2025, Berachain Foundation. All rights reserved.\nUse of this software is governed by the Business Source License included \nin the LICENSE file of this repository and at www.mariadb.com/bsl11.\n\nANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\nTERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\nVERSIONS OF THE LICENSED WORK.\n\nTHIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\nLICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\nLICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n\nTO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\nAN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\nEXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\nTITLE."
  },
  {
    "path": "Makefile",
    "content": "#!/usr/bin/make -f\n\ninclude scripts/build/build.mk\ninclude scripts/build/codegen.mk\ninclude scripts/build/constants.mk\ninclude scripts/build/devtools.mk\ninclude scripts/build/linting.mk\ninclude scripts/build/protobuf.mk\ninclude scripts/build/release.mk\ninclude scripts/build/testing.mk\ninclude contracts/Makefile\ninclude kurtosis/Makefile\ninclude scripts/build/help.mk\ninclude testing/forge-script/Makefile\n\n# Specify the default target if none is provided\n.DEFAULT_GOAL := build\nROOT_DIR := $(shell pwd)\n\n\n##############################################################################\n###                             Dependencies                                ###\n###############################################################################\n\n.PHONY: clean format lint \\\n\tbuf-install proto-clean \\\n\ttest-unit test-unit-cover test-simulated test-forge-cover test-forge-fuzz \\\n\tforge-snapshot forge-snapshot-diff \\\n\ttest-e2e test-e2e-no-build \\\n\tforge-lint-fix forge-lint golangci-install golangci golangci-fix \\\n\tlicense license-fix \\\n\tgosec vulncheck golines repo-rinse proto build\n\n\n"
  },
  {
    "path": "README.md",
    "content": "<div align=\"center\">\n  <a href=\"https://github.com/berachain/beacon-kit\">\n    <img alt=\"beacon-kit-banner\" src=\".github/assets/banner.png\" width=\"auto\" height=\"auto\">\n  </a>\n</div>\n<h2>\n  Berachain's Consensus Client\n</h2>\n\n<div>\n\n[![CI status](https://github.com/berachain/beacon-kit/workflows/pipeline/badge.svg)](https://github.com/berachain/beacon-kit/actions/workflows/pipeline.yml)\n[![Deps status](https://github.com/berachain/beacon-kit/workflows/deps/badge.svg)](https://github.com/berachain/beacon-kit/actions/workflows/vuln-and-dep-check.yml)\n[![CodeCov](https://codecov.io/gh/berachain/beacon-kit/graph/badge.svg?token=0l5iJ3ZbzV)](https://codecov.io/gh/berachain/beacon-kit)\n[![Telegram Chat](https://img.shields.io/endpoint?color=neon&logo=telegram&label=chat&url=https%3A%2F%2Ftg.sumanjay.workers.dev%2Fbeacon_kit)](https://t.me/beacon_kit)\n[![X Follow](https://img.shields.io/twitter/follow/berachain)](https://x.com/berachain)\n[![Discord](https://img.shields.io/discord/924442927399313448?label=discord)](https://discord.gg/berachain)\n\n</div>\n\n## What is BeaconKit?\n\nBeaconKit is Berachain's consensus client. It implements the Ethereum consensus layer specification with Berachain-specific modifications, using a modified [CometBFT](https://github.com/berachain/cometbft) for consensus instead of Ethereum's standard beacon chain consensus.\n\nBerachain is a high-performance L1 blockchain powered by [Proof of Liquidity](https://docs.berachain.com/general/introduction/what-is-proof-of-liquidity) (PoL), an incentive mechanism that aligns validators, protocols, and users through its three-token system (BERA, BGT, HONEY).\n\nBeaconKit communicates with [Bera-Reth](https://github.com/berachain/bera-reth) (the execution client) via the standard [Engine API](https://github.com/ethereum/execution-apis/blob/main/src/engine), forming the two-client architecture used by Berachain nodes.\n\n### Key Differences from Ethereum\n\n- **CometBFT Consensus** — Uses timeout-based rounds instead of fixed 12-second slots. If a proposer fails, a new round starts at the same height with a different proposer.\n- **Single-Slot Finality** — Blocks are finalized immediately when 2/3+ validators commit, unlike Ethereum's ~13-minute finalization through Casper FFG checkpoints.\n- **No Missed Slots** — Block heights are strictly sequential with no gaps. Every height eventually produces a block through round-based consensus.\n- **No Attestations or Committees** — Consensus is driven by CometBFT's validator voting (prevotes/precommits) rather than Ethereum's attestation committees and sync committees.\n- **Capped Validator Set** — The active validator set is capped (currently 69 validators) rather than being open-ended.\n- **EVM Inflation Withdrawal** — Every block includes a mandatory EVM inflation withdrawal as its first withdrawal, a Berachain-specific economic mechanism.\n\n## Networks\n\n| Network | Chain ID | Description |\n|---------|----------|-------------|\n| **Mainnet** | 80094 | Production network |\n| **Bepolia** | 80069 | Public testnet |\n| **Devnet** | 80087 | Local development |\n\nNetwork configurations are stored in `testing/networks/<chain-id>/`.\n\n## Execution Client\n\nBeaconKit requires [**Bera-Reth**](https://github.com/berachain/bera-reth), a Berachain-specific fork of [Reth](https://github.com/paradigmxyz/reth). Communication happens over the Engine API with JWT authentication.\n\n## Quick Start\n\n### Prerequisites\n\n- [Docker](https://docs.docker.com/engine/install/)\n- [Golang](https://go.dev/doc/install)\n- [Foundry](https://book.getfoundry.sh/)\n\nOpen two terminals side by side.\n\n**Terminal 1** — Start the consensus client:\n\n```bash\nmake start\n```\n\n**Terminal 2** — Start the execution client (after `beacond` is running, since `make start` generates the execution genesis file):\n\n```bash\nmake start-reth\n```\n\nThe devnet runs with chain ID **80087**. The following dev account is preloaded with the native token:\n\n```\nAddress:     0x20f33ce90a13a4b5e7697e3544c3083b8f8a51d4\nPrivate Key: 0xfffdbb37105441e14b0ee6330d855d8504ff39e705c3afa8f859ac9865f99306\n```\n\n### Multinode Devnet (Kurtosis)\n\nFor running a multinode local devnet using [Kurtosis](https://www.kurtosis.com/):\n\n```bash\nmake start-devnet\n```\n\nSee the [Kurtosis README](kurtosis/README.md) for full details on configuration and usage.\n\n## Project Structure\n\n```\nbeacon/              Core beacon chain logic (blockchain service, validator service)\nchain/               Chain specifications and network configs\ncli/                 CLI commands and configuration\nconfig/              Configuration templates (TOML)\nconsensus-types/     Consensus layer types (blocks, states, validators, SSZ)\ncontracts/           Solidity contracts (deposit contract, staking)\nda/                  Data availability (blob management, KZG commitments)\nengine-primitives/   Execution engine types (Engine API types, payloads)\nexecution/           Execution client integration (Engine API client, deposit syncing)\nkurtosis/            Kurtosis multinode devnet deployment\nnode-api/            REST API implementation (beacon API handlers)\nnode-core/           Core infrastructure (dependency injection, service registry)\nprimitives/          Basic types and constants (Slot, Gwei, ValidatorIndex)\nstate-transition/    State transition logic (state machine, fork transitions)\nstorage/             Database backends (block store, blob store, beacon DB)\ntesting/             Test utilities, network configs, e2e and simulation tests\n```\n\n## Development\n\n### Building\n\n```bash\nmake build                # Build beacond binary to build/bin/beacond\nmake install              # Install beacond to $GOPATH/bin\nmake build-docker         # Build Docker image\n```\n\n### Testing\n\n```bash\nmake test                 # Run all tests (unit + forge)\nmake test-unit            # Run unit tests with coverage\nmake test-unit-bench      # Run benchmarks\nmake test-unit-fuzz       # Run Go fuzz tests\nmake test-simulated       # Run simulation tests\nmake test-e2e             # Run e2e tests (builds Docker image first)\nmake test-forge-cover     # Run Solidity tests with coverage\n```\n\n### Linting & Formatting\n\n```bash\nmake lint                 # Run all linters\nmake format               # Run all formatters\nmake golangci-fix         # Auto-fix Go linting issues\nmake gosec                # Run security scanner\nmake nilaway              # Run nil pointer checker\nmake vulncheck            # Run govulncheck vulnerability scanner\n```\n\n### Code Generation\n\n```bash\nmake generate             # Run all code generation\nmake proto                # Generate protobuf code\nmake generate-check       # Verify generated code is up to date\n```\n\n## Documentation\n\n- [Berachain Docs](https://docs.berachain.com/) — Official documentation\n- [What is BeaconKit](https://docs.berachain.com/validators/beaconkit/overview) — Conceptual overview\n- [Node Quickstart](https://docs.berachain.com/validators/operations/quickstart) — Deploy a mainnet or testnet node\n- [Docker Devnet Guide](https://docs.berachain.com/validators/guides/local-devnet-docker) — Run a devnet with Docker\n- [Kurtosis Guide](https://docs.berachain.com/validators/guides/local-devnet-kurtosis) — Multinode deployment with Kurtosis\n- [Kurtosis README](kurtosis/README.md) — Local Kurtosis configuration and usage\n\n## License\n\nBeaconKit is licensed under [BUSL-1.1](LICENSE).\n"
  },
  {
    "path": "beacon/blockchain/common.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage blockchain\n\nimport (\n\t\"fmt\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/encoding\"\n\t\"github.com/berachain/beacon-kit/da/types\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\nfunc (s *Service) ParseBeaconBlock(req encoding.ABCIRequest) (\n\t*ctypes.SignedBeaconBlock,\n\ttypes.BlobSidecars,\n\terror,\n) {\n\tif countTx := len(req.GetTxs()); countTx > MaxConsensusTxsCount {\n\t\treturn nil, nil, fmt.Errorf(\"max expected %d, got %d: %w\",\n\t\t\tMaxConsensusTxsCount, countTx,\n\t\t\tErrTooManyConsensusTxs,\n\t\t)\n\t}\n\n\tforkVersion := s.chainSpec.ActiveForkVersionForTimestamp(math.U64(req.GetTime().Unix())) //#nosec: G115\n\t// Decode signed block and sidecars.\n\tsignedBlk, sidecars, err := encoding.ExtractBlobsAndBlockFromRequest(\n\t\treq,\n\t\tBeaconBlockTxIndex,\n\t\tBlobSidecarsTxIndex,\n\t\tforkVersion,\n\t)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tif signedBlk == nil {\n\t\ts.logger.Warn(\n\t\t\t\"Aborting block verification - beacon block not found in proposal\",\n\t\t)\n\t\treturn nil, nil, ErrNilBlk\n\t}\n\tif sidecars == nil {\n\t\ts.logger.Warn(\n\t\t\t\"Aborting block verification - blob sidecars not found in proposal\",\n\t\t)\n\t\treturn nil, nil, ErrNilBlob\n\t}\n\n\treturn signedBlk, sidecars, nil\n}\n"
  },
  {
    "path": "beacon/blockchain/deposit.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage blockchain\n\nimport (\n\t\"context\"\n\t\"maps\"\n\t\"slices\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// defaultRetryInterval processes a deposit event.\nconst defaultRetryInterval = 20 * time.Second\n\nfunc (s *Service) depositFetcher(\n\tctx context.Context,\n\tblockNum math.U64,\n) {\n\tif blockNum <= s.eth1FollowDistance {\n\t\ts.logger.Info(\n\t\t\t\"depositFetcher, nothing to fetch\",\n\t\t\t\"block num\", blockNum,\n\t\t\t\"eth1FollowDistance\", s.eth1FollowDistance,\n\t\t)\n\t\treturn\n\t}\n\n\ts.fetchAndStoreDeposits(ctx, blockNum-s.eth1FollowDistance)\n}\n\n// fetchAndStoreDeposits processes all deposits at a particular EL block height.\n// TODO: This could be optimized to process a contiguous range of blocks simultaneously to minimize EL RPC calls.\nfunc (s *Service) fetchAndStoreDeposits(\n\tctx context.Context,\n\tblockNum math.U64,\n) {\n\tblockNumStr := strconv.FormatUint(blockNum.Unwrap(), 10)\n\tdeposits, err := s.depositContract.ReadDeposits(ctx, blockNum, blockNum)\n\tif err != nil {\n\t\ts.logger.Error(\"Failed to read deposits\", \"error\", err)\n\t\ts.metrics.sink.IncrementCounter(\n\t\t\t\"beacon_kit.execution.deposit.failed_to_get_block_logs\",\n\t\t\t\"block_num\",\n\t\t\tblockNumStr,\n\t\t)\n\t\ts.failedBlocksMu.Lock()\n\t\ts.failedBlocks[blockNum] = struct{}{}\n\t\ts.failedBlocksMu.Unlock()\n\t\treturn\n\t}\n\n\tif len(deposits) > 0 {\n\t\ts.logger.Info(\n\t\t\t\"Found deposits on execution layer\",\n\t\t\t\"block\", blockNum, \"deposits\", len(deposits),\n\t\t)\n\t}\n\n\tif err = s.storageBackend.DepositStore().EnqueueDeposits(ctx, deposits); err != nil {\n\t\ts.logger.Error(\"Failed to store deposits\", \"error\", err)\n\t\ts.metrics.sink.IncrementCounter(\n\t\t\t\"beacon_kit.execution.deposit.failed_to_enqueue_deposits\",\n\t\t\t\"block_num\",\n\t\t\tblockNumStr,\n\t\t)\n\t\ts.failedBlocksMu.Lock()\n\t\ts.failedBlocks[blockNum] = struct{}{}\n\t\ts.failedBlocksMu.Unlock()\n\t\treturn\n\t}\n\ts.failedBlocksMu.Lock()\n\tdelete(s.failedBlocks, blockNum)\n\ts.failedBlocksMu.Unlock()\n}\n\nfunc (s *Service) depositCatchupFetcher(ctx context.Context) {\n\tticker := time.NewTicker(defaultRetryInterval)\n\tdefer ticker.Stop()\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\tcase <-ticker.C:\n\t\t\ts.failedBlocksMu.RLock()\n\t\t\tfailedBlks := slices.Collect(maps.Keys(s.failedBlocks))\n\t\t\ts.failedBlocksMu.RUnlock()\n\t\t\tif len(failedBlks) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ts.logger.Warn(\n\t\t\t\t\"Failed to get deposits from block(s), retrying...\",\n\t\t\t\t\"num_blocks\",\n\t\t\t\tfailedBlks,\n\t\t\t)\n\n\t\t\t// Fetch deposits for blocks that failed to be processed.\n\t\t\t// TODO: This can be optimized to process all the blocks queried at once by utilizing log query ranges\n\t\t\t// for contiguous ranges of blocks\n\t\t\tfor _, blockNum := range failedBlks {\n\t\t\t\ts.fetchAndStoreDeposits(ctx, blockNum)\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "beacon/blockchain/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage blockchain\n\nimport \"github.com/berachain/beacon-kit/errors\"\n\nvar (\n\t// ErrTooManyConsensusTxs is an error for consensus blocks having more than MaxConsensusTxsCount txs.\n\tErrTooManyConsensusTxs = errors.New(\"too many consensus txs\")\n\t// ErrUnexpectedBlockSlot is an error for consensus blocks with non consecutive slots.\n\tErrUnexpectedBlockSlot = errors.New(\"unexpected block slot\")\n\t// ErrNilBlk is an error for when the beacon block is nil.\n\tErrNilBlk = errors.New(\"nil beacon block\")\n\t// ErrNilBlob is an error for when the BlobSidecars is nil.\n\tErrNilBlob = errors.New(\"nil blob\")\n\t// ErrVersionMismatch is an error for when the fork for the block timestamp does not match the fork\n\t// for the ABCI timestamp.\n\tErrVersionMismatch = errors.New(\"ABCI fork version mismatch\")\n\t// ErrDataNotAvailable indicates that the required data is not available.\n\tErrDataNotAvailable = errors.New(\"data not available\")\n\t// ErrSidecarCommitmentMismatch indicates that the BeaconBlockBody commitments do not match the sidecars.\n\tErrSidecarCommitmentMismatch = errors.New(\"sidecars commitments mismatch\")\n\t// ErrSidecarSignatureMismatch indicates that the sidecar signature is invalid.\n\tErrSidecarSignatureMismatch = errors.New(\"sidecar signature mismatch\")\n)\n"
  },
  {
    "path": "beacon/blockchain/execution_engine.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage blockchain\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n)\n\n// sendPostBlockFCU sends a forkchoice update to the execution client after a\n// block is finalized.\nfunc (s *Service) sendPostBlockFCU(\n\tctx context.Context,\n\tst *statedb.StateDB,\n) error {\n\tlph, err := st.GetLatestExecutionPayloadHeader()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed getting latest payload: %w\", err)\n\t}\n\n\t// Send a forkchoice update without payload attributes to notify EL of the new head.\n\t// Note that we are being conservative here as we don't mark the block we just finalized\n\t// (which is irreversible due to CometBFT SSF) as final. If we keep doing this, we can\n\t// spare the FCU update in case we have optimistic block building on, as we may have\n\t// already sent the very same FCU request after we verified the block.\n\tfcuData := &engineprimitives.ForkchoiceStateV1{\n\t\tHeadBlockHash:      lph.GetBlockHash(),\n\t\tSafeBlockHash:      lph.GetParentHash(),\n\t\tFinalizedBlockHash: lph.GetParentHash(),\n\t}\n\n\tlatestRequestedFCU := s.latestFcuReq.Load()\n\ts.latestFcuReq.Store(&engineprimitives.ForkchoiceStateV1{}) // reset and prepare for next block\n\tif latestRequestedFCU.Equals(fcuData) {\n\t\t// we already sent the same FCU, likely due to optimistic block building\n\t\t// being active. Avoid re-issuing the same request.\n\t\treturn nil\n\t}\n\n\treq := ctypes.BuildForkchoiceUpdateRequestNoAttrs(\n\t\tfcuData,\n\t\ts.chainSpec.ActiveForkVersionForTimestamp(lph.GetTimestamp()),\n\t)\n\tif _, err = s.executionEngine.NotifyForkchoiceUpdate(ctx, req); err != nil {\n\t\treturn fmt.Errorf(\"failed forkchoice update, head %s: %w\",\n\t\t\tlph.GetBlockHash().String(),\n\t\t\terr,\n\t\t)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "beacon/blockchain/finalize_block.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage blockchain\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/consensus/types\"\n\tdatypes \"github.com/berachain/beacon-kit/da/types\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n\tcmtabci \"github.com/cometbft/cometbft/abci/types\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n)\n\nfunc (s *Service) FinalizeBlock(\n\tctx sdk.Context,\n\treq *cmtabci.FinalizeBlockRequest,\n) (transition.ValidatorUpdates, error) {\n\t// STEP 1: Decode block and blobs.\n\tsignedBlk, blobs, err := s.ParseBeaconBlock(req)\n\tif err != nil {\n\t\ts.logger.Error(\"Failed to decode block and blobs\", \"error\", err)\n\t\treturn nil, fmt.Errorf(\"failed to decode block and blobs: %w\", err)\n\t}\n\tblk := signedBlk.GetBeaconBlock()\n\tst := s.storageBackend.StateFromContext(ctx)\n\n\t// Send an FCU to force the HEAD of the chain on the EL on startup.\n\tvar finalizeErr error\n\ts.forceStartupSyncOnce.Do(func() {\n\t\tvar parentProposerPubkey *crypto.BLSPubkey\n\t\tparentProposerPubkey, finalizeErr = st.ParentProposerPubkey(blk.GetTimestamp())\n\t\tif finalizeErr != nil {\n\t\t\tfinalizeErr = fmt.Errorf(\"force sync upon finalize: failed retrieving parent proposer pubkey: %w\", finalizeErr)\n\t\t} else {\n\t\t\tfinalizeErr = s.forceSyncUponFinalize(ctx, blk, parentProposerPubkey)\n\t\t}\n\t})\n\tif finalizeErr != nil {\n\t\treturn nil, finalizeErr\n\t}\n\n\t// STEP 2: Finalize sidecars first (block will check for sidecar availability).\n\tif err = s.FinalizeSidecars(ctx, req.SyncingToHeight, blk, blobs); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed finalizing sidecars: %w\", err)\n\t}\n\n\t// STEP 3: Finalize the block.\n\tconsensusBlk := types.NewConsensusBlock(blk, req.GetProposerAddress(), req.GetTime())\n\tvalUpdates, err := s.finalizeBeaconBlock(ctx, st, consensusBlk)\n\tif err != nil {\n\t\ts.logger.Error(\"Failed to process verified beacon block\",\n\t\t\t\"error\", err,\n\t\t)\n\t\treturn nil, err\n\t}\n\n\t// STEP 4: Post Finalizations cleanups.\n\treturn valUpdates, s.PostFinalizeBlockOps(ctx, blk)\n}\n\nfunc (s *Service) FinalizeSidecars(\n\tctx sdk.Context,\n\tsyncingToHeight int64,\n\tblk *ctypes.BeaconBlock,\n\tblobs datypes.BlobSidecars,\n) error {\n\t// SyncingToHeight is always the tip of the chain both during sync and when\n\t// caught up. We don't need to process sidecars unless they are within DA period.\n\t//\n\t//#nosec: G115 // SyncingToHeight will never be negative.\n\tif s.chainSpec.WithinDAPeriod(blk.GetSlot(), math.Slot(syncingToHeight)) {\n\t\terr := s.blobProcessor.ProcessSidecars(\n\t\t\ts.storageBackend.AvailabilityStore(),\n\t\t\tblobs,\n\t\t)\n\t\tif err != nil {\n\t\t\ts.logger.Error(\"Failed to process blob sidecars\", \"error\", err)\n\t\t\treturn fmt.Errorf(\"failed to process blob sidecars: %w\", err)\n\t\t}\n\n\t\t// Ensure we can access the data using the commitments from the block.\n\t\tif !s.storageBackend.AvailabilityStore().IsDataAvailable(\n\t\t\tctx, blk.GetSlot(), blk.GetBody(),\n\t\t) {\n\t\t\treturn ErrDataNotAvailable\n\t\t}\n\t\treturn nil\n\t}\n\n\t// Here outside Data Availability window. Just log if needed\n\tif len(blobs) > 0 {\n\t\ts.logger.Info(\n\t\t\t\"Skipping blob processing outside of Data Availability Period\",\n\t\t\t\"slot\", blk.GetSlot().Base10(), \"head\", syncingToHeight,\n\t\t)\n\t}\n\treturn nil\n}\n\nfunc (s *Service) PostFinalizeBlockOps(ctx sdk.Context, blk *ctypes.BeaconBlock) error {\n\t// TODO: consider extracting LatestExecutionPayloadHeader instead of using state here\n\tst := s.storageBackend.StateFromContext(ctx)\n\n\t// Fetch and store the deposit for the block.\n\tblockNum := blk.GetBody().GetExecutionPayload().GetNumber()\n\ts.depositFetcher(ctx, blockNum)\n\n\t// Store the finalized block in the KVStore.\n\tslot := blk.GetSlot()\n\tif err := s.storageBackend.BlockStore().Set(blk); err != nil {\n\t\ts.logger.Error(\n\t\t\t\"failed to store block\", \"slot\", slot, \"error\", err,\n\t\t)\n\t\treturn err\n\t}\n\n\t// Prune the availability and deposit store.\n\tif err := s.processPruning(ctx, blk); err != nil {\n\t\ts.logger.Error(\"failed to processPruning\", \"error\", err)\n\t}\n\n\tif err := s.sendPostBlockFCU(ctx, st); err != nil {\n\t\treturn fmt.Errorf(\"sendPostBlockFCU failed: %w\", err)\n\t}\n\n\t// reset latest verified payload in block builder to signal\n\t// that no payload is available to reuse for blk.Slot\n\ts.localBuilder.CacheLatestVerifiedPayload(blk.Slot, nil)\n\n\treturn nil\n}\n\n// finalizeBeaconBlock receives an incoming beacon block, it first validates\n// and then processes the block.\nfunc (s *Service) finalizeBeaconBlock(\n\tctx context.Context,\n\tst *statedb.StateDB,\n\tblk *types.ConsensusBlock,\n) (transition.ValidatorUpdates, error) {\n\tbeaconBlk := blk.GetBeaconBlock()\n\n\t// If the block is nil, exit early.\n\tif beaconBlk == nil {\n\t\treturn nil, ErrNilBlk\n\t}\n\n\tvalUpdates, err := s.executeStateTransition(ctx, st, blk)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn valUpdates.CanonicalSort(), nil\n}\n\n// executeStateTransition runs the stf.\nfunc (s *Service) executeStateTransition(\n\tctx context.Context,\n\tst *statedb.StateDB,\n\tblk *types.ConsensusBlock,\n) (transition.ValidatorUpdates, error) {\n\tstartTime := time.Now()\n\tdefer s.metrics.measureStateTransitionDuration(startTime)\n\n\t// Notes about context attributes:\n\t// - VerifyPayload: set to true. When we are NOT synced to the tip,\n\t// process proposal does NOT get called and thus we must ensure that\n\t// NewPayload is called to get the execution client the payload.\n\t// When we are synced to the tip, we can skip the\n\t// NewPayload call since we already gave our execution client\n\t// the payload in process proposal.\n\t// In both cases the payload was already accepted by a majority\n\t// of validators in their process proposal call and thus\n\t// the \"verification aspect\" of this NewPayload call is\n\t// actually irrelevant at this point.\n\t// - VerifyRandao: set to false. We skip randao validation in FinalizeBlock\n\t// since either\n\t//   1. we validated it during ProcessProposal at the head of the chain OR\n\t//   2. we are bootstrapping and implicitly trust that the randao was validated by\n\t//    the super majority during ProcessProposal of the given block height.\n\ttxCtx := transition.NewTransitionCtx(\n\t\tctx,\n\t\tblk.GetConsensusTime(),\n\t\tblk.GetProposerAddress(),\n\t).\n\t\tWithVerifyPayload(true).\n\t\tWithVerifyRandao(false).\n\t\tWithVerifyResult(false).\n\t\tWithMeterGas(true)\n\n\treturn s.stateProcessor.Transition(\n\t\ttxCtx,\n\t\tst,\n\t\tblk.GetBeaconBlock(),\n\t)\n}\n"
  },
  {
    "path": "beacon/blockchain/init_chain.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage blockchain\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n)\n\n// ProcessGenesisData processes the genesis state and initializes the beacon state.\nfunc (s *Service) ProcessGenesisData(\n\tctx context.Context,\n\tbytes []byte,\n) (transition.ValidatorUpdates, error) {\n\tgenesisData := ctypes.Genesis{}\n\tif err := json.Unmarshal(bytes, &genesisData); err != nil {\n\t\ts.logger.Error(\"Failed to unmarshal genesis data\", \"error\", err)\n\t\treturn nil, err\n\t}\n\n\t// Ensure consistency of the genesis timestamp.\n\texecPayloadHeader := genesisData.GetExecutionPayloadHeader()\n\tif s.chainSpec.GenesisTime() != execPayloadHeader.GetTimestamp().Unwrap() {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"mismatch between chain spec genesis time (%d) and execution payload header time (%d)\",\n\t\t\ts.chainSpec.GenesisTime(),\n\t\t\texecPayloadHeader.GetTimestamp().Unwrap(),\n\t\t)\n\t}\n\n\t// Ensure consistency of the genesis fork version.\n\tgenesisVersion := genesisData.GetForkVersion()\n\tif !version.Equals(genesisVersion, s.chainSpec.GenesisForkVersion()) {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"fork mismatch between CL genesis file version (%s) and chain spec genesis version (%s)\",\n\t\t\tgenesisVersion, s.chainSpec.GenesisForkVersion(),\n\t\t)\n\t}\n\n\t// Initialize the beacon state from the genesis deposits.\n\tvalidatorUpdates, err := s.stateProcessor.InitializeBeaconStateFromEth1(\n\t\ts.storageBackend.StateFromContext(ctx),\n\t\tgenesisData.GetDeposits(),\n\t\texecPayloadHeader,\n\t\tgenesisVersion,\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// After deposits are validated, store the genesis deposits in the deposit store.\n\tif err = s.storageBackend.DepositStore().EnqueueDeposits(\n\t\tctx,\n\t\tgenesisData.GetDeposits(),\n\t); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn validatorUpdates, nil\n}\n"
  },
  {
    "path": "beacon/blockchain/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage blockchain\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/chain\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/delay\"\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/encoding\"\n\tdastore \"github.com/berachain/beacon-kit/da/store\"\n\tdatypes \"github.com/berachain/beacon-kit/da/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/payload/builder\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n\t\"github.com/berachain/beacon-kit/state-transition/core\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n\t\"github.com/berachain/beacon-kit/storage/block\"\n\t\"github.com/berachain/beacon-kit/storage/deposit\"\n\tcmtabci \"github.com/cometbft/cometbft/abci/types\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n)\n\n// ExecutionEngine is the interface for the execution engine.\ntype ExecutionEngine interface {\n\t// NotifyNewPayload notifies the execution client of new payload.\n\tNotifyNewPayload(\n\t\tctx context.Context,\n\t\treq ctypes.NewPayloadRequest,\n\t\tretryOnSyncingStatus bool,\n\t) error\n\t// NotifyForkchoiceUpdate notifies the execution client of a forkchoice\n\t// update.\n\tNotifyForkchoiceUpdate(\n\t\tctx context.Context,\n\t\treq *ctypes.ForkchoiceUpdateRequest,\n\t) (*engineprimitives.PayloadID, error)\n}\n\n// LocalBuilder is the interface for the builder service.\ntype LocalBuilder interface {\n\t// Enabled returns true if the local builder is enabled.\n\tEnabled() bool\n\t// RequestPayloadAsync requests a new payload for the given slot.\n\tRequestPayloadAsync(\n\t\tctx context.Context,\n\t\tr *builder.RequestPayloadData,\n\t) (*engineprimitives.PayloadID, common.Version, error)\n\tCacheLatestVerifiedPayload(\n\t\tlatestEnvelopeSlot math.Slot,\n\t\tlatestEnvelope ctypes.BuiltExecutionPayloadEnv,\n\t)\n}\n\n// StateProcessor defines the interface for processing various state transitions\n// in the beacon chain.\ntype StateProcessor interface {\n\t// InitializeBeaconStateFromEth1 initializes the premined beacon\n\t// state from the eth1 deposits.\n\tInitializeBeaconStateFromEth1(\n\t\t*statedb.StateDB,\n\t\tctypes.Deposits,\n\t\t*ctypes.ExecutionPayloadHeader,\n\t\tcommon.Version,\n\t) (transition.ValidatorUpdates, error)\n\t// ProcessFork prepares the state for the fork version at the given timestamp.\n\tProcessFork(\n\t\tst *statedb.StateDB, timestamp math.U64, logUpgrade bool,\n\t) error\n\t// ProcessSlots processes the state transition for a range of slots.\n\tProcessSlots(\n\t\t*statedb.StateDB, math.Slot,\n\t) (transition.ValidatorUpdates, error)\n\t// Transition processes the state transition for a given block.\n\tTransition(\n\t\tcore.ReadOnlyContext,\n\t\t*statedb.StateDB,\n\t\t*ctypes.BeaconBlock,\n\t) (transition.ValidatorUpdates, error)\n\tGetSignatureVerifierFn(*statedb.StateDB) (\n\t\tfunc(\n\t\t\tblk *ctypes.BeaconBlock,\n\t\t\tsignature crypto.BLSSignature) error,\n\t\terror,\n\t)\n}\n\n// StorageBackend defines an interface for accessing various storage components\n// required by the beacon node.\ntype StorageBackend interface {\n\t// AvailabilityStore returns the availability store for the given context.\n\tAvailabilityStore() *dastore.Store\n\t// StateFromContext retrieves the beacon state from the given context.\n\tStateFromContext(context.Context) *statedb.StateDB\n\t// DepositStore retrieves the deposit store.\n\tDepositStore() deposit.StoreManager\n\t// BlockStore retrieves the block store.\n\tBlockStore() *block.KVStore[*ctypes.BeaconBlock]\n}\n\n// TelemetrySink is an interface for sending metrics to a telemetry backend.\ntype TelemetrySink interface {\n\t// IncrementCounter increments the counter identified by\n\t// the provided key.\n\tIncrementCounter(key string, args ...string)\n\n\t// MeasureSince measures the time since the provided start time,\n\t// identified by the provided keys.\n\tMeasureSince(key string, start time.Time, args ...string)\n}\n\n//nolint:revive // its ok\ntype BlockchainI interface {\n\tProcessGenesisData(\n\t\tcontext.Context,\n\t\t[]byte,\n\t) (transition.ValidatorUpdates, error)\n\tParseBeaconBlock(req encoding.ABCIRequest) (\n\t\t*ctypes.SignedBeaconBlock,\n\t\tdatypes.BlobSidecars,\n\t\terror,\n\t)\n\tProcessProposal(\n\t\tsdk.Context,\n\t\t*cmtabci.ProcessProposalRequest,\n\t\t[]byte, // this node address\n\t) (transition.ValidatorUpdates, error)\n\tFinalizeSidecars(\n\t\tctx sdk.Context,\n\t\tsyncingToHeight int64,\n\t\tblk *ctypes.BeaconBlock,\n\t\tblobs datypes.BlobSidecars,\n\t) error\n\tFinalizeBlock(\n\t\tsdk.Context,\n\t\t*cmtabci.FinalizeBlockRequest,\n\t) (transition.ValidatorUpdates, error)\n\tPostFinalizeBlockOps(\n\t\tsdk.Context,\n\t\t*ctypes.BeaconBlock,\n\t) error\n\tPruneOrphanedBlobs(lastBlockHeight int64) error\n}\n\n// BlobProcessor is the interface for the blobs processor.\ntype BlobProcessor interface {\n\t// ProcessSidecars processes the blobs and ensures they match the local\n\t// state.\n\tProcessSidecars(\n\t\tavs *dastore.Store,\n\t\tsidecars datypes.BlobSidecars,\n\t) error\n\t// VerifySidecars verifies the blobs and ensures they match the local state.\n\tVerifySidecars(\n\t\tctx context.Context,\n\t\tsidecars datypes.BlobSidecars,\n\t\tblkHeader *ctypes.BeaconBlockHeader,\n\t\tkzgCommitments eip4844.KZGCommitments[common.ExecutionHash],\n\t) error\n}\n\ntype PruningChainSpec interface {\n\tMinEpochsForBlobsSidecarsRequest() math.Epoch\n\tSlotsPerEpoch() uint64\n}\n\ntype ServiceChainSpec interface {\n\tPruningChainSpec\n\tchain.BlobSpec\n\tchain.ForkSpec\n\tchain.ForkVersionSpec\n\tdelay.ConfigGetter\n\n\tEpochsPerHistoricalVector() uint64\n\tSlotToEpoch(slot math.Slot) math.Epoch\n\tEth1FollowDistance() uint64\n}\n"
  },
  {
    "path": "beacon/blockchain/metrics.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage blockchain\n\nimport (\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// chainMetrics is a struct that contains metrics for the chain.\ntype chainMetrics struct {\n\t// sink is the sink for the metrics.\n\tsink TelemetrySink\n}\n\n// newChainMetrics creates a new chainMetrics.\nfunc newChainMetrics(\n\tsink TelemetrySink,\n) *chainMetrics {\n\treturn &chainMetrics{\n\t\tsink: sink,\n\t}\n}\n\n// measureStateTransitionDuration measures the time to process\n// the state transition for a block.\nfunc (cm *chainMetrics) measureStateTransitionDuration(\n\tstart time.Time,\n) {\n\tcm.sink.MeasureSince(\n\t\t\"beacon_kit.beacon.blockchain.state_transition_duration\",\n\t\tstart,\n\t)\n}\n\n// markRebuildPayloadForRejectedBlockSuccess increments the counter for the\n// number of times\n// the validator successfully rebuilt the payload for a rejected block.\nfunc (cm *chainMetrics) markRebuildPayloadForRejectedBlockSuccess(\n\tslot math.Slot,\n) {\n\tcm.sink.IncrementCounter(\n\t\t\"beacon_kit.blockchain.rebuild_payload_for_rejected_block_success\",\n\t\t\"slot\",\n\t\tslot.Base10(),\n\t)\n}\n\n// markRebuildPayloadForRejectedBlockFailure increments the counter for the\n// number of times the validator failed to build an optimistic payload\n// due to a failure.\nfunc (cm *chainMetrics) markRebuildPayloadForRejectedBlockFailure(\n\tslot math.Slot,\n\terr error,\n) {\n\tcm.sink.IncrementCounter(\n\t\t\"beacon_kit.blockchain.rebuild_payload_for_rejected_block_failure\",\n\t\t\"slot\",\n\t\tslot.Base10(),\n\t\t\"error\",\n\t\terr.Error(),\n\t)\n}\n\n// markOptimisticPayloadBuildSuccess increments the counter for the number of\n// times the validator successfully built an optimistic payload.\nfunc (cm *chainMetrics) markOptimisticPayloadBuildSuccess(slot math.Slot) {\n\tcm.sink.IncrementCounter(\n\t\t\"beacon_kit.blockchain.optimistic_payload_build_success\",\n\t\t\"slot\",\n\t\tslot.Base10(),\n\t)\n}\n\n// markOptimisticPayloadBuildFailure increments the counter for the number of\n// times the validator failed to build an optimistic payload.\nfunc (cm *chainMetrics) markOptimisticPayloadBuildFailure(\n\tslot math.Slot,\n\terr error,\n) {\n\tcm.sink.IncrementCounter(\n\t\t\"beacon_kit.blockchain.optimistic_payload_build_failure\",\n\t\t\"slot\",\n\t\tslot.Base10(),\n\t\t\"error\",\n\t\terr.Error(),\n\t)\n}\n\n// TODO: remove once state caching is activated\n// measureStateRootVerificationTime measures the time taken to verify the state\n// root of a block.\n// It records the duration from the provided start time to the current time.\nfunc (cm *chainMetrics) measureStateRootVerificationTime(start time.Time) {\n\tcm.sink.MeasureSince(\n\t\t\"beacon_kit.blockchain.state_root_verification_duration\", start,\n\t)\n}\n"
  },
  {
    "path": "beacon/blockchain/mocks/genesis_state_processor.mock.go",
    "content": "// Code generated by mockery v2.53.5. DO NOT EDIT.\n\npackage mocks\n\nimport (\n\tcommon \"github.com/berachain/beacon-kit/primitives/common\"\n\tmock \"github.com/stretchr/testify/mock\"\n\n\tstate \"github.com/berachain/beacon-kit/state-transition/core/state\"\n\n\ttransition \"github.com/berachain/beacon-kit/primitives/transition\"\n\n\ttypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n)\n\n// GenesisStateProcessor is an autogenerated mock type for the GenesisStateProcessor type\ntype GenesisStateProcessor struct {\n\tmock.Mock\n}\n\ntype GenesisStateProcessor_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *GenesisStateProcessor) EXPECT() *GenesisStateProcessor_Expecter {\n\treturn &GenesisStateProcessor_Expecter{mock: &_m.Mock}\n}\n\n// InitializeBeaconStateFromEth1 provides a mock function with given fields: st, deposits, execPayloadHeader, genesisVersion\nfunc (_m *GenesisStateProcessor) InitializeBeaconStateFromEth1(st *state.StateDB, deposits types.Deposits, execPayloadHeader *types.ExecutionPayloadHeader, genesisVersion common.Version) (transition.ValidatorUpdates, error) {\n\tret := _m.Called(st, deposits, execPayloadHeader, genesisVersion)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for InitializeBeaconStateFromEth1\")\n\t}\n\n\tvar r0 transition.ValidatorUpdates\n\tvar r1 error\n\tif rf, ok := ret.Get(0).(func(*state.StateDB, types.Deposits, *types.ExecutionPayloadHeader, common.Version) (transition.ValidatorUpdates, error)); ok {\n\t\treturn rf(st, deposits, execPayloadHeader, genesisVersion)\n\t}\n\tif rf, ok := ret.Get(0).(func(*state.StateDB, types.Deposits, *types.ExecutionPayloadHeader, common.Version) transition.ValidatorUpdates); ok {\n\t\tr0 = rf(st, deposits, execPayloadHeader, genesisVersion)\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(transition.ValidatorUpdates)\n\t\t}\n\t}\n\n\tif rf, ok := ret.Get(1).(func(*state.StateDB, types.Deposits, *types.ExecutionPayloadHeader, common.Version) error); ok {\n\t\tr1 = rf(st, deposits, execPayloadHeader, genesisVersion)\n\t} else {\n\t\tr1 = ret.Error(1)\n\t}\n\n\treturn r0, r1\n}\n\n// GenesisStateProcessor_InitializeBeaconStateFromEth1_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'InitializeBeaconStateFromEth1'\ntype GenesisStateProcessor_InitializeBeaconStateFromEth1_Call struct {\n\t*mock.Call\n}\n\n// InitializeBeaconStateFromEth1 is a helper method to define mock.On call\n//   - st *state.StateDB\n//   - deposits types.Deposits\n//   - execPayloadHeader *types.ExecutionPayloadHeader\n//   - genesisVersion common.Version\nfunc (_e *GenesisStateProcessor_Expecter) InitializeBeaconStateFromEth1(st interface{}, deposits interface{}, execPayloadHeader interface{}, genesisVersion interface{}) *GenesisStateProcessor_InitializeBeaconStateFromEth1_Call {\n\treturn &GenesisStateProcessor_InitializeBeaconStateFromEth1_Call{Call: _e.mock.On(\"InitializeBeaconStateFromEth1\", st, deposits, execPayloadHeader, genesisVersion)}\n}\n\nfunc (_c *GenesisStateProcessor_InitializeBeaconStateFromEth1_Call) Run(run func(st *state.StateDB, deposits types.Deposits, execPayloadHeader *types.ExecutionPayloadHeader, genesisVersion common.Version)) *GenesisStateProcessor_InitializeBeaconStateFromEth1_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(*state.StateDB), args[1].(types.Deposits), args[2].(*types.ExecutionPayloadHeader), args[3].(common.Version))\n\t})\n\treturn _c\n}\n\nfunc (_c *GenesisStateProcessor_InitializeBeaconStateFromEth1_Call) Return(_a0 transition.ValidatorUpdates, _a1 error) *GenesisStateProcessor_InitializeBeaconStateFromEth1_Call {\n\t_c.Call.Return(_a0, _a1)\n\treturn _c\n}\n\nfunc (_c *GenesisStateProcessor_InitializeBeaconStateFromEth1_Call) RunAndReturn(run func(*state.StateDB, types.Deposits, *types.ExecutionPayloadHeader, common.Version) (transition.ValidatorUpdates, error)) *GenesisStateProcessor_InitializeBeaconStateFromEth1_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewGenesisStateProcessor creates a new instance of GenesisStateProcessor. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewGenesisStateProcessor(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *GenesisStateProcessor {\n\tmock := &GenesisStateProcessor{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "beacon/blockchain/mocks/local_builder.mock.go",
    "content": "// Code generated by mockery v2.53.5. DO NOT EDIT.\n\npackage mocks\n\nimport (\n\tcontext \"context\"\n\n\ttypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\tbuilder \"github.com/berachain/beacon-kit/payload/builder\"\n\tcommon \"github.com/berachain/beacon-kit/primitives/common\"\n\tmath \"github.com/berachain/beacon-kit/primitives/math\"\n\tmock \"github.com/stretchr/testify/mock\"\n)\n\n// LocalBuilder is an autogenerated mock type for the LocalBuilder type\ntype LocalBuilder struct {\n\tmock.Mock\n}\n\ntype LocalBuilder_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *LocalBuilder) EXPECT() *LocalBuilder_Expecter {\n\treturn &LocalBuilder_Expecter{mock: &_m.Mock}\n}\n\n// CacheLatestVerifiedPayload provides a mock function with given fields: latestEnvelopeSlot, latestEnvelope\nfunc (_m *LocalBuilder) CacheLatestVerifiedPayload(latestEnvelopeSlot math.Slot, latestEnvelope types.BuiltExecutionPayloadEnv) {\n\t_m.Called(latestEnvelopeSlot, latestEnvelope)\n}\n\n// LocalBuilder_CacheLatestVerifiedPayload_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CacheLatestVerifiedPayload'\ntype LocalBuilder_CacheLatestVerifiedPayload_Call struct {\n\t*mock.Call\n}\n\n// CacheLatestVerifiedPayload is a helper method to define mock.On call\n//   - latestEnvelopeSlot math.Slot\n//   - latestEnvelope types.BuiltExecutionPayloadEnv\nfunc (_e *LocalBuilder_Expecter) CacheLatestVerifiedPayload(latestEnvelopeSlot interface{}, latestEnvelope interface{}) *LocalBuilder_CacheLatestVerifiedPayload_Call {\n\treturn &LocalBuilder_CacheLatestVerifiedPayload_Call{Call: _e.mock.On(\"CacheLatestVerifiedPayload\", latestEnvelopeSlot, latestEnvelope)}\n}\n\nfunc (_c *LocalBuilder_CacheLatestVerifiedPayload_Call) Run(run func(latestEnvelopeSlot math.Slot, latestEnvelope types.BuiltExecutionPayloadEnv)) *LocalBuilder_CacheLatestVerifiedPayload_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(math.Slot), args[1].(types.BuiltExecutionPayloadEnv))\n\t})\n\treturn _c\n}\n\nfunc (_c *LocalBuilder_CacheLatestVerifiedPayload_Call) Return() *LocalBuilder_CacheLatestVerifiedPayload_Call {\n\t_c.Call.Return()\n\treturn _c\n}\n\nfunc (_c *LocalBuilder_CacheLatestVerifiedPayload_Call) RunAndReturn(run func(math.Slot, types.BuiltExecutionPayloadEnv)) *LocalBuilder_CacheLatestVerifiedPayload_Call {\n\t_c.Run(run)\n\treturn _c\n}\n\n// Enabled provides a mock function with no fields\nfunc (_m *LocalBuilder) Enabled() bool {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for Enabled\")\n\t}\n\n\tvar r0 bool\n\tif rf, ok := ret.Get(0).(func() bool); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tr0 = ret.Get(0).(bool)\n\t}\n\n\treturn r0\n}\n\n// LocalBuilder_Enabled_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Enabled'\ntype LocalBuilder_Enabled_Call struct {\n\t*mock.Call\n}\n\n// Enabled is a helper method to define mock.On call\nfunc (_e *LocalBuilder_Expecter) Enabled() *LocalBuilder_Enabled_Call {\n\treturn &LocalBuilder_Enabled_Call{Call: _e.mock.On(\"Enabled\")}\n}\n\nfunc (_c *LocalBuilder_Enabled_Call) Run(run func()) *LocalBuilder_Enabled_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *LocalBuilder_Enabled_Call) Return(_a0 bool) *LocalBuilder_Enabled_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *LocalBuilder_Enabled_Call) RunAndReturn(run func() bool) *LocalBuilder_Enabled_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// RequestPayloadAsync provides a mock function with given fields: ctx, r\nfunc (_m *LocalBuilder) RequestPayloadAsync(ctx context.Context, r *builder.RequestPayloadData) (*engineprimitives.PayloadID, common.Version, error) {\n\tret := _m.Called(ctx, r)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for RequestPayloadAsync\")\n\t}\n\n\tvar r0 *engineprimitives.PayloadID\n\tvar r1 common.Version\n\tvar r2 error\n\tif rf, ok := ret.Get(0).(func(context.Context, *builder.RequestPayloadData) (*engineprimitives.PayloadID, common.Version, error)); ok {\n\t\treturn rf(ctx, r)\n\t}\n\tif rf, ok := ret.Get(0).(func(context.Context, *builder.RequestPayloadData) *engineprimitives.PayloadID); ok {\n\t\tr0 = rf(ctx, r)\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(*engineprimitives.PayloadID)\n\t\t}\n\t}\n\n\tif rf, ok := ret.Get(1).(func(context.Context, *builder.RequestPayloadData) common.Version); ok {\n\t\tr1 = rf(ctx, r)\n\t} else {\n\t\tif ret.Get(1) != nil {\n\t\t\tr1 = ret.Get(1).(common.Version)\n\t\t}\n\t}\n\n\tif rf, ok := ret.Get(2).(func(context.Context, *builder.RequestPayloadData) error); ok {\n\t\tr2 = rf(ctx, r)\n\t} else {\n\t\tr2 = ret.Error(2)\n\t}\n\n\treturn r0, r1, r2\n}\n\n// LocalBuilder_RequestPayloadAsync_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RequestPayloadAsync'\ntype LocalBuilder_RequestPayloadAsync_Call struct {\n\t*mock.Call\n}\n\n// RequestPayloadAsync is a helper method to define mock.On call\n//   - ctx context.Context\n//   - r *builder.RequestPayloadData\nfunc (_e *LocalBuilder_Expecter) RequestPayloadAsync(ctx interface{}, r interface{}) *LocalBuilder_RequestPayloadAsync_Call {\n\treturn &LocalBuilder_RequestPayloadAsync_Call{Call: _e.mock.On(\"RequestPayloadAsync\", ctx, r)}\n}\n\nfunc (_c *LocalBuilder_RequestPayloadAsync_Call) Run(run func(ctx context.Context, r *builder.RequestPayloadData)) *LocalBuilder_RequestPayloadAsync_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(context.Context), args[1].(*builder.RequestPayloadData))\n\t})\n\treturn _c\n}\n\nfunc (_c *LocalBuilder_RequestPayloadAsync_Call) Return(_a0 *engineprimitives.PayloadID, _a1 common.Version, _a2 error) *LocalBuilder_RequestPayloadAsync_Call {\n\t_c.Call.Return(_a0, _a1, _a2)\n\treturn _c\n}\n\nfunc (_c *LocalBuilder_RequestPayloadAsync_Call) RunAndReturn(run func(context.Context, *builder.RequestPayloadData) (*engineprimitives.PayloadID, common.Version, error)) *LocalBuilder_RequestPayloadAsync_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewLocalBuilder creates a new instance of LocalBuilder. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewLocalBuilder(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *LocalBuilder {\n\tmock := &LocalBuilder{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "beacon/blockchain/mocks/storage_backend.mock.go",
    "content": "// Code generated by mockery v2.53.5. DO NOT EDIT.\n\npackage mocks\n\nimport (\n\tblock \"github.com/berachain/beacon-kit/storage/block\"\n\n\tcontext \"context\"\n\n\ttypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tstore \"github.com/berachain/beacon-kit/da/store\"\n\tstate \"github.com/berachain/beacon-kit/state-transition/core/state\"\n\tdeposit \"github.com/berachain/beacon-kit/storage/deposit\"\n\tmock \"github.com/stretchr/testify/mock\"\n)\n\n// StorageBackend is an autogenerated mock type for the StorageBackend type\ntype StorageBackend struct {\n\tmock.Mock\n}\n\ntype StorageBackend_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *StorageBackend) EXPECT() *StorageBackend_Expecter {\n\treturn &StorageBackend_Expecter{mock: &_m.Mock}\n}\n\n// AvailabilityStore provides a mock function with no fields\nfunc (_m *StorageBackend) AvailabilityStore() *store.Store {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for AvailabilityStore\")\n\t}\n\n\tvar r0 *store.Store\n\tif rf, ok := ret.Get(0).(func() *store.Store); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(*store.Store)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// StorageBackend_AvailabilityStore_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AvailabilityStore'\ntype StorageBackend_AvailabilityStore_Call struct {\n\t*mock.Call\n}\n\n// AvailabilityStore is a helper method to define mock.On call\nfunc (_e *StorageBackend_Expecter) AvailabilityStore() *StorageBackend_AvailabilityStore_Call {\n\treturn &StorageBackend_AvailabilityStore_Call{Call: _e.mock.On(\"AvailabilityStore\")}\n}\n\nfunc (_c *StorageBackend_AvailabilityStore_Call) Run(run func()) *StorageBackend_AvailabilityStore_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *StorageBackend_AvailabilityStore_Call) Return(_a0 *store.Store) *StorageBackend_AvailabilityStore_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *StorageBackend_AvailabilityStore_Call) RunAndReturn(run func() *store.Store) *StorageBackend_AvailabilityStore_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// BlockStore provides a mock function with no fields\nfunc (_m *StorageBackend) BlockStore() *block.KVStore[*types.BeaconBlock] {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for BlockStore\")\n\t}\n\n\tvar r0 *block.KVStore[*types.BeaconBlock]\n\tif rf, ok := ret.Get(0).(func() *block.KVStore[*types.BeaconBlock]); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(*block.KVStore[*types.BeaconBlock])\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// StorageBackend_BlockStore_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BlockStore'\ntype StorageBackend_BlockStore_Call struct {\n\t*mock.Call\n}\n\n// BlockStore is a helper method to define mock.On call\nfunc (_e *StorageBackend_Expecter) BlockStore() *StorageBackend_BlockStore_Call {\n\treturn &StorageBackend_BlockStore_Call{Call: _e.mock.On(\"BlockStore\")}\n}\n\nfunc (_c *StorageBackend_BlockStore_Call) Run(run func()) *StorageBackend_BlockStore_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *StorageBackend_BlockStore_Call) Return(_a0 *block.KVStore[*types.BeaconBlock]) *StorageBackend_BlockStore_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *StorageBackend_BlockStore_Call) RunAndReturn(run func() *block.KVStore[*types.BeaconBlock]) *StorageBackend_BlockStore_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// DepositStore provides a mock function with no fields\nfunc (_m *StorageBackend) DepositStore() deposit.StoreManager {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for DepositStore\")\n\t}\n\n\tvar r0 deposit.StoreManager\n\tif rf, ok := ret.Get(0).(func() deposit.StoreManager); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(deposit.StoreManager)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// StorageBackend_DepositStore_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DepositStore'\ntype StorageBackend_DepositStore_Call struct {\n\t*mock.Call\n}\n\n// DepositStore is a helper method to define mock.On call\nfunc (_e *StorageBackend_Expecter) DepositStore() *StorageBackend_DepositStore_Call {\n\treturn &StorageBackend_DepositStore_Call{Call: _e.mock.On(\"DepositStore\")}\n}\n\nfunc (_c *StorageBackend_DepositStore_Call) Run(run func()) *StorageBackend_DepositStore_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *StorageBackend_DepositStore_Call) Return(_a0 deposit.StoreManager) *StorageBackend_DepositStore_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *StorageBackend_DepositStore_Call) RunAndReturn(run func() deposit.StoreManager) *StorageBackend_DepositStore_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// StateFromContext provides a mock function with given fields: _a0\nfunc (_m *StorageBackend) StateFromContext(_a0 context.Context) *state.StateDB {\n\tret := _m.Called(_a0)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for StateFromContext\")\n\t}\n\n\tvar r0 *state.StateDB\n\tif rf, ok := ret.Get(0).(func(context.Context) *state.StateDB); ok {\n\t\tr0 = rf(_a0)\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(*state.StateDB)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// StorageBackend_StateFromContext_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'StateFromContext'\ntype StorageBackend_StateFromContext_Call struct {\n\t*mock.Call\n}\n\n// StateFromContext is a helper method to define mock.On call\n//   - _a0 context.Context\nfunc (_e *StorageBackend_Expecter) StateFromContext(_a0 interface{}) *StorageBackend_StateFromContext_Call {\n\treturn &StorageBackend_StateFromContext_Call{Call: _e.mock.On(\"StateFromContext\", _a0)}\n}\n\nfunc (_c *StorageBackend_StateFromContext_Call) Run(run func(_a0 context.Context)) *StorageBackend_StateFromContext_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(context.Context))\n\t})\n\treturn _c\n}\n\nfunc (_c *StorageBackend_StateFromContext_Call) Return(_a0 *state.StateDB) *StorageBackend_StateFromContext_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *StorageBackend_StateFromContext_Call) RunAndReturn(run func(context.Context) *state.StateDB) *StorageBackend_StateFromContext_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewStorageBackend creates a new instance of StorageBackend. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewStorageBackend(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *StorageBackend {\n\tmock := &StorageBackend{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "beacon/blockchain/payload.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage blockchain\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\tpayloadtime \"github.com/berachain/beacon-kit/beacon/payload-time\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\tengineerrors \"github.com/berachain/beacon-kit/engine-primitives/errors\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/payload/builder\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n)\n\n// forceSyncUponProcess sends a force head FCU to the execution client.\nfunc (s *Service) forceSyncUponProcess(\n\tctx context.Context,\n\tst *statedb.StateDB,\n) {\n\tlph, err := st.GetLatestExecutionPayloadHeader()\n\tif err != nil {\n\t\ts.logger.Error(\n\t\t\t\"failed to get latest execution payload header\",\n\t\t\t\"error\", err,\n\t\t)\n\t\treturn\n\t}\n\n\ts.logger.Info(\n\t\t\"Sending startup forkchoice update to execution client\",\n\t\t\"head_eth1_hash\", lph.GetBlockHash(),\n\t\t\"safe_eth1_hash\", lph.GetParentHash(),\n\t\t\"finalized_eth1_hash\", lph.GetParentHash(),\n\t\t\"for_slot\", lph.GetNumber(),\n\t)\n\n\t// Submit the forkchoice update to the execution client.\n\treq := ctypes.BuildForkchoiceUpdateRequestNoAttrs(\n\t\t&engineprimitives.ForkchoiceStateV1{\n\t\t\tHeadBlockHash:      lph.GetBlockHash(),\n\t\t\tSafeBlockHash:      lph.GetParentHash(),\n\t\t\tFinalizedBlockHash: lph.GetParentHash(),\n\t\t},\n\t\ts.chainSpec.ActiveForkVersionForTimestamp(lph.GetTimestamp()),\n\t)\n\tif _, err = s.executionEngine.NotifyForkchoiceUpdate(ctx, req); err != nil {\n\t\ts.logger.Error(\n\t\t\t\"failed to send force head FCU\",\n\t\t\t\"error\", err,\n\t\t)\n\t}\n}\n\n// forceSyncUponFinalize sends a new payload and force startup FCU to the Execution\n// Layer client. This informs the EL client of the new head and forces a SYNC\n// if blocks are missing. This function should only be run once at startup.\nfunc (s *Service) forceSyncUponFinalize(\n\tctx context.Context,\n\tbeaconBlock *ctypes.BeaconBlock,\n\tparentProposerPubkey *crypto.BLSPubkey,\n) error {\n\t// NewPayload call first to load payload into EL client.\n\texecutionPayload := beaconBlock.GetBody().GetExecutionPayload()\n\tpayloadReq, err := ctypes.BuildNewPayloadRequestFromFork(beaconBlock, parentProposerPubkey)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err = payloadReq.HasValidVersionedAndBlockHashes(); err != nil {\n\t\treturn err\n\t}\n\n\t// We set retryOnSyncingStatus to false here. We can ignore SYNCING status and proceed\n\t// to the FCU.\n\terr = s.executionEngine.NotifyNewPayload(ctx, payloadReq, false)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"startSyncUponFinalize NotifyNewPayload failed: %w\", err)\n\t}\n\n\t// Submit the forkchoice update to the EL client. This will ensure that it is either synced or\n\t// starts up a sync.\n\treq := ctypes.BuildForkchoiceUpdateRequestNoAttrs(\n\t\t&engineprimitives.ForkchoiceStateV1{\n\t\t\tHeadBlockHash:      executionPayload.GetBlockHash(),\n\t\t\tSafeBlockHash:      executionPayload.GetParentHash(),\n\t\t\tFinalizedBlockHash: executionPayload.GetParentHash(),\n\t\t},\n\t\ts.chainSpec.ActiveForkVersionForTimestamp(executionPayload.GetTimestamp()),\n\t)\n\n\tswitch _, err = s.executionEngine.NotifyForkchoiceUpdate(ctx, req); {\n\tcase err == nil:\n\t\treturn nil\n\n\tcase errors.IsAny(err,\n\t\tengineerrors.ErrSyncingPayloadStatus,\n\t\tengineerrors.ErrAcceptedPayloadStatus):\n\t\ts.logger.Warn(\n\t\t\t//nolint:lll // long message on one line for readability.\n\t\t\t`Your execution client is syncing. It should be downloading eth blocks from its peers. Restart the beacon node once the execution client is caught up.`,\n\t\t)\n\t\treturn err\n\n\tdefault:\n\t\treturn fmt.Errorf(\"force startup NotifyForkchoiceUpdate failed: %w\", err)\n\t}\n}\n\n// Once you provide the right state, we really need to carry out the very same operations\n// to extract the data necessary to build the next block, whether current block is\n// being rejected or accepted. This is way there can be (and so should be)\n// a single function doing these ops. preFetchBuildData is that function.\nfunc (s *Service) preFetchBuildData(st *statedb.StateDB, currentTime math.U64) (\n\t*builder.RequestPayloadData,\n\terror,\n) {\n\tlph, err := st.GetLatestExecutionPayloadHeader()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed retrieving latest execution payload header: %w\", err)\n\t}\n\tnextPayloadTimestamp := payloadtime.Next(\n\t\tcurrentTime,\n\t\tlph.GetTimestamp(),\n\t\ttrue, // buildOptimistically\n\t)\n\n\tstateSlot, err := st.GetSlot()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed retrieving slot from state: %w\", err)\n\t}\n\tblkSlot := stateSlot + 1\n\n\t// Carry out on the support state st all the operations needed to\n\t// process a new payload, namely ProcessSlots and ProcessFork\n\tif _, err = s.stateProcessor.ProcessSlots(st, blkSlot); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed processing block slot: %w\", err)\n\t}\n\tif err = s.stateProcessor.ProcessFork(st, nextPayloadTimestamp, false); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed processing fork: %w\", err)\n\t}\n\n\t// Once the state is ready, extract relevant data to build next payload\n\tpayloadWithdrawals, _, err := st.ExpectedWithdrawals(nextPayloadTimestamp)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed computing expected withdrawals: %w\", err)\n\t}\n\tepoch := s.chainSpec.SlotToEpoch(blkSlot)\n\tprevRandao, err := st.GetRandaoMixAtIndex(\n\t\tepoch.Unwrap() % s.chainSpec.EpochsPerHistoricalVector(),\n\t)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed retrieving randao: %w\", err)\n\t}\n\n\tlatestHeader, err := st.GetLatestBlockHeader()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tparentProposerPubkey, err := st.ParentProposerPubkey(nextPayloadTimestamp)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed retrieving previous proposer public key: %w\", err)\n\t}\n\n\treturn &builder.RequestPayloadData{\n\t\tSlot:               blkSlot,\n\t\tTimestamp:          nextPayloadTimestamp,\n\t\tPayloadWithdrawals: payloadWithdrawals,\n\t\tPrevRandao:         prevRandao,\n\t\tParentBlockRoot:    latestHeader.HashTreeRoot(),\n\t\tFCState: engineprimitives.ForkchoiceStateV1{\n\t\t\t// We set the head of our chain to the latest verified block (whether it is final or not)\n\t\t\tHeadBlockHash: lph.GetBlockHash(),\n\n\t\t\tSafeBlockHash: lph.GetParentHash(),\n\t\t\t// Assuming consensus guarantees single slot finality, the parent\n\t\t\t// of the latest block we verified must be final already.\n\t\t\tFinalizedBlockHash: lph.GetParentHash(),\n\t\t},\n\t\tParentProposerPubkey: parentProposerPubkey,\n\t}, nil\n}\n\n// handleRebuildPayloadForRejectedBlock handles the case where the incoming\n// block was rejected and we need to rebuild the payload for the current slot.\nfunc (s *Service) handleRebuildPayloadForRejectedBlock(\n\tctx context.Context,\n\tbuildData *builder.RequestPayloadData,\n) {\n\ts.logger.Info(\"Rebuilding payload for rejected block ⏳ \")\n\tnextBlkSlot := buildData.Slot\n\tif _, _, err := s.localBuilder.RequestPayloadAsync(ctx, buildData); err != nil {\n\t\ts.metrics.markRebuildPayloadForRejectedBlockFailure(nextBlkSlot, err)\n\t\ts.logger.Error(\n\t\t\t\"failed to rebuild payload for nil block\",\n\t\t\t\"error\", err,\n\t\t)\n\t\treturn\n\t}\n\n\ts.latestFcuReq.Store(&buildData.FCState)\n\n\ts.metrics.markRebuildPayloadForRejectedBlockSuccess(nextBlkSlot)\n}\n\n// handleOptimisticPayloadBuild handles optimistically\n// building for the next slot.\nfunc (s *Service) handleOptimisticPayloadBuild(\n\tctx context.Context,\n\tbuildData *builder.RequestPayloadData,\n) {\n\ts.logger.Info(\n\t\t\"Optimistically triggering payload build for next slot 🛩️ \",\n\t\t\"next_slot\", buildData.Slot.Base10(),\n\t)\n\tif _, _, err := s.localBuilder.RequestPayloadAsync(ctx, buildData); err != nil {\n\t\ts.metrics.markOptimisticPayloadBuildFailure(buildData.Slot, err)\n\t\ts.logger.Error(\n\t\t\t\"Failed to build optimistic payload\",\n\t\t\t\"for_slot\", buildData.Slot.Base10(),\n\t\t\t\"error\", err,\n\t\t)\n\t\treturn\n\t}\n\n\ts.latestFcuReq.Store(&buildData.FCState)\n\n\ts.metrics.markOptimisticPayloadBuildSuccess(buildData.Slot)\n}\n"
  },
  {
    "path": "beacon/blockchain/payload_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage blockchain_test\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"cosmossdk.io/log\"\n\tstoretypes \"cosmossdk.io/store/types\"\n\t\"github.com/berachain/beacon-kit/beacon/blockchain\"\n\tbcmocks \"github.com/berachain/beacon-kit/beacon/blockchain/mocks\"\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/consensus/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\tgethtypes \"github.com/berachain/beacon-kit/gethlib/types\"\n\t\"github.com/berachain/beacon-kit/node-core/components/metrics\"\n\t\"github.com/berachain/beacon-kit/payload/builder\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/berachain/beacon-kit/state-transition/core\"\n\tstmocks \"github.com/berachain/beacon-kit/state-transition/core/mocks\"\n\t\"github.com/berachain/beacon-kit/state-transition/core/state\"\n\t\"github.com/berachain/beacon-kit/storage/deposit\"\n\tstatetransition \"github.com/berachain/beacon-kit/testing/state-transition\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n\t\"github.com/stretchr/testify/mock\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// When we reject a block and we have optimistic payload building enabled\n// we must make sure that a few beacon state quantities are duly pre-processed\n// before building the block.\nfunc TestOptimisticBlockBuildingRejectedBlockStateChecks(t *testing.T) {\n\tt.Parallel()\n\n\tcs, err := spec.MainnetChainSpec()\n\trequire.NoError(t, err)\n\n\tchain, st, _, ctx, _, b, sb, eng, depStore := setupOptimisticPayloadTests(t, cs)\n\tsb.EXPECT().StateFromContext(mock.Anything).Return(st)\n\tsb.EXPECT().DepositStore().RunAndReturn(func() deposit.StoreManager { return depStore })\n\tb.EXPECT().Enabled().Return(true)\n\n\t// Note: test avoid calling chain.Start since it only starts the deposits\n\t// goroutine which is not really relevant for this test\n\n\t// Before processing any block it is mandatory to handle genesis\n\tgenesisData := testProcessGenesis(t, cs, chain, ctx)\n\n\t// Finally create a block that will be rejected and\n\t// verify the state on top of which is next payload built\n\tvar (\n\t\tconsensusTime   = time.Now()\n\t\tproposerAddress = []byte{'d', 'u', 'm', 'm', 'y'} // this will err on purpose\n\t)\n\n\t// Since this is the first block called post genesis\n\t// forceSyncUponProcess will be called.\n\tdummyPayloadID := &engineprimitives.PayloadID{1, 2, 3}\n\teng.EXPECT().NotifyForkchoiceUpdate(mock.Anything, mock.Anything).Return(dummyPayloadID, nil)\n\n\t// we set just enough data in invalid block to let it pass\n\t// the first validations in chain before state processor is invoked\n\tinvalidBlk := &ctypes.BeaconBlock{\n\t\tSlot: 1, // first block after genesis\n\t\tBody: &ctypes.BeaconBlockBody{\n\t\t\tExecutionPayload: &ctypes.ExecutionPayload{\n\t\t\t\tTimestamp: math.U64(cs.GenesisTime() + 1),\n\t\t\t},\n\t\t},\n\t}\n\n\t// register async call to block building\n\tvar wg sync.WaitGroup          // useful to make test wait on async checks\n\tstateRoot := st.HashTreeRoot() // track state root before the changes done by optimistic build\n\tlatestHeader, err := st.GetLatestBlockHeader()\n\trequire.NoError(t, err)\n\tlatestHeader.SetStateRoot(stateRoot)\n\texpectedParentBlockRoot := latestHeader.HashTreeRoot()\n\n\tb.EXPECT().RequestPayloadAsync(mock.Anything, mock.Anything).Run(\n\t\tfunc(_ context.Context, r *builder.RequestPayloadData) {\n\t\t\tdefer wg.Done()\n\t\t\tgenesisHeader := genesisData.ExecutionPayloadHeader\n\t\t\tgenesisBlkHeader := core.GenesisBlockHeader(cs.GenesisForkVersion())\n\t\t\tgenesisBlkHeader.SetStateRoot(stateRoot)\n\n\t\t\trequire.Equal(t, math.U64(consensusTime.Unix())+1, r.Timestamp)\n\n\t\t\trequire.Equal(t, genesisHeader.GetBlockHash(), r.FCState.HeadBlockHash)\n\n\t\t\trequire.Equal(t, expectedParentBlockRoot, r.ParentBlockRoot)\n\n\t\t\trequire.Empty(t, r.FCState.FinalizedBlockHash)    // this is first block post genesis\n\t\t\trequire.Equal(t, constants.GenesisSlot+1, r.Slot) // rebuild block on top of genesis\n\t\t},\n\t).Return(nil, common.Version{0xff}, errors.New(\"does not matter\")) // return values do not really matter in this test\n\twg.Add(1)\n\n\t// check slot pre test\n\tslot, err := st.GetSlot()\n\trequire.NoError(t, err)\n\trequire.Equal(t, constants.GenesisSlot, slot)\n\n\t_, err = chain.VerifyIncomingBlock(\n\t\tctx.ConsensusCtx(),\n\t\ttypes.NewConsensusBlock(invalidBlk, proposerAddress, consensusTime),\n\t\ttrue, // this block is next block proposer\n\t)\n\trequire.ErrorIs(t, err, core.ErrProposerMismatch)\n\n\t// wait for block building goroutine to carry out all the checks\n\twg.Wait()\n\n\t// No checks on state st post block. The block is invalid so\n\t// its state will be dropped and its content does not matter\n}\n\n// When we verify successfully a block and we have optimistic payload building enabled\n// we must make sure that a few beacon state quantities are duly pre-processed\n// before building the block.\nfunc TestOptimisticBlockBuildingVerifiedBlockStateChecks(t *testing.T) {\n\tt.Parallel()\n\n\tcs, err := spec.MainnetChainSpec()\n\trequire.NoError(t, err)\n\n\tchain, st, cms, ctx, sp, b, sb, eng, depStore := setupOptimisticPayloadTests(t, cs)\n\tsb.EXPECT().StateFromContext(mock.Anything).Return(st).Times(1) // only for genesis\n\tsb.EXPECT().DepositStore().RunAndReturn(func() deposit.StoreManager { return depStore })\n\tb.EXPECT().Enabled().Return(true)\n\n\t// Before processing any block it is mandatory to handle genesis\n\tgenesisData := testProcessGenesis(t, cs, chain, ctx)\n\n\t// write genesis changes to make them available for next block\n\t//nolint:errcheck // false positive as this has no return value\n\tctx.ConsensusCtx().(sdk.Context).MultiStore().(storetypes.CacheMultiStore).Write()\n\n\t// Finally create a block that will be rejected and\n\t// verify the state on top of which is next payload built\n\tvar (\n\t\tconsensusTime = time.Now()\n\t\tproposer      = ctx.ProposerAddress()\n\t)\n\n\t// Since this is the first block called post genesis\n\t// forceSyncUponProcess will be called.\n\tdummyPayloadID := &engineprimitives.PayloadID{1, 2, 3}\n\teng.EXPECT().NotifyForkchoiceUpdate(mock.Anything, mock.Anything).Return(dummyPayloadID, nil)\n\n\t// BUILD A VALID BLOCK (without polluting state st)\n\tsdkCtx := sdk.NewContext(cms.CacheMultiStore(), true, log.NewNopLogger())\n\tbuildState := state.NewBeaconStateFromDB(\n\t\tst.KVStore.WithContext(sdkCtx), cs, sdkCtx.Logger(), metrics.NewNoOpTelemetrySink(),\n\t)\n\n\tnextBlkTimestamp := math.U64(cs.GenesisTime() + 1)\n\t_, err = sp.ProcessSlots(buildState, constants.GenesisSlot+1)\n\trequire.NoError(t, err)\n\n\tdepositsRoot := ctypes.Deposits(genesisData.Deposits).HashTreeRoot()\n\n\tvalidBlk := buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tbuildState,\n\t\tctypes.NewEth1Data(depositsRoot),\n\t\tnextBlkTimestamp,\n\t)\n\tstateRoot, err := computeStateRoot( // fix state root in block\n\t\tctx.ConsensusCtx(),\n\t\tproposer,\n\t\tmath.U64(consensusTime.Unix()),\n\t\tsp,\n\t\tbuildState,\n\t\tvalidBlk,\n\t)\n\trequire.NoError(t, err)\n\tvalidBlk.SetStateRoot(stateRoot)\n\t// end of BUILD A VALID BLOCK\n\n\t// register async call to block building\n\tvar wg sync.WaitGroup // useful to make test wait on async checks\n\tb.EXPECT().RequestPayloadAsync(mock.Anything, mock.Anything).Run(\n\t\tfunc(_ context.Context, r *builder.RequestPayloadData) {\n\t\t\tdefer wg.Done()\n\t\t\trequire.Equal(t, math.U64(consensusTime.Unix())+1, r.Timestamp)\n\n\t\t\trequire.Equal(\n\t\t\t\tt,\n\t\t\t\tvalidBlk.GetBody().GetExecutionPayload().GetBlockHash(),\n\t\t\t\tr.FCState.HeadBlockHash,\n\t\t\t)\n\n\t\t\tgenesisHeader := genesisData.ExecutionPayloadHeader.GetBlockHash()\n\t\t\trequire.Equal(t, genesisHeader, r.FCState.FinalizedBlockHash)\n\n\t\t\trequire.Equal(t, validBlk.HashTreeRoot(), r.ParentBlockRoot)\n\t\t\trequire.Equal(t, validBlk.Slot+1, r.Slot)\n\t\t},\n\t).Return(nil, common.Version{0xff}, errors.New(\"does not matter\")) // return values do not really matter in this test\n\twg.Add(1)\n\n\t// check slot pre test\n\tslot, err := st.GetSlot()\n\trequire.NoError(t, err)\n\trequire.Equal(t, constants.GenesisSlot, slot)\n\n\teng.EXPECT().NotifyNewPayload(mock.Anything, mock.Anything, mock.Anything).Return(nil)\n\tsb.EXPECT().StateFromContext(mock.Anything).Return(st).Times(1)\n\t_, err = chain.VerifyIncomingBlock(\n\t\tctx.ConsensusCtx(),\n\t\ttypes.NewConsensusBlock(validBlk, ctx.ProposerAddress(), consensusTime),\n\t\ttrue, // this block is next block proposer\n\t)\n\trequire.NoError(t, err)\n\n\t// wait for block building goroutine to carry out all the checks\n\twg.Wait()\n\n\t// check slot post test\n\tslot, err = st.GetSlot()\n\trequire.NoError(t, err)\n\trequire.Equal(t, validBlk.GetSlot(), slot)\n}\n\nfunc setupOptimisticPayloadTests(t *testing.T, cs chain.Spec) (\n\t*blockchain.Service,\n\t*statetransition.TestBeaconStateT,\n\tstoretypes.CommitMultiStore,\n\tcore.ReadOnlyContext,\n\t*statetransition.TestStateProcessorT,\n\t*bcmocks.LocalBuilder,\n\t*bcmocks.StorageBackend,\n\t*stmocks.ExecutionEngine,\n\tdeposit.StoreManager,\n) {\n\tt.Helper()\n\tsp, st, depStore, ctx, cms, eng := statetransition.SetupTestState(t, cs)\n\n\tlogger := log.NewNopLogger()\n\tts := metrics.NewNoOpTelemetrySink()\n\tsb := bcmocks.NewStorageBackend(t)\n\tb := bcmocks.NewLocalBuilder(t)\n\n\tchain := blockchain.NewService(\n\t\tsb,\n\t\tnil, // blockchain.BlobProcessor unused in this test\n\t\tnil, // deposit.Contract unused in this test\n\t\tlogger,\n\t\tcs,\n\t\teng,\n\t\tb,\n\t\tsp,\n\t\tts,\n\t)\n\treturn chain, st, cms, ctx, sp, b, sb, eng, depStore\n}\n\nfunc testProcessGenesis(\n\tt *testing.T,\n\tcs chain.Spec,\n\tchain *blockchain.Service,\n\tctx core.ReadOnlyContext,\n) *ctypes.Genesis {\n\tt.Helper()\n\n\t// TODO: I had to manually align default genesis and cs specs\n\t// Check if this is correct/necessary\n\tgenesisData := ctypes.DefaultGenesis(cs.GenesisForkVersion())\n\tgenesisData.ExecutionPayloadHeader.Timestamp = math.U64(cs.GenesisTime())\n\tgenesisData.Deposits = []*ctypes.Deposit{\n\t\t{\n\t\t\tPubkey: [48]byte{0x01},\n\t\t\tAmount: cs.MaxEffectiveBalance(),\n\t\t\tCredentials: ctypes.NewCredentialsFromExecutionAddress(\n\t\t\t\tcommon.ExecutionAddress{0x01},\n\t\t\t),\n\t\t\tIndex: uint64(0),\n\t\t},\n\t}\n\tgenBytes, err := json.Marshal(genesisData)\n\trequire.NoError(t, err)\n\t_, err = chain.ProcessGenesisData(ctx.ConsensusCtx(), genBytes)\n\trequire.NoError(t, err)\n\treturn genesisData\n}\n\nfunc buildNextBlock(\n\tt *testing.T,\n\tcs chain.Spec,\n\tst *state.StateDB,\n\teth1Data *ctypes.Eth1Data,\n\ttimestamp math.U64,\n) *ctypes.BeaconBlock {\n\tt.Helper()\n\trequire.NotNil(t, cs)\n\n\tparentBlkHeader, err := st.GetLatestBlockHeader()\n\trequire.NoError(t, err)\n\tnextBlockSlot := parentBlkHeader.GetSlot() + 1\n\tnextBlockEpoch := cs.SlotToEpoch(nextBlockSlot)\n\n\trandaoMix, err := st.GetRandaoMixAtIndex(nextBlockEpoch.Unwrap() % cs.EpochsPerHistoricalVector())\n\trequire.NoError(t, err)\n\n\t// build the block\n\tfv := cs.ActiveForkVersionForTimestamp(timestamp)\n\tversionable := ctypes.NewVersionable(fv)\n\tblk, err := ctypes.NewBeaconBlockWithVersion(\n\t\tnextBlockSlot,\n\t\tparentBlkHeader.GetProposerIndex(),\n\t\tparentBlkHeader.HashTreeRoot(),\n\t\tfv,\n\t)\n\trequire.NoError(t, err)\n\n\t// build the payload\n\tlph, err := st.GetLatestExecutionPayloadHeader()\n\trequire.NoError(t, err)\n\n\t// Check chain canonicity\n\tpayload := &ctypes.ExecutionPayload{\n\t\tVersionable: versionable,\n\t\tTimestamp:   timestamp,\n\t\tParentHash:  lph.GetBlockHash(),\n\t\tRandom:      randaoMix,\n\n\t\tExtraData:     []byte(\"testing\"),\n\t\tTransactions:  [][]byte{},\n\t\tWithdrawals:   []*engineprimitives.Withdrawal{st.EVMInflationWithdrawal(timestamp)},\n\t\tBaseFeePerGas: math.NewU256(0),\n\t}\n\tparentBeaconBlockRoot := parentBlkHeader.HashTreeRoot()\n\n\tvar (\n\t\tethBlk    *gethtypes.Block\n\t\tnoExecReq = &ctypes.ExecutionRequests{}\n\t)\n\tif version.IsBefore(fv, version.Electra()) {\n\t\tethBlk, _, err = ctypes.MakeEthBlock(payload, parentBeaconBlockRoot, nil, nil)\n\t\trequire.NoError(t, err)\n\t} else {\n\t\tencodedER, erErr := ctypes.GetExecutionRequestsList(noExecReq)\n\t\trequire.NoError(t, erErr)\n\t\trequire.NotNil(t, encodedER)\n\t\tethBlk, _, err = ctypes.MakeEthBlock(payload, parentBeaconBlockRoot, encodedER, nil)\n\t\trequire.NoError(t, err)\n\t}\n\tpayload.BlockHash = common.ExecutionHash(ethBlk.Hash())\n\n\trequire.NoError(t, err)\n\tblk.Body = &ctypes.BeaconBlockBody{\n\t\tVersionable:      versionable,\n\t\tExecutionPayload: payload,\n\t\tEth1Data:         eth1Data,\n\t}\n\tif version.EqualsOrIsAfter(fv, version.Electra()) {\n\t\terr = blk.Body.SetExecutionRequests(noExecReq)\n\t\trequire.NoError(t, err)\n\t}\n\treturn blk\n}\n\nfunc computeStateRoot(\n\tctx context.Context,\n\tproposerAddress []byte,\n\tconsensusTime math.U64,\n\tsp *statetransition.TestStateProcessorT,\n\tst *state.StateDB,\n\tblk *ctypes.BeaconBlock,\n) (common.Root, error) {\n\ttxCtx := transition.NewTransitionCtx(\n\t\tctx,\n\t\tconsensusTime,\n\t\tproposerAddress,\n\t).\n\t\tWithVerifyPayload(false).\n\t\tWithVerifyRandao(false).\n\t\tWithVerifyResult(false).\n\t\tWithMeterGas(false)\n\n\t//nolint:contextcheck // we need txCtx\n\tif _, err := sp.Transition(txCtx, st, blk); err != nil {\n\t\treturn common.Root{}, err\n\t}\n\n\treturn st.HashTreeRoot(), nil\n}\n"
  },
  {
    "path": "beacon/blockchain/process_proposal.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage blockchain\n\nimport (\n\t\"bytes\"\n\t\"cmp\"\n\t\"context\"\n\t\"fmt\"\n\t\"slices\"\n\t\"time\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/cache\"\n\t\"github.com/berachain/beacon-kit/consensus/types\"\n\tdatypes \"github.com/berachain/beacon-kit/da/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/payload/builder\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/berachain/beacon-kit/state-transition/core\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n\tcmtabci \"github.com/cometbft/cometbft/abci/types\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n)\n\nconst (\n\t// BeaconBlockTxIndex represents the index of the beacon block transaction.\n\t// It is the first transaction in the tx list.\n\tBeaconBlockTxIndex uint = iota\n\t// BlobSidecarsTxIndex represents the index of the blob sidecar transaction.\n\t// It follows the beacon block transaction in the tx list.\n\tBlobSidecarsTxIndex\n\n\t// A Consensus block has at most two transactions (block and blob).\n\tMaxConsensusTxsCount = 2\n)\n\n//nolint:funlen // abundantly commented\nfunc (s *Service) ProcessProposal(\n\tctx sdk.Context,\n\treq *cmtabci.ProcessProposalRequest,\n\tthisNodeAddress []byte,\n) (transition.ValidatorUpdates, error) {\n\tsignedBlk, sidecars, err := s.ParseBeaconBlock(req)\n\tif err != nil {\n\t\ts.logger.Error(\"Failed to decode block and blobs\", \"error\", err)\n\t\treturn nil, fmt.Errorf(\"failed to decode block and blobs: %w\", err)\n\t}\n\tblk := signedBlk.GetBeaconBlock()\n\n\t// Sort the sidecars by index for verification and processing.\n\tslices.SortFunc(sidecars, func(a, b *datypes.BlobSidecar) int {\n\t\treturn cmp.Compare(a.GetIndex(), b.GetIndex())\n\t})\n\n\t// There are two different timestamps:\n\t//     - The \"consensus time\" is determined by CometBFT consensus and can be retrieved with `req.GetTime()`\n\t//     - The \"block time\" is determined by beacon-kit consensus and can be retrieved with `blk.GetTimestamp()`\n\t// The \"consensus time\" is what the network agrees the current time is based on CometBFT PBTS.\n\t// This \"consensus time\" is used to constrain the timestamp set as the \"block time\" by the\n\t// beacon-kit app, but they are not always equal in value. The \"block time\" is used by the\n\t// beacon-kit consensus and execution layers to determine the active fork version.\n\t//\n\t// When unmarshaling the BeaconBlock, we do not yet have access to the \"block time\", so we\n\t// must rely on the \"consensus time\" as our best estimation of the \"block time\" needed to\n\t// determine the current fork version. Since the two timestamps could be different, we need to\n\t// ensure that the fork version for these timestamps are the same. This may result in a failed\n\t// proposal or two at the start of the fork.\n\tforkVersion := s.chainSpec.ActiveForkVersionForTimestamp(math.U64(req.GetTime().Unix())) //#nosec: G115\n\tblkVersion := s.chainSpec.ActiveForkVersionForTimestamp(blk.GetTimestamp())\n\tif !version.Equals(blkVersion, forkVersion) {\n\t\treturn nil, fmt.Errorf(\"CometBFT version %v, BeaconBlock version %v: %w\",\n\t\t\tforkVersion, blkVersion,\n\t\t\tErrVersionMismatch,\n\t\t)\n\t}\n\n\t// Make sure we have the right number of BlobSidecars\n\tblobKzgCommitments := blk.GetBody().GetBlobKzgCommitments()\n\tnumCommitments := len(blobKzgCommitments)\n\tif numCommitments != len(sidecars) {\n\t\treturn nil, fmt.Errorf(\"expected %d sidecars, got %d: %w\",\n\t\t\tnumCommitments, len(sidecars),\n\t\t\tErrSidecarCommitmentMismatch,\n\t\t)\n\t}\n\tif uint64(numCommitments) > s.chainSpec.MaxBlobsPerBlock() {\n\t\treturn nil, fmt.Errorf(\"expected less than %d sidecars, got %d: %w\",\n\t\t\ts.chainSpec.MaxBlobsPerBlock(), numCommitments,\n\t\t\tcore.ErrExceedsBlockBlobLimit,\n\t\t)\n\t}\n\n\t// Verify the block and sidecar signatures. We can simply verify the block\n\t// signature and then make sure the sidecar signatures match the block.\n\tblkSignature := signedBlk.GetSignature()\n\tfor i, sidecar := range sidecars {\n\t\tsidecarSignature := sidecar.GetSignature()\n\t\tif !bytes.Equal(blkSignature[:], sidecarSignature[:]) {\n\t\t\treturn nil, fmt.Errorf(\"%w, idx: %d\", ErrSidecarSignatureMismatch, i)\n\t\t}\n\t}\n\terr = s.VerifyIncomingBlockSignature(ctx, blk, signedBlk.GetSignature())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif numCommitments > 0 {\n\t\t// Process the blob sidecars\n\t\t//\n\t\t// In theory, swapping the order of verification between the sidecars\n\t\t// and the incoming block should not introduce any inconsistencies\n\t\t// in the state on which the sidecar verification depends on (notably\n\t\t// the currently active fork). ProcessProposal should only\n\t\t// keep the state changes as candidates (which is what we do in\n\t\t// VerifyIncomingBlock).\n\t\terr = s.VerifyIncomingBlobSidecars(ctx, sidecars, blk.GetHeader(), blobKzgCommitments)\n\t\tif err != nil {\n\t\t\ts.logger.Error(\"failed to verify incoming blob sidecars\", \"error\", err)\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\t// Process the block.\n\ts.logger.Debug( // needed for some checks in sim tests\n\t\t\"Processing block with fork version\",\n\t\t\"block\", req.Height,\n\t\t\"fork\", blkVersion.String(),\n\t)\n\tconsensusBlk := types.NewConsensusBlock(\n\t\tblk,\n\t\treq.GetProposerAddress(),\n\t\treq.GetTime(),\n\t)\n\n\tvar valUpdates transition.ValidatorUpdates\n\tvalUpdates, err = s.VerifyIncomingBlock(\n\t\tctx,\n\t\tconsensusBlk,\n\t\tbytes.Equal(thisNodeAddress, req.NextProposerAddress),\n\t)\n\tif err != nil {\n\t\ts.logger.Error(\"failed to verify incoming block\", \"error\", err)\n\t\treturn nil, err\n\t}\n\n\t// once we have successfully verified the block we cache it in the node builder.\n\t// This ensures the node will be able to build a payload even in scenarios where\n\t// EVM won't provide a new payload (e.g. if it received FCU(Head == N+1) due to\n\t// optimistic block building, then FCU(Head == N)) if verified block is not finalized)\n\tenvelope, err := payloadEnvFromPayload(sidecars, blk)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ts.localBuilder.CacheLatestVerifiedPayload(blk.Slot, envelope)\n\treturn valUpdates.CanonicalSort(), nil\n}\n\nfunc payloadEnvFromPayload(sidecars datypes.BlobSidecars, blk *ctypes.BeaconBlock) (ctypes.BuiltExecutionPayloadEnv, error) {\n\tblobBundle := &engineprimitives.BlobsBundleV1{}\n\tfor _, s := range sidecars {\n\t\tblobBundle.Commitments = append(blobBundle.Commitments, s.GetKzgCommitment())\n\t\tblobBundle.Proofs = append(blobBundle.Proofs, s.GetKzgProof())\n\n\t\tblob := s.GetBlob()\n\t\tblobBundle.Blobs = append(blobBundle.Blobs, &blob)\n\t}\n\n\tvar (\n\t\texecutionRequests []ctypes.EncodedExecutionRequest\n\t\terr               error\n\t)\n\tswitch reqs, errReqs := blk.Body.GetExecutionRequests(); {\n\tcase errReqs == nil:\n\t\texecutionRequests, err = ctypes.GetExecutionRequestsList(reqs)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed retrieving encoded execution requests from payload: %w\", err)\n\t\t}\n\tcase errors.Is(errReqs, ctypes.ErrFieldNotSupportedOnFork):\n\t\t// nothing to do, executionRequests is nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"failed getting execution requests from payload: %w\", errReqs)\n\t}\n\n\treturn ctypes.NewExecutionPayloadEnvelope[*engineprimitives.BlobsBundleV1](\n\t\tblk.Body.ExecutionPayload,\n\t\tblobBundle,\n\t\texecutionRequests,\n\t), nil\n}\n\nfunc (s *Service) VerifyIncomingBlockSignature(\n\tctx context.Context,\n\tbeaconBlk *ctypes.BeaconBlock,\n\tsignature crypto.BLSSignature,\n) error {\n\t// Get the sidecar verification function from the state processor\n\tsignatureVerifierFn, err := s.stateProcessor.GetSignatureVerifierFn(\n\t\ts.storageBackend.StateFromContext(ctx),\n\t)\n\tif err != nil {\n\t\treturn errors.New(\"failed to create block signature verifier\")\n\t}\n\terr = signatureVerifierFn(beaconBlk, signature)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed verifying incoming block signature: %w\", err)\n\t}\n\treturn err\n}\n\n// VerifyIncomingBlobSidecars verifies the BlobSidecars of an incoming\n// proposal and logs the process.\nfunc (s *Service) VerifyIncomingBlobSidecars(\n\tctx context.Context,\n\tsidecars datypes.BlobSidecars,\n\tblkHeader *ctypes.BeaconBlockHeader,\n\tkzgCommitments eip4844.KZGCommitments[common.ExecutionHash],\n) error {\n\t// Verify the blobs and ensure they match the local state.\n\terr := s.blobProcessor.VerifySidecars(ctx, sidecars, blkHeader, kzgCommitments)\n\tif err != nil {\n\t\ts.logger.Error(\n\t\t\t\"Blob sidecars verification failed - rejecting incoming blob sidecars\",\n\t\t\t\"reason\", err, \"slot\", blkHeader.GetSlot(),\n\t\t)\n\t\treturn err\n\t}\n\n\ts.logger.Info(\n\t\t\"Blob sidecars verification succeeded - accepting incoming blob sidecars\",\n\t\t\"num_blobs\", len(sidecars), \"slot\", blkHeader.GetSlot(),\n\t)\n\treturn nil\n}\n\n// VerifyIncomingBlock verifies the state root of an incoming block\n// and logs the process.\n//\n//nolint:funlen // abundantly commented\nfunc (s *Service) VerifyIncomingBlock(\n\tctx context.Context,\n\tblk *types.ConsensusBlock,\n\tisNextBlockProposer bool,\n) (transition.ValidatorUpdates, error) {\n\tbeaconBlk := blk.GetBeaconBlock()\n\tstate := s.storageBackend.StateFromContext(ctx)\n\n\t// Force a sync of the startup head if we haven't done so already.\n\t// TODO: Address the need for calling forceStartupSyncOnce in ProcessProposal. On a running\n\t// network (such as mainnet), it should be theoretically impossible to hit the case where\n\t// ProcessProposal is called before FinalizeBlock. It may be the case that new networks run\n\t// into this case during the first block after genesis.\n\t// TODO: Consider panicing here if this fails. If our node cannot successfully run\n\t// forceStartupSync, then we should shut down the node and fix the problem.\n\ts.forceStartupSyncOnce.Do(func() { s.forceSyncUponProcess(ctx, state) })\n\n\ts.logger.Debug(\n\t\t\"Received incoming beacon block\",\n\t\t\"state_root\", beaconBlk.GetStateRoot(),\n\t\t\"slot\", beaconBlk.GetSlot(),\n\t)\n\n\t// verify block slot\n\tstateSlot, err := state.GetSlot()\n\tif err != nil {\n\t\ts.logger.Error(\n\t\t\t\"failed loading state slot to verify block slot\",\n\t\t\t\"reason\", err,\n\t\t)\n\t\treturn nil, err\n\t}\n\n\tblkSlot := beaconBlk.GetSlot()\n\tif blkSlot != stateSlot+1 {\n\t\ts.logger.Error(\n\t\t\t\"Rejecting incoming beacon block ❌ \",\n\t\t\t\"state slot\", stateSlot.Base10(),\n\t\t\t\"block slot\", blkSlot.Base10(),\n\t\t\t\"reason\", ErrUnexpectedBlockSlot.Error(),\n\t\t)\n\t\treturn nil, ErrUnexpectedBlockSlot\n\t}\n\n\tvar (\n\t\tnextBlockData          *builder.RequestPayloadData\n\t\terrFetch               error\n\t\tshouldBuildNextPayload = s.shouldBuildNextPayload(isNextBlockProposer)\n\t)\n\n\tif shouldBuildNextPayload {\n\t\t// makes sure that preFetchBuildData does not affect state\n\t\tephemeralState := state.Protect(ctx)\n\t\tnextBlockData, errFetch = s.preFetchBuildData(ephemeralState, blk.GetConsensusTime())\n\t\tif errFetch != nil {\n\t\t\t// We don't return with err if pre-fetch fails. Instead we log the issue\n\t\t\t// and still move to process the current block. Next block can always be\n\t\t\t// built right after current height is finalized.\n\t\t\ts.logger.Warn(\n\t\t\t\t\"Failed pre fetching data for optimistic block building\",\n\t\t\t\t\"case\", \"block rejectiong\",\n\t\t\t\t\"err\", errFetch,\n\t\t\t)\n\t\t}\n\t}\n\n\t// Verify the state root of the incoming block.\n\tvalUpdates, err := s.verifyStateRoot(ctx, state, blk)\n\tif err != nil {\n\t\ts.logger.Error(\n\t\t\t\"Rejecting incoming beacon block ❌ \",\n\t\t\t\"state_root\", beaconBlk.GetStateRoot(),\n\t\t\t\"reason\", err,\n\t\t)\n\n\t\tif shouldBuildNextPayload {\n\t\t\tif nextBlockData == nil {\n\t\t\t\t// Failed fetching data to build next block. Just return block error\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tgo s.handleRebuildPayloadForRejectedBlock(ctx, nextBlockData)\n\t\t}\n\n\t\treturn nil, err\n\t}\n\n\ts.logger.Debug(\n\t\t\"State root verification succeeded - accepting incoming beacon block\",\n\t\t\"state_root\", beaconBlk.GetStateRoot(),\n\t)\n\n\tif shouldBuildNextPayload {\n\t\t// makes sure that preFetchBuildDataForSuccess does not affect state\n\t\tephemeralState := state.Protect(ctx)\n\t\tnextBlockData, errFetch = s.preFetchBuildData(ephemeralState, blk.GetConsensusTime())\n\t\tif errFetch != nil {\n\t\t\t// We don't mark the block as rejected if it is valid but pre-fetch fails.\n\t\t\t// Instead we log the issue and move to process the current block.\n\t\t\t// Next block can always be built right after current height is finalized.\n\t\t\ts.logger.Warn(\n\t\t\t\t\"Failed pre fetching data for optimistic block building\",\n\t\t\t\t\"case\", \"block success\",\n\t\t\t\t\"err\", errFetch,\n\t\t\t)\n\t\t\treturn valUpdates, nil\n\t\t}\n\t\tgo s.handleOptimisticPayloadBuild(ctx, nextBlockData)\n\t}\n\n\treturn valUpdates, nil\n}\n\n// verifyStateRoot verifies the state root of an incoming block.\nfunc (s *Service) verifyStateRoot(\n\tctx context.Context,\n\tst *statedb.StateDB,\n\tblk *types.ConsensusBlock,\n) (transition.ValidatorUpdates, error) {\n\tstartTime := time.Now()\n\n\tisCacheActive := cache.IsStateCachingActive(s.chainSpec, blk.GetBeaconBlock().GetSlot())\n\tif isCacheActive {\n\t\t// Re-use finalize block metrics if caching is active\n\t\tdefer s.metrics.measureStateTransitionDuration(startTime)\n\t} else {\n\t\t// Keep ProcessProposal specific metrics before fork is active\n\t\tdefer s.metrics.measureStateRootVerificationTime(startTime)\n\t}\n\n\ttxCtx := transition.NewTransitionCtx(\n\t\tctx,\n\t\tblk.GetConsensusTime(),\n\t\tblk.GetProposerAddress(),\n\t).\n\t\tWithVerifyPayload(true).\n\t\tWithVerifyRandao(true).\n\t\tWithVerifyResult(true).\n\t\tWithMeterGas(isCacheActive)\n\n\tvalUpdates, err := s.stateProcessor.Transition(txCtx, st, blk.GetBeaconBlock())\n\treturn valUpdates, err\n}\n\n// shouldBuildNextPayload returns true if optimistic\n// payload builds are enabled.\nfunc (s *Service) shouldBuildNextPayload(isNextBlockProposer bool) bool {\n\treturn isNextBlockProposer && s.localBuilder.Enabled()\n}\n"
  },
  {
    "path": "beacon/blockchain/pruning.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage blockchain\n\nimport (\n\t\"context\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n)\n\nfunc (s *Service) processPruning(ctx context.Context, beaconBlk *ctypes.BeaconBlock) error {\n\t// prune availability store\n\tstart, end := availabilityPruneRangeFn(beaconBlk.GetSlot().Unwrap(), s.chainSpec)\n\terr := s.storageBackend.AvailabilityStore().Prune(start, end)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// prune deposit store\n\tstart, end = depositPruneRangeFn(beaconBlk.GetBody().GetDeposits(), s.chainSpec)\n\terr = s.storageBackend.DepositStore().Prune(ctx, start, end)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc depositPruneRangeFn([]*ctypes.Deposit, PruningChainSpec) (uint64, uint64) {\n\t// The whole deposit list is validated in consensus and its Merkle root is part of\n\t// Beacon State. Therefore, every node must keep the full deposit list and deposits\n\t// pruning must be turned off.\n\treturn 0, 0\n}\n\n//nolint:unparam // this is ok\nfunc availabilityPruneRangeFn(slot uint64, cs PruningChainSpec) (uint64, uint64) {\n\twindow := cs.MinEpochsForBlobsSidecarsRequest().Unwrap() * cs.SlotsPerEpoch()\n\tif slot < window {\n\t\treturn 0, 0\n\t}\n\n\treturn 0, slot - window\n}\n"
  },
  {
    "path": "beacon/blockchain/service.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage blockchain\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"sync\"\n\t\"sync/atomic\"\n\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/execution/deposit\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// Service is the blockchain service.\ntype Service struct {\n\t// storageBackend represents the backend storage for not state-enforced data.\n\tstorageBackend StorageBackend\n\t// blobProcessor is used for processing sidecars.\n\tblobProcessor BlobProcessor\n\t// depositContract is the contract interface for interacting with the\n\t// deposit contract.\n\tdepositContract deposit.Contract\n\t// eth1FollowDistance is the follow distance for Ethereum 1.0 blocks.\n\teth1FollowDistance math.U64\n\t// failedBlocksMu protects failedBlocks for concurrent access.\n\tfailedBlocksMu sync.RWMutex\n\t// failedBlocks is a map of blocks that failed to be processed\n\t// and should be retried.\n\tfailedBlocks map[math.U64]struct{}\n\t// logger is used for logging messages in the service.\n\tlogger log.Logger\n\t// chainSpec holds the chain specifications.\n\tchainSpec ServiceChainSpec\n\t// executionEngine is the execution engine responsible for processing\n\t//\n\t// execution payloads.\n\texecutionEngine ExecutionEngine\n\t// localBuilder is a local builder for constructing new beacon states.\n\tlocalBuilder LocalBuilder\n\t// stateProcessor is the state processor for beacon blocks and states.\n\tstateProcessor StateProcessor\n\t// metrics is the metrics for the service.\n\tmetrics *chainMetrics\n\t// forceStartupSyncOnce is used to force a sync of the startup head.\n\tforceStartupSyncOnce *sync.Once\n\n\t// latestFcuReq holds a copy of the latest FCU sent to the execution layer.\n\t// It helps avoid resending the same FCU data (and spares a network call)\n\t// in case optimistic block building is active\n\tlatestFcuReq atomic.Pointer[engineprimitives.ForkchoiceStateV1]\n}\n\n// NewService creates a new validator service.\nfunc NewService(\n\tstorageBackend StorageBackend,\n\tblobProcessor BlobProcessor,\n\tdepositContract deposit.Contract,\n\tlogger log.Logger,\n\tchainSpec ServiceChainSpec,\n\texecutionEngine ExecutionEngine,\n\tlocalBuilder LocalBuilder,\n\tstateProcessor StateProcessor,\n\ttelemetrySink TelemetrySink,\n) *Service {\n\treturn &Service{\n\t\tstorageBackend:       storageBackend,\n\t\tblobProcessor:        blobProcessor,\n\t\tdepositContract:      depositContract,\n\t\teth1FollowDistance:   math.U64(chainSpec.Eth1FollowDistance()),\n\t\tfailedBlocks:         make(map[math.Slot]struct{}),\n\t\tlogger:               logger,\n\t\tchainSpec:            chainSpec,\n\t\texecutionEngine:      executionEngine,\n\t\tlocalBuilder:         localBuilder,\n\t\tstateProcessor:       stateProcessor,\n\t\tmetrics:              newChainMetrics(telemetrySink),\n\t\tforceStartupSyncOnce: new(sync.Once),\n\t}\n}\n\n// Name returns the name of the service.\nfunc (s *Service) Name() string {\n\treturn \"blockchain\"\n}\n\n// Start starts the blockchain service.\nfunc (s *Service) Start(ctx context.Context) error {\n\t// Catchup deposits for failed blocks. TODO: remove.\n\tgo s.depositCatchupFetcher(ctx)\n\n\treturn nil\n}\n\n// Stop stops the blockchain service and closes the deposit store.\nfunc (s *Service) Stop() error {\n\ts.logger.Info(\"Stopping blockchain service\")\n\n\terr := s.storageBackend.DepositStore().Close()\n\tif err != nil {\n\t\ts.logger.Error(\"failed to close deposit store\", \"err\", err)\n\t}\n\n\treturn nil\n}\n\n// StorageBackend returns the storage backend.\nfunc (s *Service) StorageBackend() StorageBackend {\n\treturn s.storageBackend\n}\n\n// PruneOrphanedBlobs removes any orphaned blob sidecars that may exist from incomplete block finalization.\nfunc (s *Service) PruneOrphanedBlobs(lastBlockHeight int64) error {\n\torphanedSlot := math.Slot(lastBlockHeight + 1) // #nosec G115\n\n\t// Check if any blob sidecars exist at the potentially orphaned slot\n\tsidecars, err := s.storageBackend.AvailabilityStore().GetBlobSidecars(orphanedSlot)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read blob sidecars at slot %d: %w\", orphanedSlot, err)\n\t}\n\n\t// If no sidecars exist at this slot, nothing to clean up\n\tif len(sidecars) == 0 {\n\t\treturn nil\n\t}\n\n\t// Sidecars exist at this slot - they are orphaned, so delete them\n\ts.logger.Warn(\"Found orphaned blob sidecars from incomplete block finalization, removing\",\n\t\t\"slot\", orphanedSlot.Base10(),\n\t\t\"num_sidecars\", len(sidecars),\n\t)\n\n\terr = s.storageBackend.AvailabilityStore().DeleteBlobSidecars(orphanedSlot)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to delete orphaned sidecars at slot %d: %w\", orphanedSlot, err)\n\t}\n\n\ts.logger.Info(\"Successfully removed orphaned blob sidecars\", \"slot\", orphanedSlot.Base10())\n\n\treturn nil\n}\n"
  },
  {
    "path": "beacon/payload-time/time.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage payloadtime\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// ErrTooFarInTheFuture is returned when the payload timestamp\n// in a block exceeds the time bound.\nvar ErrTooFarInTheFuture = errors.New(\"timestamp too far in the future\")\n\nfunc Verify(\n\tconsensusTime,\n\tparentPayloadTimestamp,\n\tpayloadTimestamp math.U64,\n) error {\n\tbound := max(\n\t\tconsensusTime+1,\n\t\tparentPayloadTimestamp+1,\n\t)\n\tif payloadTimestamp > bound {\n\t\treturn fmt.Errorf(\n\t\t\t\"%w: timestamp bound: %d, got: %d\",\n\t\t\tErrTooFarInTheFuture,\n\t\t\tbound, payloadTimestamp,\n\t\t)\n\t}\n\treturn nil\n}\n\nfunc Next(\n\tconsensusTime,\n\tparentPayloadTimestamp math.U64,\n\tbuildOptimistically bool,\n) math.U64 {\n\tdelta := math.U64(0)\n\tif buildOptimistically {\n\t\t// we're building a payload to be included into next block.\n\t\t// We estimate it to be included next second. If this estimate\n\t\t// turns out wrong (cause consensus block are finalized faster or\n\t\t// slower than consensusTime+1 sec), we're still fine as long as\n\t\t// Verify pass which should always to since:\n\t\t// Next.consensusTime <= Verify.consensusTime\n\t\tdelta = 1\n\t}\n\treturn max(\n\t\tconsensusTime+delta,\n\t\tparentPayloadTimestamp+1,\n\t)\n}\n"
  },
  {
    "path": "beacon/payload-time/time_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage payloadtime_test\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\tpayloadtime \"github.com/berachain/beacon-kit/beacon/payload-time\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// TestNextTimestampVerifies checks that next payload timestamp\n// built via payloadtime.Next always pass payloadtime.Verify.\nfunc TestNextTimestampVerifies(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname        string\n\t\ttimes       func() (time.Time, time.Time)\n\t\texpectedErr error\n\t}{\n\t\t{\n\t\t\tname: \"Payload timestamp < consensus timestamp\",\n\t\t\ttimes: func() (time.Time, time.Time) {\n\t\t\t\tconsensusTime := time.Now().Truncate(time.Second)\n\t\t\t\tparentPayloadTimestamp := consensusTime.Add(-10 * time.Second)\n\t\t\t\treturn consensusTime, parentPayloadTimestamp\n\t\t\t},\n\t\t\texpectedErr: nil,\n\t\t},\n\t\t{\n\t\t\tname: \"Payload timestamp == consensus timestamp\",\n\t\t\ttimes: func() (time.Time, time.Time) {\n\t\t\t\tconsensusTime := time.Now().Truncate(time.Second)\n\t\t\t\tparentPayloadTimestamp := consensusTime\n\t\t\t\treturn consensusTime, parentPayloadTimestamp\n\t\t\t},\n\t\t\texpectedErr: nil,\n\t\t},\n\t\t{\n\t\t\tname: \"Payload timestamp > consensus timestamp\",\n\t\t\ttimes: func() (time.Time, time.Time) {\n\t\t\t\tconsensusTime := time.Now().Truncate(time.Second)\n\t\t\t\tparentPayloadTimestamp := consensusTime.Add(10 * time.Second)\n\t\t\t\treturn consensusTime, parentPayloadTimestamp\n\t\t\t},\n\t\t\texpectedErr: nil,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tconsensusTime, parentPayloadTimestamp := tt.times()\n\n\t\t\t// Optimistic build case\n\t\t\tnextPayload := payloadtime.Next(\n\t\t\t\tmath.U64(consensusTime.Unix()),\n\t\t\t\tmath.U64(parentPayloadTimestamp.Unix()),\n\t\t\t\ttrue, // buildOptimistically\n\t\t\t)\n\n\t\t\tgotErr := payloadtime.Verify(\n\t\t\t\tmath.U64(consensusTime.Unix()),\n\t\t\t\tmath.U64(parentPayloadTimestamp.Unix()),\n\t\t\t\tnextPayload,\n\t\t\t)\n\t\t\tif tt.expectedErr == nil {\n\t\t\t\trequire.NoError(t, gotErr)\n\t\t\t} else {\n\t\t\t\trequire.ErrorIs(t, tt.expectedErr, gotErr)\n\t\t\t}\n\n\t\t\t// Just in time build case\n\t\t\tnextPayload = payloadtime.Next(\n\t\t\t\tmath.U64(consensusTime.Unix()),\n\t\t\t\tmath.U64(parentPayloadTimestamp.Unix()),\n\t\t\t\tfalse, // buildOptimistically\n\t\t\t)\n\n\t\t\tgotErr = payloadtime.Verify(\n\t\t\t\tmath.U64(consensusTime.Unix()),\n\t\t\t\tmath.U64(parentPayloadTimestamp.Unix()),\n\t\t\t\tnextPayload,\n\t\t\t)\n\t\t\tif tt.expectedErr == nil {\n\t\t\t\trequire.NoError(t, gotErr)\n\t\t\t} else {\n\t\t\t\trequire.ErrorIs(t, tt.expectedErr, gotErr)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "beacon/validator/block_builder.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage validator\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\tpayloadtime \"github.com/berachain/beacon-kit/beacon/payload-time\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/consensus/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/payload/builder\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n)\n\n// BuildBlockAndSidecars builds a new beacon block.\n//\n//nolint:funlen // comments are pretty verbose\nfunc (s *Service) BuildBlockAndSidecars(\n\tctx context.Context,\n\tslotData *types.SlotData,\n) ([]byte, []byte, error) {\n\tstartTime := time.Now()\n\tdefer s.metrics.measureRequestBlockForProposalTime(startTime)\n\n\tif !s.localPayloadBuilder.Enabled() {\n\t\t// node is not supposed to build blocks\n\t\treturn nil, nil, builder.ErrPayloadBuilderDisabled\n\t}\n\n\t// The goal here is to acquire a payload whose parent is the previously\n\t// finalized block, such that, if this payload is accepted, it will be\n\t// the next finalized block in the chain. A byproduct of this design\n\t// is that we get the nice property of lazily propagating the finalized\n\t// and safe block hashes to the execution client.\n\tst := s.sb.StateFromContext(ctx)\n\n\t// blkSlot is the height for the next block, which consensus is requesting BeaconKit to build.\n\tblkSlot := slotData.GetSlot()\n\n\t// Prepare the state such that it is ready to build a block for the requested slot.\n\tif _, err := s.stateProcessor.ProcessSlots(st, blkSlot); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\t// Grab parent block root for payload request.\n\tparentBlockRoot, err := st.GetBlockRootAtIndex(\n\t\t(blkSlot.Unwrap() - 1) % s.chainSpec.SlotsPerHistoricalRoot(),\n\t)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\t// Get the payload for the block.\n\tenvelope, err := s.retrieveExecutionPayload(ctx, st, parentBlockRoot, slotData)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed retrieving execution payload: %w\", err)\n\t}\n\n\t// We introduce hard forks with the expectation that the first block proposed after the\n\t// hard fork timestamp is when new rules apply. When building blocks, we provide the Execution\n\t// Layer client with a timestamp, and it will create its payload based on that timestamp. We\n\t// must use this same timestamp from the payload to build the beacon block. This ensures that\n\t// we are building on the same fork version as the Execution Layer.\n\ttimestamp := envelope.GetExecutionPayload().GetTimestamp()\n\n\t// Build forkdata used for the signing root of the reveal and the sidecars.\n\tforkData, err := s.buildForkData(st, timestamp)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\t// Create a new empty block from the current state.\n\tblk, err := s.getEmptyBeaconBlockForSlot(st, blkSlot, forkData.CurrentVersion, parentBlockRoot)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\t// Build the reveal for the current slot.\n\t// TODO: We can optimize to pre-compute this in parallel?\n\treveal, err := s.buildRandaoReveal(forkData, blkSlot)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\t// We have to assemble the block body prior to producing the sidecars\n\t// since we need to generate the inclusion proofs.\n\tif err = s.buildBlockBody(ctx, st, blk, reveal, envelope); err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed build block body: %w\", err)\n\t}\n\n\t// Compute the state root for the block.\n\tif err = s.computeAndSetStateRoot(\n\t\tctx,\n\t\tslotData.GetProposerAddress(),\n\t\tslotData.GetConsensusTime(),\n\t\tst,\n\t\tblk,\n\t); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\t// Craft the signature and signed beacon block.\n\tsignedBlk, err := ctypes.NewSignedBeaconBlock(blk, forkData, s.chainSpec, s.signer)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\t// Produce blob sidecars with new StateRoot\n\tsidecars, err := s.blobFactory.BuildSidecars(signedBlk, envelope.GetBlobsBundle())\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\ts.logger.Info(\n\t\t\"Beacon block successfully built\",\n\t\t\"slot\", blkSlot.Base10(),\n\t\t\"state_root\", blk.GetStateRoot(),\n\t\t\"duration\", time.Since(startTime).String(),\n\t)\n\n\tsignedBlkBytes, bbErr := signedBlk.MarshalSSZ()\n\tif bbErr != nil {\n\t\treturn nil, nil, bbErr\n\t}\n\tsidecarsBytes, scErr := sidecars.MarshalSSZ()\n\tif scErr != nil {\n\t\treturn nil, nil, scErr\n\t}\n\n\treturn signedBlkBytes, sidecarsBytes, nil\n}\n\n// getEmptyBeaconBlockForSlot creates a new empty block.\nfunc (s *Service) getEmptyBeaconBlockForSlot(\n\tst *statedb.StateDB, requestedSlot math.Slot,\n\tforkVersion common.Version, parentBlockRoot common.Root,\n) (*ctypes.BeaconBlock, error) {\n\t// Get the proposer index for the slot.\n\tproposerIndex, err := st.ValidatorIndexByPubkey(\n\t\ts.signer.PublicKey(),\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Create a new block.\n\treturn ctypes.NewBeaconBlockWithVersion(\n\t\trequestedSlot,\n\t\tproposerIndex,\n\t\tparentBlockRoot,\n\t\tforkVersion,\n\t)\n}\n\nfunc (s *Service) buildForkData(st *statedb.StateDB, timestamp math.U64) (*ctypes.ForkData, error) {\n\tgenesisValidatorsRoot, err := st.GetGenesisValidatorsRoot()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn ctypes.NewForkData(\n\t\ts.chainSpec.ActiveForkVersionForTimestamp(timestamp),\n\t\tgenesisValidatorsRoot,\n\t), nil\n}\n\n// buildRandaoReveal builds a randao reveal for the given slot.\nfunc (s *Service) buildRandaoReveal(\n\tforkData *ctypes.ForkData, slot math.Slot,\n) (crypto.BLSSignature, error) {\n\tsigningRoot := forkData.ComputeRandaoSigningRoot(\n\t\ts.chainSpec.DomainTypeRandao(),\n\t\ts.chainSpec.SlotToEpoch(slot),\n\t)\n\tsignature, err := s.signer.Sign(signingRoot[:])\n\tif err != nil {\n\t\treturn signature, fmt.Errorf(\"block building failed randao checks: %w\", err)\n\t}\n\treturn signature, nil\n}\n\n// retrieveExecutionPayload retrieves the execution payload for the block.\nfunc (s *Service) retrieveExecutionPayload(\n\tctx context.Context,\n\tst *statedb.StateDB,\n\tparentBlockRoot common.Root,\n\tslotData *types.SlotData,\n) (ctypes.BuiltExecutionPayloadEnv, error) {\n\t// TODO: Add external block builders to this flow.\n\t//\n\t// Get the payload for the block. Pass the expected fork given the current\n\t// CometBFT timestamp to try and build coherent blocks (i.e. blocks whose fork\n\t// version is the same for payload and the rest of CometBFT block). This coherence\n\t// is checked in ProcessProposal. Remember that CometBFT does not guarantee that the\n\t// timestamp provided here will be the one used in the block (Comet takes into account\n\t// the time it takes to build the block, which should be very small normally).\n\tslot := slotData.GetSlot()\n\texpectedPayloadFork := s.chainSpec.ActiveForkVersionForTimestamp(slotData.GetConsensusTime())\n\tenvelope, err := s.localPayloadBuilder.RetrievePayload(ctx, slot, parentBlockRoot, expectedPayloadFork)\n\tif err == nil {\n\t\treturn envelope, nil\n\t}\n\n\t// If we failed to retrieve the payload, request a synchronous payload.\n\t//\n\t// NOTE: The state here is properly configured by the\n\t// prepareStateForBuilding\n\t//\n\t// call that needs to be called before requesting the Payload.\n\t// TODO: We should decouple the PayloadBuilder from BeaconState to make\n\t// this less confusing.\n\ts.metrics.failedToRetrievePayload(slot, err)\n\n\t// The latest execution payload header will be from the previous block\n\t// during the block building phase.\n\tlph, err := st.GetLatestExecutionPayloadHeader()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// We must prepare the state for the fork version of the new block being built to handle\n\t// the case where the new block is on a new fork version. Although we do not have the\n\t// confirmed timestamp by the EL, we will assume it to be `nextPayloadTimestamp` to decide\n\t// the new block's fork version.\n\tnextPayloadTimestamp := payloadtime.Next(\n\t\tslotData.GetConsensusTime(),\n\t\tlph.GetTimestamp(),\n\t\tfalse, // buildOptimistically\n\t)\n\terr = s.stateProcessor.ProcessFork(st, nextPayloadTimestamp, false)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Expected payloadWithdrawals to include in this payload.\n\tpayloadWithdrawals, _, err := st.ExpectedWithdrawals(nextPayloadTimestamp)\n\tif err != nil {\n\t\ts.logger.Error(\n\t\t\t\"Could not get expected withdrawals to get payload attribute\",\n\t\t\t\"error\",\n\t\t\terr,\n\t\t)\n\t\treturn nil, err\n\t}\n\t// Get the previous randao mix.\n\tepoch := s.chainSpec.SlotToEpoch(slot)\n\tprevRandao, err := st.GetRandaoMixAtIndex(\n\t\tepoch.Unwrap() % s.chainSpec.EpochsPerHistoricalVector(),\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tparentProposerPubkey, err := st.ParentProposerPubkey(nextPayloadTimestamp)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed retrieving previous proposer public key: %w\", err)\n\t}\n\n\tr := &builder.RequestPayloadData{\n\t\tSlot:               slot,\n\t\tTimestamp:          nextPayloadTimestamp,\n\t\tPayloadWithdrawals: payloadWithdrawals,\n\t\tPrevRandao:         prevRandao,\n\t\tParentBlockRoot:    parentBlockRoot,\n\t\tFCState: engineprimitives.ForkchoiceStateV1{\n\t\t\tHeadBlockHash:      lph.GetBlockHash(),\n\t\t\tSafeBlockHash:      lph.GetParentHash(),\n\t\t\tFinalizedBlockHash: lph.GetParentHash(),\n\t\t},\n\t\tParentProposerPubkey: parentProposerPubkey,\n\t}\n\treturn s.localPayloadBuilder.RequestPayloadSync(ctx, r)\n}\n\n// BuildBlockBody assembles the block body with necessary components.\nfunc (s *Service) buildBlockBody(\n\tctx context.Context,\n\tst *statedb.StateDB,\n\tblk *ctypes.BeaconBlock,\n\treveal crypto.BLSSignature,\n\tenvelope ctypes.BuiltExecutionPayloadEnv,\n) error {\n\t// Assemble a new block with the payload.\n\tbody := blk.GetBody()\n\tif body == nil {\n\t\treturn ErrNilBlkBody\n\t}\n\n\t// Set the reveal on the block body.\n\tbody.SetRandaoReveal(reveal)\n\n\t// If we get returned a nil blobs bundle, we should return an error.\n\tblobsBundle := envelope.GetBlobsBundle()\n\tif blobsBundle == nil {\n\t\treturn ErrNilBlobsBundle\n\t}\n\n\t// Set the KZG commitments on the block body.\n\tbody.SetBlobKzgCommitments(blobsBundle.GetCommitments())\n\n\t// Dequeue deposits from the state.\n\tdepositIndex, err := st.GetEth1DepositIndex()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed loading eth1 deposit index: %w\", err)\n\t}\n\n\t// Grab all previous deposits from genesis up to the current index + max deposits per block.\n\tdeposits, localDepositRoot, err := s.sb.DepositStore().GetDepositsByIndex(\n\t\tctx,\n\t\tconstants.FirstDepositIndex,\n\t\tdepositIndex+s.chainSpec.MaxDepositsPerBlock(),\n\t)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif uint64(len(deposits)) < depositIndex {\n\t\treturn errors.Wrapf(ErrDepositStoreIncomplete,\n\t\t\t\"all historical deposits not available, expected: %d, got: %d\",\n\t\t\tdepositIndex, len(deposits),\n\t\t)\n\t}\n\ts.logger.Info(\n\t\t\"Building block body with local deposits\",\n\t\t\"start_index\", depositIndex, \"num_deposits\", uint64(len(deposits))-depositIndex,\n\t)\n\n\teth1Data := ctypes.NewEth1Data(localDepositRoot)\n\tbody.SetEth1Data(eth1Data)\n\tbody.SetDeposits(deposits[depositIndex:])\n\n\t// Set the graffiti on the block body.\n\tsizedGraffiti := bytes.ExtendToSize([]byte(s.cfg.Graffiti), bytes.B32Size)\n\tgraffiti, err := bytes.ToBytes32(sizedGraffiti)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed processing graffiti: %w\", err)\n\t}\n\tbody.SetGraffiti(graffiti)\n\n\t// Fill in unused field with non-nil value\n\tbody.SetSyncAggregate(&ctypes.SyncAggregate{})\n\n\t// Set the execution payload on the block body.\n\tbody.SetExecutionPayload(envelope.GetExecutionPayload())\n\n\tif version.EqualsOrIsAfter(body.GetForkVersion(), version.Electra()) {\n\t\tencodedReqs := envelope.GetEncodedExecutionRequests()\n\t\tresult := make([][]byte, len(encodedReqs))\n\t\tfor i, req := range encodedReqs {\n\t\t\tresult[i] = req // conversion from ExecutionRequest to []byte\n\t\t}\n\n\t\tvar requests *ctypes.ExecutionRequests\n\t\tif requests, err = ctypes.DecodeExecutionRequests(result); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err = body.SetExecutionRequests(requests); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// computeAndSetStateRoot computes the state root of an outgoing block\n// and sets it in the block.\nfunc (s *Service) computeAndSetStateRoot(\n\tctx context.Context,\n\tproposerAddress []byte,\n\tconsensusTime math.U64,\n\tst *statedb.StateDB,\n\tblk *ctypes.BeaconBlock,\n) error {\n\tstateRoot, err := s.computeStateRoot(\n\t\tctx,\n\t\tproposerAddress,\n\t\tconsensusTime,\n\t\tst,\n\t\tblk,\n\t)\n\tif err != nil {\n\t\ts.logger.Error(\n\t\t\t\"failed to compute state root while building block ❗️ \",\n\t\t\t\"slot\", blk.GetSlot().Base10(),\n\t\t\t\"error\", err,\n\t\t)\n\t\treturn err\n\t}\n\tblk.SetStateRoot(stateRoot)\n\treturn nil\n}\n\n// computeStateRoot computes the state root of an outgoing block.\nfunc (s *Service) computeStateRoot(\n\tctx context.Context,\n\tproposerAddress []byte,\n\tconsensusTime math.U64,\n\tst *statedb.StateDB,\n\tblk *ctypes.BeaconBlock,\n) (common.Root, error) {\n\tstartTime := time.Now()\n\tdefer s.metrics.measureStateRootComputationTime(startTime)\n\n\t// TODO: Think about how this would affect the proposer when\n\t// the payload in their block has come from a remote builder.\n\ttxCtx := transition.NewTransitionCtx(\n\t\tctx,\n\t\tconsensusTime,\n\t\tproposerAddress,\n\t).\n\t\tWithVerifyPayload(false).\n\t\tWithVerifyRandao(false).\n\t\tWithVerifyResult(false).\n\t\tWithMeterGas(false)\n\n\tif _, err := s.stateProcessor.Transition(txCtx, st, blk); err != nil {\n\t\treturn common.Root{}, err\n\t}\n\n\treturn st.HashTreeRoot(), nil\n}\n"
  },
  {
    "path": "beacon/validator/config.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage validator\n\n// defaultGraffiti is the default graffiti string.\nconst defaultGraffiti = \"\"\n\n// Config is the validator configuration.\ntype Config struct {\n\t// Graffiti is the string that will be included in the\n\t// graffiti field of the beacon block.\n\tGraffiti string `mapstructure:\"graffiti\"`\n}\n\n// DefaultConfig returns the default fork configuration.\nfunc DefaultConfig() Config {\n\treturn Config{\n\t\tGraffiti: defaultGraffiti,\n\t}\n}\n"
  },
  {
    "path": "beacon/validator/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage validator\n\nimport \"github.com/berachain/beacon-kit/errors\"\n\nvar (\n\t// ErrNilBlkBody is an error for when the block body is nil.\n\tErrNilBlkBody = errors.New(\"nil block body\")\n\n\t// ErrNilBlobsBundle is an error for when the blobs bundle is nil.\n\tErrNilBlobsBundle = errors.New(\"nil blobs bundle\")\n\n\t// ErrDepositStoreIncomplete is an error for when the deposit store has not returned\n\t// the expected amount of deposits. Could be due to pruning when it should not be enabled.\n\tErrDepositStoreIncomplete = errors.New(\"deposits from deposit store incomplete\")\n)\n"
  },
  {
    "path": "beacon/validator/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage validator\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/consensus/types\"\n\tdatypes \"github.com/berachain/beacon-kit/da/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/payload/builder\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n\t\"github.com/berachain/beacon-kit/state-transition/core\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n\t\"github.com/berachain/beacon-kit/storage/deposit\"\n)\n\n// BlobFactory represents a blob factory interface.\ntype BlobFactory interface {\n\t// BuildSidecars builds sidecars for a given block and blobs bundle.\n\tBuildSidecars(\n\t\tsignedBlk *ctypes.SignedBeaconBlock,\n\t\tblobs engineprimitives.BlobsBundle,\n\t) (datypes.BlobSidecars, error)\n}\n\n// PayloadBuilder represents a service that is responsible for\n// building eth1 blocks.\ntype PayloadBuilder interface {\n\t// Enabled may be enabled (e.g. for validators)\n\t// or disabled (e.g. full nodes)\n\tEnabled() bool\n\t// RetrievePayload retrieves the payload for the given slot and parentBlockRoot.\n\t// If returned error is nil, payload is guaranteed to have expectedForkVersion version.\n\tRetrievePayload(\n\t\tctx context.Context,\n\t\tslot math.Slot,\n\t\tparentBlockRoot common.Root,\n\t\texpectedForkVersion common.Version,\n\t) (ctypes.BuiltExecutionPayloadEnv, error)\n\t// RequestPayloadSync requests a payload for the given slot and\n\t// blocks until the payload is delivered.\n\tRequestPayloadSync(\n\t\tctx context.Context,\n\t\tr *builder.RequestPayloadData,\n\t) (ctypes.BuiltExecutionPayloadEnv, error)\n}\n\n// StateProcessor defines the interface for processing the state.\ntype StateProcessor interface {\n\t// ProcessFork prepares the state for the fork version at the given timestamp.\n\tProcessFork(\n\t\tst *statedb.StateDB, timestamp math.U64, logUpgrade bool,\n\t) error\n\t// ProcessSlots processes the slot.\n\tProcessSlots(\n\t\tst *statedb.StateDB, slot math.Slot,\n\t) (transition.ValidatorUpdates, error)\n\t// Transition performs the core state transition.\n\tTransition(\n\t\tctx core.ReadOnlyContext,\n\t\tst *statedb.StateDB,\n\t\tblk *ctypes.BeaconBlock,\n\t) (transition.ValidatorUpdates, error)\n}\n\n// StorageBackend is the interface for the storage backend.\ntype StorageBackend interface {\n\t// DepositStore retrieves the deposit store.\n\tDepositStore() deposit.StoreManager\n\t// StateFromContext retrieves the beacon state from the context.\n\tStateFromContext(context.Context) *statedb.StateDB\n}\n\n// TelemetrySink is an interface for sending metrics to a telemetry backend.\ntype TelemetrySink interface {\n\t// IncrementCounter increments a counter metric identified by the provided\n\t// keys.\n\tIncrementCounter(key string, args ...string)\n\t// MeasureSince measures the time since the provided start time,\n\t// identified by the provided keys.\n\tMeasureSince(key string, start time.Time, args ...string)\n}\n\ntype BlockBuilderI interface {\n\tBuildBlockAndSidecars(\n\t\tcontext.Context,\n\t\t*types.SlotData,\n\t) ([]byte, []byte, error)\n}\n\n// ChainSpec defines an interface for accessing chain-specific parameters.\ntype ChainSpec interface {\n\tSlotsPerHistoricalRoot() uint64\n\tDomainTypeRandao() common.DomainType\n\tMaxDepositsPerBlock() uint64\n\tActiveForkVersionForTimestamp(timestamp math.U64) common.Version\n\tSlotToEpoch(slot math.Slot) math.Epoch\n\tEpochsPerHistoricalVector() uint64\n\n\tctypes.ProposerDomain\n}\n"
  },
  {
    "path": "beacon/validator/metrics.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage validator\n\nimport (\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// validatorMetrics is a struct that contains metrics for the chain.\ntype validatorMetrics struct {\n\t// sink is the sink for the metrics.\n\tsink TelemetrySink\n}\n\n// newValidatorMetrics creates a new validatorMetrics.\nfunc newValidatorMetrics(\n\tsink TelemetrySink,\n) *validatorMetrics {\n\treturn &validatorMetrics{\n\t\tsink: sink,\n\t}\n}\n\n// measureRequestBlockForProposalTime measures the time taken to run the request\n// best\n// block function.\nfunc (cm *validatorMetrics) measureRequestBlockForProposalTime(\n\tstart time.Time,\n) {\n\tcm.sink.MeasureSince(\n\t\t\"beacon_kit.validator.request_block_for_proposal_duration\", start,\n\t)\n}\n\n// measureStateRootComputationTime measures the time taken to compute the state\n// root of a block.\n// It records the duration from the provided start time to the current time.\nfunc (cm *validatorMetrics) measureStateRootComputationTime(start time.Time) {\n\tcm.sink.MeasureSince(\n\t\t\"beacon_kit.validator.state_root_computation_duration\", start,\n\t)\n}\n\n// failedToRetrievePayload increments the counter for the number of\n// times the validator failed to retrieve payloads.\nfunc (cm *validatorMetrics) failedToRetrievePayload(\n\tslot math.Slot, err error,\n) {\n\tcm.sink.IncrementCounter(\n\t\t\"beacon_kit.validator.failed_to_retrieve_payload\",\n\t\t\"slot\",\n\t\tslot.Base10(),\n\t\t\"error\",\n\t\terr.Error(),\n\t)\n}\n"
  },
  {
    "path": "beacon/validator/service.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage validator\n\nimport (\n\t\"context\"\n\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n)\n\n// Service is responsible for building beacon blocks and sidecars.\ntype Service struct {\n\t// cfg is the validator config.\n\tcfg *Config\n\t// logger is a logger.\n\tlogger log.Logger\n\t// chainSpec is the chain spec.\n\tchainSpec ChainSpec\n\t// signer is used to retrieve the public key of this node.\n\tsigner crypto.BLSSigner\n\t// blobFactory is used to create blob sidecars for blocks.\n\tblobFactory BlobFactory\n\t// sb is the beacon state backend.\n\tsb StorageBackend\n\t// stateProcessor is responsible for processing the state.\n\tstateProcessor StateProcessor\n\t// localPayloadBuilder represents the local block builder, this builder\n\t// is connected to this nodes execution client via the EngineAPI.\n\t// Building blocks are done by submitting forkchoice updates through.\n\t// The local Builder.\n\tlocalPayloadBuilder PayloadBuilder\n\t// metrics is a metrics collector.\n\tmetrics *validatorMetrics\n}\n\n// NewService creates a new validator service.\nfunc NewService(\n\tcfg *Config,\n\tlogger log.Logger,\n\tchainSpec ChainSpec,\n\tsb StorageBackend,\n\tstateProcessor StateProcessor,\n\tsigner crypto.BLSSigner,\n\tblobFactory BlobFactory,\n\tlocalPayloadBuilder PayloadBuilder,\n\tts TelemetrySink,\n) *Service {\n\treturn &Service{\n\t\tcfg:                 cfg,\n\t\tlogger:              logger,\n\t\tsb:                  sb,\n\t\tchainSpec:           chainSpec,\n\t\tsigner:              signer,\n\t\tstateProcessor:      stateProcessor,\n\t\tblobFactory:         blobFactory,\n\t\tlocalPayloadBuilder: localPayloadBuilder,\n\t\tmetrics:             newValidatorMetrics(ts),\n\t}\n}\n\n// Name returns the name of the service.\nfunc (s *Service) Name() string {\n\treturn \"validator\"\n}\n\nfunc (s *Service) Start(\n\t_ context.Context,\n) error {\n\treturn nil\n}\n\nfunc (s *Service) Stop() error {\n\treturn nil\n}\n"
  },
  {
    "path": "chain/chain_ids.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage chain\n\n// Chain IDs that must be used for specific Berachain networks.\nconst (\n\t// DevnetEth1ChainID is the chain ID for a local devnet. Used by `make start`, e2e tests, and\n\t// many unit tests.\n\tDevnetEth1ChainID uint64 = 80087\n\n\t// MainnetEth1ChainID is the chain ID for the Berachain mainnet.\n\tMainnetEth1ChainID uint64 = 80094\n\n\t// TestnetEth1ChainID is the chain ID for the Berachain public testnet, Bepolia. Also used by\n\t// simulated tests.\n\tTestnetEth1ChainID uint64 = 80069\n)\n"
  },
  {
    "path": "chain/data.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage chain\n\nimport (\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/delay\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n)\n\n// SpecData is the underlying data structure for chain-specific parameters. All fields with a\n// `mapstructure` tag are required.\ntype SpecData struct {\n\tdelay.Config `mapstructure:\"block-delay-configuration\"`\n\n\t// Gwei value constants.\n\t//\n\t// MaxEffectiveBalance is the maximum effective balance allowed for a validator.\n\tMaxEffectiveBalance uint64 `mapstructure:\"max-effective-balance\"`\n\t// EffectiveBalanceIncrement is the effective balance increment.\n\tEffectiveBalanceIncrement uint64 `mapstructure:\"effective-balance-increment\"`\n\n\t// HysteresisQuotient is the quotient used in effective balance calculations\n\tHysteresisQuotient uint64 `mapstructure:\"hysteresis-quotient\"`\n\t// HysteresisDownwardMultiplier is the multiplier for downward balance\n\t// adjustments.\n\tHysteresisDownwardMultiplier uint64 `mapstructure:\"hysteresis-downward-multiplier\"`\n\t// HysteresisUpwardMultiplier is the multiplier for upward balance\n\t// adjustments.\n\tHysteresisUpwardMultiplier uint64 `mapstructure:\"hysteresis-upward-multiplier\"`\n\n\t// Time parameters constants.\n\t//\n\t// SlotsPerEpoch is the number of slots per epoch.\n\tSlotsPerEpoch uint64 `mapstructure:\"slots-per-epoch\"`\n\t// SlotsPerHistoricalRoot is the number of slots per historical root.\n\tSlotsPerHistoricalRoot uint64 `mapstructure:\"slots-per-historical-root\"`\n\t// MinEpochsToInactivityPenalty is the minimum number of epochs before a\n\t// validator is penalized for inactivity.\n\tMinEpochsToInactivityPenalty uint64 `mapstructure:\"min-epochs-to-inactivity-penalty\"`\n\n\t// Signature domains.\n\t//\n\t// DomainDomainTypeProposerProposer is the domain for beacon proposer\n\t// signatures.\n\tDomainTypeProposer common.DomainType `mapstructure:\"domain-type-beacon-proposer\"`\n\t// DomainTypeAttester is the domain for beacon attester signatures.\n\tDomainTypeAttester common.DomainType `mapstructure:\"domain-type-beacon-attester\"`\n\t// DomainTypeRandao is the domain for RANDAO reveal signatures.\n\tDomainTypeRandao common.DomainType `mapstructure:\"domain-type-randao\"`\n\t// DomainTypeDeposit is the domain for deposit contract signatures.\n\tDomainTypeDeposit common.DomainType `mapstructure:\"domain-type-deposit\"`\n\t// DomainTypeVoluntaryExit is the domain for voluntary exit signatures.\n\tDomainTypeVoluntaryExit common.DomainType `mapstructure:\"domain-type-voluntary-exit\"`\n\t// DomainTypeSelectionProof is the domain for selection proof signatures.\n\tDomainTypeSelectionProof common.DomainType `mapstructure:\"domain-type-selection-proof\"`\n\t// DomainTypeAggregateAndProof is the domain for aggregate and proof\n\t// signatures.\n\tDomainTypeAggregateAndProof common.DomainType `mapstructure:\"domain-type-aggregate-and-proof\"`\n\t// DomainTypeApplicationMask is the domain for the application mask.\n\tDomainTypeApplicationMask common.DomainType `mapstructure:\"domain-type-application-mask\"`\n\n\t// Eth1-related values.\n\t//\n\t// DepositContractAddress is the address of the deposit contract.\n\tDepositContractAddress common.ExecutionAddress `mapstructure:\"deposit-contract-address\"`\n\t// MaxDepositsPerBlock specifies the maximum number of deposit operations\n\t// allowed per block.\n\tMaxDepositsPerBlock uint64 `mapstructure:\"max-deposits-per-block\"`\n\t// DepositEth1ChainID is the chain ID of the execution client.\n\tDepositEth1ChainID uint64 `mapstructure:\"deposit-eth1-chain-id\"`\n\t// Eth1FollowDistance is the distance between the eth1 chain and the beacon\n\t// chain with respect to reading deposits.\n\tEth1FollowDistance uint64 `mapstructure:\"eth1-follow-distance\"`\n\t// TargetSecondsPerEth1Block is the target time between eth1 blocks.\n\tTargetSecondsPerEth1Block uint64 `mapstructure:\"target-seconds-per-eth1-block\"`\n\n\t// Fork-related values.\n\t//\n\t// GenesisTime is the time at which the genesis block was created.\n\tGenesisTime uint64 `mapstructure:\"genesis-time\"`\n\t// Deneb1ForkTime is the time at which the Deneb1 fork is activated.\n\tDeneb1ForkTime uint64 `mapstructure:\"deneb-one-fork-time\"`\n\t// ElectraForkTime is the time at which the Electra fork is activated.\n\tElectraForkTime uint64 `mapstructure:\"electra-fork-time\"`\n\t// Electra1ForkTime is the time at which the Electra1 fork is activated.\n\tElectra1ForkTime uint64 `mapstructure:\"electra-one-fork-time\"`\n\t// FuluForkTime is the time at which the Fulu fork is activated (Fusaka CL fork).\n\tFuluForkTime uint64 `mapstructure:\"fulu-fork-time\"`\n\n\t// State list lengths\n\t//\n\t// EpochsPerHistoricalVector is the number of epochs in the historical\n\t// vector.\n\tEpochsPerHistoricalVector uint64 `mapstructure:\"epochs-per-historical-vector\"`\n\t// EpochsPerSlashingsVector is the number of epochs in the slashings vector.\n\tEpochsPerSlashingsVector uint64 `mapstructure:\"epochs-per-slashings-vector\"`\n\t// HistoricalRootsLimit is the maximum number of historical roots.\n\tHistoricalRootsLimit uint64 `mapstructure:\"historical-roots-limit\"`\n\t// ValidatorRegistryLimit is the maximum number of validators in the\n\t// registry.\n\tValidatorRegistryLimit uint64 `mapstructure:\"validator-registry-limit\"`\n\n\t// Capella Values\n\t//\n\t// MaxWithdrawalsPerPayload indicates the maximum number of withdrawal\n\t// operations allowed in a single payload.\n\tMaxWithdrawalsPerPayload uint64 `mapstructure:\"max-withdrawals-per-payload\"`\n\t// MaxValidatorsPerWithdrawalsSweep specifies the maximum number of validator withdrawals\n\t// allowed per sweep. Note that this value should ideally be smaller than the total number\n\t// of validators in the registry.\n\tMaxValidatorsPerWithdrawalsSweep uint64 `mapstructure:\"max-validators-per-withdrawals-sweep\"`\n\n\t// Deneb Values\n\t//\n\t// MinEpochsForBlobsSidecarsRequest is the minimum number of epochs the node\n\t// will keep the blobs for.\n\tMinEpochsForBlobsSidecarsRequest uint64 `mapstructure:\"min-epochs-for-blobs-sidecars-request\"`\n\t// MaxBlobCommitmentsPerBlock specifies the maximum number of blob\n\t// commitments allowed per block.\n\tMaxBlobCommitmentsPerBlock uint64 `mapstructure:\"max-blob-commitments-per-block\"`\n\t// MaxBlobsPerBlock specifies the maximum number of blobs allowed per block.\n\tMaxBlobsPerBlock uint64 `mapstructure:\"max-blobs-per-block\"`\n\t// FieldElementsPerBlob specifies the number of field elements per blob.\n\tFieldElementsPerBlob uint64 `mapstructure:\"field-elements-per-blob\"`\n\t// BytesPerBlob denotes the size of EIP-4844 blobs in bytes.\n\tBytesPerBlob uint64 `mapstructure:\"bytes-per-blob\"`\n\n\t// Berachain Values at genesis\n\t//\n\t// ValidatorSetCap is the maximum number of validators that can be active\n\t// for a given epoch\n\t// Note: ValidatorSetCap must be smaller than ValidatorRegistryLimit.\n\tValidatorSetCap uint64 `mapstructure:\"validator-set-cap\"`\n\t// EVMInflationAddressGenesis is the address on the EVM which will receive the\n\t// inflation amount of native EVM balance through a withdrawal every block.\n\tEVMInflationAddressGenesis common.ExecutionAddress `mapstructure:\"evm-inflation-address\"`\n\t// EVMInflationPerBlockGenesis is the amount of native EVM balance (in Gwei) to be\n\t// minted to the EVMInflationAddress via a withdrawal every block.\n\tEVMInflationPerBlockGenesis uint64 `mapstructure:\"evm-inflation-per-block\"`\n\n\t// Deneb1 Value Changes\n\t//\n\t// EVMInflationAddressDeneb1 is the address on the EVM which will receive the\n\t// inflation amount of native EVM balance through a withdrawal every block in the Deneb1 fork.\n\tEVMInflationAddressDeneb1 common.ExecutionAddress `mapstructure:\"evm-inflation-address-deneb-one\"`\n\t// EVMInflationPerBlockDeneb1 is the amount of native EVM balance (in Gwei) to be\n\t// minted to the EVMInflationAddressDeneb1 via a withdrawal every block in the Deneb1 fork.\n\tEVMInflationPerBlockDeneb1 uint64 `mapstructure:\"evm-inflation-per-block-deneb-one\"`\n\n\t// Electra Values\n\t//\n\t// MinActivationBalance [New in Electra:EIP7251] Minimum balance for a validator to become active\n\tMinActivationBalance uint64 `mapstructure:\"min-activation-balance\"`\n\t// MinValidatorWithdrawabilityDelay is defined in the Electra spec and introduces\n\t// withdrawability delays to allow for slashing.\n\tMinValidatorWithdrawabilityDelay uint64 `mapstructure:\"min-validator-withdrawability-delay\"`\n\n\t// Fulu Value Changes\n\t//\n\t// HysteresisQuotientFulu is the hysteresis quotient for the Fulu fork (BRIP-0008).\n\tHysteresisQuotientFulu uint64 `mapstructure:\"hysteresis-quotient-fulu\"`\n\t// HysteresisUpwardMultiplierFulu is the hysteresis upward multiplier for the Fulu fork.\n\tHysteresisUpwardMultiplierFulu uint64 `mapstructure:\"hysteresis-upward-multiplier-fulu\"`\n\t// EVMInflationAddressFulu is the address on the EVM which will receive the\n\t// inflation amount of native EVM balance through a withdrawal every block in the Fulu fork.\n\tEVMInflationAddressFulu common.ExecutionAddress `mapstructure:\"evm-inflation-address-fulu\"`\n\t// EVMInflationPerBlockFulu is the amount of native EVM balance (in Gwei) to be\n\t// minted to the EVMInflationAddressFulu via a withdrawal every block in the Fulu fork.\n\tEVMInflationPerBlockFulu uint64 `mapstructure:\"evm-inflation-per-block-fulu\"`\n}\n"
  },
  {
    "path": "chain/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage chain\n\nimport \"github.com/berachain/beacon-kit/errors\"\n\nvar (\n\t// ErrInsufficientMaxWithdrawalsPerPayload is returned when the max\n\t// withdrawals per payload less than 2. Must allow at least one for the EVM\n\t// inflation withdrawal, and at least one more for a validator withdrawal\n\t// per block.\n\tErrInsufficientMaxWithdrawalsPerPayload = errors.New(\n\t\t\"max withdrawals per payload must be greater than 1\")\n\n\t// ErrInvalidValidatorSetCap is returned when the validator set cap is\n\t// greater than the validator registry limit.\n\tErrInvalidValidatorSetCap = errors.New(\n\t\t\"validator set cap must be less than the validator registry limit\",\n\t)\n)\n"
  },
  {
    "path": "chain/helpers.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage chain\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n)\n\n// ActiveForkVersionForTimestamp returns the active fork version for a given timestamp.\nfunc (s spec) ActiveForkVersionForTimestamp(timestamp math.U64) common.Version {\n\ttime := timestamp.Unwrap()\n\tif time >= s.FuluForkTime() {\n\t\treturn version.Fulu()\n\t}\n\tif time >= s.Electra1ForkTime() {\n\t\treturn version.Electra1()\n\t}\n\tif time >= s.ElectraForkTime() {\n\t\treturn version.Electra()\n\t}\n\tif time >= s.Deneb1ForkTime() {\n\t\treturn version.Deneb1()\n\t}\n\treturn version.Deneb()\n}\n\n// GenesisForkVersion returns the fork version at genesis.\nfunc (s spec) GenesisForkVersion() common.Version {\n\treturn s.ActiveForkVersionForTimestamp(math.U64(s.GenesisTime()))\n}\n\n// SlotToEpoch converts a slot to an epoch.\nfunc (s spec) SlotToEpoch(slot math.Slot) math.Epoch {\n\treturn math.Epoch(slot.Unwrap() / s.SlotsPerEpoch())\n}\n\n// WithinDAPeriod checks if the block epoch is within MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS\n// of the given current epoch.\nfunc (s spec) WithinDAPeriod(block, current math.Slot) bool {\n\treturn s.SlotToEpoch(block)+s.MinEpochsForBlobsSidecarsRequest() >= s.SlotToEpoch(current)\n}\n\n// IsMainnet returns true if the chain is running with the mainnet chain ID.\nfunc (s spec) IsMainnet() bool {\n\treturn s.DepositEth1ChainID() == MainnetEth1ChainID\n}\n\n// IsTestnet returns true if the chain is running with the testnet chain ID.\nfunc (s spec) IsTestnet() bool {\n\treturn s.DepositEth1ChainID() == TestnetEth1ChainID\n}\n\n// IsDevnet returns true if the chain is running with the devnet chain ID.\nfunc (s spec) IsDevnet() bool {\n\treturn s.DepositEth1ChainID() == DevnetEth1ChainID\n}\n"
  },
  {
    "path": "chain/helpers_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage chain_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// TODO: Add setupValid, setupInvalid functions and use in each test.\n\n// Create an instance of chainSpec with test data.\nvar spec, _ = chain.NewSpec(\n\t&chain.SpecData{\n\t\tDeneb1ForkTime:                   9 * 32 * 2,\n\t\tElectraForkTime:                  10 * 32 * 2,\n\t\tElectra1ForkTime:                 11 * 32 * 2,\n\t\tFuluForkTime:                     12 * 32 * 2,\n\t\tSlotsPerEpoch:                    32,\n\t\tMinEpochsForBlobsSidecarsRequest: 5,\n\t\tMaxWithdrawalsPerPayload:         2,\n\t},\n)\n\n// TestActiveForkVersionForTimestamp tests the ActiveForkVersionForTimestamp method.\nfunc TestActiveForkVersionForTimestamp(t *testing.T) {\n\tt.Parallel()\n\t// Define test cases\n\ttests := []struct {\n\t\tname      string\n\t\ttimestamp uint64\n\t\texpected  common.Version\n\t}{\n\t\t{name: \"Before Electra Fork\", timestamp: spec.ElectraForkTime() - 1, expected: version.Deneb1()},\n\t\t{name: \"At Electra Fork\", timestamp: spec.ElectraForkTime(), expected: version.Electra()},\n\t\t{name: \"After Electra Fork\", timestamp: spec.ElectraForkTime() + 1, expected: version.Electra()},\n\t}\n\n\t// Run test cases\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := spec.ActiveForkVersionForTimestamp(math.U64(tt.timestamp))\n\t\t\trequire.Equal(t, tt.expected, result, \"Test case : %s\", tt.name)\n\t\t})\n\t}\n}\n\n// TestSlotToEpoch tests the SlotToEpoch method.\nfunc TestSlotToEpoch(t *testing.T) {\n\tt.Parallel()\n\t// Define test cases\n\ttests := []struct {\n\t\tname     string\n\t\tslot     math.Slot\n\t\texpected math.Epoch\n\t}{\n\t\t{name: \"Epoch 0, Slot 0\", slot: 0, expected: 0},\n\t\t{name: \"Epoch 0, Slot 31\", slot: 31, expected: 0},\n\t\t{name: \"Epoch 1, Slot 32\", slot: 32, expected: 1},\n\t\t{name: \"Epoch 1, Slot 63\", slot: 63, expected: 1},\n\t\t{name: \"Epoch 2, Slot 64\", slot: 64, expected: 2},\n\t\t{name: \"Epoch 2, Slot 95\", slot: 95, expected: 2},\n\t}\n\n\t// Run test cases\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := spec.SlotToEpoch(tt.slot)\n\t\t\trequire.Equal(t, tt.expected, result, \"Test case : %s\", tt.name)\n\t\t})\n\t}\n}\n\n// TestWithinDAPeriod tests the WithinDAPeriod method.\nfunc TestWithinDAPeriod(t *testing.T) {\n\tt.Parallel()\n\t// Define test cases\n\ttests := []struct {\n\t\tname     string\n\t\tblock    math.Slot\n\t\tcurrent  math.Slot\n\t\texpected bool\n\t}{\n\t\t// Block is within DA period (5 epochs).\n\t\t{name: \"Within DA Period\", block: 0, current: 160, expected: true},\n\t\t// Block is outside DA period (>5 epochs).\n\t\t{name: \"Outside DA Period\", block: 0, current: 192, expected: false},\n\t\t// Block is within DA period.\n\t\t{name: \"Within DA Period 2\", block: 160, current: 320, expected: true},\n\t\t// Block is outside DA period.\n\t\t{\n\t\t\tname:     \"Outside DA Period 2\",\n\t\t\tblock:    160,\n\t\t\tcurrent:  352,\n\t\t\texpected: false,\n\t\t},\n\t}\n\n\t// Run test cases\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := spec.WithinDAPeriod(tt.block, tt.current)\n\t\t\trequire.Equal(t, tt.expected, result, \"Test case : %s\", tt.name)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "chain/spec.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage chain\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/delay\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n)\n\ntype BalancesSpec interface {\n\t// MaxEffectiveBalance returns the maximum balance counted in rewards calculations in Gwei.\n\tMaxEffectiveBalance() math.Gwei\n\n\t// EffectiveBalanceIncrement returns the increment of balance used in reward calculations in\n\t// Gwei.\n\tEffectiveBalanceIncrement() math.Gwei\n\n\t// MinActivationBalance returns the minimum balance required to become an active validator in\n\t// Gwei\n\tMinActivationBalance() math.Gwei\n}\n\ntype HysteresisSpec interface {\n\t// HysteresisQuotient returns the quotient used in effective balance\n\t// calculations to create hysteresis. This provides resistance to small\n\t// balance changes triggering effective balance updates.\n\t// This value is fork-gated by timestamp (updated in Fulu per BRIP-0008).\n\tHysteresisQuotient(timestamp math.U64) math.U64\n\n\t// HysteresisDownwardMultiplier returns the multiplier used when checking\n\t// if the effective balance should be decreased.\n\t// This value is NOT fork-gated by timestamped as no changes are expected to this value.\n\tHysteresisDownwardMultiplier() math.U64\n\n\t// HysteresisUpwardMultiplier returns the multiplier used when checking\n\t// if the effective balance should be increased.\n\t// This value is fork-gated by timestamp (updated in Fulu per BRIP-0008).\n\tHysteresisUpwardMultiplier(timestamp math.U64) math.U64\n}\n\ntype DepositSpec interface {\n\t// MaxDepositsPerBlock returns the maximum number of deposit operations per\n\t// block.\n\tMaxDepositsPerBlock() uint64\n\n\t// DepositEth1ChainID returns the chain ID of the deposit contract.\n\tDepositEth1ChainID() uint64\n}\n\ntype DomainTypeSpec interface {\n\t// Signature Domains\n\n\t// DomainTypeProposer returns the domain for proposer signatures.\n\tDomainTypeProposer() common.DomainType\n\n\t// DomainTypeAttester returns the domain for attester signatures.\n\tDomainTypeAttester() common.DomainType\n\n\t// DomainTypeRandao returns the domain for RANDAO reveal signatures.\n\tDomainTypeRandao() common.DomainType\n\n\t// DomainTypeDeposit returns the domain for deposit signatures.\n\tDomainTypeDeposit() common.DomainType\n\n\t// DomainTypeVoluntaryExit returns the domain for voluntary exit signatures.\n\tDomainTypeVoluntaryExit() common.DomainType\n\n\t// DomainTypeSelectionProof returns the domain for selection proof\n\tDomainTypeSelectionProof() common.DomainType\n\n\t// DomainTypeAggregateAndProof returns the domain for aggregate and proof\n\tDomainTypeAggregateAndProof() common.DomainType\n\n\t// DomainTypeApplicationMask returns the domain for application signatures.\n\tDomainTypeApplicationMask() common.DomainType\n}\n\n// Fork-related values.\ntype ForkSpec interface {\n\t// GenesisTime returns the time at which the genesis block was created.\n\tGenesisTime() uint64\n\n\t// Deneb1ForkTime returns the time at which the Deneb1 fork takes effect.\n\tDeneb1ForkTime() uint64\n\n\t// ElectraForkTime returns the time at which the Electra fork takes effect.\n\tElectraForkTime() uint64\n\n\t// Electra1ForkTime returns the time at which the Electra1 fork takes effect.\n\tElectra1ForkTime() uint64\n\n\t// FuluForkTime returns the time at which the Fulu fork takes effect.\n\tFuluForkTime() uint64\n}\n\ntype BlobSpec interface {\n\t// MaxBlobCommitmentsPerBlock returns the maximum number of blob commitments\n\t// per block.\n\tMaxBlobCommitmentsPerBlock() uint64\n\n\t// MaxBlobsPerBlock returns the maximum number of blobs per block.\n\tMaxBlobsPerBlock() uint64\n\n\t// FieldElementsPerBlob returns the number of field elements per blob.\n\tFieldElementsPerBlob() uint64\n\n\t// WithinDAPeriod checks if a given block slot is within the data\n\t// availability period relative to the current slot.\n\tWithinDAPeriod(block, current math.Slot) bool\n\n\t// BytesPerBlob returns the number of bytes per blob.\n\tBytesPerBlob() uint64\n\n\t// MinEpochsForBlobsSidecarsRequest returns the minimum number of epochs for\n\t// blob sidecar requests.\n\tMinEpochsForBlobsSidecarsRequest() math.Epoch\n}\n\n// Helpers for Fork Version\ntype ForkVersionSpec interface {\n\t// GenesisForkVersion returns the fork version at genesis.\n\tGenesisForkVersion() common.Version\n\n\t// ActiveForkVersionForTimestamp returns the active fork version for a given timestamp.\n\tActiveForkVersionForTimestamp(timestamp math.U64) common.Version\n}\n\ntype BerachainSpec interface {\n\t// EVMInflationAddress returns the address on the EVM which will receive\n\t// the inflation amount of native EVM balance through a withdrawal every\n\t// block.\n\tEVMInflationAddress(timestamp math.U64) common.ExecutionAddress\n\n\t// EVMInflationPerBlock returns the amount of native EVM balance (in Gwei)\n\t// to be minted to the EVMInflationAddress via a withdrawal every block.\n\tEVMInflationPerBlock(timestamp math.U64) math.Gwei\n\n\t// ValidatorSetCap retrieves the maximum number of validators allowed in the active set.\n\tValidatorSetCap() uint64\n\n\t// IsMainnet returns true if the chain is running with the mainnet chain ID.\n\tIsMainnet() bool\n\n\t// IsTestnet returns true if the chain is running with the testnet chain ID.\n\tIsTestnet() bool\n\n\t// IsDevnet returns true if the chain is running with the devnet chain ID.\n\tIsDevnet() bool\n}\n\ntype WithdrawalsSpec interface {\n\t// MaxWithdrawalsPerPayload returns the maximum number of withdrawals per\n\t// payload.\n\tMaxWithdrawalsPerPayload() uint64\n\n\t// MaxValidatorsPerWithdrawalsSweep returns the maximum number of validators\n\t// per withdrawal sweep.\n\tMaxValidatorsPerWithdrawalsSweep() math.U64\n\n\t// MinValidatorWithdrawabilityDelay - an exited validator remains eligible to be slashed until its withdrawable_epoch,\n\t// which is set to MIN_VALIDATOR_WITHDRAWABILITY_DELAY epochs after its exit_epoch.\n\t// This is to allow some extra time for any slashable offences by the validator to be detected and reported.\n\tMinValidatorWithdrawabilityDelay() math.Epoch\n}\n\n// Spec defines an interface for accessing chain-specific parameters.\ntype Spec interface {\n\tdelay.ConfigGetter\n\tDepositSpec\n\tBalancesSpec\n\tHysteresisSpec\n\tDomainTypeSpec\n\tForkSpec\n\tBlobSpec\n\tForkVersionSpec\n\tBerachainSpec\n\tWithdrawalsSpec\n\n\t// Time parameters constants.\n\n\t// SlotToEpoch converts a slot number to an epoch number.\n\tSlotToEpoch(slot math.Slot) math.Epoch\n\n\t// SlotsPerEpoch returns the number of slots in an epoch.\n\tSlotsPerEpoch() uint64\n\n\t// SlotsPerHistoricalRoot returns the number of slots per historical root.\n\tSlotsPerHistoricalRoot() uint64\n\n\t// MinEpochsToInactivityPenalty returns the minimum number of epochs before\n\t// an inactivity penalty is applied.\n\tMinEpochsToInactivityPenalty() uint64\n\n\t// Eth1-related values.\n\n\t// DepositContractAddress returns the deposit contract address.\n\tDepositContractAddress() common.ExecutionAddress\n\n\t// Eth1FollowDistance returns the distance between the eth1 chain and the\n\t// beacon chain for eth1 data.\n\tEth1FollowDistance() uint64\n\n\t// TargetSecondsPerEth1Block returns the target time between eth1 blocks.\n\tTargetSecondsPerEth1Block() uint64\n\n\t// State list lengths\n\n\t// EpochsPerHistoricalVector returns the length of the historical vector.\n\tEpochsPerHistoricalVector() uint64\n\n\t// EpochsPerSlashingsVector returns the length of the slashing vector.\n\tEpochsPerSlashingsVector() uint64\n\n\t// HistoricalRootsLimit returns the maximum number of historical root\n\t// entries.\n\tHistoricalRootsLimit() uint64\n\n\t// ValidatorRegistryLimit returns the maximum number of validators in the\n\t// registry.\n\tValidatorRegistryLimit() uint64\n}\n\n// spec is a concrete implementation of the Spec interface, holding the actual data.\ntype spec struct {\n\t// Data contains the actual chain-specific parameter values.\n\tData *SpecData\n}\n\n// NewSpec creates a new instance of a Spec with the provided data.\nfunc NewSpec(data *SpecData) (Spec, error) {\n\ts := spec{Data: data}\n\treturn s, s.validate()\n}\n\n// validate ensures that the chain spec is valid, returning error if it is not.\nfunc (s spec) validate() error {\n\tif s.Data.MaxWithdrawalsPerPayload <= 1 {\n\t\treturn ErrInsufficientMaxWithdrawalsPerPayload\n\t}\n\n\tif s.Data.ValidatorSetCap > s.Data.ValidatorRegistryLimit {\n\t\treturn ErrInvalidValidatorSetCap\n\t}\n\n\t// EVM Inflation values can be zero or non-zero, no validation needed.\n\n\t// Enforce ordering of the forks. Like most chains, BeaconKit does not support arbitrary ordering of forks.\n\t// Fork times here are in chronological order\n\torderedForkTimes := []uint64{\n\t\ts.Data.GenesisTime,\n\t\ts.Data.Deneb1ForkTime,\n\t\ts.Data.ElectraForkTime,\n\t\ts.Data.Electra1ForkTime,\n\t\ts.Data.FuluForkTime,\n\t}\n\tfor i := 1; i < len(orderedForkTimes); i++ {\n\t\tprev, cur := orderedForkTimes[i-1], orderedForkTimes[i]\n\t\t// must not go backwards\n\t\tif prev > cur {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"fork ordering violation: timestamp at index %d (%d) > index %d (%d)\",\n\t\t\t\ti-1, prev, i, cur,\n\t\t\t)\n\t\t}\n\t}\n\n\tif s.Data.ConsensusUpdateHeight != 0 {\n\t\tif s.Data.ConsensusUpdateHeight >= s.Data.ConsensusEnableHeight {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"stable block time parameters violation: ConsensusUpdateHeight %d must be smaller than ConsensusEnableHeight %d\",\n\t\t\t\ts.Data.ConsensusUpdateHeight, s.Data.ConsensusEnableHeight,\n\t\t\t)\n\t\t}\n\n\t\tif s.Data.MaxBlockDelay == 0 {\n\t\t\treturn errors.New(\"max block delay can't be zero\")\n\t\t}\n\t\tif s.Data.TargetBlockTime == 0 {\n\t\t\treturn errors.New(\"target block time can't be zero\")\n\t\t}\n\t}\n\n\t// TODO: Add more validation rules here.\n\treturn nil\n}\n\nfunc (s spec) SbtMaxBlockDelay() time.Duration {\n\treturn s.Data.MaxBlockDelay\n}\nfunc (s spec) SbtTargetBlockTime() time.Duration {\n\treturn s.Data.TargetBlockTime\n}\nfunc (s spec) SbtConstBlockDelay() time.Duration {\n\treturn s.Data.ConstBlockDelay\n}\nfunc (s spec) SbtConsensusUpdateHeight() int64 {\n\treturn s.Data.ConsensusUpdateHeight\n}\nfunc (s spec) SbtConsensusEnableHeight() int64 {\n\treturn s.Data.ConsensusEnableHeight\n}\n\n// MaxEffectiveBalance returns the maximum effective balance.\nfunc (s spec) MaxEffectiveBalance() math.Gwei {\n\treturn math.Gwei(s.Data.MaxEffectiveBalance)\n}\n\n// MinActivationBalance returns the minimum activation balance effective. Introduced in Electra.\nfunc (s spec) MinActivationBalance() math.Gwei {\n\treturn math.Gwei(s.Data.MinActivationBalance)\n}\n\n// EffectiveBalanceIncrement returns the increment of effective balance.\nfunc (s spec) EffectiveBalanceIncrement() math.Gwei {\n\treturn math.Gwei(s.Data.EffectiveBalanceIncrement)\n}\n\nfunc (s spec) HysteresisQuotient(timestamp math.U64) math.U64 {\n\tfv := s.ActiveForkVersionForTimestamp(timestamp)\n\tswitch {\n\tcase version.Equals(fv, version.Fulu()):\n\t\treturn math.U64(s.Data.HysteresisQuotientFulu)\n\tcase version.Equals(fv, s.GenesisForkVersion()),\n\t\tversion.Equals(fv, version.Deneb1()),\n\t\tversion.Equals(fv, version.Electra()),\n\t\tversion.Equals(fv, version.Electra1()):\n\t\treturn math.U64(s.Data.HysteresisQuotient)\n\t}\n\tpanic(fmt.Sprintf(\"HysteresisQuotient not supported for this fork version: %d\", fv))\n}\n\nfunc (s spec) HysteresisDownwardMultiplier() math.U64 {\n\treturn math.U64(s.Data.HysteresisDownwardMultiplier)\n}\n\nfunc (s spec) HysteresisUpwardMultiplier(timestamp math.U64) math.U64 {\n\tfv := s.ActiveForkVersionForTimestamp(timestamp)\n\tswitch {\n\tcase version.Equals(fv, version.Fulu()):\n\t\treturn math.U64(s.Data.HysteresisUpwardMultiplierFulu)\n\tcase version.Equals(fv, s.GenesisForkVersion()),\n\t\tversion.Equals(fv, version.Deneb1()),\n\t\tversion.Equals(fv, version.Electra()),\n\t\tversion.Equals(fv, version.Electra1()):\n\t\treturn math.U64(s.Data.HysteresisUpwardMultiplier)\n\t}\n\tpanic(fmt.Sprintf(\"HysteresisUpwardMultiplier not supported for this fork version: %d\", fv))\n}\n\n// SlotsPerEpoch returns the number of slots per epoch.\nfunc (s spec) SlotsPerEpoch() uint64 {\n\treturn s.Data.SlotsPerEpoch\n}\n\n// SlotsPerHistoricalRoot returns the number of slots per historical root.\nfunc (s spec) SlotsPerHistoricalRoot() uint64 {\n\treturn s.Data.SlotsPerHistoricalRoot\n}\n\n// MinEpochsToInactivityPenalty returns the minimum number of epochs before an\n// inactivity penalty is applied.\nfunc (s spec) MinEpochsToInactivityPenalty() uint64 {\n\treturn s.Data.MinEpochsToInactivityPenalty\n}\n\n// DomainTypeProposer returns the domain for beacon proposer signatures.\nfunc (s spec) DomainTypeProposer() common.DomainType {\n\treturn s.Data.DomainTypeProposer\n}\n\n// DomainTypeAttester returns the domain for beacon attester signatures.\nfunc (s spec) DomainTypeAttester() common.DomainType {\n\treturn s.Data.DomainTypeAttester\n}\n\n// DomainTypeRandao returns the domain for RANDAO reveal signatures.\nfunc (s spec) DomainTypeRandao() common.DomainType {\n\treturn s.Data.DomainTypeRandao\n}\n\n// DomainTypeDeposit returns the domain for deposit contract signatures.\nfunc (s spec) DomainTypeDeposit() common.DomainType {\n\treturn s.Data.DomainTypeDeposit\n}\n\n// DomainTypeVoluntaryExit returns the domain for voluntary exit signatures.\nfunc (s spec) DomainTypeVoluntaryExit() common.DomainType {\n\treturn s.Data.DomainTypeVoluntaryExit\n}\n\n// DomainTypeSelectionProof returns the domain for selection proof signatures.\nfunc (s spec) DomainTypeSelectionProof() common.DomainType {\n\treturn s.Data.DomainTypeSelectionProof\n}\n\n// DomainTypeAggregateAndProof returns the domain for aggregate and proof\n// signatures.\nfunc (s spec) DomainTypeAggregateAndProof() common.DomainType {\n\treturn s.Data.DomainTypeAggregateAndProof\n}\n\n// DomainTypeApplicationMask returns the domain for the application mask.\nfunc (s spec) DomainTypeApplicationMask() common.DomainType {\n\treturn s.Data.DomainTypeApplicationMask\n}\n\n// DepositContractAddress returns the address of the deposit contract.\nfunc (s spec) DepositContractAddress() common.ExecutionAddress {\n\treturn s.Data.DepositContractAddress\n}\n\n// MaxDepositsPerBlock returns the maximum number of deposits per block.\nfunc (s spec) MaxDepositsPerBlock() uint64 {\n\treturn s.Data.MaxDepositsPerBlock\n}\n\n// DepositEth1ChainID returns the chain ID of the execution chain.\nfunc (s spec) DepositEth1ChainID() uint64 {\n\treturn s.Data.DepositEth1ChainID\n}\n\n// Eth1FollowDistance returns the distance between the eth1 chain and the beacon\n// chain.\nfunc (s spec) Eth1FollowDistance() uint64 {\n\treturn s.Data.Eth1FollowDistance\n}\n\n// TargetSecondsPerEth1Block returns the target time between eth1 blocks.\nfunc (s spec) TargetSecondsPerEth1Block() uint64 {\n\treturn s.Data.TargetSecondsPerEth1Block\n}\n\n// GenesisTime returns the time at which the genesis block was created.\nfunc (s spec) GenesisTime() uint64 {\n\treturn s.Data.GenesisTime\n}\n\n// Deneb1ForkTime returns the timestamp of the Deneb1 fork.\nfunc (s spec) Deneb1ForkTime() uint64 {\n\treturn s.Data.Deneb1ForkTime\n}\n\n// ElectraForkTime returns the timestamp of the Electra fork.\nfunc (s spec) ElectraForkTime() uint64 {\n\treturn s.Data.ElectraForkTime\n}\n\n// Electra1ForkTime returns the epoch of the Electra1 fork.\nfunc (s spec) Electra1ForkTime() uint64 {\n\treturn s.Data.Electra1ForkTime\n}\n\n// FuluForkTime returns the timestamp of the Fulu fork.\nfunc (s spec) FuluForkTime() uint64 {\n\treturn s.Data.FuluForkTime\n}\n\n// EpochsPerHistoricalVector returns the number of epochs per historical vector.\nfunc (s spec) EpochsPerHistoricalVector() uint64 {\n\treturn s.Data.EpochsPerHistoricalVector\n}\n\n// EpochsPerSlashingsVector returns the number of epochs per slashings vector.\nfunc (s spec) EpochsPerSlashingsVector() uint64 {\n\treturn s.Data.EpochsPerSlashingsVector\n}\n\n// HistoricalRootsLimit returns the limit of historical roots.\nfunc (s spec) HistoricalRootsLimit() uint64 {\n\treturn s.Data.HistoricalRootsLimit\n}\n\n// ValidatorRegistryLimit returns the limit of the validator registry.\nfunc (s spec) ValidatorRegistryLimit() uint64 {\n\treturn s.Data.ValidatorRegistryLimit\n}\n\n// MaxWithdrawalsPerPayload returns the maximum number of withdrawals per\n// payload.\nfunc (s spec) MaxWithdrawalsPerPayload() uint64 {\n\treturn s.Data.MaxWithdrawalsPerPayload\n}\n\n// MaxValidatorsPerWithdrawalsSweep returns the maximum number of validators per withdrawals sweep.\nfunc (s spec) MaxValidatorsPerWithdrawalsSweep() math.U64 {\n\treturn math.U64(s.Data.MaxValidatorsPerWithdrawalsSweep)\n}\n\nfunc (s spec) MinValidatorWithdrawabilityDelay() math.Epoch {\n\treturn math.Epoch(s.Data.MinValidatorWithdrawabilityDelay)\n}\n\n// MinEpochsForBlobsSidecarsRequest returns the minimum number of epochs for\n// blobs sidecars request.\nfunc (s spec) MinEpochsForBlobsSidecarsRequest() math.Epoch {\n\treturn math.Epoch(s.Data.MinEpochsForBlobsSidecarsRequest)\n}\n\n// MaxBlobCommitmentsPerBlock returns the maximum number of blob commitments per\n// block.\nfunc (s spec) MaxBlobCommitmentsPerBlock() uint64 {\n\treturn s.Data.MaxBlobCommitmentsPerBlock\n}\n\n// MaxBlobsPerBlock returns the maximum number of blobs per block.\nfunc (s spec) MaxBlobsPerBlock() uint64 {\n\treturn s.Data.MaxBlobsPerBlock\n}\n\n// FieldElementsPerBlob returns the number of field elements per blob.\nfunc (s spec) FieldElementsPerBlob() uint64 {\n\treturn s.Data.FieldElementsPerBlob\n}\n\n// BytesPerBlob returns the number of bytes per blob.\nfunc (s spec) BytesPerBlob() uint64 {\n\treturn s.Data.BytesPerBlob\n}\n\n// ValidatorSetCap retrieves the maximum number of validators allowed in the active set.\nfunc (s spec) ValidatorSetCap() uint64 {\n\treturn s.Data.ValidatorSetCap\n}\n\n// EVMInflationAddress returns the address on the EVM which will receive the\n// inflation amount of native EVM balance through a withdrawal every block.\nfunc (s spec) EVMInflationAddress(timestamp math.U64) common.ExecutionAddress {\n\tfv := s.ActiveForkVersionForTimestamp(timestamp)\n\tswitch {\n\tcase version.Equals(fv, version.Fulu()):\n\t\treturn s.Data.EVMInflationAddressFulu\n\tcase version.Equals(fv, version.Deneb1()),\n\t\tversion.Equals(fv, version.Electra()),\n\t\tversion.Equals(fv, version.Electra1()):\n\t\treturn s.Data.EVMInflationAddressDeneb1\n\tcase version.Equals(fv, s.GenesisForkVersion()):\n\t\treturn s.Data.EVMInflationAddressGenesis\n\t}\n\tpanic(fmt.Sprintf(\"EVMInflationAddress not supported for this fork version: %d\", fv))\n}\n\n// EVMInflationPerBlock returns the amount of native EVM balance (in Gwei) to\n// be minted to the EVMInflationAddress via a withdrawal every block.\nfunc (s spec) EVMInflationPerBlock(timestamp math.U64) math.Gwei {\n\tfv := s.ActiveForkVersionForTimestamp(timestamp)\n\tswitch {\n\tcase version.Equals(fv, version.Fulu()):\n\t\treturn math.Gwei(s.Data.EVMInflationPerBlockFulu)\n\tcase version.Equals(fv, version.Deneb1()),\n\t\tversion.Equals(fv, version.Electra()),\n\t\tversion.Equals(fv, version.Electra1()):\n\t\treturn math.Gwei(s.Data.EVMInflationPerBlockDeneb1)\n\tcase version.Equals(fv, s.GenesisForkVersion()):\n\t\treturn math.Gwei(s.Data.EVMInflationPerBlockGenesis)\n\t}\n\tpanic(fmt.Sprintf(\"EVMInflationPerBlock not supported for this fork version: %d\", fv))\n}\n"
  },
  {
    "path": "chain/spec_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage chain_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc baseSpecData() *chain.SpecData {\n\treturn &chain.SpecData{\n\t\t// satisfy the pre-checks in validate()\n\t\tMaxWithdrawalsPerPayload: 2,\n\t\tValidatorSetCap:          100,\n\t\tValidatorRegistryLimit:   100,\n\t}\n}\n\n// Fork timestamps used by the fork-gated method tests. Values are chosen to be\n// well-separated so boundary cases around each fork can be tested explicitly.\nconst (\n\tforkGatedGenesisTime  uint64 = 0\n\tforkGatedDeneb1Time   uint64 = 100\n\tforkGatedElectraTime  uint64 = 200\n\tforkGatedElectra1Time uint64 = 300\n\tforkGatedFuluTime     uint64 = 400\n)\n\n// Pre-Fulu hysteresis values. Distinct from the Fulu values so tests can detect\n// when the wrong fork branch is taken.\nconst (\n\tpreFuluHysteresisQuotient          uint64 = 4\n\tpreFuluHysteresisUpwardMultiplier  uint64 = 5\n\tfuluHysteresisQuotient             uint64 = 40\n\tfuluHysteresisUpwardMultiplierFulu uint64 = 50\n)\n\n// EVM inflation per block values, distinct per fork region.\nconst (\n\tevmInflationPerBlockGenesis uint64 = 10\n\tevmInflationPerBlockDeneb1  uint64 = 20\n\tevmInflationPerBlockFulu    uint64 = 30\n)\n\nvar (\n\tevmInflationAddrGenesis = common.MustNewExecutionAddressFromHex(\n\t\t\"0x1111111111111111111111111111111111111111\",\n\t)\n\tevmInflationAddrDeneb1 = common.MustNewExecutionAddressFromHex(\n\t\t\"0x2222222222222222222222222222222222222222\",\n\t)\n\tevmInflationAddrFulu = common.MustNewExecutionAddressFromHex(\n\t\t\"0x3333333333333333333333333333333333333333\",\n\t)\n)\n\n// buildForkGatedSpec builds a Spec with distinct fork-gated values so tests can\n// assert which fork branch is taken for a given timestamp.\nfunc buildForkGatedSpec(t *testing.T) chain.Spec {\n\tt.Helper()\n\tdata := baseSpecData()\n\tdata.GenesisTime = forkGatedGenesisTime\n\tdata.Deneb1ForkTime = forkGatedDeneb1Time\n\tdata.ElectraForkTime = forkGatedElectraTime\n\tdata.Electra1ForkTime = forkGatedElectra1Time\n\tdata.FuluForkTime = forkGatedFuluTime\n\n\tdata.HysteresisQuotient = preFuluHysteresisQuotient\n\tdata.HysteresisUpwardMultiplier = preFuluHysteresisUpwardMultiplier\n\tdata.HysteresisQuotientFulu = fuluHysteresisQuotient\n\tdata.HysteresisUpwardMultiplierFulu = fuluHysteresisUpwardMultiplierFulu\n\n\tdata.EVMInflationAddressGenesis = evmInflationAddrGenesis\n\tdata.EVMInflationPerBlockGenesis = evmInflationPerBlockGenesis\n\tdata.EVMInflationAddressDeneb1 = evmInflationAddrDeneb1\n\tdata.EVMInflationPerBlockDeneb1 = evmInflationPerBlockDeneb1\n\tdata.EVMInflationAddressFulu = evmInflationAddrFulu\n\tdata.EVMInflationPerBlockFulu = evmInflationPerBlockFulu\n\n\ts, err := chain.NewSpec(data)\n\trequire.NoError(t, err)\n\treturn s\n}\n\n// TestHysteresisQuotient_ForkBoundary asserts HysteresisQuotient returns the\n// pre-Fulu value for all fork versions up to and including Electra1, and the\n// Fulu value at or after FuluForkTime.\nfunc TestHysteresisQuotient_ForkBoundary(t *testing.T) {\n\tt.Parallel()\n\ts := buildForkGatedSpec(t)\n\n\ttests := []struct {\n\t\tname      string\n\t\ttimestamp uint64\n\t\texpected  math.U64\n\t}{\n\t\t{name: \"At genesis (Deneb)\", timestamp: forkGatedGenesisTime, expected: math.U64(preFuluHysteresisQuotient)},\n\t\t{name: \"At Deneb1 fork\", timestamp: forkGatedDeneb1Time, expected: math.U64(preFuluHysteresisQuotient)},\n\t\t{name: \"At Electra fork\", timestamp: forkGatedElectraTime, expected: math.U64(preFuluHysteresisQuotient)},\n\t\t{name: \"At Electra1 fork\", timestamp: forkGatedElectra1Time, expected: math.U64(preFuluHysteresisQuotient)},\n\t\t{name: \"Just before Fulu\", timestamp: forkGatedFuluTime - 1, expected: math.U64(preFuluHysteresisQuotient)},\n\t\t{name: \"At Fulu fork\", timestamp: forkGatedFuluTime, expected: math.U64(fuluHysteresisQuotient)},\n\t\t{name: \"Just after Fulu\", timestamp: forkGatedFuluTime + 1, expected: math.U64(fuluHysteresisQuotient)},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot := s.HysteresisQuotient(math.U64(tt.timestamp))\n\t\t\trequire.Equal(t, tt.expected, got)\n\t\t})\n\t}\n}\n\n// TestHysteresisUpwardMultiplier_ForkBoundary asserts HysteresisUpwardMultiplier\n// returns the pre-Fulu value before FuluForkTime and the Fulu value at or\n// after FuluForkTime.\nfunc TestHysteresisUpwardMultiplier_ForkBoundary(t *testing.T) {\n\tt.Parallel()\n\ts := buildForkGatedSpec(t)\n\n\ttests := []struct {\n\t\tname      string\n\t\ttimestamp uint64\n\t\texpected  math.U64\n\t}{\n\t\t{name: \"At genesis (Deneb)\", timestamp: forkGatedGenesisTime, expected: math.U64(preFuluHysteresisUpwardMultiplier)},\n\t\t{name: \"At Deneb1 fork\", timestamp: forkGatedDeneb1Time, expected: math.U64(preFuluHysteresisUpwardMultiplier)},\n\t\t{name: \"At Electra fork\", timestamp: forkGatedElectraTime, expected: math.U64(preFuluHysteresisUpwardMultiplier)},\n\t\t{name: \"At Electra1 fork\", timestamp: forkGatedElectra1Time, expected: math.U64(preFuluHysteresisUpwardMultiplier)},\n\t\t{name: \"Just before Fulu\", timestamp: forkGatedFuluTime - 1, expected: math.U64(preFuluHysteresisUpwardMultiplier)},\n\t\t{name: \"At Fulu fork\", timestamp: forkGatedFuluTime, expected: math.U64(fuluHysteresisUpwardMultiplierFulu)},\n\t\t{name: \"Just after Fulu\", timestamp: forkGatedFuluTime + 1, expected: math.U64(fuluHysteresisUpwardMultiplierFulu)},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot := s.HysteresisUpwardMultiplier(math.U64(tt.timestamp))\n\t\t\trequire.Equal(t, tt.expected, got)\n\t\t})\n\t}\n}\n\n// TestEVMInflationAddress_ForkBoundary asserts EVMInflationAddress returns the\n// correct address for each of the three fork regions: genesis (Deneb),\n// Deneb1/Electra/Electra1, and Fulu.\nfunc TestEVMInflationAddress_ForkBoundary(t *testing.T) {\n\tt.Parallel()\n\ts := buildForkGatedSpec(t)\n\n\ttests := []struct {\n\t\tname      string\n\t\ttimestamp uint64\n\t\texpected  common.ExecutionAddress\n\t}{\n\t\t{name: \"At genesis (Deneb)\", timestamp: forkGatedGenesisTime, expected: evmInflationAddrGenesis},\n\t\t{name: \"Between genesis and Deneb1\", timestamp: forkGatedDeneb1Time - 1, expected: evmInflationAddrGenesis},\n\t\t{name: \"At Deneb1 fork\", timestamp: forkGatedDeneb1Time, expected: evmInflationAddrDeneb1},\n\t\t{name: \"At Electra fork\", timestamp: forkGatedElectraTime, expected: evmInflationAddrDeneb1},\n\t\t{name: \"At Electra1 fork\", timestamp: forkGatedElectra1Time, expected: evmInflationAddrDeneb1},\n\t\t{name: \"Just before Fulu\", timestamp: forkGatedFuluTime - 1, expected: evmInflationAddrDeneb1},\n\t\t{name: \"At Fulu fork\", timestamp: forkGatedFuluTime, expected: evmInflationAddrFulu},\n\t\t{name: \"Just after Fulu\", timestamp: forkGatedFuluTime + 1, expected: evmInflationAddrFulu},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot := s.EVMInflationAddress(math.U64(tt.timestamp))\n\t\t\trequire.Equal(t, tt.expected, got)\n\t\t})\n\t}\n}\n\n// TestEVMInflationPerBlock_ForkBoundary asserts EVMInflationPerBlock returns\n// the correct amount for each of the three fork regions: genesis (Deneb),\n// Deneb1/Electra/Electra1, and Fulu.\nfunc TestEVMInflationPerBlock_ForkBoundary(t *testing.T) {\n\tt.Parallel()\n\ts := buildForkGatedSpec(t)\n\n\ttests := []struct {\n\t\tname      string\n\t\ttimestamp uint64\n\t\texpected  math.Gwei\n\t}{\n\t\t{name: \"At genesis (Deneb)\", timestamp: forkGatedGenesisTime, expected: math.Gwei(evmInflationPerBlockGenesis)},\n\t\t{name: \"Between genesis and Deneb1\", timestamp: forkGatedDeneb1Time - 1, expected: math.Gwei(evmInflationPerBlockGenesis)},\n\t\t{name: \"At Deneb1 fork\", timestamp: forkGatedDeneb1Time, expected: math.Gwei(evmInflationPerBlockDeneb1)},\n\t\t{name: \"At Electra fork\", timestamp: forkGatedElectraTime, expected: math.Gwei(evmInflationPerBlockDeneb1)},\n\t\t{name: \"At Electra1 fork\", timestamp: forkGatedElectra1Time, expected: math.Gwei(evmInflationPerBlockDeneb1)},\n\t\t{name: \"Just before Fulu\", timestamp: forkGatedFuluTime - 1, expected: math.Gwei(evmInflationPerBlockDeneb1)},\n\t\t{name: \"At Fulu fork\", timestamp: forkGatedFuluTime, expected: math.Gwei(evmInflationPerBlockFulu)},\n\t\t{name: \"Just after Fulu\", timestamp: forkGatedFuluTime + 1, expected: math.Gwei(evmInflationPerBlockFulu)},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot := s.EVMInflationPerBlock(math.U64(tt.timestamp))\n\t\t\trequire.Equal(t, tt.expected, got)\n\t\t})\n\t}\n}\n\nfunc TestValidate_ForkOrder_Success(t *testing.T) {\n\tt.Parallel()\n\tdata := baseSpecData()\n\tdata.GenesisTime = 10\n\tdata.Deneb1ForkTime = 20\n\tdata.ElectraForkTime = 30\n\tdata.Electra1ForkTime = 40\n\tdata.FuluForkTime = 50\n\n\t_, err := chain.NewSpec(data)\n\trequire.NoError(t, err)\n}\n\nfunc TestValidate_ForkOrder_GenesisAfterDeneb(t *testing.T) {\n\tt.Parallel()\n\tdata := baseSpecData()\n\tdata.GenesisTime = 50\n\tdata.Deneb1ForkTime = 20\n\tdata.ElectraForkTime = 60\n\tdata.Electra1ForkTime = 70\n\tdata.FuluForkTime = 80\n\n\t_, err := chain.NewSpec(data)\n\trequire.Error(t, err)\n\trequire.Contains(t, err.Error(), \"timestamp at index 0 (50) > index 1 (20)\")\n}\n\nfunc TestValidate_ForkOrder_DenebAfterElectra(t *testing.T) {\n\tt.Parallel()\n\tdata := baseSpecData()\n\tdata.GenesisTime = 10\n\tdata.Deneb1ForkTime = 80\n\tdata.ElectraForkTime = 40\n\tdata.Electra1ForkTime = 50\n\tdata.FuluForkTime = 90\n\n\t_, err := chain.NewSpec(data)\n\trequire.Error(t, err)\n\trequire.Contains(t, err.Error(), \"timestamp at index 1 (80) > index 2 (40)\")\n}\n\nfunc TestValidate_ForkOrder_AllForksAtGenesis(t *testing.T) {\n\tt.Parallel()\n\tdata := baseSpecData()\n\tdata.GenesisTime = 0\n\tdata.Deneb1ForkTime = 0\n\tdata.ElectraForkTime = 0\n\tdata.Electra1ForkTime = 0\n\n\t_, err := chain.NewSpec(data)\n\trequire.NoError(t, err)\n}\n"
  },
  {
    "path": "cli/builder/builder.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage builder\n\nimport (\n\t\"os\"\n\n\t\"cosmossdk.io/depinject\"\n\tcmdlib \"github.com/berachain/beacon-kit/cli/commands\"\n\tservertypes \"github.com/berachain/beacon-kit/cli/commands/server/types\"\n\t\"github.com/berachain/beacon-kit/cli/config\"\n\tcometbft \"github.com/berachain/beacon-kit/consensus/cometbft/service\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\t\"github.com/cosmos/cosmos-sdk/client\"\n\t\"github.com/spf13/cobra\"\n)\n\n// CLIBuilder is the builder for the commands.Root (root command).\ntype CLIBuilder struct {\n\tname        string\n\tdescription string\n\t// components is a list of component providers for depinject.\n\tcomponents []any\n\t// suppliers is a list of suppliers for depinject.\n\tsuppliers []any\n\t// nodeBuilderFunc is a function that builds the Node,\n\t// eventually called by the cosmos-sdk.\n\t// TODO: CLI should not know about the AppCreator\n\tnodeBuilderFunc      servertypes.AppCreator\n\tchainSpecBuilderFunc servertypes.ChainSpecCreator\n}\n\n// New returns a new CLIBuilder with the given options.\nfunc New(opts ...Opt) *CLIBuilder {\n\tcb := &CLIBuilder{\n\t\tsuppliers: []any{\n\t\t\tos.Stdout, // supply io.Writer for logger\n\t\t},\n\t}\n\tfor _, opt := range opts {\n\t\topt(cb)\n\t}\n\treturn cb\n}\n\n// Build builds the CLI commands.\nfunc (cb *CLIBuilder) Build() (*cmdlib.Root, error) {\n\t// allocate memory to hold the dependencies\n\tvar (\n\t\tclientCtx client.Context\n\t\tlogger    *phuslu.Logger\n\t)\n\n\t// build dependencies for the root command\n\tif err := depinject.Inject(\n\t\tdepinject.Configs(\n\t\t\tdepinject.Supply(cb.suppliers...),\n\t\t\tdepinject.Provide(\n\t\t\t\tcb.components...,\n\t\t\t),\n\t\t),\n\t\t&logger,\n\t\t&clientCtx,\n\t); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// pass in deps to build the root command\n\trootCmd := cmdlib.New(\n\t\tcb.name,\n\t\tcb.description,\n\t\tcb.defaultRunHandler(logger),\n\t\tclientCtx,\n\t)\n\n\t// apply default root command setup\n\tcmdlib.DefaultRootCommandSetup(\n\t\trootCmd,\n\t\t&cometbft.Service{},\n\t\tcb.nodeBuilderFunc,\n\t\tcb.chainSpecBuilderFunc,\n\t)\n\n\treturn rootCmd, nil\n}\n\n// defaultRunHandler returns the default run handler for the CLIBuilder.\nfunc (cb *CLIBuilder) defaultRunHandler(logger *phuslu.Logger) func(cmd *cobra.Command) error {\n\treturn func(cmd *cobra.Command) error {\n\t\treturn cb.InterceptConfigsPreRunHandler(\n\t\t\tcmd,\n\t\t\tlogger,\n\t\t\tDefaultAppConfigTemplate(),\n\t\t\tDefaultAppConfig(),\n\t\t\tcometbft.DefaultConfig(),\n\t\t)\n\t}\n}\n\nfunc (cb *CLIBuilder) InterceptConfigsPreRunHandler(\n\tcmd *cobra.Command,\n\tlogger *phuslu.Logger,\n\tcustomAppConfigTemplate string,\n\tcustomAppConfig interface{},\n\tcmtConfig *cmtcfg.Config,\n) error {\n\treturn config.SetupCommand(\n\t\tcmd,\n\t\tcustomAppConfigTemplate,\n\t\tcustomAppConfig,\n\t\tcmtConfig,\n\t\tlogger,\n\t)\n}\n"
  },
  {
    "path": "cli/builder/config.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage builder\n\nimport (\n\t\"github.com/berachain/beacon-kit/config\"\n\tserverconfig \"github.com/berachain/beacon-kit/config/config\"\n\t\"github.com/berachain/beacon-kit/config/template\"\n)\n\n// DefaultAppConfigTemplate returns the default configuration template for the\n// application.\nfunc DefaultAppConfigTemplate() string {\n\treturn serverconfig.DefaultConfigTemplate +\n\t\t\"\\n\" + template.TomlTemplate\n}\n\n// DefaultAppConfig returns the default configuration for the application.\nfunc DefaultAppConfig() any {\n\t// Define a struct for the custom app configuration.\n\ttype CustomAppConfig struct {\n\t\tserverconfig.Config\n\t\tBeaconKit *config.Config `mapstructure:\"beacon-kit\"`\n\t}\n\n\t// Start with the default server configuration.\n\tcfg := serverconfig.DefaultConfig()\n\tcfg.Telemetry.Enabled = true\n\n\t// BeaconKit forces PebbleDB as the database backend.\n\tcfg.Pruning = \"everything\"\n\n\t// IAVL FastNode should ALWAYS be disabled on IAVL v1.x.\n\tcfg.IAVLDisableFastNode = true\n\tcfg.IAVLCacheSize = 2500\n\n\t// Create the custom app configuration.\n\tcustomAppConfig := CustomAppConfig{\n\t\tConfig:    *cfg,\n\t\tBeaconKit: config.DefaultConfig(),\n\t}\n\n\treturn customAppConfig\n}\n"
  },
  {
    "path": "cli/builder/options.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage builder\n\nimport (\n\tservertypes \"github.com/berachain/beacon-kit/cli/commands/server/types\"\n)\n\n// Opt is a type that defines a function that modifies CLIBuilder.\ntype Opt func(*CLIBuilder)\n\n// WithName sets the name for the CLIBuilder.\nfunc WithName(name string) Opt {\n\treturn func(cb *CLIBuilder) {\n\t\tcb.name = name\n\t}\n}\n\n// WithDescription sets the description for the CLIBuilder.\nfunc WithDescription(description string) Opt {\n\treturn func(cb *CLIBuilder) {\n\t\tcb.description = description\n\t}\n}\n\n// WithComponents sets the components for the CLIBuilder.\nfunc WithComponents(components []any) Opt {\n\treturn func(cb *CLIBuilder) {\n\t\tcb.components = components\n\t}\n}\n\n// WithNodeBuilderFunc sets the cosmos app creator for the CLIBuilder.\nfunc WithNodeBuilderFunc(nodeBuilderFunc servertypes.AppCreator) Opt {\n\treturn func(cb *CLIBuilder) {\n\t\tcb.nodeBuilderFunc = nodeBuilderFunc\n\t}\n}\n\n// WithChainSpecBuilderFunc sets the chainspec builder\nfunc WithChainSpecBuilderFunc(chainBuilderFunc servertypes.ChainSpecCreator) Opt {\n\treturn func(cb *CLIBuilder) {\n\t\tcb.chainSpecBuilderFunc = chainBuilderFunc\n\t}\n}\n"
  },
  {
    "path": "cli/commands/deposit/commands.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage deposit\n\nimport (\n\tservertypes \"github.com/berachain/beacon-kit/cli/commands/server/types\"\n\t\"github.com/cosmos/cosmos-sdk/client\"\n\t\"github.com/spf13/cobra\"\n)\n\n// Commands creates a new command for deposit related actions.\nfunc Commands(chainSpecCreator servertypes.ChainSpecCreator, appCreator servertypes.AppCreator) *cobra.Command {\n\tcmd := &cobra.Command{\n\t\tUse:                        \"deposit\",\n\t\tShort:                      \"deposit subcommands\",\n\t\tDisableFlagParsing:         false,\n\t\tSuggestionsMinimumDistance: 2, //nolint:mnd // from sdk.\n\t\tRunE:                       client.ValidateCmd,\n\t}\n\n\tcmd.AddCommand(\n\t\tGetValidateDepositCmd(chainSpecCreator),\n\t\tGetCreateValidatorCmd(chainSpecCreator),\n\t\tGetValidatorKeysCmd(),\n\t\tGetDBCheckCmd(appCreator),\n\t)\n\n\treturn cmd\n}\n"
  },
  {
    "path": "cli/commands/deposit/commands_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage deposit_test\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\t\"testing/quick\"\n\n\t\"github.com/berachain/beacon-kit/cli/commands/deposit\"\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/node-core/components/signer\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\tcmtbls12381 \"github.com/cometbft/cometbft/crypto/bls12381\"\n\t\"github.com/cometbft/cometbft/privval\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestCreateAndValidateCommandsDuality(t *testing.T) {\n\tt.Parallel()\n\n\tqc := &quick.Config{MaxCount: 100}\n\n\tcs, err := spec.DevnetChainSpec()\n\trequire.NoError(t, err)\n\n\t// create a tmp folder where test stores bls keys and\n\t// overwrite relevant files across test cases\n\ttmpFolder := t.TempDir()\n\n\tcometCfg := cmtcfg.DefaultConfig()\n\tcometCfg.RootDir = tmpFolder\n\n\tkeyFilePath := cometCfg.PrivValidatorKeyFile()\n\tstateFilePath := cometCfg.PrivValidatorStateFile()\n\n\trequire.NoError(t, os.MkdirAll(filepath.Dir(keyFilePath), 0o777))\n\trequire.NoError(t, os.MkdirAll(filepath.Dir(stateFilePath), 0o777))\n\n\tf := func(\n\t\tblsKeySecret [32]byte,\n\t\tgenValRoot common.Root,\n\t\tcreds types.WithdrawalCredentials,\n\t\tamount math.Gwei,\n\t) bool {\n\t\t// generate random blsKey from the given secret\n\t\tvar privKey *cmtbls12381.PrivKey\n\t\tprivKey, err = cmtbls12381.GenPrivKeyFromSecret(blsKeySecret[:])\n\t\trequire.NoError(t, err)\n\n\t\t// update relevant files and create corresponding blsSigner\n\t\tpv := privval.NewFilePV(privKey, keyFilePath, stateFilePath)\n\t\tpv.Save()\n\t\tblsSigner := signer.NewBLSSigner(keyFilePath, stateFilePath)\n\n\t\t// create the deposit and check that it verifies\n\t\tvar (\n\t\t\tmsg  *types.DepositMessage\n\t\t\tsign crypto.BLSSignature\n\t\t)\n\t\tmsg, sign, err = deposit.CreateDepositMessage(cs, blsSigner, genValRoot, creds, amount)\n\t\trequire.NoError(t, err)\n\n\t\treturn deposit.ValidateDeposit(cs, msg.Pubkey, msg.Credentials, msg.Amount, genValRoot, sign) == nil\n\t}\n\n\trequire.NoError(t, quick.Check(f, qc))\n}\n"
  },
  {
    "path": "cli/commands/deposit/create.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage deposit\n\nimport (\n\t\"fmt\"\n\n\tclitypes \"github.com/berachain/beacon-kit/cli/commands/server/types\"\n\tclicontext \"github.com/berachain/beacon-kit/cli/context\"\n\t\"github.com/berachain/beacon-kit/cli/utils/parser\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/node-core/components\"\n\t\"github.com/berachain/beacon-kit/node-core/components/signer\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/spf13/cobra\"\n)\n\nconst (\n\tcreateAddr0 = iota\n\tcreateAmt1  = iota\n\tcreateRoot2 = iota\n\n\tminArgsCreateDeposit = 2\n\tmaxArgsCreateDeposit = 3\n\n\toverrideNodeKey         = \"override-node-key\"\n\tvalPrivateKey           = \"validator-private-key\"\n\tuseGenesisValidatorRoot = \"genesis-validator-root\"\n\n\tuseGenesisValidatorRootShorthand = \"g\"\n\n\tdefaultGenesisValidatorRoot = \"\"\n)\n\n// GetCreateValidatorCmd returns a command to create a validator deposit.\n//\n//nolint:lll // Reads better if long description is one line.\nfunc GetCreateValidatorCmd(\n\tchainSpecCreator clitypes.ChainSpecCreator,\n) *cobra.Command {\n\tcmd := &cobra.Command{\n\t\tUse:   \"create-validator [withdrawal-address] [amount] ?[beacond/genesis.json]\",\n\t\tShort: \"Creates a validator deposit message\",\n\t\tLong:  `Creates a validator deposit message with the necessary credentials. The arguments are expected in the order of withdrawal address, deposit amount, and optionally the beacond genesis file. If the genesis validator root flag is NOT set, the beacond genesis file MUST be provided as the last argument. If the override flag is set to true, a private key must be provided to sign the message.`,\n\t\tArgs:  cobra.RangeArgs(minArgsCreateDeposit, maxArgsCreateDeposit),\n\t\tRunE:  createValidatorCmd(chainSpecCreator),\n\t}\n\n\tcmd.Flags().BoolP(\n\t\toverrideNodeKey,\n\t\t\"o\",\n\t\tfalse, // no override by default\n\t\t\"override the node private key\",\n\t)\n\tcmd.Flags().String(\n\t\tvalPrivateKey,\n\t\t\"\", // no default private key\n\t\t\"validator private key. This is required if the override-node-key flag is set.\",\n\t)\n\tcmd.Flags().StringP(\n\t\tuseGenesisValidatorRoot,\n\t\tuseGenesisValidatorRootShorthand,\n\t\tdefaultGenesisValidatorRoot,\n\t\t\"Use the provided genesis validator root. If this is not set, the beacond genesis file must be provided manually as the last argument.\",\n\t)\n\n\treturn cmd\n}\n\n// createValidatorCmd returns a command that builds a create validator request.\nfunc createValidatorCmd(\n\tchainSpecCreator clitypes.ChainSpecCreator,\n) func(*cobra.Command, []string) error {\n\treturn func(cmd *cobra.Command, args []string) error {\n\t\tappOpts := clicontext.GetViperFromCmd(cmd)\n\t\tchainSpec, err := chainSpecCreator(appOpts)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// Get the BLS signer.\n\t\tblsSigner, err := getBLSSigner(cmd)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\twithdrawalAddressStr := args[createAddr0]\n\t\twithdrawalAddress, err := common.NewExecutionAddressFromHex(withdrawalAddressStr)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tcredentials := types.NewCredentialsFromExecutionAddress(withdrawalAddress)\n\n\t\tamountStr := args[createAmt1]\n\t\tamount, err := parser.ConvertAmount(amountStr)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tgenesisValidatorRoot, err := getGenesisValidatorRoot(\n\t\t\tcmd, chainSpec, args, maxArgsCreateDeposit,\n\t\t)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tdepositMsg, signature, err := CreateDepositMessage(chainSpec, blsSigner, genesisValidatorRoot, credentials, amount)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tcmd.Println(\"✅ Deposit message created successfully!\")\n\t\tcmd.Println(\"Note: This is NOT a transaction receipt; use these values to create a deposit contract transaction.\")\n\t\tcmd.Printf(\"\\npubkey: %s\\n\", depositMsg.Pubkey)\n\t\tcmd.Printf(\"credentials: %s\\n\", depositMsg.Credentials)\n\t\tcmd.Printf(\"amount: %s\\n\", depositMsg.Amount.Base10())\n\t\tcmd.Printf(\"signature: %s\\n\", signature.String())\n\t\treturn nil\n\t}\n}\n\nfunc CreateDepositMessage(\n\tcs ChainSpec,\n\tblsSigner crypto.BLSSigner,\n\tgenValRoot common.Root,\n\tcreds types.WithdrawalCredentials,\n\tamount math.Gwei,\n) (\n\t*types.DepositMessage,\n\tcrypto.BLSSignature,\n\terror,\n) {\n\t// Create and sign the deposit message. All deposits are signed with the genesis version.\n\tdepositMsg, signature, err := types.CreateAndSignDepositMessage(\n\t\ttypes.NewForkData(cs.GenesisForkVersion(), genValRoot),\n\t\tcs.DomainTypeDeposit(),\n\t\tblsSigner,\n\t\tcreds,\n\t\tamount,\n\t)\n\tif err != nil {\n\t\treturn nil, crypto.BLSSignature{}, fmt.Errorf(\"failed CreateAndSignDepositMessage: %w\", err)\n\t}\n\n\treturn depositMsg,\n\t\tsignature,\n\t\tValidateDeposit(\n\t\t\tcs,\n\t\t\tdepositMsg.Pubkey,\n\t\t\tdepositMsg.Credentials,\n\t\t\tdepositMsg.Amount,\n\t\t\tgenValRoot,\n\t\t\tsignature,\n\t\t)\n}\n\n// getBLSSigner returns a BLS signer based on the override commands key flag.\nfunc getBLSSigner(\n\tcmd *cobra.Command,\n) (crypto.BLSSigner, error) {\n\tvar legacyKey components.LegacyKey\n\toverrideFlag, err := cmd.Flags().GetBool(overrideNodeKey)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Build the BLS signer.\n\tif overrideFlag {\n\t\tvar validatorPrivKey string\n\t\tvalidatorPrivKey, err = cmd.Flags().GetString(valPrivateKey)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif validatorPrivKey == \"\" {\n\t\t\treturn nil, ErrValidatorPrivateKeyRequired\n\t\t}\n\t\tlegacyKey, err = signer.LegacyKeyFromString(validatorPrivKey)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn components.ProvideBlsSigner(\n\t\tcomponents.BlsSignerInput{\n\t\t\tAppOpts: clicontext.GetViperFromCmd(cmd),\n\t\t\tPrivKey: legacyKey,\n\t\t},\n\t)\n}\n"
  },
  {
    "path": "cli/commands/deposit/db_check.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage deposit\n\nimport (\n\tservertypes \"github.com/berachain/beacon-kit/cli/commands/server/types\"\n\tclicontext \"github.com/berachain/beacon-kit/cli/context\"\n\tservercmtlog \"github.com/berachain/beacon-kit/consensus/cometbft/service/log\"\n\t\"github.com/berachain/beacon-kit/state-transition/core\"\n\t\"github.com/berachain/beacon-kit/storage/db\"\n\tdbm \"github.com/cosmos/cosmos-db\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n\t\"github.com/spf13/cobra\"\n)\n\n// GetDBCheckCmd returns a command for checking that the deposit store\n// is in sync with the beacon state.\nfunc GetDBCheckCmd(appCreator servertypes.AppCreator) *cobra.Command {\n\tcmd := &cobra.Command{\n\t\tUse:   \"db-check\",\n\t\tShort: `Checks if the deposit store is in sync with the beacon state. Fails if either of the beacon or deposit DBs are not available.`,\n\t\tRunE: func(cmd *cobra.Command, _ []string) error {\n\t\t\t// Create the application from home directory configs and data.\n\t\t\tv := clicontext.GetViperFromCmd(cmd)\n\t\t\tlogger := clicontext.GetLoggerFromCmd(cmd)\n\t\t\tcfg := clicontext.GetConfigFromCmd(cmd)\n\t\t\tdb, err := db.OpenDB(cfg.RootDir, dbm.PebbleDBBackend)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tapp := appCreator(logger, db, nil, cfg, v)\n\n\t\t\t// Setup the state to check.\n\t\t\tctx := sdk.NewContext(\n\t\t\t\tapp.CommitMultiStore().CacheMultiStore(), false, servercmtlog.WrapSDKLogger(logger),\n\t\t\t).WithContext(cmd.Context())\n\t\t\tbeaconState := app.StorageBackend().StateFromContext(ctx)\n\t\t\tdepositStore := app.StorageBackend().DepositStore()\n\n\t\t\t// Verify that the deposit store is in sync with the Beacon state.\n\t\t\teth1Data, err := beaconState.GetEth1Data()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err = core.ValidateNonGenesisDeposits(\n\t\t\t\tctx,\n\t\t\t\tbeaconState,\n\t\t\t\tdepositStore,\n\t\t\t\t// maxDepositsPerBlock: 0\n\t\t\t\t// In this snapshotted state, we will check up to the existing deposits and not any more.\n\t\t\t\t0,\n\t\t\t\t// blkDeposits: nil\n\t\t\t\t// There are no new block deposits as we are checking at this snapshotted state.\n\t\t\t\tnil,\n\t\t\t\t// blkDepositRoot: eth1Data.DepositRoot\n\t\t\t\t// We will compare against the beacon state's deposit root at this snapshotted state.\n\t\t\t\teth1Data.DepositRoot,\n\t\t\t); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tlogger.Info(\"✅ Deposit store is in sync with the Beacon state!\")\n\t\t\treturn nil\n\t\t},\n\t}\n\n\treturn cmd\n}\n"
  },
  {
    "path": "cli/commands/deposit/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage deposit\n\nimport \"errors\"\n\nvar (\n\t// ErrValidatorPrivateKeyRequired is returned when the validator private key\n\t// is required but not provided.\n\tErrValidatorPrivateKeyRequired = errors.New(\n\t\t\"validator private key required\",\n\t)\n\n\t// ErrPrivateKeyRequired is returned when the broadcast flag is set but a\n\t// private key is not provided.\n\tErrPrivateKeyRequired = errors.New(\n\t\t\"private key required\",\n\t)\n\n\t// ErrDepositReceiptEmpty is returned when the deposit receipt is nil.\n\tErrDepositReceiptEmpty = errors.New(\n\t\t\"deposit receipt is nil\")\n\n\t// ErrPrivateKeyEmpty is returned when the private key is empty.\n\tErrPrivateKeyEmpty = errors.New(\n\t\t\"private key is empty\")\n)\n"
  },
  {
    "path": "cli/commands/deposit/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage deposit\n\nimport (\n\t\"github.com/berachain/beacon-kit/cli/utils/genesis\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n)\n\ntype ChainSpec interface {\n\tDomainTypeDeposit() common.DomainType\n\tGenesisForkVersion() common.Version\n\tgenesis.ChainSpec\n}\n"
  },
  {
    "path": "cli/commands/deposit/keys.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage deposit\n\nimport (\n\t\"encoding/base64\"\n\n\t\"github.com/berachain/beacon-kit/cli/context\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/node-core/components\"\n\t\"github.com/berachain/beacon-kit/node-core/components/signer\"\n\t\"github.com/cometbft/cometbft/crypto/bls12381\"\n\t\"github.com/spf13/cobra\"\n)\n\n// GetValidatorKeysCmd returns a command that returns the validator public key in different formats\n// for the given private key files.\n//\n//nolint:lll // reads better if long description is one line.\nfunc GetValidatorKeysCmd() *cobra.Command {\n\tcmd := &cobra.Command{\n\t\tUse:   \"validator-keys\",\n\t\tShort: \"Outputs the validator public key in different formats.\",\n\t\tLong:  `Outputs the validator public key in formats of Comet address, Comet pubkey, and Eth/Beacon pubkey. Uses the private key file specified as the value of \"priv_validator_key_file\" in the config.toml file in the beacond HOMEDIR.`,\n\t\tArgs:  cobra.ExactArgs(0),\n\t\tRunE: func(cmd *cobra.Command, _ []string) error {\n\t\t\t// Get the BLS signer.\n\t\t\tblsSignerI, err := components.ProvideBlsSigner(\n\t\t\t\tcomponents.BlsSignerInput{\n\t\t\t\t\tAppOpts: context.GetViperFromCmd(cmd),\n\t\t\t\t},\n\t\t\t)\n\t\t\tif err != nil {\n\t\t\t\treturn errors.Wrap(err, \"failed to initialize BLS signer from validator files\")\n\t\t\t}\n\t\t\tblsSigner, ok := blsSignerI.(*signer.BLSSigner)\n\t\t\tif !ok {\n\t\t\t\treturn errors.New(\"failed to assert BLS signer type\")\n\t\t\t}\n\n\t\t\t// Get the comet public key.\n\t\t\tcometKey, err := blsSigner.PrivValidator.GetPubKey()\n\t\t\tif err != nil {\n\t\t\t\treturn errors.Wrap(err, \"failed to get comet public key from bls signer\")\n\t\t\t}\n\n\t\t\t// Get the comet BLS public key.\n\t\t\tblsKey, err := bls12381.NewPublicKeyFromBytes(cometKey.Bytes())\n\t\t\tif err != nil {\n\t\t\t\treturn errors.Wrap(err, \"failed to create BLS key from bytes\")\n\t\t\t}\n\n\t\t\t// Output the validator public key in different formats.\n\t\t\tcmd.Printf(\n\t\t\t\t\"Comet Address:\\n%s\\n\\n\",\n\t\t\t\tcometKey.Address(),\n\t\t\t)\n\t\t\tcmd.Printf(\n\t\t\t\t\"Comet Pubkey (Uncompressed Base64):\\n%s\\n\\n\",\n\t\t\t\tbase64.StdEncoding.EncodeToString(blsKey.Bytes()),\n\t\t\t)\n\t\t\tcmd.Printf(\n\t\t\t\t\"Eth/Beacon Pubkey (Compressed 48-byte Hex):\\n%s\\n\",\n\t\t\t\tblsSigner.PublicKey().String(),\n\t\t\t)\n\n\t\t\treturn nil\n\t\t},\n\t}\n\n\treturn cmd\n}\n"
  },
  {
    "path": "cli/commands/deposit/utils.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage deposit\n\nimport (\n\t\"github.com/berachain/beacon-kit/cli/utils/genesis\"\n\t\"github.com/berachain/beacon-kit/cli/utils/parser\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/spf13/cobra\"\n)\n\n// Get the genesis validator root. If the genesis validator root flag is not set, the genesis\n// validator root is computed from the genesis file at the last argument (idx: maxArgs - 1).\nfunc getGenesisValidatorRoot(\n\tcmd *cobra.Command, chainSpec ChainSpec, args []string, maxArgs int,\n) (common.Root, error) {\n\tvar genesisValidatorRoot common.Root\n\tgenesisValidatorRootStr, err := cmd.Flags().GetString(useGenesisValidatorRoot)\n\tif err != nil {\n\t\treturn common.Root{}, err\n\t}\n\n\tif genesisValidatorRootStr != defaultGenesisValidatorRoot {\n\t\tgenesisValidatorRoot, err = parser.ConvertGenesisValidatorRoot(genesisValidatorRootStr)\n\t} else {\n\t\tif len(args) != maxArgs {\n\t\t\treturn common.Root{}, errors.New(\n\t\t\t\t\"genesis validator root is required if not using the genesis file flag\",\n\t\t\t)\n\t\t}\n\t\tgenesisValidatorRoot, err = genesis.ComputeValidatorsRootFromFile(args[maxArgs-1], chainSpec)\n\t}\n\n\treturn genesisValidatorRoot, err\n}\n"
  },
  {
    "path": "cli/commands/deposit/validate.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage deposit\n\nimport (\n\tclitypes \"github.com/berachain/beacon-kit/cli/commands/server/types\"\n\t\"github.com/berachain/beacon-kit/cli/context\"\n\t\"github.com/berachain/beacon-kit/cli/utils/parser\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/node-core/components/signer\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/spf13/cobra\"\n)\n\nconst (\n\tvalidatePubKey0 = iota\n\tvalidateCreds1  = iota\n\tvalidateAmt2    = iota\n\tvalidateSign3   = iota\n\n\tminArgsValidateDeposit = 4\n\tmaxArgsValidateDeposit = 5\n)\n\n// GetValidateDepositCmd creates a new command for validating a deposit message.\n//\n//nolint:lll // Reads better if long description is one line.\nfunc GetValidateDepositCmd(chainSpecCreator clitypes.ChainSpecCreator) *cobra.Command {\n\tcmd := &cobra.Command{\n\t\tUse:   \"validate [pubkey] [withdrawal-credentials] [amount] [signature] ?[beacond/genesis.json]\",\n\t\tShort: \"Validates a deposit message for creating a new validator\",\n\t\tLong:  `Validates a deposit message (public key, withdrawal credentials, deposit amount) for creating a new validator. The args taken are in the order of the public key, withdrawal credentials, deposit amount, signature, and optionally the beacond genesis file. If the genesis validator root flag is NOT set, the beacond genesis file MUST be provided as the last argument.`,\n\t\tArgs:  cobra.RangeArgs(minArgsValidateDeposit, maxArgsValidateDeposit),\n\t\tRunE:  validateDepositMessage(chainSpecCreator),\n\t}\n\n\tcmd.Flags().StringP(\n\t\tuseGenesisValidatorRoot,\n\t\tuseGenesisValidatorRootShorthand,\n\t\tdefaultGenesisValidatorRoot,\n\t\t\"Use the provided genesis validator root. If this is not set, the beacond genesis file must be provided manually as the last argument.\",\n\t)\n\n\treturn cmd\n}\n\n// validateDepositMessage validates a deposit message for creating a new validator.\nfunc validateDepositMessage(chainSpecCreator clitypes.ChainSpecCreator) func(cmd *cobra.Command, args []string) error {\n\treturn func(cmd *cobra.Command, args []string) error {\n\t\tv := context.GetViperFromCmd(cmd)\n\t\tchainSpec, err := chainSpecCreator(v)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tpubKeyStr := args[validatePubKey0]\n\t\tpubkey, err := parser.ConvertPubkey(pubKeyStr)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tcredsStr := args[validateCreds1]\n\t\tcredentials, err := parser.ConvertWithdrawalCredentials(credsStr)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tamountStr := args[validateAmt2]\n\t\tamount, err := parser.ConvertAmount(amountStr)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tsigStr := args[validateSign3]\n\t\tsignature, err := parser.ConvertSignature(sigStr)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tgenesisValidatorRoot, err := getGenesisValidatorRoot(\n\t\t\tcmd, chainSpec, args, maxArgsValidateDeposit,\n\t\t)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif err = ValidateDeposit(\n\t\t\tchainSpec, pubkey, credentials, amount, genesisValidatorRoot, signature,\n\t\t); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tcmd.Println(\"✅ Deposit message is valid!\")\n\t\treturn nil\n\t}\n}\n\nfunc ValidateDeposit(\n\tcs ChainSpec,\n\tpubkey crypto.BLSPubkey,\n\tcreds types.WithdrawalCredentials,\n\tamount math.Gwei,\n\tgenValRoot common.Root,\n\tsignature crypto.BLSSignature,\n) error {\n\tdepositMessage := types.DepositMessage{\n\t\tPubkey:      pubkey,\n\t\tCredentials: creds,\n\t\tAmount:      amount,\n\t}\n\n\t// All deposits are signed with the genesis version.\n\treturn depositMessage.VerifyCreateValidator(\n\t\ttypes.NewForkData(cs.GenesisForkVersion(), genValRoot),\n\t\tsignature,\n\t\tcs.DomainTypeDeposit(),\n\t\tsigner.BLSSigner{}.VerifySignature,\n\t)\n}\n"
  },
  {
    "path": "cli/commands/genesis/collect.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage genesis\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/berachain/beacon-kit/cli/context\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\t\"github.com/cosmos/cosmos-sdk/x/genutil\"\n\tgenutiltypes \"github.com/cosmos/cosmos-sdk/x/genutil/types\"\n\t\"github.com/spf13/afero\"\n\t\"github.com/spf13/cobra\"\n)\n\n// CollectGenesisDepositsCmd - return the cobra command to\n// collect genesis transactions.\nfunc CollectGenesisDepositsCmd() *cobra.Command {\n\tcmd := &cobra.Command{\n\t\tUse:   \"collect-premined-deposits\",\n\t\tShort: \"adds a validator to the genesis file\",\n\t\tRunE: func(cmd *cobra.Command, _ []string) error {\n\t\t\tconfig := context.GetConfigFromCmd(cmd)\n\t\t\treturn CollectGenesisDeposits(config)\n\t\t},\n\t}\n\treturn cmd\n}\n\nfunc CollectGenesisDeposits(config *cmtcfg.Config) error {\n\tappGenesis, err := genutiltypes.AppGenesisFromFile(\n\t\tconfig.GenesisFile(),\n\t)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to read genesis doc from file\")\n\t}\n\n\t// create the app state\n\tappGenesisState, err := genutiltypes.GenesisStateFromAppGenesis(appGenesis)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Ensure the map is initialized before it is indexed below. If the\n\t// underlying function returned a nil map with a nil error (which is\n\t// permissible in Go), we defensively allocate an empty map to avoid\n\t// potential nil dereference panics that static analysis (nilaway)\n\t// rightfully complains about.\n\tif appGenesisState == nil {\n\t\tappGenesisState = make(map[string]json.RawMessage)\n\t}\n\n\tvar deposits []*types.Deposit\n\tif deposits, err = CollectValidatorJSONFiles(\n\t\tfilepath.Join(config.RootDir, \"config\", \"premined-deposits\"),\n\t\tappGenesis,\n\t); err != nil {\n\t\treturn errors.Wrap(\n\t\t\terr,\n\t\t\t\"failed to collect validator json files\",\n\t\t)\n\t}\n\n\tgenesisInfo := &types.Genesis{}\n\n\tif err = json.Unmarshal(\n\t\tappGenesisState[\"beacon\"], genesisInfo,\n\t); err != nil {\n\t\treturn errors.Wrap(err, \"failed to unmarshal beacon genesis\")\n\t}\n\n\tfor i, deposit := range deposits {\n\t\tdeposit.Index = uint64(i) // #nosec G115 -- won't realistically overflow.\n\t\tgenesisInfo.Deposits = append(genesisInfo.Deposits, deposit)\n\t}\n\n\tappGenesisState[\"beacon\"], err = json.Marshal(genesisInfo)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to marshal beacon genesis\")\n\t}\n\n\tif appGenesis.AppState, err = json.MarshalIndent(\n\t\tappGenesisState, \"\", \"  \",\n\t); err != nil {\n\t\treturn err\n\t}\n\n\treturn genutil.ExportGenesisFile(appGenesis, config.GenesisFile())\n}\n\n// CollectValidatorJSONFiles collects JSON files from the specified directory\n// and unmarshals them into a list of Deposit objects.\nfunc CollectValidatorJSONFiles(\n\tgenTxsDir string,\n\tgenesis *genutiltypes.AppGenesis,\n) ([]*types.Deposit, error) {\n\t// prepare a map of all balances in genesis state to then validate\n\t// against the validators addresses\n\tvar appState map[string]json.RawMessage\n\tif err := json.Unmarshal(genesis.AppState, &appState); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// get the list of files in the genTxsDir\n\tfos, err := os.ReadDir(genTxsDir)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// prepare the list of validators\n\tdeposits := make([]*types.Deposit, 0)\n\tfor _, fo := range fos {\n\t\tif fo.IsDir() {\n\t\t\tcontinue\n\t\t}\n\t\tif !strings.HasSuffix(fo.Name(), \".json\") {\n\t\t\tcontinue\n\t\t}\n\n\t\tvar bz []byte\n\t\tbz, err = afero.ReadFile(\n\t\t\tafero.NewOsFs(),\n\t\t\tfilepath.Join(genTxsDir, fo.Name()),\n\t\t)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tval := &types.Deposit{}\n\t\tif err = json.Unmarshal(bz, val); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tdeposits = append(deposits, val)\n\t}\n\n\treturn deposits, nil\n}\n"
  },
  {
    "path": "cli/commands/genesis/deposit.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage genesis\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\tservertypes \"github.com/berachain/beacon-kit/cli/commands/server/types\"\n\t\"github.com/berachain/beacon-kit/cli/context\"\n\t\"github.com/berachain/beacon-kit/cli/utils/parser\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/node-core/components\"\n\t\"github.com/berachain/beacon-kit/node-core/components/signer\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\t\"github.com/cosmos/cosmos-sdk/client/flags\"\n\t\"github.com/cosmos/cosmos-sdk/x/genutil\"\n\t\"github.com/spf13/afero\"\n\t\"github.com/spf13/cobra\"\n)\n\n// AddGenesisDepositCmd - returns the cobra command to\n// add a premined deposit to the genesis file.\n//\n//nolint:lll // reads better if long description is one line.\nfunc AddGenesisDepositCmd(chainSpecCreator servertypes.ChainSpecCreator) *cobra.Command {\n\tcmd := &cobra.Command{\n\t\tUse:   \"add-premined-deposit\",\n\t\tShort: \"adds a validator to the genesis file\",\n\t\tLong:  `Adds a validator to the genesis file with the necessary credentials. The arguments are expected in the order of the deposit amount and withdrawal address.`,\n\t\tArgs:  cobra.ExactArgs(2), //nolint:mnd // The number of arguments.\n\t\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\t\t// Get the deposit amount.\n\t\t\tdepositAmount, err := parser.ConvertAmount(args[0])\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\t// Get the withdrawal address.\n\t\t\twithdrawalAddress, err := common.NewExecutionAddressFromHex(args[1])\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcometConfig := context.GetConfigFromCmd(cmd)\n\t\t\tappOpts := context.GetViperFromCmd(cmd)\n\t\t\toutputDocument, _ := cmd.Flags().GetString(flags.FlagOutputDocument)\n\n\t\t\t// Get the BLS signer.\n\t\t\tblsSigner, err := components.ProvideBlsSigner(\n\t\t\t\tcomponents.BlsSignerInput{\n\t\t\t\t\tAppOpts: appOpts,\n\t\t\t\t},\n\t\t\t)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tchainSpec, err := chainSpecCreator(appOpts)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn AddGenesisDeposit(chainSpec, cometConfig, blsSigner, depositAmount, withdrawalAddress, outputDocument)\n\t\t},\n\t}\n\treturn cmd\n}\n\n// AddGenesisDeposit is the modularized version of AddGenesisDepositCmd that can be properly tested from within the runtime.\nfunc AddGenesisDeposit(\n\tcs ChainSpec,\n\tcometConfig *cmtcfg.Config,\n\tblsSigner crypto.BLSSigner,\n\tdepositAmount math.Gwei,\n\twithdrawalAddress common.ExecutionAddress,\n\toutputDocument string,\n) error {\n\t_, valPubKey, err := genutil.InitializeNodeValidatorFiles(\n\t\tcometConfig, crypto.CometBLSType,\n\t)\n\tif err != nil {\n\t\treturn errors.Wrap(\n\t\t\terr,\n\t\t\t\"failed to initialize commands validator files\",\n\t\t)\n\t}\n\n\tif valPubKey == nil {\n\t\t// addresses nilaway\n\t\treturn errors.New(\"failed to initialize commands validator files\")\n\t}\n\n\tgenesisVersion := cs.GenesisForkVersion()\n\n\tdepositMsg, signature, err := types.CreateAndSignDepositMessage(\n\t\ttypes.NewForkData(genesisVersion, common.Root{}),\n\t\tcs.DomainTypeDeposit(),\n\t\tblsSigner,\n\t\ttypes.NewCredentialsFromExecutionAddress(withdrawalAddress),\n\t\tdepositAmount,\n\t)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Verify the deposit message.\n\tif err = depositMsg.VerifyCreateValidator(\n\t\ttypes.NewForkData(genesisVersion, common.Root{}),\n\t\tsignature,\n\t\tcs.DomainTypeDeposit(),\n\t\tsigner.BLSSigner{}.VerifySignature,\n\t); err != nil {\n\t\treturn err\n\t}\n\n\tdeposit := types.Deposit{\n\t\tPubkey:      depositMsg.Pubkey,\n\t\tAmount:      depositMsg.Amount,\n\t\tSignature:   signature,\n\t\tCredentials: depositMsg.Credentials,\n\t}\n\n\tif outputDocument == \"\" {\n\t\toutputDocument, err = makeOutputFilepath(cometConfig.RootDir,\n\t\t\tcrypto.BLSPubkey(valPubKey.Bytes()).String())\n\t\tif err != nil {\n\t\t\treturn errors.Wrap(err, \"failed to create output file path\")\n\t\t}\n\t}\n\n\tif err = writeDepositToFile(outputDocument, &deposit); err != nil {\n\t\treturn errors.Wrap(err, \"failed to write signed gen tx\")\n\t}\n\n\treturn nil\n}\n\nfunc makeOutputFilepath(rootDir, pubkey string) (string, error) {\n\twritePath := filepath.Join(rootDir, \"config\", \"premined-deposits\")\n\tif err := afero.NewOsFs().MkdirAll(writePath, 0o700); err != nil { //nolint:mnd // dir permissions.\n\t\treturn \"\", errors.Wrapf(\n\t\t\terrors.New(\"could not create directory\"), \"%q: %w\",\n\t\t\twritePath,\n\t\t\terr,\n\t\t)\n\t}\n\n\treturn filepath.Join(\n\t\twritePath,\n\t\tfmt.Sprintf(\"premined-deposit-%v.json\", pubkey),\n\t), nil\n}\n\nfunc writeDepositToFile(\n\toutputDocument string,\n\tdepositMessage *types.Deposit,\n) error {\n\t//#nosec:G302,G304 // Ignore errors on this line.\n\toutputFile, err := afero.NewOsFs().OpenFile(\n\t\toutputDocument,\n\t\tos.O_CREATE|os.O_EXCL|os.O_WRONLY,\n\t\t0o644, //nolint:mnd // file permissions.\n\t)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t//#nosec:G307 // Ignore errors on this line.\n\tdefer outputFile.Close()\n\n\tbz, err := json.Marshal(depositMessage)\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = fmt.Fprintf(outputFile, \"%s\\n\", bz)\n\n\treturn err\n}\n"
  },
  {
    "path": "cli/commands/genesis/deposit_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage genesis_test\n\nimport (\n\t\"path\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/cli/commands/genesis\"\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\t\"github.com/berachain/beacon-kit/node-core/components/signer\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\t\"github.com/cometbft/cometbft/crypto/bls12381\"\n\t\"github.com/cometbft/cometbft/types\"\n\t\"github.com/ethereum/go-ethereum/params\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestGenesisDeposit(t *testing.T) {\n\tt.Parallel()\n\thomeDir := t.TempDir()\n\tt.Log(\"Home folder:\", homeDir)\n\n\tchainSpec, err := spec.MainnetChainSpec()\n\trequire.NoError(t, err)\n\n\tcometConfig := cmtcfg.DefaultConfig()\n\n\tcometConfig.SetRoot(homeDir)\n\n\t// Forces Comet to Create it\n\tcometConfig.NodeKey = \"nodekey.json\"\n\n\tdepositAmount := math.Gwei(250_000 * params.GWei)\n\twithdrawalAdress, err := common.NewExecutionAddressFromHex(\"0x981114102592310C347E61368342DDA67017bf84\")\n\trequire.NoError(t, err)\n\toutputDocument := \"\"\n\n\tblsSigner := signer.BLSSigner{PrivValidator: types.NewMockPVWithKeyType(bls12381.KeyType)}\n\n\terr = genesis.AddGenesisDeposit(chainSpec, cometConfig, blsSigner, depositAmount, withdrawalAdress, outputDocument)\n\trequire.NoError(t, err)\n\n\trequire.FileExists(t, path.Join(homeDir, \"nodekey.json\"))\n\trequire.FileExists(t, path.Join(homeDir, \"data\", \"priv_validator_state.json\"))\n\trequire.FileExists(t, path.Join(homeDir, \"config\", \"priv_validator_key.json\"))\n\trequire.DirExists(t, path.Join(homeDir, \"config\", \"premined-deposits\"))\n\t// TODO: Extend tests to assert on the contents of the files\n}\n"
  },
  {
    "path": "cli/commands/genesis/genesis.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage genesis\n\nimport (\n\tservertypes \"github.com/berachain/beacon-kit/cli/commands/server/types\"\n\t\"github.com/cosmos/cosmos-sdk/client\"\n\t\"github.com/spf13/cobra\"\n)\n\n// Commands builds the genesis-related command. Users may\n// provide application specific commands as a parameter.\nfunc Commands(\n\tcsc servertypes.ChainSpecCreator,\n\tcmds ...*cobra.Command,\n) *cobra.Command {\n\tcmd := &cobra.Command{\n\t\tUse:                        \"genesis\",\n\t\tShort:                      \"Application's genesis-related subcommands\",\n\t\tDisableFlagParsing:         false,\n\t\tSuggestionsMinimumDistance: 2, //nolint:mnd // from sdk.\n\t\tRunE:                       client.ValidateCmd,\n\t}\n\n\t// Adding subcommands for genesis-related operations.\n\tcmd.AddCommand(\n\t\tAddGenesisDepositCmd(csc),\n\t\tCollectGenesisDepositsCmd(),\n\t\tAddExecutionPayloadCmd(csc),\n\t\tGetGenesisValidatorRootCmd(csc),\n\t\tSetDepositStorageCmd(csc),\n\t)\n\n\t// Add additional commands\n\tfor _, subCmd := range cmds {\n\t\tcmd.AddCommand(subCmd)\n\t}\n\n\treturn cmd\n}\n"
  },
  {
    "path": "cli/commands/genesis/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage genesis\n\nimport (\n\t\"github.com/berachain/beacon-kit/cli/utils/genesis\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n)\n\ntype ChainSpec interface {\n\tgenesis.ChainSpec\n\tGenesisForkVersion() common.Version\n\tDomainTypeDeposit() common.DomainType\n\tMaxWithdrawalsPerPayload() uint64\n\tDepositContractAddress() common.ExecutionAddress\n}\n"
  },
  {
    "path": "cli/commands/genesis/payload.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage genesis\n\nimport (\n\t\"fmt\"\n\t\"unsafe\"\n\n\tservertypes \"github.com/berachain/beacon-kit/cli/commands/server/types\"\n\t\"github.com/berachain/beacon-kit/cli/context\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\tbkitgethtypes \"github.com/berachain/beacon-kit/gethlib/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\t\"github.com/cosmos/cosmos-sdk/x/genutil\"\n\tgenutiltypes \"github.com/cosmos/cosmos-sdk/x/genutil/types\"\n\tgethengine \"github.com/ethereum/go-ethereum/beacon/engine\"\n\t\"github.com/spf13/afero\"\n\t\"github.com/spf13/cobra\"\n)\n\nfunc AddExecutionPayloadCmd(chainSpecCreator servertypes.ChainSpecCreator) *cobra.Command {\n\tcmd := &cobra.Command{\n\t\tUse:   \"execution-payload [eth/genesis/file.json]\",\n\t\tShort: \"adds the eth1 genesis execution payload to the genesis file\",\n\t\tArgs:  cobra.ExactArgs(1),\n\t\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\t\t// Read the genesis file.\n\t\t\telGenesisPath := args[0]\n\t\t\tconfig := context.GetConfigFromCmd(cmd)\n\t\t\tv := context.GetViperFromCmd(cmd)\n\t\t\tchainSpec, err := chainSpecCreator(v)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn AddExecutionPayload(chainSpec, elGenesisPath, config)\n\t\t},\n\t}\n\n\treturn cmd\n}\n\nfunc AddExecutionPayload(chainSpec ChainSpec, elGenesisPath string, config *cmtcfg.Config) error {\n\tgenesisBz, err := afero.ReadFile(afero.NewOsFs(), elGenesisPath)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to read eth1 genesis file\")\n\t}\n\n\t// Unmarshal the genesis file.\n\tethGenesis := &bkitgethtypes.Genesis{}\n\tif err = ethGenesis.UnmarshalJSON(genesisBz); err != nil {\n\t\treturn errors.Wrap(err, \"failed to unmarshal eth1 genesis\")\n\t}\n\tgenesisBlock := ethGenesis.ToBlock()\n\n\t// Create the execution payload.\n\tpayload := bkitgethtypes.BlockToExecutableData(\n\t\tgenesisBlock,\n\t\tnil,\n\t\tnil,\n\t\tnil,\n\t).ExecutionPayload\n\n\tappGenesis, err := genutiltypes.AppGenesisFromFile(config.GenesisFile())\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to read genesis doc from file\")\n\t}\n\n\t// create the app state\n\tappGenesisState, err := genutiltypes.GenesisStateFromAppGenesis(appGenesis)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Defensive: ensure the map returned is non-nil before indexing. This\n\t// prevents potential nil dereference panics flagged by static analysis\n\t// tools such as nilaway.\n\tif appGenesisState == nil {\n\t\tappGenesisState = make(map[string]json.RawMessage)\n\t}\n\n\tgenesisInfo := &types.Genesis{}\n\n\tif err = json.Unmarshal(\n\t\tappGenesisState[\"beacon\"], genesisInfo,\n\t); err != nil {\n\t\treturn errors.Wrap(err, \"failed to unmarshal beacon state\")\n\t}\n\t// Inject the execution payload.\n\teph, err := executableDataToExecutionPayloadHeader(\n\t\tchainSpec.GenesisForkVersion(),\n\t\tpayload,\n\t\tchainSpec.MaxWithdrawalsPerPayload(),\n\t)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to convert executable data to execution payload header\")\n\t}\n\tif eph == nil {\n\t\treturn errors.New(\"failed to get execution payload header\")\n\t}\n\tgenesisInfo.ExecutionPayloadHeader = eph\n\n\tappGenesisState[\"beacon\"], err = json.Marshal(genesisInfo)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to marshal beacon state\")\n\t}\n\n\tif appGenesis.AppState, err = json.MarshalIndent(\n\t\tappGenesisState, \"\", \"  \",\n\t); err != nil {\n\t\treturn err\n\t}\n\n\treturn genutil.ExportGenesisFile(appGenesis, config.GenesisFile())\n}\n\n// Converts the eth executable data type to the beacon execution payload header\n// interface.\nfunc executableDataToExecutionPayloadHeader(\n\tforkVersion common.Version,\n\tdata *gethengine.ExecutableData,\n\t// todo: re-enable when codec supports.\n\t_ uint64,\n) (*types.ExecutionPayloadHeader, error) {\n\teph := &types.ExecutionPayloadHeader{}\n\n\t// We do not support fork versions before Deneb and after Fulu.\n\tif version.IsAfter(forkVersion, version.Fulu()) ||\n\t\tversion.IsBefore(forkVersion, version.Deneb()) {\n\t\treturn nil, types.ErrForkVersionNotSupported\n\t}\n\n\twithdrawals := make(\n\t\tengineprimitives.Withdrawals,\n\t\tlen(data.Withdrawals),\n\t)\n\tfor i, withdrawal := range data.Withdrawals {\n\t\t// #nosec:G103 // primitives.Withdrawals is data.Withdrawals with\n\t\t// hard\n\t\t// types.\n\t\twithdrawals[i] = (*engineprimitives.Withdrawal)(\n\t\t\tunsafe.Pointer(withdrawal),\n\t\t)\n\t}\n\n\tif len(data.ExtraData) > constants.ExtraDataLength {\n\t\tdata.ExtraData = data.ExtraData[:constants.ExtraDataLength]\n\t}\n\n\tvar blobGasUsed uint64\n\tif data.BlobGasUsed != nil {\n\t\tblobGasUsed = *data.BlobGasUsed\n\t}\n\n\tvar excessBlobGas uint64\n\tif data.ExcessBlobGas != nil {\n\t\texcessBlobGas = *data.ExcessBlobGas\n\t}\n\n\tbaseFeePerGas, err := math.NewU256FromBigInt(data.BaseFeePerGas)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed baseFeePerGas conversion: %w\", err)\n\t}\n\n\teph.Versionable = types.NewVersionable(forkVersion)\n\teph.ParentHash = common.ExecutionHash(data.ParentHash)\n\teph.FeeRecipient = common.ExecutionAddress(data.FeeRecipient)\n\teph.StateRoot = common.Bytes32(data.StateRoot)\n\teph.ReceiptsRoot = common.Bytes32(data.ReceiptsRoot)\n\teph.LogsBloom = [256]byte(data.LogsBloom)\n\teph.Random = common.Bytes32(data.Random)\n\teph.Number = math.U64(data.Number)\n\teph.GasLimit = math.U64(data.GasLimit)\n\teph.GasUsed = math.U64(data.GasUsed)\n\teph.Timestamp = math.U64(data.Timestamp)\n\teph.ExtraData = data.ExtraData\n\teph.BaseFeePerGas = baseFeePerGas\n\teph.BlockHash = common.ExecutionHash(data.BlockHash)\n\teph.TransactionsRoot = engineprimitives.Transactions(data.Transactions).HashTreeRoot()\n\teph.WithdrawalsRoot = withdrawals.HashTreeRoot()\n\teph.BlobGasUsed = math.U64(blobGasUsed)\n\teph.ExcessBlobGas = math.U64(excessBlobGas)\n\n\treturn eph, nil\n}\n"
  },
  {
    "path": "cli/commands/genesis/root.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage genesis\n\nimport (\n\t\"github.com/berachain/beacon-kit/cli/commands/server/types\"\n\t\"github.com/berachain/beacon-kit/cli/context\"\n\t\"github.com/berachain/beacon-kit/cli/utils/genesis\"\n\t\"github.com/spf13/cobra\"\n)\n\n// GetGenesisValidatorRootCmd returns a command that gets the genesis validator root from a given\n// beacond genesis file.\nfunc GetGenesisValidatorRootCmd(chainSpecCreator types.ChainSpecCreator) *cobra.Command {\n\tcmd := &cobra.Command{\n\t\tUse:   \"validator-root [beacond/genesis.json]\",\n\t\tShort: \"gets and returns the genesis validator root\",\n\t\tArgs:  cobra.ExactArgs(1),\n\t\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\t\tv := context.GetViperFromCmd(cmd)\n\t\t\tchainSpec, err := chainSpecCreator(v)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tgenesisValidatorsRoot, err := genesis.ComputeValidatorsRootFromFile(args[0], chainSpec)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tcmd.Printf(\"%s\\n\", genesisValidatorsRoot)\n\t\t\treturn nil\n\t\t},\n\t}\n\n\treturn cmd\n}\n"
  },
  {
    "path": "cli/commands/genesis/storage.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage genesis\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"math/big\"\n\t\"path/filepath\"\n\n\t\"github.com/berachain/beacon-kit/cli/commands/genesis/types\"\n\tclitypes \"github.com/berachain/beacon-kit/cli/commands/server/types\"\n\t\"github.com/berachain/beacon-kit/cli/context\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\tgenutiltypes \"github.com/cosmos/cosmos-sdk/x/genutil/types\"\n\tgethcommon \"github.com/ethereum/go-ethereum/common\"\n\tgethtypes \"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/spf13/afero\"\n\t\"github.com/spf13/cobra\"\n)\n\n// SetDepositStorageCmd sets deposit contract storage in genesis alloc file.\n//\n//nolint:lll // reads better if long description is one line\nfunc SetDepositStorageCmd(chainSpecCreator clitypes.ChainSpecCreator) *cobra.Command {\n\tcmd := &cobra.Command{\n\t\tUse:   \"set-deposit-storage [eth/genesis/file.json]\",\n\t\tShort: \"sets deposit contract storage in eth genesis\",\n\t\tLong:  `Updates the deposit contract storage in the passed in eth genesis file. Creates a new EL genesis file with the changes in the BEACOND_HOME directory.`,\n\t\tArgs:  cobra.ExactArgs(1),\n\t\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\t\t// Read the EL genesis file.\n\t\t\telGenesisFilePath := args[0]\n\t\t\t// Get the deposits from the beacon chain genesis appstate.\n\t\t\tconfig := context.GetConfigFromCmd(cmd)\n\t\t\tappOpts := context.GetViperFromCmd(cmd)\n\t\t\tchainSpec, err := chainSpecCreator(appOpts)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn SetDepositStorage(chainSpec, config, elGenesisFilePath)\n\t\t},\n\t}\n\n\treturn cmd\n}\n\nfunc SetDepositStorage(\n\tchainSpec ChainSpec,\n\tconfig *cmtcfg.Config,\n\telGenesisFilePath string,\n) error {\n\telGenesisBz, err := afero.ReadFile(afero.NewOsFs(), elGenesisFilePath)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to read eth1 genesis file\")\n\t}\n\n\tclGenesis, err := genutiltypes.AppGenesisFromFile(\n\t\tconfig.GenesisFile(),\n\t)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to read genesis doc from file\")\n\t}\n\n\tgenesisState, err := genutiltypes.GenesisStateFromAppGenesis(\n\t\tclGenesis,\n\t)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to read appstate from genesis\")\n\t}\n\n\tbeaconStateRaw := genesisState[\"beacon\"]\n\tvar beaconState struct {\n\t\tDeposits ctypes.Deposits `json:\"deposits\"`\n\t}\n\tif err = json.Unmarshal(beaconStateRaw, &beaconState); err != nil {\n\t\treturn errors.Wrap(err, \"failed to unmarshal beacon state\")\n\t}\n\tdeposits := beaconState.Deposits\n\n\t// Set the storage of the deposit contract with deposits count and root.\n\tcount := big.NewInt(int64(len(deposits)))\n\troot := deposits.HashTreeRoot()\n\n\t// Unmarshal the genesis file.\n\telGenesis := &types.DefaultEthGenesisJSON{}\n\tallocsKey := types.DefaultAllocsKey\n\tif err = json.Unmarshal(elGenesisBz, elGenesis); err != nil {\n\t\treturn errors.Wrap(err, \"failed to unmarshal eth1 genesis\")\n\t}\n\n\tdepositAddr := gethcommon.Address(chainSpec.DepositContractAddress())\n\tallocs := writeDepositStorage(elGenesis, depositAddr, count, root)\n\n\t// Get just the filename from the path\n\tfilename := filepath.Base(elGenesisFilePath)\n\toutputPath := filepath.Join(config.RootDir, filename)\n\n\t// Write to file.\n\terr = writeGenesisAllocToFile(depositAddr, outputPath, elGenesisFilePath, allocs, allocsKey)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to write genesis alloc to file\")\n\t}\n\treturn nil\n}\n\nfunc writeDepositStorage(\n\telGenesis types.EthGenesis,\n\tdepositAddr gethcommon.Address,\n\tdepositsCount *big.Int,\n\tdepositsRoot common.Root,\n) gethtypes.GenesisAlloc {\n\tslot0 := gethcommon.HexToHash(\"0x0000000000000000000000000000000000000000000000000000000000000000\")\n\tslot1 := gethcommon.HexToHash(\"0x0000000000000000000000000000000000000000000000000000000000000001\")\n\n\tallocs := elGenesis.Alloc()\n\tif entry, ok := allocs[depositAddr]; ok {\n\t\tif entry.Storage == nil {\n\t\t\tentry.Storage = make(map[gethcommon.Hash]gethcommon.Hash)\n\t\t}\n\t\tentry.Storage[slot0] = gethcommon.BigToHash(depositsCount)\n\t\tentry.Storage[slot1] = gethcommon.BytesToHash(depositsRoot[:])\n\t\tallocs[depositAddr] = entry\n\t}\n\treturn allocs\n}\n\nfunc writeGenesisAllocToFile(\n\tdepositAddr gethcommon.Address,\n\toutputDocument string,\n\tinputDocument string,\n\tgenesisAlloc gethtypes.GenesisAlloc,\n\tallocsKey string,\n) error {\n\t// Read existing el genesis file\n\texistingBz, err := afero.ReadFile(afero.NewOsFs(), inputDocument)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Unmarshal existing genesis using json.Number to preserve integer precision\n\tvar existingGenesis map[string]interface{}\n\tdecoder := json.NewDecoder(bytes.NewReader(existingBz))\n\tdecoder.UseNumber()\n\tif err = decoder.Decode(&existingGenesis); err != nil {\n\t\treturn err\n\t}\n\n\t// Get existing alloc.\n\talloc, ok := existingGenesis[allocsKey].(map[string]interface{})\n\tif !ok {\n\t\treturn errors.New(\"invalid alloc format in genesis file\")\n\t}\n\n\t// Update only the deposit contract entry\n\tif account, exists := genesisAlloc[depositAddr]; exists {\n\t\talloc[depositAddr.Hex()] = account\n\t}\n\n\t// Marshal back to JSON\n\tbz, err := json.MarshalIndent(existingGenesis, \"\", \"  \")\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Write back to file\n\treturn afero.WriteFile(\n\t\tafero.NewOsFs(),\n\t\toutputDocument,\n\t\tbz,\n\t\t0o644, //nolint:mnd // file permissions.\n\t)\n}\n"
  },
  {
    "path": "cli/commands/genesis/storage_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage genesis_test\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/cli/commands/genesis\"\n\tservertypes \"github.com/berachain/beacon-kit/cli/commands/server/types\"\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n\t\"github.com/cosmos/cosmos-sdk/client\"\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/spf13/afero\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n//nolint:paralleltest // t.TempDir() do not allow parallelism\nfunc TestSetDepositStorageCmd(t *testing.T) {\n\tt.Run(\"command should be available and have correct use\", func(t *testing.T) {\n\t\tchainSpec, err := spec.DevnetChainSpec()\n\t\trequire.NoError(t, err)\n\t\tcmd := genesis.SetDepositStorageCmd(func(_ servertypes.AppOptions) (chain.Spec, error) {\n\t\t\treturn chainSpec, nil\n\t\t})\n\t\trequire.Equal(t, \"set-deposit-storage [eth/genesis/file.json]\", cmd.Use)\n\t})\n\n\tt.Run(\"should set deposit storage correctly\", func(t *testing.T) {\n\t\t// Create a temporary directory for test files\n\t\ttmpDir := t.TempDir()\n\n\t\t// Setup test files\n\t\tmockGenesisPath := setupMockGenesis(t, tmpDir)\n\t\t_ = setupMockCLGenesis(t, tmpDir)\n\n\t\t// Setup client context\n\t\tclientCtx := client.Context{\n\t\t\tHomeDir: tmpDir,\n\t\t}\n\t\tctx := context.WithValue(t.Context(), client.ClientContextKey, &clientCtx)\n\n\t\t// Create and execute the command\n\t\tchainSpec, err := spec.DevnetChainSpec()\n\t\trequire.NoError(t, err)\n\t\tcmd := genesis.SetDepositStorageCmd(func(_ servertypes.AppOptions) (chain.Spec, error) {\n\t\t\treturn chainSpec, nil\n\t\t})\n\t\tcmd.SetContext(ctx)\n\t\t// Change working directory to tmpDir for the test\n\t\tcurrentDir, err := os.Getwd()\n\t\trequire.NoError(t, err)\n\t\tt.Chdir(tmpDir)\n\t\tdefer func() {\n\t\t\tt.Chdir(currentDir)\n\t\t}()\n\n\t\tcmd.SetArgs([]string{mockGenesisPath})\n\t\trequire.NoError(t, cmd.Execute())\n\n\t\tverifyStorageOutput(t, mockGenesisPath)\n\t})\n}\n\nfunc setupMockGenesis(t *testing.T, tmpDir string) string {\n\tt.Helper()\n\tchainSpec, err := spec.DevnetChainSpec()\n\trequire.NoError(t, err)\n\tdepositAddr := common.Address(chainSpec.DepositContractAddress())\n\n\tmockGenesisPath := filepath.Join(tmpDir, \"genesis.json\")\n\tmockGenesis := map[string]interface{}{\n\t\t\"alloc\": map[string]interface{}{\n\t\t\tdepositAddr.Hex(): map[string]interface{}{\n\t\t\t\t\"balance\": \"0x0\",\n\t\t\t\t\"code\":    \"0x1234\",\n\t\t\t},\n\t\t},\n\t}\n\tgenesisBz, err := json.MarshalIndent(mockGenesis, \"\", \"  \")\n\trequire.NoError(t, err)\n\terr = afero.WriteFile(afero.NewOsFs(), mockGenesisPath, genesisBz, 0o644)\n\trequire.NoError(t, err)\n\treturn mockGenesisPath\n}\n\nfunc setupMockCLGenesis(t *testing.T, tmpDir string) string {\n\tt.Helper()\n\t// Create config directory in the root of tmpDir\n\tconfigDir := filepath.Join(tmpDir, \"config\")\n\trequire.NoError(t, os.MkdirAll(configDir, 0o755))\n\tmockCLGenesisPath := filepath.Join(configDir, \"genesis.json\")\n\n\tmockCLGenesis := map[string]interface{}{\n\t\t\"app_state\": map[string]interface{}{\n\t\t\t\"beacon\": map[string]interface{}{\n\t\t\t\t\"deposits\": []interface{}{\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"data\": map[string]interface{}{\n\t\t\t\t\t\t\t\"amount\":               \"32000000000\",\n\t\t\t\t\t\t\t\"pubkey\":               \"0x1234\",\n\t\t\t\t\t\t\t\"withdrawal_address\":   \"0x5678\",\n\t\t\t\t\t\t\t\"signature\":            \"0x9abc\",\n\t\t\t\t\t\t\t\"deposit_message_root\": \"0xdef0\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tclGenesisBz, err := json.MarshalIndent(mockCLGenesis, \"\", \"  \")\n\trequire.NoError(t, err)\n\terr = afero.WriteFile(afero.NewOsFs(), mockCLGenesisPath, clGenesisBz, 0o644)\n\trequire.NoError(t, err)\n\treturn mockCLGenesisPath\n}\n\nfunc verifyStorageOutput(t *testing.T, genesisPath string) {\n\tt.Helper()\n\tchainSpec, err := spec.DevnetChainSpec()\n\trequire.NoError(t, err)\n\tdepositAddr := common.Address(chainSpec.DepositContractAddress())\n\n\t// Verify the output genesis file\n\toutputBz, err := afero.ReadFile(afero.NewOsFs(), genesisPath)\n\trequire.NoError(t, err)\n\n\tvar output map[string]interface{}\n\terr = json.Unmarshal(outputBz, &output)\n\trequire.NoError(t, err)\n\n\t// Check that the deposit contract storage was set correctly\n\talloc, ok := output[\"alloc\"].(map[string]interface{})\n\trequire.True(t, ok)\n\tdepositContract, ok := alloc[depositAddr.Hex()].(map[string]interface{})\n\trequire.True(t, ok)\n\tstorage, ok := depositContract[\"storage\"].(map[string]interface{})\n\trequire.True(t, ok)\n\n\t// Verify storage slots\n\tslot0 := common.HexToHash(\"0x0000000000000000000000000000000000000000000000000000000000000000\")\n\tslot1 := common.HexToHash(\"0x0000000000000000000000000000000000000000000000000000000000000001\")\n\trequire.NotEmpty(t, storage[slot0.Hex()]) // Deposit count\n\trequire.NotEmpty(t, storage[slot1.Hex()]) // Deposit root\n}\n"
  },
  {
    "path": "cli/commands/genesis/types/constants.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nconst (\n\t// DefaultAllocsKey is the key for the allocs in the default genesis file.\n\tDefaultAllocsKey = \"alloc\"\n)\n"
  },
  {
    "path": "cli/commands/genesis/types/json.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport gethtypes \"github.com/ethereum/go-ethereum/core/types\"\n\ntype EthGenesis interface {\n\tAlloc() gethtypes.GenesisAlloc\n}\n\ntype DefaultEthGenesisJSON struct {\n\tAllocs gethtypes.GenesisAlloc `json:\"alloc\"`\n}\n\nfunc (g *DefaultEthGenesisJSON) Alloc() gethtypes.GenesisAlloc {\n\treturn g.Allocs\n}\n"
  },
  {
    "path": "cli/commands/initialize/initialize.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n// implementation taken from github.com/cosmos/cosmos-sdk/blob/main/x/genutil/client/cli/init.go\n// and modified to circumvent using default cometbft config which sets the timeout_commit to 0\npackage initialize\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\n\terrorsmod \"cosmossdk.io/errors\"\n\t\"cosmossdk.io/math/unsafe\"\n\t\"github.com/berachain/beacon-kit/chain\"\n\tclitypes \"github.com/berachain/beacon-kit/cli/commands/server/types\"\n\t\"github.com/berachain/beacon-kit/cli/context\"\n\tcometbft \"github.com/berachain/beacon-kit/consensus/cometbft/service\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n\tcfg \"github.com/cometbft/cometbft/config\"\n\t\"github.com/cosmos/cosmos-sdk/client\"\n\t\"github.com/cosmos/cosmos-sdk/client/flags\"\n\t\"github.com/cosmos/cosmos-sdk/client/input\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n\t\"github.com/cosmos/cosmos-sdk/version\"\n\t\"github.com/cosmos/cosmos-sdk/x/genutil\"\n\t\"github.com/cosmos/cosmos-sdk/x/genutil/types\"\n\t\"github.com/cosmos/go-bip39\"\n\t\"github.com/spf13/cobra\"\n)\n\nconst (\n\t// FlagOverwrite defines a flag to overwrite an existing genesis JSON file.\n\tFlagOverwrite = \"overwrite\"\n\n\t// FlagSeed defines a flag to initialize the private validator key from a specific seed.\n\tFlagRecover = \"recover\"\n\n\t// FlagDefaultBondDenom defines the default denom to use in the genesis file.\n\tFlagDefaultBondDenom = \"default-denom\"\n\n\t// In BeaconKit we use crypto.CometBLSType only so we don't allow to specify\n\t// any consensus key.\n\tconsensusKeyAlgo = crypto.CometBLSType\n)\n\ntype printInfo struct {\n\tMoniker    string          `json:\"moniker\"     yaml:\"moniker\"`\n\tChainID    string          `json:\"chain_id\"    yaml:\"chain_id\"`\n\tNodeID     string          `json:\"node_id\"     yaml:\"node_id\"`\n\tGenTxsDir  string          `json:\"gentxs_dir\"  yaml:\"gentxs_dir\"`\n\tAppMessage json.RawMessage `json:\"app_message\" yaml:\"app_message\"`\n}\n\nfunc newPrintInfo(moniker, chainID, nodeID, genTxsDir string, appMessage json.RawMessage) printInfo {\n\treturn printInfo{\n\t\tMoniker:    moniker,\n\t\tChainID:    chainID,\n\t\tNodeID:     nodeID,\n\t\tGenTxsDir:  genTxsDir,\n\t\tAppMessage: appMessage,\n\t}\n}\n\nfunc displayInfo(dst io.Writer, info printInfo) error {\n\tout, err := json.MarshalIndent(info, \"\", \" \")\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t_, err = fmt.Fprintf(dst, \"%s\\n\", out) //#nosec:G705 // CLI output of JSON-marshaled config, not web content.\n\n\treturn err\n}\n\n//nolint:funlen,gocognit,mnd // based on cosmossdk implementation\nfunc InitCmd(creator clitypes.ChainSpecCreator, mm interface {\n\tDefaultGenesis(chain.Spec) map[string]json.RawMessage\n\tValidateGenesis(genesisData map[string]json.RawMessage) error\n}) *cobra.Command {\n\tcmd := &cobra.Command{\n\t\tUse:   \"init <moniker>\",\n\t\tShort: \"Initialize private validator, p2p, genesis, and application configuration files\",\n\t\tLong:  `Initialize validators's and node's configuration files.`,\n\t\tArgs:  cobra.ExactArgs(1),\n\t\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\t\tclientCtx := client.GetClientContextFromCmd(cmd)\n\n\t\t\t// it's very important here to use `GetConfigFromCmd` as redefined\n\t\t\t// in BeaconKit instead of cosmos sdk original implementation. Failure\n\t\t\t// to do so, would result in cosmos sdk default configs being picked\n\t\t\t// instead of BeaconKit ones\n\t\t\tconfig := context.GetConfigFromCmd(cmd)\n\t\t\tchainID, err := cmd.Flags().GetString(flags.FlagChainID)\n\t\t\tif err != nil {\n\t\t\t\treturn errors.New(\"failed to parse FlagChainID\")\n\t\t\t}\n\n\t\t\tswitch {\n\t\t\tcase chainID != \"\":\n\t\t\tcase clientCtx.ChainID != \"\":\n\t\t\t\tchainID = clientCtx.ChainID\n\t\t\tdefault:\n\t\t\t\tchainID = fmt.Sprintf(\"test-chain-%v\", unsafe.Str(6))\n\t\t\t}\n\t\t\tif config.RootDir == \"\" {\n\t\t\t\tconfig.RootDir = clientCtx.HomeDir\n\t\t\t}\n\n\t\t\t// Get bip39 mnemonic\n\t\t\tvar mnemonic string\n\t\t\tshouldRecover, err := cmd.Flags().GetBool(FlagRecover)\n\t\t\tif err != nil {\n\t\t\t\treturn errors.New(\"failed to parse FlagRecover\")\n\t\t\t}\n\t\t\tif shouldRecover {\n\t\t\t\tinBuf := bufio.NewReader(cmd.InOrStdin())\n\t\t\t\tvar value string\n\t\t\t\tvalue, err = input.GetString(\"Enter your bip39 mnemonic\", inBuf)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\n\t\t\t\tmnemonic = value\n\t\t\t\tif !bip39.IsMnemonicValid(mnemonic) {\n\t\t\t\t\treturn errors.New(\"invalid mnemonic\")\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Get initial height\n\t\t\tinitHeight, err := cmd.Flags().GetInt64(flags.FlagInitHeight)\n\t\t\tif err != nil {\n\t\t\t\treturn errors.New(\"failed to parse FlagInitHeight\")\n\t\t\t}\n\t\t\tif initHeight < 1 {\n\t\t\t\tinitHeight = 1\n\t\t\t}\n\n\t\t\tnodeID, _, err := genutil.InitializeNodeValidatorFilesFromMnemonic(config, mnemonic, consensusKeyAlgo)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tconfig.Moniker = args[0]\n\n\t\t\tgenFile := config.GenesisFile()\n\t\t\toverwrite, err := cmd.Flags().GetBool(FlagOverwrite)\n\t\t\tif err != nil {\n\t\t\t\treturn errors.New(\"failed to parse FlagOverwrite\")\n\t\t\t}\n\t\t\tdefaultDenom, err := cmd.Flags().GetString(FlagDefaultBondDenom)\n\t\t\tif err != nil {\n\t\t\t\treturn errors.New(\"failed to parse FlagDefaultBondDenom\")\n\t\t\t}\n\n\t\t\t// use os.Stat to check if the file exists\n\t\t\t_, err = os.Stat(genFile)\n\t\t\tif !overwrite && !os.IsNotExist(err) {\n\t\t\t\treturn fmt.Errorf(\"genesis.json file already exists: %v\", genFile)\n\t\t\t}\n\n\t\t\t// Overwrites the SDK default denom for side-effects\n\t\t\tif defaultDenom != \"\" {\n\t\t\t\tsdk.DefaultBondDenom = defaultDenom\n\t\t\t}\n\n\t\t\tchainSpec, err := creator(context.GetViperFromCmd(cmd))\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to create chain spec: %w\", err)\n\t\t\t}\n\t\t\tappGenState := mm.DefaultGenesis(chainSpec)\n\n\t\t\tappState, err := json.MarshalIndent(appGenState, \"\", \" \")\n\t\t\tif err != nil {\n\t\t\t\treturn errorsmod.Wrap(err, \"Failed to marshal default genesis state\")\n\t\t\t}\n\n\t\t\tappGenesis := &types.AppGenesis{}\n\t\t\tif _, err = os.Stat(genFile); err != nil {\n\t\t\t\tif !os.IsNotExist(err) {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tappGenesis, err = types.AppGenesisFromFile(genFile)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn errorsmod.Wrap(err, \"Failed to read genesis doc from file\")\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tappGenesis.AppName = version.AppName\n\t\t\tappGenesis.AppVersion = version.Version\n\t\t\tappGenesis.ChainID = chainID\n\t\t\tappGenesis.AppState = appState\n\t\t\tappGenesis.InitialHeight = initHeight\n\t\t\tappGenesis.Consensus = &types.ConsensusGenesis{\n\t\t\t\tValidators: nil,\n\t\t\t\tParams:     cometbft.DefaultConsensusParams(consensusKeyAlgo, chainSpec),\n\t\t\t}\n\n\t\t\tif err = genutil.ExportGenesisFile(appGenesis, genFile); err != nil {\n\t\t\t\treturn errorsmod.Wrap(err, \"Failed to export genesis file\")\n\t\t\t}\n\n\t\t\ttoPrint := newPrintInfo(config.Moniker, chainID, nodeID, \"\", appState)\n\n\t\t\t// Note: the config file was already creating before execution this command\n\t\t\t// by [SetupCommand], and it is being overwritten here. The only difference,\n\t\t\t// post default values cleanups, should be in the moniker, which is only setup\n\t\t\t// correctly here\n\t\t\tcfg.WriteConfigFile(filepath.Join(config.RootDir, \"config\", \"config.toml\"), config)\n\t\t\treturn displayInfo(cmd.ErrOrStderr(), toPrint)\n\t\t},\n\t}\n\n\tcmd.Flags().BoolP(FlagOverwrite, \"o\", false, \"overwrite the genesis.json file\")\n\tcmd.Flags().Bool(FlagRecover, false, \"provide seed phrase to recover existing key instead of creating\")\n\tcmd.Flags().String(flags.FlagChainID, \"\", \"genesis file chain-id, if left blank will be randomly created\")\n\tcmd.Flags().String(FlagDefaultBondDenom, \"\", \"genesis file default denomination, if left blank default value is 'stake'\")\n\tcmd.Flags().Int64(flags.FlagInitHeight, 1, \"specify the initial block height at genesis\")\n\treturn cmd\n}\n"
  },
  {
    "path": "cli/commands/jwt/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage jwt\n\nimport \"github.com/berachain/beacon-kit/errors\"\n\nvar (\n\t// ErrNoClientCtx indicates that the client context was not found.\n\tErrNoClientCtx = errors.New(\"client context not found\")\n)\n"
  },
  {
    "path": "cli/commands/jwt/jwt.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage jwt\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/berachain/beacon-kit/node-core/components\"\n\t\"github.com/berachain/beacon-kit/primitives/net/jwt\"\n\t\"github.com/cosmos/cosmos-sdk/client\"\n\t\"github.com/spf13/afero\"\n\t\"github.com/spf13/cobra\"\n)\n\nconst (\n\tDefaultSecretFileName = \"jwt.hex\"\n\tFlagOutputPath        = \"output-path\"\n\tFlagInputPath         = \"input-path\"\n\tConfigFolder          = \"config\"\n\n\tsecretDirPerms  os.FileMode = 0o700\n\tsecretFilePerms os.FileMode = 0o600\n)\n\n// Commands creates a new command for managing JWT secrets.\nfunc Commands() *cobra.Command {\n\tcmd := &cobra.Command{\n\t\tUse:                        \"jwt\",\n\t\tShort:                      \"JWT subcommands\",\n\t\tDisableFlagParsing:         false,\n\t\tSuggestionsMinimumDistance: 2, //nolint:mnd // from sdk.\n\t\tRunE:                       client.ValidateCmd,\n\t}\n\n\tcmd.AddCommand(\n\t\tNewGenerateJWTCommand(),\n\t\tNewValidateJWTCommand(),\n\t)\n\n\treturn cmd\n}\n\n// NewGenerateJWTCommand creates a new command for generating a JWT secret.\n//\n//nolint:lll // reads better if long description is one line\nfunc NewGenerateJWTCommand() *cobra.Command {\n\tcmd := &cobra.Command{\n\t\tUse:   \"generate\",\n\t\tShort: \"Generates a new JWT authentication secret\",\n\t\tLong:  `This command generates a new JWT authentication secret and writes it to a file. If no output file path is specified, it uses the default file name \"jwt.hex\" in the current directory.`,\n\t\tRunE: func(cmd *cobra.Command, _ []string) error {\n\t\t\t// Get the file path from the command flags.\n\t\t\toutputPath, err := getFilePath(cmd, FlagOutputPath)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\treturn generateAuthSecretInFile(cmd, outputPath)\n\t\t},\n\t}\n\tcmd.Flags().StringP(\n\t\tFlagOutputPath, \"o\", \"\", \"Optional output file path for the JWT secret\")\n\treturn cmd\n}\n\n// NewValidateJWTCommand creates a new command for validating a JWT secret.\n//\n//nolint:lll // reads better if long description is one line\nfunc NewValidateJWTCommand() *cobra.Command {\n\tcmd := &cobra.Command{\n\t\tUse:   \"validate\",\n\t\tShort: \"Validates a JWT secret conforms to Engine-RPC requirements\",\n\t\tLong:  `This command validates a JWT secret by checking if the JWT secret is formatted properly. If no output file path is specified, it uses the default file name \"jwt.hex\" in the current directory.`,\n\t\tRunE: func(cmd *cobra.Command, _ []string) error {\n\t\t\t// Get the file path from the command flags.\n\t\t\tinputPath, err := getFilePath(cmd, FlagInputPath)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\treturn validateJWTSecret(cmd, inputPath)\n\t\t},\n\t}\n\n\tcmd.Flags().StringP(\n\t\tFlagInputPath, \"i\", \"\", \"Optional input file path for the JWT secret\",\n\t)\n\treturn cmd\n}\n\n// getFilePath retrieves the file path for the JWT secret from the command flag.\n// If no path is specified, it returns the default secret file name.\nfunc getFilePath(cmd *cobra.Command, path string) (string, error) {\n\tspecifiedFilePath, err := cmd.Flags().GetString(path)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif specifiedFilePath != \"\" {\n\t\treturn specifiedFilePath, nil\n\t}\n\n\t// If no path is specified, try to get the cosmos client context and use\n\t// the configured home directory to write the secret to the default file\n\t// name.\n\tclientCtx, ok := cmd.Context().\n\t\tValue(client.ClientContextKey).(*client.Context)\n\tif !ok {\n\t\treturn \"\", ErrNoClientCtx\n\t}\n\tspecifiedFilePath = filepath.Join(\n\t\tclientCtx.HomeDir, ConfigFolder, DefaultSecretFileName,\n\t)\n\n\t// Use default secret file name if no path is specified\n\treturn specifiedFilePath, nil\n}\n\n// generateAuthSecretInFile writes a newly generated JWT secret\n// to a specified file.\nfunc generateAuthSecretInFile(cmd *cobra.Command, fileName string) error {\n\tvar err error\n\tfs := afero.NewOsFs()\n\tfileDir := filepath.Dir(fileName)\n\texists, err := afero.DirExists(fs, fileDir)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif !exists {\n\t\tif err = fs.MkdirAll(fileDir, secretDirPerms); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tsecret, err := jwt.NewRandom()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfileExists, err := afero.Exists(fs, fileName)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err = afero.WriteFile(\n\t\tfs, fileName, []byte(secret.Hex()), secretFilePerms,\n\t); err != nil {\n\t\treturn err\n\t}\n\n\t// WriteFile only sets permissions on file creation, so explicitly chmod if the file already existed.\n\tif fileExists {\n\t\tif err = fs.Chmod(fileName, secretFilePerms); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tcmd.Printf(\n\t\t\"Successfully wrote new JSON-RPC authentication secret to: %s\",\n\t\tfileName,\n\t)\n\treturn nil\n}\n\nfunc validateJWTSecret(cmd *cobra.Command, filePath string) error {\n\t_, err := components.LoadJWTFromFile(filePath)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcmd.Printf(\"Successfully validated JWT secret\")\n\treturn nil\n}\n"
  },
  {
    "path": "cli/commands/jwt/jwt_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage jwt_test\n\nimport (\n\t\"encoding/hex\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\tjwt \"github.com/berachain/beacon-kit/cli/commands/jwt\"\n\t\"github.com/spf13/afero\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc Test_NewGenerateJWTCommand(t *testing.T) {\n\tt.Parallel()\n\tt.Run(\n\t\t\"command should be available and have correct use\",\n\t\tfunc(t *testing.T) {\n\t\t\tcmd := jwt.NewGenerateJWTCommand()\n\t\t\trequire.Equal(t, \"generate\", cmd.Use)\n\t\t},\n\t)\n\n\tt.Run(\"should create proper file in current directory\", func(t *testing.T) {\n\t\tcmd := jwt.NewGenerateJWTCommand()\n\t\tcmd.SetArgs([]string{\"--output-path\", jwt.DefaultSecretFileName})\n\t\trequire.NoError(t, cmd.Execute())\n\n\t\t// We check the file has the contents we expect.\n\t\tcheckAuthFileIntegrity(t, jwt.DefaultSecretFileName)\n\n\t\trequire.NoError(t, os.RemoveAll(jwt.DefaultSecretFileName))\n\t})\n\n\tt.Run(\"should create proper file in specified folder\", func(t *testing.T) {\n\t\tcustomOutput := filepath.Join(\"data\", \"jwt.hex\")\n\t\tcmd := jwt.NewGenerateJWTCommand()\n\t\tcmd.SetArgs([]string{\"--output-path\", customOutput})\n\t\trequire.NoError(t, cmd.Execute())\n\n\t\t// We check the file has the contents we expect.\n\t\tcheckAuthFileIntegrity(t, customOutput)\n\n\t\trequire.NoError(t, os.RemoveAll(filepath.Dir(customOutput)))\n\t})\n\n\tt.Run(\"creates proper file in nested specified folder\", func(t *testing.T) {\n\t\trootDirectory := \"data\"\n\t\tcustomOutputPath := filepath.Join(\n\t\t\trootDirectory,\n\t\t\t\"nest\",\n\t\t\t\"nested\",\n\t\t\t\"jwt.hex\",\n\t\t)\n\t\tcmd := jwt.NewGenerateJWTCommand()\n\t\tcmd.SetArgs([]string{\"--output-path\", customOutputPath})\n\t\trequire.NoError(t, cmd.Execute())\n\n\t\t// We check the file has the contents we expect.\n\t\tcheckAuthFileIntegrity(t, customOutputPath)\n\n\t\trequire.NoError(t, os.RemoveAll(rootDirectory))\n\t})\n\n\tt.Run(\"should override existing file when flag is set\", func(t *testing.T) {\n\t\t// Create a temporary file to simulate an existing file\n\t\ttempFile, err := os.CreateTemp(t.TempDir(), \"existing_jwt.hex\")\n\t\trequire.NoError(t, err)\n\t\tdefer os.Remove(tempFile.Name()) // clean up\n\n\t\t// Write some content to the file to simulate an existing JWT\n\t\t_, err = tempFile.WriteString(\"not_a_jwt_secret\")\n\t\trequire.NoError(t, err)\n\t\ttempFile.Close()\n\n\t\t// Execute the command with the --force flag to override the existing\n\t\t// file\n\t\tcmd := jwt.NewGenerateJWTCommand()\n\t\tcmd.SetArgs([]string{\"--output-path\", tempFile.Name()})\n\t\trequire.NoError(t, cmd.Execute())\n\n\t\t// Check the file has been overridden with the new content\n\t\tcheckAuthFileIntegrity(t, tempFile.Name())\n\n\t\trequire.NoError(t, os.RemoveAll(tempFile.Name()))\n\t})\n}\n\nfunc Test_GenerateJWTCommand_FilePermissions(t *testing.T) {\n\tt.Parallel()\n\n\tt.Run(\"new file should have 0600 permissions\", func(t *testing.T) {\n\t\ttempDir := t.TempDir()\n\t\toutputPath := filepath.Join(tempDir, \"jwt.hex\")\n\n\t\tcmd := jwt.NewGenerateJWTCommand()\n\t\tcmd.SetArgs([]string{\"--output-path\", outputPath})\n\t\trequire.NoError(t, cmd.Execute())\n\n\t\tinfo, err := os.Stat(outputPath)\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, os.FileMode(0600), info.Mode().Perm(),\n\t\t\t\"new JWT file should have 0600 permissions\")\n\t})\n\n\tt.Run(\"pre-existing file with permissive permissions should be fixed\", func(t *testing.T) {\n\t\ttempDir := t.TempDir()\n\t\toutputPath := filepath.Join(tempDir, \"jwt.hex\")\n\n\t\t// Create file with world-readable permissions\n\t\terr := os.WriteFile(outputPath, []byte(\"old_content\"), 0755)\n\t\trequire.NoError(t, err)\n\n\t\t// Verify it has permissive permissions\n\t\tinfo, err := os.Stat(outputPath)\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, os.FileMode(0755), info.Mode().Perm())\n\n\t\t// Run the generate command\n\t\tcmd := jwt.NewGenerateJWTCommand()\n\t\tcmd.SetArgs([]string{\"--output-path\", outputPath})\n\t\trequire.NoError(t, cmd.Execute())\n\n\t\t// Verify permissions are now restricted\n\t\tinfo, err = os.Stat(outputPath)\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, os.FileMode(0600), info.Mode().Perm(),\n\t\t\t\"pre-existing JWT file should have permissions fixed to 0600\")\n\n\t\t// Also verify the content is valid\n\t\tcheckAuthFileIntegrity(t, outputPath)\n\t})\n}\n\nfunc checkAuthFileIntegrity(tb testing.TB, fPath string) {\n\ttb.Helper()\n\tfs := afero.NewOsFs()\n\tfileInfo, err := fs.Stat(fPath)\n\trequire.NoError(tb, err)\n\trequire.NotNil(tb, fileInfo)\n\n\tenc, err := afero.ReadFile(fs, fPath)\n\trequire.NoError(tb, err)\n\tvar decoded = make([]byte, hex.DecodedLen(len(enc[2:])))\n\t_, err = hex.Decode(decoded, enc[2:])\n\trequire.NoError(tb, err)\n\trequire.Len(tb, decoded, 32)\n}\n"
  },
  {
    "path": "cli/commands/root.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage commands\n\nimport (\n\tsvrcmd \"github.com/berachain/beacon-kit/cli/commands/server/cmd\"\n\t\"github.com/berachain/beacon-kit/cli/config\"\n\tsdkclient \"github.com/cosmos/cosmos-sdk/client\"\n\tsdkconfig \"github.com/cosmos/cosmos-sdk/client/config\"\n\t\"github.com/spf13/cobra\"\n)\n\n// Root is a wrapper around cobra.Command.\ntype Root struct {\n\tcmd *cobra.Command\n}\n\n// New returns a new root command with the provided configuration.\nfunc New(\n\tname string,\n\tdescription string,\n\trunHandler func(cmd *cobra.Command) error,\n\tclientCtx sdkclient.Context,\n) *Root {\n\t// create the underlying cobra command\n\tcmd := &cobra.Command{\n\t\tUse:   name,\n\t\tShort: description,\n\t\tPersistentPreRunE: func(cmd *cobra.Command, _ []string) error {\n\t\t\t// set the default command outputs\n\t\t\tcmd.SetOut(cmd.OutOrStdout())\n\t\t\tcmd.SetErr(cmd.ErrOrStderr())\n\n\t\t\tvar err error\n\t\t\t// Update the client context with the flags from the command\n\t\t\tclientCtx, err = sdkclient.ReadPersistentCommandFlags(\n\t\t\t\tclientCtx,\n\t\t\t\tcmd.Flags(),\n\t\t\t)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tcustomClientTemplate, customClientConfig := config.InitClientConfig()\n\t\t\t// Update the client context with the default custom config\n\t\t\tclientCtx, err = sdkconfig.CreateClientConfig(\n\t\t\t\tclientCtx,\n\t\t\t\tcustomClientTemplate,\n\t\t\t\tcustomClientConfig,\n\t\t\t)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tif err = sdkclient.SetCmdClientContextHandler(\n\t\t\t\tclientCtx, cmd,\n\t\t\t); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\treturn runHandler(cmd)\n\t\t},\n\t}\n\n\tcmd.CompletionOptions.DisableDefaultCmd = true\n\n\treturn &Root{\n\t\tcmd: cmd,\n\t}\n}\n\n// Run executes the root command.\nfunc (root *Root) Run(defaultNodeHome string) error {\n\treturn svrcmd.Execute(\n\t\troot.cmd, \"\", defaultNodeHome,\n\t)\n}\n"
  },
  {
    "path": "cli/commands/server/cmd/execute.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n//\n\npackage cmd\n\nimport (\n\t\"context\"\n\t\"strings\"\n\n\t\"github.com/berachain/beacon-kit/cli/flags\"\n\t\"github.com/berachain/beacon-kit/config\"\n\t\"github.com/cosmos/cosmos-sdk/client\"\n\tsdkflags \"github.com/cosmos/cosmos-sdk/client/flags\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/viper\"\n)\n\n// Execute executes the root command of an application. It handles creating a\n// server context object with the appropriate server and client objects injected\n// into the underlying stdlib Context. It also handles adding core CLI flags,\n// specifically the logging flags. It returns an error upon execution failure.\nfunc Execute(rootCmd *cobra.Command, envPrefix, defaultHome string) error {\n\t// Create and set a client.Context on the command's Context. During the\n\t// pre-run\n\t// of the root command, a default initialized client.Context is provided to\n\t// seed child command execution with values such as AccountRetriever,\n\t// Keyring,\n\t// and a CometBFT RPC. This requires the use of a pointer reference when\n\t// getting and setting the client.Context. Ideally, we utilize\n\t// https://github.com/spf13/cobra/pull/1118.\n\tctx := CreateExecuteContext(context.Background())\n\trootCmd.PersistentFlags().String(\n\t\tsdkflags.FlagHome, defaultHome, \"directory for config and data\")\n\n\t// Chain Spec flags.\n\trootCmd.PersistentFlags().String(\n\t\tflags.ChainSpec, config.DefaultChainSpec, \"chain spec to use\")\n\trootCmd.PersistentFlags().String(\n\t\tflags.ChainSpecFilePath, config.DefaultChainSpecFilePath,\n\t\t\"path to the chain spec toml file\")\n\n\t// Update the global viper with the root command's configuration.\n\tviper.SetEnvPrefix(envPrefix)\n\tviper.SetEnvKeyReplacer(strings.NewReplacer(\".\", \"_\", \"-\", \"_\"))\n\tviper.AutomaticEnv()\n\n\treturn rootCmd.ExecuteContext(ctx)\n}\n\n// CreateExecuteContext returns a base Context with client context\n// values initialized.\nfunc CreateExecuteContext(ctx context.Context) context.Context {\n\treturn context.WithValue(ctx, client.ClientContextKey, &client.Context{})\n}\n"
  },
  {
    "path": "cli/commands/server/pruning.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage server\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\tpruningtypes \"cosmossdk.io/store/pruning/types\"\n\t\"github.com/berachain/beacon-kit/cli/commands/server/types\"\n\t\"github.com/spf13/cast\"\n)\n\n// GetPruningOptionsFromFlags parses command flags and returns the correct\n// PruningOptions. If a pruning strategy is provided, that will be parsed and\n// returned, otherwise, it is assumed custom pruning options are provided.\nfunc GetPruningOptionsFromFlags(\n\tappOpts types.AppOptions,\n) (pruningtypes.PruningOptions, error) {\n\tstrategy := strings.ToLower(cast.ToString(appOpts.Get(FlagPruning)))\n\n\tswitch strategy {\n\tcase pruningtypes.PruningOptionDefault,\n\t\tpruningtypes.PruningOptionNothing,\n\t\tpruningtypes.PruningOptionEverything:\n\t\treturn pruningtypes.NewPruningOptionsFromString(strategy), nil\n\n\tcase pruningtypes.PruningOptionCustom:\n\t\topts := pruningtypes.NewCustomPruningOptions(\n\t\t\tcast.ToUint64(appOpts.Get(FlagPruningKeepRecent)),\n\t\t\tcast.ToUint64(appOpts.Get(FlagPruningInterval)),\n\t\t)\n\n\t\tif err := opts.Validate(); err != nil {\n\t\t\treturn opts, fmt.Errorf(\"invalid custom pruning options: %w\", err)\n\t\t}\n\n\t\treturn opts, nil\n\n\tdefault:\n\t\treturn pruningtypes.PruningOptions{}, fmt.Errorf(\n\t\t\t\"unknown pruning strategy %s\",\n\t\t\tstrategy,\n\t\t)\n\t}\n}\n"
  },
  {
    "path": "cli/commands/server/rollback.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage server\n\nimport (\n\t\"fmt\"\n\n\ttypes \"github.com/berachain/beacon-kit/cli/commands/server/types\"\n\tclicontext \"github.com/berachain/beacon-kit/cli/context\"\n\t\"github.com/berachain/beacon-kit/storage/db\"\n\tcmtcmd \"github.com/cometbft/cometbft/cmd/cometbft/commands\"\n\tdbm \"github.com/cosmos/cosmos-db\"\n\t\"github.com/spf13/cobra\"\n)\n\n// NewRollbackCmd creates a command to rollback CometBFT and multistore state by\n// one height.\nfunc NewRollbackCmd(\n\tappCreator types.AppCreator,\n) *cobra.Command {\n\tvar removeBlock bool\n\n\tcmd := &cobra.Command{\n\t\tUse:   \"rollback\",\n\t\tShort: \"rollback Cosmos SDK and CometBFT state by one height\",\n\t\tLong: `\nA state rollback is performed to recover from an incorrect application state transition,\nwhen CometBFT has persisted an incorrect app hash and is thus unable to make\nprogress. Rollback overwrites a state at height n with the state at height n - 1.\nThe application also rolls back to height n - 1. No blocks are removed, so upon\nrestarting CometBFT the transactions in block n will be re-executed against the\napplication.\n`,\n\t\tRunE: func(cmd *cobra.Command, _ []string) error {\n\t\t\tv := clicontext.GetViperFromCmd(cmd)\n\t\t\tlogger := clicontext.GetLoggerFromCmd(cmd)\n\t\t\tcfg := clicontext.GetConfigFromCmd(cmd)\n\n\t\t\tdb, err := db.OpenDB(cfg.RootDir, dbm.PebbleDBBackend)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tapp := appCreator(logger, db, nil, cfg, v)\n\n\t\t\t// rollback CometBFT state\n\t\t\theight, hash, err := cmtcmd.RollbackState(cfg, removeBlock)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to rollback CometBFT state: %w\", err)\n\t\t\t}\n\n\t\t\t// rollback the multistore\n\t\t\tif err = app.CommitMultiStore().RollbackToVersion(height); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to rollback to version: %w\", err)\n\t\t\t}\n\n\t\t\tlogger.Info(\n\t\t\t\t\"Rolled back state\",\n\t\t\t\t\"height\", height,\n\t\t\t\t\"hash\", fmt.Sprintf(\"%X\", hash),\n\t\t\t)\n\t\t\treturn nil\n\t\t},\n\t}\n\n\tcmd.Flags().\n\t\tBoolVar(&removeBlock, \"hard\", false, \"remove last block as well as state\")\n\treturn cmd\n}\n"
  },
  {
    "path": "cli/commands/server/start.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n//\n\npackage server\n\nimport (\n\tpruningtypes \"cosmossdk.io/store/pruning/types\"\n\ttypes \"github.com/berachain/beacon-kit/cli/commands/server/types\"\n\tclicontext \"github.com/berachain/beacon-kit/cli/context\"\n\t\"github.com/berachain/beacon-kit/storage/db\"\n\tcmtcmd \"github.com/cometbft/cometbft/cmd/cometbft/commands\"\n\tdbm \"github.com/cosmos/cosmos-db\"\n\t\"github.com/spf13/cobra\"\n)\n\nconst (\n\t// CometBFT full-node start flags.\n\tflagAddress         = \"address\"\n\tflagTransport       = \"transport\"\n\tFlagHaltHeight      = \"halt-height\"\n\tFlagHaltTime        = \"halt-time\"\n\tFlagInterBlockCache = \"inter-block-cache\"\n\n\tFlagPruning             = \"pruning\"\n\tFlagPruningKeepRecent   = \"pruning-keep-recent\"\n\tFlagPruningInterval     = \"pruning-interval\"\n\tFlagMinRetainBlocks     = \"min-retain-blocks\"\n\tFlagIAVLCacheSize       = \"iavl-cache-size\"\n\tFlagDisableIAVLFastNode = \"iavl-disable-fastnode\"\n)\n\n// StartCmdOptions defines options that can be customized in\n// `StartCmdWithOptions`,.\ntype StartCmdOptions struct {\n\t// AddFlags allows adding custom flags to the start command.\n\tAddFlags func(cmd *cobra.Command)\n}\n\n// StartCmdWithOptions runs the service passed in, either stand-alone or\n// in-process with\n// CometBFT.\nfunc StartCmdWithOptions(\n\tappCreator types.AppCreator,\n\topts StartCmdOptions,\n) *cobra.Command {\n\tcmd := &cobra.Command{\n\t\tUse:          \"start\",\n\t\tSilenceUsage: true,\n\t\tShort:        \"Run the node\",\n\t\tLong: `Run the node application with CometBFT in process. By\ndefault, the application will run with CometBFT in process.\n\nPruning options can be provided via the '--pruning' flag or alternatively with '--pruning-keep-recent', and\n'pruning-interval' together.\n\nFor '--pruning' the options are as follows:\n\ndefault: the last 362880 states are kept, pruning at 10 block intervals\nnothing: all historic states will be saved, nothing will be deleted (i.e. archiving node)\neverything: 2 latest states will be kept; pruning at 10 block intervals.\ncustom: allow pruning options to be manually specified through 'pruning-keep-recent', and 'pruning-interval'\n\n`,\n\t\tRunE: func(cmd *cobra.Command, _ []string) error {\n\t\t\tlogger := clicontext.GetLoggerFromCmd(cmd)\n\t\t\tcfg := clicontext.GetConfigFromCmd(cmd)\n\n\t\t\tv := clicontext.GetViperFromCmd(cmd)\n\t\t\t_, err := GetPruningOptionsFromFlags(v)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t// Open the Database\n\t\t\tdb, err := db.OpenDB(cfg.RootDir, dbm.PebbleDBBackend)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t// Create the application.\n\t\t\treturn appCreator(logger, db, nil, cfg, v).\n\t\t\t\tStart(cmd.Context())\n\t\t},\n\t}\n\n\taddStartNodeFlags(cmd, opts)\n\treturn cmd\n}\n\n// addStartNodeFlags should be added to any CLI commands that start the network.\nfunc addStartNodeFlags(\n\tcmd *cobra.Command,\n\topts StartCmdOptions,\n) {\n\tcmd.Flags().String(\n\t\tflagAddress, \"tcp://127.0.0.1:26658\", \"Listen address\")\n\tcmd.Flags().\n\t\tString(\n\t\t\tflagTransport,\n\t\t\t\"socket\",\n\t\t\t\"Transport protocol: socket, grpc\")\n\tcmd.Flags().\n\t\tUint64(\n\t\t\tFlagHaltHeight,\n\t\t\t0, \"Block height at which to gracefully halt the chain and shutdown the node\")\n\tcmd.Flags().\n\t\tUint64(\n\t\t\tFlagHaltTime,\n\t\t\t0,\n\t\t\t\"Minimum block time (in Unix seconds) at which to gracefully halt the chain and shutdown the node\")\n\tcmd.Flags().Bool(\n\t\tFlagInterBlockCache,\n\t\ttrue,\n\t\t\"Enable inter-block caching\")\n\tcmd.Flags().\n\t\tString(\n\t\t\tFlagPruning,\n\t\t\tpruningtypes.PruningOptionDefault,\n\t\t\t\"Pruning strategy (default|nothing|everything|custom)\")\n\tcmd.Flags().\n\t\tUint64(\n\t\t\tFlagPruningKeepRecent,\n\t\t\t0,\n\t\t\t\"Number of recent heights to keep on disk (ignored if pruning is not 'custom')\")\n\tcmd.Flags().\n\t\tUint64(FlagPruningInterval,\n\t\t\t0,\n\t\t\t\"Height interval at which pruned heights are removed from disk (ignored if pruning is not 'custom')\")\n\tcmd.Flags().\n\t\tUint64(\n\t\t\tFlagMinRetainBlocks,\n\t\t\t0,\n\t\t\t\"Minimum block height offset during ABCI commit to prune CometBFT blocks\")\n\tcmd.Flags().\n\t\tBool(FlagDisableIAVLFastNode, false, \"Disable fast node for IAVL tree\")\n\n\t// add support for all CometBFT-specific command line options\n\tcmtcmd.AddNodeFlags(cmd)\n\n\tif opts.AddFlags != nil {\n\t\topts.AddFlags(cmd)\n\t}\n}\n"
  },
  {
    "path": "cli/commands/server/types/types.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"io\"\n\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/node-core/types\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\tdbm \"github.com/cosmos/cosmos-db\"\n)\n\ntype (\n\t// AppOptions, usually implemented by Viper, holds the configuration for the application.\n\tAppOptions interface {\n\t\tGet(string) interface{}\n\t}\n\n\t// AppCreator is a function that allows us to lazily initialize an application using various\n\t// configurations.\n\tAppCreator func(*phuslu.Logger, dbm.DB, io.Writer, *cmtcfg.Config, AppOptions) types.Node\n\n\t// ChainSpecCreator is a function that allows us to lazily initialize the ChainSpec.\n\tChainSpecCreator func(AppOptions) (chain.Spec, error)\n)\n"
  },
  {
    "path": "cli/commands/setup.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage commands\n\nimport (\n\t\"github.com/berachain/beacon-kit/cli/commands/deposit\"\n\t\"github.com/berachain/beacon-kit/cli/commands/genesis\"\n\t\"github.com/berachain/beacon-kit/cli/commands/initialize\"\n\t\"github.com/berachain/beacon-kit/cli/commands/jwt\"\n\t\"github.com/berachain/beacon-kit/cli/commands/server\"\n\tservertypes \"github.com/berachain/beacon-kit/cli/commands/server/types\"\n\t\"github.com/berachain/beacon-kit/cli/flags\"\n\tcmtcli \"github.com/berachain/beacon-kit/consensus/cometbft/cli\"\n\tcometbft \"github.com/berachain/beacon-kit/consensus/cometbft/service\"\n\t\"github.com/cosmos/cosmos-sdk/version\"\n)\n\n// DefaultRootCommandSetup sets up the default commands for the root command.\nfunc DefaultRootCommandSetup(\n\troot *Root,\n\tmm *cometbft.Service,\n\tappCreator servertypes.AppCreator,\n\tchainSpecCreator servertypes.ChainSpecCreator,\n) {\n\t// Add all the commands to the root command.\n\troot.cmd.AddCommand(\n\t\t// `comet`\n\t\tcmtcli.Commands(appCreator),\n\t\t// `init`\n\t\tinitialize.InitCmd(chainSpecCreator, mm),\n\t\t// `genesis`\n\t\tgenesis.Commands(chainSpecCreator),\n\t\t// `deposit`\n\t\tdeposit.Commands(chainSpecCreator, appCreator),\n\t\t// `jwt`\n\t\tjwt.Commands(),\n\t\t// `rollback`\n\t\tserver.NewRollbackCmd(appCreator),\n\t\t// `start`\n\t\tserver.StartCmdWithOptions(appCreator, server.StartCmdOptions{\n\t\t\tAddFlags: flags.AddBeaconKitFlags,\n\t\t}),\n\t\t// `status`\n\t\tcmtcli.StatusCommand(),\n\t\t// `version`\n\t\tversion.NewVersionCommand(),\n\t)\n}\n"
  },
  {
    "path": "cli/components/client_context.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/cosmos/cosmos-sdk/client\"\n)\n\n//nolint:gochecknoglobals // todo:fix from sdk.\nvar DefaultNodeHome string\n\n//nolint:gochecknoinits // annoying from sdk.\nfunc init() {\n\tuserHomeDir, err := os.UserHomeDir()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tDefaultNodeHome = filepath.Join(userHomeDir, \".beacond\")\n}\n\n// ProvideClientContext returns a new client context with the given options.\nfunc ProvideClientContext() (client.Context, error) {\n\tclientCtx := client.Context{}.\n\t\tWithInput(os.Stdin).\n\t\tWithHomeDir(DefaultNodeHome).\n\t\tWithViper(\"\") // uses by default the binary name as prefix\n\n\t// Do not call CreateClientConfig here as it may create directories\n\t// in the default home directory before the --home flag is parsed.\n\t// This will be called again in PersistentPreRunE after flags are parsed.\n\treturn clientCtx, nil\n}\n"
  },
  {
    "path": "cli/components/defaults.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\n// DefaultClientComponents returns the default components for\n// the client.\nfunc DefaultClientComponents() []any {\n\treturn []any{\n\t\tProvideClientContext,\n\t\tProvideLogger,\n\t}\n}\n"
  },
  {
    "path": "cli/components/logger.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"io\"\n\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n)\n\ntype LoggerInput struct {\n\tdepinject.In\n\tOut io.Writer\n}\n\n// ProvideLogger creates a the default phuslu logger.\n// It reads the log level and format from the server context.\nfunc ProvideLogger(\n\tin LoggerInput,\n) *phuslu.Logger {\n\t// the logger config should be passed in here, but it is not yet populated\n\t// so we pass in nil for now to get the default logger.\n\tlogger := phuslu.NewLogger(in.Out, nil)\n\tlogger.AddKeyColor(\"error\", log.Red)\n\tlogger.AddKeyColor(\"err\", log.Red)\n\treturn logger\n}\n"
  },
  {
    "path": "cli/config/app.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage config\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/berachain/beacon-kit/config/config\"\n\t\"github.com/spf13/viper\"\n)\n\n// handleAppConfig writes the provided <customConfig> to the file at <configDirPath>/app.toml, or\n// reads it into the provided <viper> instance if it exists.\nfunc handleAppConfig(\n\tviper *viper.Viper,\n\tconfigDirPath string,\n\tcustomAppTemplate string,\n\tappConfig any,\n) error {\n\t// If the app.toml file does not exist, populate it with the values from <appConfig>.\n\tappCfgFilePath := filepath.Join(configDirPath, \"app.toml\")\n\tif _, err := os.Stat(appCfgFilePath); os.IsNotExist(err) {\n\t\treturn writeAppConfig(\n\t\t\tviper,\n\t\t\tappCfgFilePath,\n\t\t\tcustomAppTemplate,\n\t\t\tappConfig,\n\t\t)\n\t}\n\n\t// Merge the app.toml file into the viper instance.\n\tviper.SetConfigType(\"toml\")\n\tviper.SetConfigName(\"app\")\n\tviper.AddConfigPath(configDirPath)\n\tif err := viper.MergeInConfig(); err != nil {\n\t\treturn fmt.Errorf(\"failed to merge configuration: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// writeAppConfig creates a new configuration file with default\n// values at the specified file path <appCfgFilePath>.\nfunc writeAppConfig(\n\trootViper *viper.Viper,\n\tappConfigFilePath string,\n\tappTemplate string,\n\tappConfig any,\n) error {\n\tvar (\n\t\twriteConfig any // config to write to the file\n\n\t\tappTemplatePopulated = appTemplate != \"\"\n\t\tappConfigPopulated   = appConfig != nil\n\t)\n\n\tswitch {\n\tcase appTemplatePopulated && appConfigPopulated:\n\t\t// template and config are both populated, so we set the template\n\t\t// and populate the config with the values from the viper instance\n\t\tif err := config.SetConfigTemplate(appTemplate); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to set config template: %w\", err)\n\t\t}\n\t\tif err := rootViper.Unmarshal(&appConfig); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to unmarshal app config: %w\", err)\n\t\t}\n\t\twriteConfig = appConfig\n\n\tcase !appTemplatePopulated && !appConfigPopulated:\n\t\t// template and config are both nil, so we read the config from the file\n\t\t// at appConfigFilePath\n\t\tappConfig, err := config.ParseConfig(rootViper)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to parse %s: %w\", appConfigFilePath, err)\n\t\t}\n\t\twriteConfig = appConfig\n\n\tdefault:\n\t\treturn errors.New(\"appTemplate and appConfig must both nil or not nil\")\n\t}\n\n\t// write the appConfig to the file at appConfigFilePath\n\tif err := config.WriteConfigFile(appConfigFilePath, writeConfig); err != nil {\n\t\treturn fmt.Errorf(\"failed to write %s: %w\", appConfigFilePath, err)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "cli/config/client.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage config\n\nimport client \"github.com/cosmos/cosmos-sdk/client/config\"\n\n// InitClientConfig sets up the default client configuration, allowing for\n// overrides.\nfunc InitClientConfig() (string, any) {\n\tclientConfig := client.DefaultConfig()\n\tclientConfig.KeyringBackend = \"test\"\n\treturn client.DefaultClientConfigTemplate, clientConfig\n}\n"
  },
  {
    "path": "cli/config/comet.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage config\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\t\"github.com/spf13/viper\"\n)\n\n// handleCometConfig reads the comet config at <cometConfigFile> into the\n// provided <viper> instance. If the file does not exist, it will be populated\n// with the values from <cometConfig>.\n// <cometConfig> will then be updated with the latest values from <viper>.\nfunc handleCometConfig(\n\tviper *viper.Viper,\n\tcometConfigFile string,\n\tcometConfig *cmtcfg.Config,\n\trootDir string,\n\tconfigDirPath string,\n) error {\n\t_, err := os.Stat(cometConfigFile)\n\tif os.IsNotExist(err) {\n\t\t// file does not exist, we create a new comet config file one\n\t\t// with default values.\n\t\tcmtcfg.EnsureRoot(rootDir)\n\t\tcmtcfg.WriteConfigFile(cometConfigFile, cometConfig)\n\t} else if err != nil {\n\t\treturn err\n\t}\n\n\t// read the config.toml file into the viper instance\n\tviper.SetConfigType(\"toml\")\n\tviper.SetConfigName(\"config\")\n\tviper.AddConfigPath(configDirPath)\n\n\tif err = viper.ReadInConfig(); err != nil {\n\t\treturn fmt.Errorf(\"failed to read in %s: %w\", cometConfigFile, err)\n\t}\n\n\t// update the comet config with the latest values from viper\n\tif err = viper.Unmarshal(cometConfig); err != nil {\n\t\treturn err\n\t}\n\n\tcometConfig.SetRoot(rootDir)\n\treturn nil\n}\n"
  },
  {
    "path": "cli/config/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage config\n\nimport \"errors\"\n\n// ErrFlagBind is returned when there is an error binding a flag to the viper\n// instance.\nvar ErrFlagBind = errors.New(\"failed to bind flag\")\n"
  },
  {
    "path": "cli/config/server.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage config\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\tclicontext \"github.com/berachain/beacon-kit/cli/context\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\t\"github.com/cosmos/cosmos-sdk/client/flags\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n\t\"github.com/spf13/viper\"\n)\n\n// SetupCommand returns a cobra.Command initialized with a viper\n// instance. If the files expected to contain the comet and app\n// configs are empty, it will be populated with the values from\n// <appConfig> and <cmtConfig>. In either case, the resulting\n// values in these files will be merged with viper.\nfunc SetupCommand(\n\tcmd *cobra.Command,\n\tappTemplate string,\n\tappConfig any,\n\tcmtConfig *cmtcfg.Config,\n\tlogger *phuslu.Logger,\n) error {\n\t// initialize the server context\n\tif err := InitializeCmd(cmd, logger); err != nil {\n\t\treturn err\n\t}\n\n\tif err := handleConfigs(\n\t\tclicontext.GetViperFromCmd(cmd),\n\t\tappTemplate,\n\t\tappConfig,\n\t\tcmtConfig,\n\t); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// InitializeCmd returns a command object with the root viper instance.\n// The comet config and app config are merged into the viper instance.\n// If the app config is empty, the viper instance is populated with\n// the app config values.\nfunc InitializeCmd(cmd *cobra.Command, logger *phuslu.Logger) error {\n\t// Get the executable name and configure the viper instance so that\n\t// environmental variables are checked based off that name.\n\tbaseName, err := baseName()\n\tif err != nil {\n\t\treturn err\n\t}\n\tviper := newPrefixedViper(baseName)\n\n\t// bind cobra flags to the viper instance\n\tif err = bindFlags(baseName, cmd, viper); err != nil {\n\t\treturn errors.Wrapf(ErrFlagBind, \"error binding flags: %w\", err)\n\t}\n\n\tctx := cmd.Context()\n\tctx = context.WithValue(ctx, clicontext.ViperContextKey, viper)\n\tctx = context.WithValue(\n\t\tctx, clicontext.LoggerContextKey, logger,\n\t)\n\tcmd.SetContext(ctx)\n\n\treturn nil\n}\n\n// newPrefixedViper creates a new viper instance with the given environment\n// prefix, and replaces all (.) and (-) with (_).\nfunc newPrefixedViper(prefix string) *viper.Viper {\n\tviper := viper.New()\n\tviper.SetEnvPrefix(prefix)\n\tviper.SetEnvKeyReplacer(strings.NewReplacer(\".\", \"_\", \"-\", \"_\"))\n\tviper.AutomaticEnv()\n\treturn viper\n}\n\n// baseName returns the base name of the executable.\n// ex: full path /usr/local/bin/myapp -> myapp\nfunc baseName() (string, error) {\n\texecutableName, err := os.Executable()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to fetch executable name: %w\", err)\n\t}\n\treturn path.Base(executableName), nil\n}\n\n// bindFlags binds the command line flags to the viper instance.\nfunc bindFlags(\n\tbasename string, cmd *cobra.Command, v *viper.Viper,\n) (err error) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\terr = fmt.Errorf(\"bindFlags failed: %v\", r)\n\t\t}\n\t}()\n\n\tcmd.Flags().VisitAll(func(f *pflag.Flag) {\n\t\t// this should be redundant\n\t\terr = v.BindEnv(f.Name, fmt.Sprintf(\"%s_%s\", basename, strings.ToUpper(\n\t\t\tstrings.ReplaceAll(f.Name, \"-\", \"_\"))))\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\terr = v.BindPFlag(f.Name, f)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\tif !f.Changed && v.IsSet(f.Name) {\n\t\t\tval := v.Get(f.Name)\n\t\t\terr = cmd.Flags().Set(f.Name, fmt.Sprintf(\"%v\", val))\n\t\t\tif err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}\n\t\t}\n\t})\n\n\treturn err\n}\n\n// handleConfigs writes a new comet config file and app config file, and\n// merges them into the provided viper instance.\nfunc handleConfigs(\n\tviper *viper.Viper,\n\tcustomAppTemplate string,\n\tcustomConfig any,\n\tcometConfig *cmtcfg.Config,\n) error {\n\trootDir := viper.GetString(flags.FlagHome)\n\tconfigDirPath := filepath.Join(rootDir, \"config\")\n\tcmtCfgFile := filepath.Join(configDirPath, \"config.toml\")\n\n\tif err := handleCometConfig(\n\t\tviper,\n\t\tcmtCfgFile, cometConfig,\n\t\trootDir, configDirPath,\n\t); err != nil {\n\t\treturn err\n\t}\n\n\treturn handleAppConfig(\n\t\tviper,\n\t\tconfigDirPath,\n\t\tcustomAppTemplate,\n\t\tcustomConfig,\n\t)\n}\n"
  },
  {
    "path": "cli/context/cmd.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage context\n\nimport (\n\tcometbft \"github.com/berachain/beacon-kit/consensus/cometbft/service\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\t\"github.com/cosmos/cosmos-sdk/client/flags\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/viper\"\n)\n\nfunc GetViperFromCmd(cmd *cobra.Command) *viper.Viper {\n\tvalue := cmd.Context().Value(ViperContextKey)\n\tv, ok := value.(*viper.Viper)\n\tif !ok {\n\t\treturn viper.New()\n\t}\n\treturn v\n}\n\nfunc GetLoggerFromCmd(cmd *cobra.Command) *phuslu.Logger {\n\tv := cmd.Context().Value(LoggerContextKey)\n\tlogger, ok := v.(*phuslu.Logger)\n\tif !ok {\n\t\treturn phuslu.NewLogger(cmd.OutOrStdout(), nil)\n\t}\n\treturn logger\n}\n\nfunc GetConfigFromCmd(cmd *cobra.Command) *cmtcfg.Config {\n\tv := cmd.Context().Value(ViperContextKey)\n\tviper, ok := v.(*viper.Viper)\n\tif !ok {\n\t\treturn cometbft.DefaultConfig()\n\t}\n\treturn GetConfigFromViper(viper)\n}\n\nfunc GetConfigFromViper(v *viper.Viper) *cmtcfg.Config {\n\tconf := cometbft.DefaultConfig()\n\terr := v.Unmarshal(conf)\n\trootDir := v.GetString(flags.FlagHome)\n\tif err != nil {\n\t\treturn cometbft.DefaultConfig().SetRoot(rootDir)\n\t}\n\treturn conf.SetRoot(rootDir)\n}\n"
  },
  {
    "path": "cli/context/keys.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage context\n\ntype (\n\tloggerContextKey struct{}\n\tviperContextKey  struct{}\n)\n\n//nolint:gochecknoglobals // context keys\nvar (\n\tLoggerContextKey loggerContextKey\n\tViperContextKey  viperContextKey\n)\n"
  },
  {
    "path": "cli/flags/flags.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage flags\n\nimport (\n\t\"github.com/berachain/beacon-kit/config\"\n\t\"github.com/spf13/cobra\"\n)\n\nconst (\n\t// Beacon Kit Root Flag.\n\tbeaconKitRoot     = \"beacon-kit.\"\n\tChainSpec         = beaconKitRoot + \"chain-spec\"\n\tChainSpecFilePath = beaconKitRoot + \"chain-spec-file\"\n\tShutdownTimeout   = beaconKitRoot + \"shutdown-timeout\"\n\n\t// Builder Config.\n\tbuilderRoot           = beaconKitRoot + \"payload-builder.\"\n\tSuggestedFeeRecipient = builderRoot + \"suggested-fee-recipient\"\n\tBuilderEnabled        = builderRoot + \"enabled\"\n\tBuildPayloadTimeout   = builderRoot + \"payload-timeout\"\n\n\t// Validator Config.\n\tvalidatorRoot = beaconKitRoot + \"validator.\"\n\tGraffiti      = validatorRoot + \"graffiti\"\n\n\t// Engine Config.\n\tengineRoot              = beaconKitRoot + \"engine.\"\n\tRPCDialURL              = engineRoot + \"rpc-dial-url\"\n\tRPCRetryInterval        = engineRoot + \"rpc-retry-interval\"\n\tRPCMaxRetryInterval     = engineRoot + \"rpc-max-retry-interval\"\n\tRPCTimeout              = engineRoot + \"rpc-timeout\"\n\tRPCStartupCheckInterval = engineRoot + \"rpc-startup-check-interval\"\n\tRPCHealthCheckInteval   = engineRoot + \"rpc-health-check-interval\"\n\tRPCJWTRefreshInterval   = engineRoot + \"rpc-jwt-refresh-interval\"\n\tJWTSecretPath           = engineRoot + \"jwt-secret-path\"\n\n\t// KZG Config.\n\tkzgRoot             = beaconKitRoot + \"kzg.\"\n\tKZGTrustedSetupPath = kzgRoot + \"trusted-setup-path\"\n\tKZGImplementation   = kzgRoot + \"implementation\"\n\n\t// Logger Config.\n\tloggerRoot = beaconKitRoot + \"logger.\"\n\tTimeFormat = loggerRoot + \"time-format\"\n\tLogLevel   = loggerRoot + \"log-level\"\n\tStyle      = loggerRoot + \"style\"\n\n\t// Block Store Service Config.\n\tblockStoreServiceRoot               = beaconKitRoot + \"block-store-service.\"\n\tBlockStoreServiceAvailabilityWindow = blockStoreServiceRoot +\n\t\t\"availability-window\"\n\n\t// Node API Config.\n\tnodeAPIRoot    = beaconKitRoot + \"node-api.\"\n\tNodeAPIEnabled = nodeAPIRoot + \"enabled\"\n\tNodeAPIAddress = nodeAPIRoot + \"address\"\n\tNodeAPILogging = nodeAPIRoot + \"logging\"\n\n\t// BLS Config.\n\tPrivValidatorKeyFile   = \"priv_validator_key_file\"\n\tPrivValidatorStateFile = \"priv_validator_state_file\"\n)\n\n// AddBeaconKitFlags implements servertypes.ModuleInitFlags interface.\nfunc AddBeaconKitFlags(startCmd *cobra.Command) {\n\tdefaultCfg := config.DefaultConfig()\n\tstartCmd.Flags().Duration(\n\t\tShutdownTimeout,\n\t\tdefaultCfg.ShutdownTimeout,\n\t\t\"maximum time to wait for the node to gracefully shutdown before forcing an exit\",\n\t)\n\tstartCmd.Flags().String(\n\t\tJWTSecretPath,\n\t\tdefaultCfg.Engine.JWTSecretPath,\n\t\t\"path to the execution client secret\",\n\t)\n\tstartCmd.Flags().String(\n\t\tRPCDialURL, defaultCfg.Engine.RPCDialURL.String(), \"rpc dial url\",\n\t)\n\tstartCmd.Flags().Duration(\n\t\tRPCRetryInterval, defaultCfg.Engine.RPCRetryInterval, \"initial rpc retry interval\",\n\t)\n\tstartCmd.Flags().Duration(\n\t\tRPCMaxRetryInterval, defaultCfg.Engine.RPCMaxRetryInterval, \"max rpc retry interval\",\n\t)\n\tstartCmd.Flags().Duration(\n\t\tRPCTimeout, defaultCfg.Engine.RPCTimeout, \"rpc timeout\",\n\t)\n\tstartCmd.Flags().Duration(\n\t\tRPCStartupCheckInterval,\n\t\tdefaultCfg.Engine.RPCStartupCheckInterval,\n\t\t\"rpc startup check interval\",\n\t)\n\tstartCmd.Flags().Duration(\n\t\tRPCJWTRefreshInterval,\n\t\tdefaultCfg.Engine.RPCJWTRefreshInterval,\n\t\t\"rpc jwt refresh interval\",\n\t)\n\tstartCmd.Flags().Bool(\n\t\tBuilderEnabled,\n\t\tdefaultCfg.PayloadBuilder.Enabled,\n\t\t\"payload builder enabled\",\n\t)\n\tstartCmd.Flags().Duration(\n\t\tBuildPayloadTimeout,\n\t\tdefaultCfg.PayloadBuilder.PayloadTimeout,\n\t\t\"payload builder timeout\",\n\t)\n\tstartCmd.Flags().String(\n\t\tSuggestedFeeRecipient,\n\t\tdefaultCfg.PayloadBuilder.SuggestedFeeRecipient.Hex(),\n\t\t\"suggested fee recipient\",\n\t)\n\tstartCmd.Flags().String(\n\t\tKZGTrustedSetupPath,\n\t\tdefaultCfg.KZG.TrustedSetupPath,\n\t\t\"kzg trusted setup path\",\n\t)\n\tstartCmd.Flags().String(\n\t\tKZGImplementation,\n\t\tdefaultCfg.KZG.Implementation,\n\t\t\"kzg implementation\",\n\t)\n\tstartCmd.Flags().String(\n\t\tTimeFormat,\n\t\tdefaultCfg.Logger.TimeFormat,\n\t\t\"time format\",\n\t)\n\tstartCmd.Flags().String(\n\t\tLogLevel,\n\t\tdefaultCfg.Logger.LogLevel,\n\t\t\"log level\",\n\t)\n\tstartCmd.Flags().String(\n\t\tStyle,\n\t\tdefaultCfg.Logger.Style,\n\t\t\"style\",\n\t)\n\tstartCmd.Flags().Int(\n\t\tBlockStoreServiceAvailabilityWindow,\n\t\tdefaultCfg.BlockStoreService.AvailabilityWindow,\n\t\t\"block service availability window\",\n\t)\n\tstartCmd.Flags().Bool(\n\t\tNodeAPIEnabled,\n\t\tdefaultCfg.NodeAPI.Enabled,\n\t\t\"node api enabled\",\n\t)\n\tstartCmd.Flags().String(\n\t\tNodeAPIAddress,\n\t\tdefaultCfg.NodeAPI.Address,\n\t\t\"node api address\",\n\t)\n\tstartCmd.Flags().Bool(\n\t\tNodeAPILogging,\n\t\tdefaultCfg.NodeAPI.Logging,\n\t\t\"node api logging\",\n\t)\n}\n"
  },
  {
    "path": "cli/utils/genesis/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage genesis\n\nimport \"github.com/berachain/beacon-kit/chain\"\n\ntype ChainSpec interface {\n\tchain.BalancesSpec\n}\n"
  },
  {
    "path": "cli/utils/genesis/root.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage genesis\n\nimport (\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n\t\"github.com/spf13/afero\"\n)\n\n// Beacon, AppState and Genesis are code duplications that\n// collectively reproduce part of genesis file structure\n\ntype Beacon struct {\n\tDeposits types.Deposits `json:\"deposits\"`\n}\n\ntype AppState struct {\n\tBeacon `json:\"beacon\"`\n}\n\ntype Genesis struct {\n\tAppState `json:\"app_state\"`\n}\n\n// ComputeValidatorsRootFromFile returns the validator root for a given genesis file and chain spec.\nfunc ComputeValidatorsRootFromFile(genesisFile string, cs ChainSpec) (common.Root, error) {\n\tgenesisBz, err := afero.ReadFile(afero.NewOsFs(), genesisFile)\n\tif err != nil {\n\t\treturn common.Root{}, errors.Wrap(err, \"failed to genesis json file\")\n\t}\n\n\tvar appGenesis Genesis\n\terr = json.Unmarshal(genesisBz, &appGenesis)\n\tif err != nil {\n\t\treturn common.Root{}, errors.Wrap(err, \"failed to unmarshal JSON\")\n\t}\n\n\treturn ComputeValidatorsRoot(appGenesis.Deposits, cs), nil\n}\n\n// ComputeValidatorsRoot returns the validator root for a given set of genesis deposits\n// and a chain spec.\nfunc ComputeValidatorsRoot(genesisDeposits types.Deposits, cs ChainSpec) common.Root {\n\tvalidators := make(types.Validators, len(genesisDeposits))\n\tminEffectiveBalance := cs.MinActivationBalance()\n\n\tfor i, deposit := range genesisDeposits {\n\t\tval := types.NewValidatorFromDeposit(\n\t\t\tdeposit.Pubkey,\n\t\t\tdeposit.Credentials,\n\t\t\tdeposit.Amount,\n\t\t\tcs.EffectiveBalanceIncrement(),\n\t\t\tcs.MaxEffectiveBalance(),\n\t\t)\n\n\t\t// mimic processGenesisActivation\n\t\tif val.GetEffectiveBalance() >= minEffectiveBalance {\n\t\t\tval.SetActivationEligibilityEpoch(0)\n\t\t\tval.SetActivationEpoch(0)\n\t\t}\n\t\tvalidators[i] = val\n\t}\n\n\treturn validators.HashTreeRoot()\n}\n"
  },
  {
    "path": "cli/utils/genesis/root_test.go",
    "content": "//go:build test\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage genesis_test\n\nimport (\n\tlibbytes \"bytes\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"reflect\"\n\t\"testing\"\n\t\"testing/quick\"\n\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/cli/utils/genesis\"\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tstatetransition \"github.com/berachain/beacon-kit/testing/state-transition\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// generator for random deposits.\ntype TestDeposits []types.Deposit\n\nfunc (TestDeposits) Generate(rand *rand.Rand, size int) reflect.Value {\n\tres := make(TestDeposits, size)\n\tfor i := range size {\n\t\tvar (\n\t\t\tpubKey crypto.BLSPubkey\n\t\t\tcreds  types.WithdrawalCredentials\n\t\t\tsign   crypto.BLSSignature\n\n\t\t\terr error\n\t\t)\n\t\t_, err = rand.Read(pubKey[:])\n\t\tif err != nil {\n\t\t\tpanic(fmt.Errorf(\"failed generating random pubKey: %w\", err))\n\t\t}\n\t\t_, err = rand.Read(creds[:])\n\t\tif err != nil {\n\t\t\tpanic(fmt.Errorf(\"failed generating random cred: %w\", err))\n\t\t}\n\t\t_, err = rand.Read(sign[:])\n\t\tif err != nil {\n\t\t\tpanic(fmt.Errorf(\"failed generating random sign: %w\", err))\n\t\t}\n\n\t\tres[i] = types.Deposit{\n\t\t\tPubkey:      pubKey,\n\t\t\tCredentials: creds,\n\t\t\tAmount:      math.Gwei(rand.Uint64()),\n\t\t\tSignature:   sign,\n\t\t\tIndex:       0, // indexes will be set in order in the test\n\t\t}\n\t}\n\treturn reflect.ValueOf(res)\n}\n\nfunc TestCompareGenesisCmdWithStateProcessor(t *testing.T) {\n\tt.Parallel()\n\tqc := &quick.Config{MaxCount: 1_000}\n\tcsDev, err := spec.DevnetChainSpec()\n\trequire.NoError(t, err)\n\tcsTest, err := spec.TestnetChainSpec()\n\trequire.NoError(t, err)\n\tcsMain, err := spec.MainnetChainSpec()\n\trequire.NoError(t, err)\n\n\tspecs := []chain.Spec{csDev, csTest, csMain}\n\tfor i, cs := range specs {\n\t\tt.Run(fmt.Sprintf(\"spec-%d\", i), func(t *testing.T) {\n\t\t\tf := func(inputs TestDeposits) bool {\n\t\t\t\tdeposits := make(types.Deposits, len(inputs))\n\t\t\t\tfor i, input := range inputs {\n\t\t\t\t\tdeposits[i] = &types.Deposit{\n\t\t\t\t\t\tPubkey:      input.Pubkey,\n\t\t\t\t\t\tCredentials: input.Credentials,\n\t\t\t\t\t\tAmount:      input.Amount,\n\t\t\t\t\t\tSignature:   input.Signature,\n\t\t\t\t\t\tIndex:       uint64(i),\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// genesis validators root from CLI\n\t\t\t\tcliValRoot := genesis.ComputeValidatorsRoot(deposits, cs)\n\n\t\t\t\t// genesis validators root from StateProcessor\n\t\t\t\tsp, st, _, _, _, _ := statetransition.SetupTestState(t, cs)\n\t\t\t\tgenPayloadHeader := types.NewEmptyExecutionPayloadHeaderWithVersion(cs.GenesisForkVersion())\n\n\t\t\t\t_, err = sp.InitializeBeaconStateFromEth1(\n\t\t\t\t\tst,\n\t\t\t\t\tdeposits,\n\t\t\t\t\tgenPayloadHeader,\n\t\t\t\t\tcs.GenesisForkVersion(),\n\t\t\t\t)\n\t\t\t\trequire.NoError(t, err)\n\n\t\t\t\tvar processorRoot common.Root\n\t\t\t\tprocessorRoot, err = st.GetGenesisValidatorsRoot()\n\t\t\t\trequire.NoError(t, err)\n\n\t\t\t\t// assert that they generate the same root, given the same list of deposits\n\t\t\t\treturn libbytes.Equal(cliValRoot[:], processorRoot[:])\n\t\t\t}\n\t\t\trequire.NoError(t, quick.Check(f, qc))\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "cli/utils/parser/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage parser\n\nimport \"errors\"\n\nvar (\n\t// ErrInvalidPubKeyLength is returned when the public key is invalid.\n\tErrInvalidPubKeyLength = errors.New(\n\t\t\"invalid public key length\",\n\t)\n\n\t// ErrInvalidWithdrawalCredentialsLength is returned when the withdrawal\n\t// credentials are invalid.\n\tErrInvalidWithdrawalCredentialsLength = errors.New(\n\t\t\"invalid withdrawal credentials length\",\n\t)\n\n\t// ErrInvalidAmount is returned when the deposit amount is invalid.\n\tErrInvalidAmount = errors.New(\n\t\t\"invalid amount\",\n\t)\n\n\t// ErrInvalidSignatureLength is returned when the signature is invalid.\n\tErrInvalidSignatureLength = errors.New(\n\t\t\"invalid signature length\",\n\t)\n\n\t// ErrInvalidRootLength is returned when the deposit root is invalid.\n\tErrInvalidRootLength = errors.New(\n\t\t\"invalid root length\",\n\t)\n\n\t// ErrInvalid0xPrefixedHexString is returned when the input string is not\n\t// a valid 0x prefixed hex string.\n\tErrInvalid0xPrefixedHexString = errors.New(\n\t\t\"invalid 0x prefixed hex string\",\n\t)\n)\n"
  },
  {
    "path": "cli/utils/parser/validator.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage parser\n\nimport (\n\t\"math/big\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// ConvertPubkey converts a string to a public key.\nfunc ConvertPubkey(pubkey string) (crypto.BLSPubkey, error) {\n\t// convert the public key to a BLSPubkey.\n\tpubkeyBytes, err := hex.ToBytes(pubkey)\n\tif err != nil {\n\t\treturn crypto.BLSPubkey{}, err\n\t}\n\tif len(pubkeyBytes) != constants.BLSPubkeyLength {\n\t\treturn crypto.BLSPubkey{}, ErrInvalidPubKeyLength\n\t}\n\n\treturn crypto.BLSPubkey(pubkeyBytes), nil\n}\n\n// ConvertWithdrawalCredentials converts a string to a withdrawal credentials.\nfunc ConvertWithdrawalCredentials(credentials string) (\n\ttypes.WithdrawalCredentials,\n\terror,\n) {\n\t// convert the credentials to a WithdrawalCredentials.\n\tcredentialsBytes, err := hex.ToBytes(credentials)\n\tif err != nil {\n\t\treturn types.WithdrawalCredentials{}, err\n\t}\n\tif len(credentialsBytes) != constants.RootLength {\n\t\treturn types.WithdrawalCredentials{},\n\t\t\tErrInvalidWithdrawalCredentialsLength\n\t}\n\treturn types.WithdrawalCredentials(credentialsBytes), nil\n}\n\n// ConvertAmount converts a string to a deposit amount.\n//\n//nolint:mnd // lots of magic numbers\nfunc ConvertAmount(amount string) (math.Gwei, error) {\n\t// Convert the amount to a Gwei.\n\tamountBigInt, ok := new(big.Int).SetString(amount, 10)\n\tif !ok || !amountBigInt.IsUint64() {\n\t\treturn 0, ErrInvalidAmount\n\t}\n\treturn math.Gwei(amountBigInt.Uint64()), nil\n}\n\n// ConvertSignature converts a string to a signature.\nfunc ConvertSignature(signature string) (crypto.BLSSignature, error) {\n\t// convert the signature to a BLSSignature.\n\tsignatureBytes, err := hex.ToBytes(signature)\n\tif err != nil {\n\t\treturn crypto.BLSSignature{}, err\n\t}\n\tif len(signatureBytes) != constants.BLSSignatureLength {\n\t\treturn crypto.BLSSignature{}, ErrInvalidSignatureLength\n\t}\n\treturn crypto.BLSSignature(signatureBytes), nil\n}\n\n// ConvertGenesisValidatorRoot converts a string to a genesis validator root.\nfunc ConvertGenesisValidatorRoot(root string) (common.Root, error) {\n\trootBytes, err := hex.ToBytes(root)\n\tif err != nil {\n\t\treturn common.Root{}, err\n\t}\n\tif len(rootBytes) != constants.RootLength {\n\t\treturn common.Root{}, ErrInvalidRootLength\n\t}\n\treturn common.Root(rootBytes), nil\n}\n"
  },
  {
    "path": "cmd/beacond/defaults.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage main\n\nimport (\n\t\"github.com/berachain/beacon-kit/node-core/components\"\n)\n\nfunc DefaultComponents() []any {\n\tc := []any{\n\t\tcomponents.ProvideAttributesFactory,\n\t\tcomponents.ProvideAvailabilityStore,\n\t\tcomponents.ProvideDepositContract,\n\t\tcomponents.ProvideBlockStore,\n\t\tcomponents.ProvideBlsSigner,\n\t\tcomponents.ProvideBlobProcessor,\n\t\tcomponents.ProvideBlobProofVerifier,\n\t\tcomponents.ProvideChainService,\n\t\tcomponents.ProvideNode,\n\t\tcomponents.ProvideConfig,\n\t\tcomponents.ProvideServerConfig,\n\t\tcomponents.ProvideDepositStore,\n\t\tcomponents.ProvideEngineClient,\n\t\tcomponents.ProvideExecutionEngine,\n\t\tcomponents.ProvideJWTSecret,\n\t\tcomponents.ProvideLocalBuilder,\n\t\tcomponents.ProvideReportingService,\n\t\tcomponents.ProvideCometBFTService,\n\t\tcomponents.ProvideServiceRegistry,\n\t\tcomponents.ProvideSidecarFactory,\n\t\tcomponents.ProvideStateProcessor,\n\t\tcomponents.ProvideKVStore,\n\t\tcomponents.ProvideStorageBackend,\n\t\tcomponents.ProvideTelemetrySink,\n\t\tcomponents.ProvideTelemetryService,\n\t\tcomponents.ProvideTrustedSetup,\n\t\tcomponents.ProvideValidatorService,\n\t\tcomponents.ProvideNodeAPIServer,\n\t\tcomponents.ProvideShutDownService,\n\t}\n\treturn c\n}\n"
  },
  {
    "path": "cmd/beacond/main.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage main\n\nimport (\n\t\"log/slog\"\n\t\"os\"\n\n\tclibuilder \"github.com/berachain/beacon-kit/cli/builder\"\n\tclicomponents \"github.com/berachain/beacon-kit/cli/components\"\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\tnodebuilder \"github.com/berachain/beacon-kit/node-core/builder\"\n\t\"go.uber.org/automaxprocs/maxprocs\"\n)\n\n// run runs the beacon node.\nfunc run() error {\n\t// Set the uber max procs\n\tif _, err := maxprocs.Set(); err != nil {\n\t\treturn err\n\t}\n\n\t// Build the node using the node-core.\n\tnb := nodebuilder.New(\n\t\t// Set the Runtime Components to the Default.\n\t\tnodebuilder.WithComponents(\n\t\t\tDefaultComponents(),\n\t\t),\n\t)\n\n\t// Build the root command using the builder\n\tcb := clibuilder.New(\n\t\t// Set the Name to the Default.\n\t\tclibuilder.WithName(\n\t\t\t\"beacond\",\n\t\t),\n\t\t// Set the Description to the Default.\n\t\tclibuilder.WithDescription(\n\t\t\t\"A beacon-kit node usable with most Ethereum execution clients\",\n\t\t),\n\t\t// Set the Runtime Components to the Default.\n\t\tclibuilder.WithComponents(\n\t\t\tclicomponents.DefaultClientComponents(),\n\t\t),\n\t\t// Set the NodeBuilderFunc to the NodeBuilder Build.\n\t\tclibuilder.WithNodeBuilderFunc(nb.Build),\n\t\tclibuilder.WithChainSpecBuilderFunc(spec.Create),\n\t)\n\n\tcmd, err := cb.Build()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// eventually we want to decouple from cosmos cli, and just pass in a built\n\t// Node and Cmd to a runner\n\n\t// for now, running the cmd will start the node\n\treturn cmd.Run(clicomponents.DefaultNodeHome)\n}\n\n// main is the entry point.\nfunc main() {\n\tif err := run(); err != nil {\n\t\t//nolint:sloglint // todo fix.\n\t\tslog.Error(\"startup failure\", \"error\", err)\n\t\tos.Exit(1)\n\t}\n}\n"
  },
  {
    "path": "codecov.yml",
    "content": "# SPDX-License-Identifier: MIT\n#\n# Copyright (c) 2025 Berachain Foundation\n#\n# Permission is hereby granted, free of charge, to any person\n# obtaining a copy of this software and associated documentation\n# files (the \"Software\"), to deal in the Software without\n# restriction, including without limitation the rights to use,\n# copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the\n# Software is furnished to do so, subject to the following\n# conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n# OTHER DEALINGS IN THE SOFTWARE.\n\ncoverage:\n  status:\n    project:\n      default:\n        target: 0%\n    patch: off\n\ncomment:\n  layout: \"reach, diff, flags, files\"\n  behavior: once\n  require_changes: true\n  show_carryforward_flags: true\n\nignore:\n  - \"**/*.pb.go\"\n  - \"**/*.pb.gw.go\"\n  - \"**/*.pulsar.go\"\n  - \"**/*.abigen.go\"\n  - \"**/*.ssz.go\"\n  - \"**/*.rlpgen.go\"\n  - \"**/*.json.go\"\n  - \"**/*.mock.go\"\n  - \"**/proto\"\n  - \"**/build\"\n  - \"**/testing/e2e\"\n"
  },
  {
    "path": "config/config/config.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage config\n\nimport (\n\t\"fmt\"\n\n\tpruningtypes \"cosmossdk.io/store/pruning/types\"\n\t\"github.com/cosmos/cosmos-sdk/telemetry\"\n\t\"github.com/spf13/viper\"\n)\n\n// BaseConfig defines the server's basic configuration.\ntype BaseConfig struct {\n\tPruning           string `mapstructure:\"pruning\"`\n\tPruningKeepRecent string `mapstructure:\"pruning-keep-recent\"`\n\tPruningInterval   string `mapstructure:\"pruning-interval\"`\n\n\t// HaltHeight contains a non-zero block height at which a node will\n\t// gracefully\n\t// halt and shutdown that can be used to assist upgrades and testing.\n\t//\n\t// Note: Commitment of state will be attempted on the corresponding block.\n\tHaltHeight uint64 `mapstructure:\"halt-height\"`\n\n\t// HaltTime contains a non-zero minimum block time (in Unix seconds) at\n\t// which\n\t// a node will gracefully halt and shutdown that can be used to assist\n\t// upgrades and testing.\n\t//\n\t// Note: Commitment of state will be attempted on the corresponding block.\n\tHaltTime uint64 `mapstructure:\"halt-time\"`\n\n\t// MinRetainBlocks defines the minimum block height offset from the current\n\t// block being committed, such that blocks past this offset may be pruned\n\t// from CometBFT. It is used as part of the process of determining the\n\t// ResponseCommit.RetainHeight value during ABCI Commit. A value of 0\n\t// indicates\n\t// that no blocks should be pruned.\n\t//\n\t// This configuration value is only responsible for pruning CometBFT blocks.\n\t// It has no bearing on application state pruning which is determined by the\n\t// \"pruning-*\" configurations.\n\t//\n\t// Note: CometBFT block pruning is dependent on this parameter in\n\t// conjunction with the unbonding (safety threshold) period, state pruning\n\t// and state sync\n\t// snapshot parameters to determine the correct minimum value of\n\t// ResponseCommit.RetainHeight.\n\tMinRetainBlocks uint64 `mapstructure:\"min-retain-blocks\"`\n\n\t// InterBlockCache enables inter-block caching.\n\tInterBlockCache bool `mapstructure:\"inter-block-cache\"`\n\n\t// IavlCacheSize set the size of the iavl tree cache.\n\tIAVLCacheSize uint64 `mapstructure:\"iavl-cache-size\"`\n\n\t// IAVLDisableFastNode enables or disables the fast sync node.\n\tIAVLDisableFastNode bool `mapstructure:\"iavl-disable-fastnode\"`\n}\n\n// Config defines the server's top level configuration.\ntype Config struct {\n\tBaseConfig `mapstructure:\",squash\"`\n\n\t// Telemetry defines the application telemetry configuration\n\tTelemetry telemetry.Config `mapstructure:\"telemetry\"`\n}\n\n// DefaultConfig returns server's default configuration.\nfunc DefaultConfig() *Config {\n\treturn &Config{\n\t\tBaseConfig: BaseConfig{\n\t\t\tInterBlockCache:   true,\n\t\t\tPruning:           pruningtypes.PruningOptionDefault,\n\t\t\tPruningKeepRecent: \"0\",\n\t\t\tPruningInterval:   \"0\",\n\t\t\tMinRetainBlocks:   0,\n\t\t\t//nolint:mnd // its a bet.\n\t\t\tIAVLCacheSize:       5000,\n\t\t\tIAVLDisableFastNode: false,\n\t\t},\n\t\tTelemetry: telemetry.Config{\n\t\t\tEnabled:      false,\n\t\t\tGlobalLabels: [][]string{},\n\t\t},\n\t}\n}\n\n// GetConfig returns a fully parsed Config object.\nfunc GetConfig(v *viper.Viper) (Config, error) {\n\tconf := DefaultConfig()\n\tif err := v.Unmarshal(conf); err != nil {\n\t\treturn Config{}, fmt.Errorf(\"error extracting app config: %w\", err)\n\t}\n\treturn *conf, nil\n}\n\n// ValidateBasic returns an error if min-gas-prices field is empty in\n// BaseConfig. Otherwise, it returns nil.\nfunc (c Config) ValidateBasic() error {\n\t// if c.Pruning == pruningtypes.PruningOptionEverything &&\n\t// c.StateSync.SnapshotInterval > 0 {\n\t// \treturn sdkerrors.ErrAppConfig.Wrapf(\n\t// \t\t\"cannot enable state sync snapshots with '%s' pruning setting\",\n\t// pruningtypes.PruningOptionEverything,\n\t// \t)\n\t// }\n\n\treturn nil\n}\n"
  },
  {
    "path": "config/config/config.toml.tpl",
    "content": "# This is a TOML config file.\n# For more information, see https://github.com/toml-lang/toml\n\n###############################################################################\n###                           Base Configuration                            ###\n###############################################################################\n\n# default: the last 362880 states are kept, pruning at 10 block intervals\n# nothing: all historic states will be saved, nothing will be deleted (i.e. archiving node)\n# everything: 2 latest states will be kept; pruning at 10 block intervals.\n# custom: allow pruning options to be manually specified through 'pruning-keep-recent', and 'pruning-interval'\npruning = \"{{ .BaseConfig.Pruning }}\"\n\n# These are applied if and only if the pruning strategy is custom.\npruning-keep-recent = \"{{ .BaseConfig.PruningKeepRecent }}\"\npruning-interval = \"{{ .BaseConfig.PruningInterval }}\"\n\n# HaltHeight contains a non-zero block height at which a node will gracefully\n# halt and shutdown that can be used to assist upgrades and testing.\n#\n# Note: Commitment of state will be attempted on the corresponding block.\nhalt-height = {{ .BaseConfig.HaltHeight }}\n\n# HaltTime contains a non-zero minimum block time (in Unix seconds) at which\n# a node will gracefully halt and shutdown that can be used to assist upgrades\n# and testing.\n#\n# Note: Commitment of state will be attempted on the corresponding block.\nhalt-time = {{ .BaseConfig.HaltTime }}\n\n# MinRetainBlocks defines the minimum block height offset from the current\n# block being committed, such that all blocks past this offset are pruned\n# from CometBFT. It is used as part of the process of determining the\n# ResponseCommit.RetainHeight value during ABCI Commit. A value of 0 indicates\n# that no blocks should be pruned.\n#\n# This configuration value is only responsible for pruning CometBFT blocks.\n# It has no bearing on application state pruning which is determined by the\n# \"pruning-*\" configurations.\n#\n# Note: CometBFT block pruning is dependent on this parameter in conjunction\n# with the unbonding (safety threshold) period, state pruning and state sync\n# snapshot parameters to determine the correct minimum value of\n# ResponseCommit.RetainHeight.\nmin-retain-blocks = {{ .BaseConfig.MinRetainBlocks }}\n\n# InterBlockCache enables inter-block caching.\ninter-block-cache = {{ .BaseConfig.InterBlockCache }}\n\n# IavlCacheSize set the size of the iavl tree cache (in number of nodes).\niavl-cache-size = {{ .BaseConfig.IAVLCacheSize }}\n\n# IAVLDisableFastNode enables or disables the fast node feature of IAVL. \n# Default is false.\niavl-disable-fastnode = {{ .BaseConfig.IAVLDisableFastNode }}\n\n\n###############################################################################\n###                         Telemetry Configuration                         ###\n###############################################################################\n\n[telemetry]\n\n# Prefixed with keys to separate services.\nservice-name = \"{{ .Telemetry.ServiceName }}\"\n\n# Enabled enables the application telemetry functionality. When enabled,\n# an in-memory sink is also enabled by default. Operators may also enabled\n# other sinks such as Prometheus.\nenabled = {{ .Telemetry.Enabled }}\n\n# Enable prefixing gauge values with hostname.\nenable-hostname = {{ .Telemetry.EnableHostname }}\n\n# Enable adding hostname to labels.\nenable-hostname-label = {{ .Telemetry.EnableHostnameLabel }}\n\n# Enable adding service to labels.\nenable-service-label = {{ .Telemetry.EnableServiceLabel }}\n\n# PrometheusRetentionTime, when positive, enables a Prometheus metrics sink.\nprometheus-retention-time = {{ .Telemetry.PrometheusRetentionTime }}\n\n# GlobalLabels defines a global set of name/value label tuples applied to all\n# metrics emitted using the wrapper functions defined in telemetry package.\n#\n# Example:\n# [[\"chain_id\", \"cosmoshub-1\"]]\nglobal-labels = [{{ range $k, $v := .Telemetry.GlobalLabels }}\n  [\"{{index $v 0 }}\", \"{{ index $v 1}}\"],{{ end }}\n]\n\n# MetricsSink defines the type of metrics sink to use.\nmetrics-sink = \"{{ .Telemetry.MetricsSink }}\"\n\n# StatsdAddr defines the address of a statsd server to send metrics to.\n# Only utilized if MetricsSink is set to \"statsd\" or \"dogstatsd\".\nstatsd-addr = \"{{ .Telemetry.StatsdAddr }}\"\n\n# DatadogHostname defines the hostname to use when emitting metrics to\n# Datadog. Only utilized if MetricsSink is set to \"dogstatsd\".\ndatadog-hostname = \"{{ .Telemetry.DatadogHostname }}\""
  },
  {
    "path": "config/config/toml.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n//\n//nolint:gochecknoglobals // todo fix.\npackage config\n\nimport (\n\t\"bytes\"\n\t_ \"embed\"\n\t\"fmt\"\n\t\"os\"\n\t\"text/template\"\n\n\t\"github.com/spf13/viper\"\n)\n\n//go:embed config.toml.tpl\nvar DefaultConfigTemplate string\n\nvar configTemplate *template.Template\n\n//nolint:gochecknoinits // i agree, todo fix.\nfunc init() {\n\tvar err error\n\n\ttmpl := template.New(\"appConfigFileTemplate\")\n\tif configTemplate, err = tmpl.Parse(DefaultConfigTemplate); err != nil {\n\t\tpanic(err)\n\t}\n}\n\n// ParseConfig retrieves the default environment configuration for the\n// application.\nfunc ParseConfig(v *viper.Viper) (*Config, error) {\n\tconf := DefaultConfig()\n\terr := v.Unmarshal(conf)\n\n\treturn conf, err\n}\n\n// SetConfigTemplate sets the custom app config template for the application.\nfunc SetConfigTemplate(customTemplate string) error {\n\tvar err error\n\n\ttmpl := template.New(\"appConfigFileTemplate\")\n\n\tif configTemplate, err = tmpl.Parse(customTemplate); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// WriteConfigFile renders config using the template and writes it to\n// configFilePath.\nfunc WriteConfigFile(configFilePath string, config interface{}) error {\n\tvar buffer bytes.Buffer\n\n\tif err := configTemplate.Execute(&buffer, config); err != nil {\n\t\treturn err\n\t}\n\n\tif err := os.WriteFile(configFilePath, buffer.Bytes(), 0o600); err != nil {\n\t\treturn fmt.Errorf(\"failed to write file: %w\", err)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "config/config.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage config\n\nimport (\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/beacon/validator\"\n\t\"github.com/berachain/beacon-kit/config/template\"\n\tviperlib \"github.com/berachain/beacon-kit/config/viper\"\n\t\"github.com/berachain/beacon-kit/da/kzg\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\tengineclient \"github.com/berachain/beacon-kit/execution/client\"\n\tlog \"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/node-api/server\"\n\t\"github.com/berachain/beacon-kit/payload/builder\"\n\t\"github.com/berachain/beacon-kit/storage/block\"\n\t\"github.com/mitchellh/mapstructure\"\n\t\"github.com/spf13/viper\"\n)\n\nconst (\n\tDefaultChainSpec         = \"mainnet\"\n\tDefaultChainSpecFilePath = \"\"\n\tdefaultShutdownTimeout   = 5 * time.Minute\n)\n\n// AppOptions is from the SDK, we should look to remove its usage.\ntype AppOptions interface {\n\tGet(string) interface{}\n}\n\n// DefaultConfig returns the default configuration for a BeaconKit chain.\nfunc DefaultConfig() *Config {\n\treturn &Config{\n\t\tChainSpec:         DefaultChainSpec,\n\t\tChainSpecFilePath: DefaultChainSpecFilePath,\n\t\tShutdownTimeout:   defaultShutdownTimeout,\n\t\tEngine:            engineclient.DefaultConfig(),\n\t\tLogger:            log.DefaultConfig(),\n\t\tKZG:               kzg.DefaultConfig(),\n\t\tPayloadBuilder:    builder.DefaultConfig(),\n\t\tValidator:         validator.DefaultConfig(),\n\t\tBlockStoreService: block.DefaultConfig(),\n\t\tNodeAPI:           server.DefaultConfig(),\n\t}\n}\n\n// Config is the main configuration struct for the BeaconKit chain.\ntype Config struct {\n\t// ChainSpec is the type of chain spec to use.\n\tChainSpec string `mapstructure:\"chain-spec\"`\n\t// ChainSpecFilePath is the path to the chain spec file to use.\n\tChainSpecFilePath string `mapstructure:\"chain-spec-file\"`\n\t// ShutdownTimeout is the maximum time to wait for the node to gracefully shutdown before\n\t// forcing an exit.\n\tShutdownTimeout time.Duration `mapstructure:\"shutdown-timeout\"`\n\t// Engine is the configuration for the execution client.\n\tEngine engineclient.Config `mapstructure:\"engine\"`\n\t// Logger is the configuration for the logger.\n\tLogger log.Config `mapstructure:\"logger\"`\n\t// KZG is the configuration for the KZG blob verifier.\n\tKZG kzg.Config `mapstructure:\"kzg\"`\n\t// PayloadBuilder is the configuration for the local build payload timeout.\n\tPayloadBuilder builder.Config `mapstructure:\"payload-builder\"`\n\t// Validator is the configuration for the validator client.\n\tValidator validator.Config `mapstructure:\"validator\"`\n\t// BlockStoreService is the configuration for the block store service.\n\tBlockStoreService block.Config `mapstructure:\"block-store-service\"`\n\t// NodeAPI is the configuration for the node API.\n\tNodeAPI server.Config `mapstructure:\"node-api\"`\n}\n\n// GetEngine returns the execution client configuration.\nfunc (c Config) GetEngine() *engineclient.Config {\n\treturn &c.Engine\n}\n\n// GetPayloadBuilder returns the block store configuration.\nfunc (c Config) GetPayloadBuilder() *builder.Config {\n\treturn &c.PayloadBuilder\n}\n\n// GetBlockStoreService returns the block store configuration.\nfunc (c Config) GetBlockStoreService() *block.Config {\n\treturn &c.BlockStoreService\n}\n\n// GetLogger returns the logger configuration.\nfunc (c Config) GetLogger() *log.Config {\n\treturn &c.Logger\n}\n\n// Template returns the configuration template.\nfunc (c Config) Template() string {\n\treturn template.TomlTemplate\n}\n\n// ReadConfigFromAppOpts reads the configuration options from the given\n// application options.\nfunc ReadConfigFromAppOpts(opts AppOptions) (*Config, error) {\n\tv, ok := opts.(*viper.Viper)\n\tif !ok {\n\t\treturn nil, errors.New(\"invalid application options type\")\n\t}\n\n\ttype cfgUnmarshaller struct {\n\t\tBeaconKit Config `mapstructure:\"beacon-kit\"`\n\t}\n\tcfg := cfgUnmarshaller{}\n\tif err := v.Unmarshal(&cfg,\n\t\tviper.DecodeHook(mapstructure.ComposeDecodeHookFunc(\n\t\t\tmapstructure.StringToTimeDurationHookFunc(),\n\t\t\tmapstructure.StringToSliceHookFunc(\",\"),\n\t\t\tviperlib.StringToExecutionAddressFunc(),\n\t\t\tviperlib.StringToDialURLFunc(),\n\t\t\tviperlib.StringToConnectionURLFunc(),\n\t\t))); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &cfg.BeaconKit, nil\n}\n"
  },
  {
    "path": "config/spec/creator.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage spec\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"reflect\"\n\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/cli/commands/server/types\"\n\t\"github.com/berachain/beacon-kit/cli/flags\"\n\tviperlib \"github.com/berachain/beacon-kit/config/viper\"\n\t\"github.com/mitchellh/mapstructure\"\n\t\"github.com/spf13/cast\"\n\t\"github.com/spf13/viper\"\n)\n\nconst (\n\tdevnet  = \"devnet\"\n\tmainnet = \"mainnet\"\n\ttestnet = \"testnet\"\n\tfile    = \"file\"\n)\n\n// Create creates a chain spec based on the app options config flag for \"chain-spec\".\n// If unset, the default of \"mainnet\" chain spec is used.\nfunc Create(appOpts types.AppOptions) (chain.Spec, error) {\n\tvar (\n\t\tchainSpec chain.Spec\n\t\terr       error\n\t)\n\tswitch cast.ToString(appOpts.Get(flags.ChainSpec)) {\n\tcase file:\n\t\tchainSpec, err = handleChainSpecFile(appOpts)\n\tcase devnet:\n\t\tchainSpec, err = DevnetChainSpec()\n\tcase testnet:\n\t\tchainSpec, err = TestnetChainSpec()\n\tcase mainnet:\n\t\tfallthrough\n\tdefault:\n\t\tchainSpec, err = MainnetChainSpec()\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif chainSpec == nil {\n\t\treturn nil, errors.New(\"no chain spec found\")\n\t}\n\treturn chainSpec, nil\n}\n\n// handleChainSpecFile loads a chain spec from the file path given in the app options.\nfunc handleChainSpecFile(appOpts types.AppOptions) (chain.Spec, error) {\n\tspecPath := cast.ToString(appOpts.Get(flags.ChainSpecFilePath))\n\tif specPath == \"\" {\n\t\treturn nil, fmt.Errorf(\"expected flag '%s' for chain spec\", flags.ChainSpecFilePath)\n\t}\n\tspecData, err := loadSpecData(specPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn chain.NewSpec(specData)\n}\n\n// loadSpecData reads the TOML chain-spec file from the given path using Viper,\n// unmarshals it into a SpecData, and validates that all required fields are set.\nfunc loadSpecData(path string) (*chain.SpecData, error) {\n\tv := viper.New()\n\tv.SetConfigFile(path)\n\tv.SetConfigType(\"toml\")\n\tif err := v.ReadInConfig(); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read config: %w\", err)\n\t}\n\n\t// Ensure all required fields are set, including embedded structs.\n\tspecData := chain.SpecData{}\n\tif err := validateRequiredFields(reflect.TypeOf(specData), v, \"\"); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Define a decode hook to handle addresses and domain types.\n\tdecodeHookFunc := mapstructure.ComposeDecodeHookFunc(\n\t\tviperlib.StringToExecutionAddressFunc(),\n\t\tviperlib.NumericToDomainTypeFunc(),\n\t)\n\tif err := v.Unmarshal(&specData, viper.DecodeHook(decodeHookFunc)); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to unmarshal config into SpecData: %w\", err)\n\t}\n\n\treturn &specData, nil\n}\n\n// validateRequiredFields validates that all fields with mapstructure tags are present in\n// the configuration. This includes fields in embedded structs.\n//\n//nolint:gocognit\nfunc validateRequiredFields(t reflect.Type, v *viper.Viper, prefix string) error {\n\t// Handle pointer types\n\tif t.Kind() == reflect.Ptr {\n\t\tt = t.Elem()\n\t}\n\n\t// Only process struct types\n\tif t.Kind() != reflect.Struct {\n\t\treturn nil\n\t}\n\n\tfor i := range t.NumField() {\n\t\tfield := t.Field(i)\n\t\ttag := field.Tag.Get(\"mapstructure\")\n\n\t\t// Skip fields without mapstructure tag\n\t\tif tag == \"\" {\n\t\t\t// Check if this is an embedded struct that might have its own fields\n\t\t\tif field.Anonymous && field.Type.Kind() == reflect.Struct {\n\t\t\t\t// For embedded structs without a tag, check their fields directly\n\t\t\t\tif err := validateRequiredFields(field.Type, v, prefix); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// Build the full key path\n\t\tfullKey := tag\n\t\tif prefix != \"\" {\n\t\t\tfullKey = prefix + \".\" + tag\n\t\t}\n\n\t\t// For struct fields (embedded or not) with mapstructure tags, validate their sub-fields\n\t\tif field.Anonymous || field.Type.Kind() == reflect.Struct {\n\t\t\t// This is an embedded struct with its own mapstructure tag\n\t\t\t// Validate its sub-fields with the tag as prefix\n\t\t\tif err := validateRequiredFields(field.Type, v, tag); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// Regular field - check if it's set in the config\n\t\tif !v.IsSet(fullKey) {\n\t\t\treturn fmt.Errorf(\"missing required configuration for key: %s\", fullKey)\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "config/spec/creator_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage spec_test\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/cli/flags\"\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// dummyAppOptions is a simple implementation of the AppOptions interface for testing.\ntype dummyAppOptions struct {\n\tvalues map[string]interface{}\n}\n\nfunc (d dummyAppOptions) Get(key string) interface{} {\n\treturn d.values[key]\n}\n\nfunc TestCreateChainSpec_Devnet(t *testing.T) {\n\tt.Parallel()\n\n\t// Set the app opts to force the devnet branch.\n\topts := dummyAppOptions{values: map[string]interface{}{\n\t\tflags.ChainSpec: \"devnet\",\n\t}}\n\tcs, err := spec.Create(opts)\n\trequire.NoError(t, err)\n\trequire.NotNil(t, cs)\n\tdevnetSpec, err := spec.DevnetChainSpec()\n\trequire.NoError(t, err)\n\trequire.Equal(t, cs, devnetSpec, \"expected devnet chain spec to match\")\n}\n\nfunc TestCreateChainSpec_Testnet(t *testing.T) {\n\tt.Parallel()\n\n\t// Set the app opts to force the testnet branch.\n\topts := dummyAppOptions{values: map[string]interface{}{\n\t\tflags.ChainSpec: \"testnet\",\n\t}}\n\tcs, err := spec.Create(opts)\n\trequire.NoError(t, err)\n\trequire.NotNil(t, cs)\n\ttestnetSpec, err := spec.TestnetChainSpec()\n\trequire.NoError(t, err)\n\trequire.Equal(t, cs, testnetSpec, \"expected testnet chain spec to match\")\n}\n\nfunc TestCreateChainSpec_Mainnet(t *testing.T) {\n\tt.Parallel()\n\n\t// Set the app opts to force the mainnet branch.\n\topts := dummyAppOptions{values: map[string]interface{}{\n\t\tflags.ChainSpec: \"mainnet\",\n\t}}\n\tcs, err := spec.Create(opts)\n\trequire.NoError(t, err)\n\trequire.NotNil(t, cs)\n\tmainnetSpec, err := spec.MainnetChainSpec()\n\trequire.NoError(t, err)\n\trequire.Equal(t, cs, mainnetSpec, \"expected mainnet chain spec to match\")\n}\n\nfunc TestCreateChainSpec_Default_NoSpecFlag(t *testing.T) {\n\tt.Parallel()\n\n\t// Provide an empty app opts so that no spec flag is present.\n\topts := dummyAppOptions{values: map[string]interface{}{}}\n\tcs, err := spec.Create(opts)\n\trequire.NoError(t, err)\n\tmainnetSpec, err := spec.MainnetChainSpec()\n\trequire.NoError(t, err)\n\trequire.Equal(t, cs, mainnetSpec, \"expected mainnet chain spec to match\")\n}\n\nfunc TestCreateChainSpec_File(t *testing.T) {\n\tt.Parallel()\n\n\t// Provide a non-empty value for the custom spec file of mainnet.\n\topts := dummyAppOptions{values: map[string]interface{}{\n\t\tflags.ChainSpec:         \"file\",\n\t\tflags.ChainSpecFilePath: \"../../testing/networks/80094/spec.toml\",\n\t}}\n\tmcs, err := spec.Create(opts)\n\trequire.NoError(t, err)\n\n\tmainnetSpec, err := spec.MainnetChainSpec()\n\trequire.NoError(t, err)\n\trequire.Equal(t, mainnetSpec, mcs, \"the chain spec loaded from TOML does not match the mainnet spec\")\n\n\t// Provide a non-empty value for the custom spec file of testnet.\n\topts.values[flags.ChainSpecFilePath] = \"../../testing/networks/80069/spec.toml\"\n\ttcs, err := spec.Create(opts)\n\trequire.NoError(t, err)\n\n\ttestnetSpec, err := spec.TestnetChainSpec()\n\trequire.NoError(t, err)\n\trequire.Equal(t, testnetSpec, tcs, \"the chain spec loaded from TOML does not match the testnet spec\")\n\n\t// Provide a non-empty value for the custom spec file of devnet.\n\topts.values[flags.ChainSpecFilePath] = \"../../testing/files/spec.toml\"\n\tdcs, err := spec.Create(opts)\n\trequire.NoError(t, err)\n\n\tdevnetSpec, err := spec.DevnetChainSpec()\n\trequire.NoError(t, err)\n\trequire.Equal(t, devnetSpec, dcs, \"the chain spec loaded from TOML does not match the devnet spec\")\n}\n\nfunc TestCreateChainSpec_FieldValidation(t *testing.T) {\n\tt.Parallel()\n\n\ttempDir := t.TempDir()\n\n\t// Read the valid spec file to use as a success case reference\n\tvalidSpec, err := os.ReadFile(\"../../testing/files/spec.toml\")\n\trequire.NoError(t, err)\n\n\ttests := []struct {\n\t\tname        string\n\t\tspecContent string\n\t\twantErr     string // empty means no error expected\n\t}{\n\t\t{\n\t\t\tname:        \"valid spec with block-delay-configuration\",\n\t\t\tspecContent: string(validSpec),\n\t\t\twantErr:     \"\",\n\t\t},\n\t\t{\n\t\t\tname:        \"empty spec file\",\n\t\t\tspecContent: \"\",\n\t\t\twantErr:     \"missing required configuration for key:\",\n\t\t},\n\t\t{\n\t\t\tname: \"partial block-delay-configuration\",\n\t\t\tspecContent: `[block-delay-configuration]\nmax-block-delay = 300_000_000_000\n`,\n\t\t\twantErr: \"missing required configuration for key: block-delay-configuration.target-block-time\",\n\t\t},\n\t\t{\n\t\t\tname: \"missing max-effective-balance after block-delay-configuration\",\n\t\t\tspecContent: `[block-delay-configuration]\nmax-block-delay = 300_000_000_000\ntarget-block-time = 2_000_000_000\nconst-block-delay = 500_000_000\nconsensus-update-height = 1\nconsensus-enable-height = 2\n`,\n\t\t\twantErr: \"missing required configuration for key: max-effective-balance\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tspecFile := filepath.Join(tempDir, tt.name+\".toml\")\n\t\t\trequire.NoError(t, os.WriteFile(specFile, []byte(tt.specContent), 0600))\n\n\t\t\topts := dummyAppOptions{values: map[string]interface{}{\n\t\t\t\tflags.ChainSpec:         \"file\",\n\t\t\t\tflags.ChainSpecFilePath: specFile,\n\t\t\t}}\n\t\t\t_, createErr := spec.Create(opts)\n\n\t\t\tif tt.wantErr == \"\" {\n\t\t\t\trequire.NoError(t, createErr)\n\t\t\t} else {\n\t\t\t\trequire.Error(t, createErr)\n\t\t\t\tassert.Contains(t, createErr.Error(), tt.wantErr)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "config/spec/defaults.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage spec\n\n// NOTE: Most of these default values are taken from ETH2.0 spec.\n// Some values (mentioned below) are modified to better suit Berachain's system.\n\nconst (\n\t// Gwei value constants.\n\tdefaultMaxEffectiveBalance       = 32e9\n\tdefaultActivationBalance         = 32e9\n\tdefaultEffectiveBalanceIncrement = 1e9\n\n\tdefaultHysteresisQuotient           = 4\n\tdefaultHysteresisDownwardMultiplier = 1\n\tdefaultHysteresisUpwardMultiplier   = 5\n\n\t// Time parameters constants.\n\tdefaultSlotsPerEpoch                = 32\n\tdefaultSlotsPerHistoricalRoot       = 8\n\tdefaultMinEpochsToInactivityPenalty = 4\n\n\t// Signature domains.\n\tdefaultDomainTypeProposer          = 0\n\tdefaultDomainTypeAttester          = 1\n\tdefaultDomainTypeRandao            = 2\n\tdefaultDomainTypeDeposit           = 3\n\tdefaultDomainTypeVoluntaryExit     = 4\n\tdefaultDomainTypeSelectionProof    = 5\n\tdefaultDomainTypeAggregateAndProof = 6\n\tdefaultDomainTypeApplicationMask   = 16777216 // \"0x00000001\" in little endian\n\n\t// Eth1-related values.\n\tdefaultDepositContractAddress    = \"0x4242424242424242424242424242424242424242\" // Berachain specific.\n\tdefaultMaxDepositsPerBlock       = 16\n\tdefaultDepositEth1ChainID        = 1\n\tdefaultEth1FollowDistance        = 1 // Berachain specific.\n\tdefaultTargetSecondsPerEth1Block = 2 // Berachain specific.\n\n\t// State list length constants.\n\tdefaultEpochsPerHistoricalVector = 8\n\tdefaultEpochsPerSlashingsVector  = 8\n\tdefaultHistoricalRootsLimit      = 8\n\tdefaultValidatorRegistryLimit    = 1099511627776\n\n\t// Capella values.\n\tdefaultMaxWithdrawalsPerPayload         = 16\n\tdefaultMaxValidatorsPerWithdrawalsSweep = 1 << 14\n\n\t// Deneb values.\n\tdefaultMinEpochsForBlobsSidecarsRequest = 4096\n\tdefaultMaxBlobCommitmentsPerBlock       = 4096\n\tdefaultMaxBlobsPerBlock                 = 6\n\tdefaultFieldElementsPerBlob             = 4096\n\tdefaultBytesPerBlob                     = 131072\n\n\t// Berachain values.\n\tdefaultValidatorSetCap      = 256\n\tdefaultEVMInflationAddress  = \"0x0000000000000000000000000000000000000000\"\n\tdefaultEVMInflationPerBlock = 0\n\n\t// Electra values.\n\tdefaultMinValidatorWithdrawabilityDelay = 256\n)\n"
  },
  {
    "path": "config/spec/defaults_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage spec_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestDomainTypeConversion(t *testing.T) {\n\tt.Parallel()\n\tcs := spec.MainnetChainSpecData()\n\trequire.Equal(t, bytes.B4([]byte{0x00, 0x00, 0x00, 0x00}), cs.DomainTypeProposer)\n\trequire.Equal(t, bytes.B4([]byte{0x01, 0x00, 0x00, 0x00}), cs.DomainTypeAttester)\n\trequire.Equal(t, bytes.B4([]byte{0x02, 0x00, 0x00, 0x00}), cs.DomainTypeRandao)\n\trequire.Equal(t, bytes.B4([]byte{0x03, 0x00, 0x00, 0x00}), cs.DomainTypeDeposit)\n\trequire.Equal(t, bytes.B4([]byte{0x04, 0x00, 0x00, 0x00}), cs.DomainTypeVoluntaryExit)\n\trequire.Equal(t, bytes.B4([]byte{0x05, 0x00, 0x00, 0x00}), cs.DomainTypeSelectionProof)\n\trequire.Equal(t, bytes.B4([]byte{0x06, 0x00, 0x00, 0x00}), cs.DomainTypeAggregateAndProof)\n\trequire.Equal(t, bytes.B4([]byte{0x00, 0x00, 0x00, 0x01}), cs.DomainTypeApplicationMask)\n}\n"
  },
  {
    "path": "config/spec/devnet.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage spec\n\nimport (\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/ethereum/go-ethereum/params\"\n)\n\nconst (\n\t// devnetEVMInflationAddress is the address of the EVM inflation contract.\n\tdevnetEVMInflationAddress = \"0x6942069420694206942069420694206942069420\"\n\n\t// devnetEVMInflationPerBlock is the amount of native EVM balance (in units\n\t// of Gwei) to be minted per EL block.\n\tdevnetEVMInflationPerBlock = 10 * params.GWei\n\n\t// devnetMaxStakeAmount is the maximum amount of native EVM balance (in units\n\t// of Gwei) that can be staked.\n\tdevnetMaxStakeAmount = 4000 * params.GWei\n\n\t// devnetGenesisTime is the timestamp of devnet genesis.\n\tdevnetGenesisTime = 0\n\n\t// devnetDeneb1ForkTime is the timestamp at which the Deneb1 fork occurs.\n\tdevnetDeneb1ForkTime = 0\n\n\t// devnetElectraForkTime is the timestamp at which the Electra fork occurs.\n\tdevnetElectraForkTime = 0\n\n\t// devnetElectra1ForkTime is the timestamp at which the Electra1 fork occurs.\n\t// devnet is configured to start on electra1.\n\tdevnetElectra1ForkTime = 0\n\n\t// devnetEVMInflationAddressDeneb1 is the address of the EVM inflation contract\n\t// after the Deneb1 fork.\n\tdevnetEVMInflationAddressDeneb1 = \"0x4206942069420694206942069420694206942069\"\n\n\t// devnetEVMInflationPerBlockDeneb1 is the amount of native EVM balance (in units\n\t// of Gwei) to be minted per EL block after the Deneb1 fork.\n\tdevnetEVMInflationPerBlockDeneb1 = 11 * params.GWei\n\n\t// devnetMinValidatorWithdrawabilityDelay is the delay (in epochs) before a validator can withdraw their stake.\n\tdevnetMinValidatorWithdrawabilityDelay = 32\n\n\t// devnetFuluForkTime is the timestamp at which the Fulu fork occurs on devnet.\n\t// Set to 0 so devnet starts with Fulu active.\n\tdevnetFuluForkTime = 0\n\n\t// devnetEVMInflationPerBlockFulu is the amount of native EVM balance (in units\n\t// of Gwei) to be minted per EL block after the Fulu fork on devnet.\n\tdevnetEVMInflationPerBlockFulu = 12 * params.GWei\n)\n\n// DevnetChainSpecData is the chain.SpecData for a devnet. It is similar to mainnet but\n// has different values for testing EVM inflation, staking, and hard forks.\n//\n// TODO: remove modifications from mainnet spec to align with mainnet behavior.\nfunc DevnetChainSpecData() *chain.SpecData {\n\tspecData := MainnetChainSpecData()\n\tspecData.DepositEth1ChainID = chain.DevnetEth1ChainID\n\n\tspecData.Config.ConsensusUpdateHeight = 1\n\tspecData.Config.ConsensusEnableHeight = 2\n\n\t// Fork timings are set to facilitate local testing across fork versions.\n\tspecData.GenesisTime = devnetGenesisTime\n\tspecData.Deneb1ForkTime = devnetDeneb1ForkTime\n\tspecData.ElectraForkTime = devnetElectraForkTime\n\tspecData.Electra1ForkTime = devnetElectra1ForkTime\n\tspecData.FuluForkTime = devnetFuluForkTime\n\n\t// EVM inflation is different from mainnet to test.\n\tspecData.EVMInflationAddressGenesis = common.MustNewExecutionAddressFromHex(devnetEVMInflationAddress)\n\tspecData.EVMInflationPerBlockGenesis = devnetEVMInflationPerBlock\n\n\t// EVM inflation is different from mainnet for now, after the Deneb1 fork.\n\tspecData.EVMInflationAddressDeneb1 = common.MustNewExecutionAddressFromHex(devnetEVMInflationAddressDeneb1)\n\tspecData.EVMInflationPerBlockDeneb1 = devnetEVMInflationPerBlockDeneb1\n\n\t// Staking is different from mainnet for now.\n\tspecData.MaxEffectiveBalance = devnetMaxStakeAmount\n\tspecData.MinActivationBalance = defaultActivationBalance\n\tspecData.EffectiveBalanceIncrement = defaultEffectiveBalanceIncrement\n\tspecData.SlotsPerEpoch = defaultSlotsPerEpoch\n\tspecData.MinValidatorWithdrawabilityDelay = devnetMinValidatorWithdrawabilityDelay\n\n\t// EVM inflation for the Fulu fork on devnet. The address remains the same as the Deneb1 fork.\n\tspecData.EVMInflationAddressFulu = common.MustNewExecutionAddressFromHex(devnetEVMInflationAddressDeneb1)\n\tspecData.EVMInflationPerBlockFulu = devnetEVMInflationPerBlockFulu\n\n\treturn specData\n}\n\n// DevnetChainSpec is the chain.Spec for a devnet. Used by `make start` and unit tests.\nfunc DevnetChainSpec() (chain.Spec, error) {\n\treturn chain.NewSpec(DevnetChainSpecData())\n}\n"
  },
  {
    "path": "config/spec/mainnet.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage spec\n\nimport (\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/delay\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/ethereum/go-ethereum/params\"\n)\n\nconst (\n\t// BGT contract address.\n\t//\n\t// A hard fork will occur to set this value as the BGT contract address\n\t// when BGT beings to be minted.\n\tmainnetEVMInflationAddress = defaultEVMInflationAddress\n\n\t// 0 BERA is minted to the BGT contract per block at genesis.\n\t//\n\t// A hard fork will occur to set this value as the upper bound of redeemable BGT per\n\t// block when BGT begins to be minted.\n\tmainnetEVMInflationPerBlock = defaultEVMInflationPerBlock\n\n\t// mainnetValidatorSetCap is 69 on Mainnet at genesis.\n\tmainnetValidatorSetCap = 69\n\n\t// mainnetMaxValidatorsPerWithdrawalsSweep is 31 because we expect at least 36\n\t// validators in the total validators set. We choose a prime number smaller\n\t// than the minimum amount of total validators possible.\n\tmainnetMaxValidatorsPerWithdrawalsSweep = 31\n\n\t// mainnetMaxEffectiveBalance is the max stake of 10 million BERA at genesis.\n\tmainnetMaxEffectiveBalance = 10_000_000 * params.GWei\n\n\t// mainnetEffectiveBalanceIncrement is 10k BERA at genesis\n\t// (equivalent to the Deposit Contract's MIN_DEPOSIT_AMOUNT).\n\tmainnetEffectiveBalanceIncrement = 10_000 * params.GWei\n\n\t// mainnetMinActivationBalance [New in Electra:EIP7251] Minimum balance for a validator to\n\t// become active.\n\tmainnetMinActivationBalance = 250_000 * params.GWei\n\n\t// mainnetSlotsPerEpoch is 192 to mirror the time of epochs on Ethereum mainnet.\n\tmainnetSlotsPerEpoch = 192\n\n\t// mainnetMinEpochsForBlobsSidecarsRequest is 4096 at genesis to match Ethereum mainnet.\n\tmainnetMinEpochsForBlobsSidecarsRequest = defaultMinEpochsForBlobsSidecarsRequest\n\n\t// mainnetMaxBlobCommitmentsPerBlock is 4096 at genesis to match Ethereum mainnet.\n\tmainnetMaxBlobCommitmentsPerBlock = defaultMaxBlobCommitmentsPerBlock\n\n\t// The deposit contract address on mainnet at genesis is the same as the\n\t// default deposit contract address.\n\tmainnetDepositContractAddress = defaultDepositContractAddress\n\n\t// mainnetGenesisTime is the timestamp of the Berachain mainnet genesis block.\n\tmainnetGenesisTime = 1_737_381_600\n\n\t// mainnetDeneb1ForkTime is the timestamp at which the Deneb1 fork occurs.\n\t// This is calculated based on the timestamp of the 2855th mainnet epoch, block 548160, which\n\t// was used to initiate the fork when beacon-kit forked by epoch instead of by timestamp.\n\tmainnetDeneb1ForkTime = 1_738_415_507\n\n\t// mainnetElectraForkTime is the timestamp at which the Electra fork occurs.\n\tmainnetElectraForkTime = 1_749_056_400\n\n\t// mainnetElectra1ForkTime is the timestamp at which the Electra1 fork occurs.\n\tmainnetElectra1ForkTime = 1_756_915_200\n\n\t// mainnetEVMInflationAddressDeneb1 is the address on the EVM which will receive the\n\t// inflation amount of native EVM balance through a withdrawal every block in the Deneb1 fork.\n\tmainnetEVMInflationAddressDeneb1 = \"0x656b95E550C07a9ffe548bd4085c72418Ceb1dba\"\n\n\t// mainnetEVMInflationPerBlockDeneb1 is the amount of native EVM balance (in Gwei) to be\n\t// minted to the EVMInflationAddressDeneb1 via a withdrawal every block in the Deneb1 fork.\n\tmainnetEVMInflationPerBlockDeneb1 = 5.75 * params.GWei\n\n\t// mainnetMinValidatorWithdrawabilityDelay is the number of epochs of delay epochs of delay for a balance to be withdrawable.\n\t// 256 Epochs equates to roughly ~27 hours of withdrawal delay. This gives us room to emergency fork if needed.\n\tmainnetMinValidatorWithdrawabilityDelay = defaultMinValidatorWithdrawabilityDelay\n\n\t// These are the heights at which SBT is activated on mainnet.\n\tmainnetSBTConsensusUpdateHeight = 9_983_085\n\tmainnetSBTConsensusEnableHeight = 9_983_086\n\n\t// mainnetFuluForkTime is the timestamp at which the Fulu fork occurs.\n\t// TODO: Set to actual fork time before Fulu activation.\n\tmainnetFuluForkTime = 9_999_999_999_999_999\n\n\t// mainnetHysteresisQuotientFulu is the hysteresis quotient for the Fulu fork (BRIP-0008).\n\tmainnetHysteresisQuotientFulu = 100\n\n\t// mainnetHysteresisUpwardMultiplierFulu is the hysteresis upward multiplier for the Fulu fork.\n\tmainnetHysteresisUpwardMultiplierFulu = 10\n\n\t// mainnetEVMInflationAddressFulu is the address on the EVM which will receive the\n\t// inflation amount of native EVM balance through a withdrawal every block in the Fulu fork.\n\t// TODO: Set to actual address before Fulu activation.\n\tmainnetEVMInflationAddressFulu = \"0x0000000000000000000000000000000000000000\"\n\n\t// mainnetEVMInflationPerBlockFulu is the amount of native EVM balance (in Gwei) to be\n\t// minted to the EVMInflationAddressFulu via a withdrawal every block in the Fulu fork.\n\t// TODO: Set to actual value before Fulu activation.\n\tmainnetEVMInflationPerBlockFulu = 0\n)\n\n// MainnetChainSpecData is the chain.SpecData for the Berachain mainnet.\nfunc MainnetChainSpecData() *chain.SpecData {\n\tspecData := &chain.SpecData{\n\t\tConfig: delay.DefaultConfig(),\n\n\t\t// Gwei values constants.\n\t\tMaxEffectiveBalance:       mainnetMaxEffectiveBalance,\n\t\tEffectiveBalanceIncrement: mainnetEffectiveBalanceIncrement,\n\n\t\tHysteresisQuotient:           defaultHysteresisQuotient,\n\t\tHysteresisDownwardMultiplier: defaultHysteresisDownwardMultiplier,\n\t\tHysteresisUpwardMultiplier:   defaultHysteresisUpwardMultiplier,\n\n\t\t// Time parameters constants.\n\t\tSlotsPerEpoch:                mainnetSlotsPerEpoch,\n\t\tSlotsPerHistoricalRoot:       defaultSlotsPerHistoricalRoot,\n\t\tMinEpochsToInactivityPenalty: defaultMinEpochsToInactivityPenalty,\n\n\t\t// Signature domains.\n\t\tDomainTypeProposer:          bytes.FromUint32(defaultDomainTypeProposer),\n\t\tDomainTypeAttester:          bytes.FromUint32(defaultDomainTypeAttester),\n\t\tDomainTypeRandao:            bytes.FromUint32(defaultDomainTypeRandao),\n\t\tDomainTypeDeposit:           bytes.FromUint32(defaultDomainTypeDeposit),\n\t\tDomainTypeVoluntaryExit:     bytes.FromUint32(defaultDomainTypeVoluntaryExit),\n\t\tDomainTypeSelectionProof:    bytes.FromUint32(defaultDomainTypeSelectionProof),\n\t\tDomainTypeAggregateAndProof: bytes.FromUint32(defaultDomainTypeAggregateAndProof),\n\t\tDomainTypeApplicationMask:   bytes.FromUint32(defaultDomainTypeApplicationMask),\n\n\t\t// Eth1-related values.\n\t\tDepositContractAddress:    common.MustNewExecutionAddressFromHex(mainnetDepositContractAddress),\n\t\tMaxDepositsPerBlock:       defaultMaxDepositsPerBlock,\n\t\tDepositEth1ChainID:        chain.MainnetEth1ChainID,\n\t\tEth1FollowDistance:        defaultEth1FollowDistance,\n\t\tTargetSecondsPerEth1Block: defaultTargetSecondsPerEth1Block,\n\n\t\t// Fork-related values.\n\t\tGenesisTime:      mainnetGenesisTime,\n\t\tDeneb1ForkTime:   mainnetDeneb1ForkTime,\n\t\tElectraForkTime:  mainnetElectraForkTime,\n\t\tElectra1ForkTime: mainnetElectra1ForkTime,\n\t\tFuluForkTime:     mainnetFuluForkTime,\n\n\t\t// State list length constants.\n\t\tEpochsPerHistoricalVector: defaultEpochsPerHistoricalVector,\n\t\tEpochsPerSlashingsVector:  defaultEpochsPerSlashingsVector,\n\t\tHistoricalRootsLimit:      defaultHistoricalRootsLimit,\n\t\tValidatorRegistryLimit:    defaultValidatorRegistryLimit,\n\n\t\t// Capella values.\n\t\tMaxWithdrawalsPerPayload:         defaultMaxWithdrawalsPerPayload,\n\t\tMaxValidatorsPerWithdrawalsSweep: mainnetMaxValidatorsPerWithdrawalsSweep,\n\n\t\t// Deneb values.\n\t\tMinEpochsForBlobsSidecarsRequest: mainnetMinEpochsForBlobsSidecarsRequest,\n\t\tMaxBlobCommitmentsPerBlock:       mainnetMaxBlobCommitmentsPerBlock,\n\t\tMaxBlobsPerBlock:                 defaultMaxBlobsPerBlock,\n\t\tFieldElementsPerBlob:             defaultFieldElementsPerBlob,\n\t\tBytesPerBlob:                     defaultBytesPerBlob,\n\n\t\t// Berachain values at genesis.\n\t\tValidatorSetCap:             mainnetValidatorSetCap,\n\t\tEVMInflationAddressGenesis:  common.MustNewExecutionAddressFromHex(mainnetEVMInflationAddress),\n\t\tEVMInflationPerBlockGenesis: mainnetEVMInflationPerBlock,\n\n\t\t// Deneb1 values.\n\t\tEVMInflationAddressDeneb1:  common.MustNewExecutionAddressFromHex(mainnetEVMInflationAddressDeneb1),\n\t\tEVMInflationPerBlockDeneb1: mainnetEVMInflationPerBlockDeneb1,\n\n\t\t// Electra values.\n\t\tMinActivationBalance:             mainnetMinActivationBalance,\n\t\tMinValidatorWithdrawabilityDelay: mainnetMinValidatorWithdrawabilityDelay,\n\n\t\t// Fulu values (BRIP-0008 hysteresis + PoL vNext).\n\t\tHysteresisQuotientFulu:         mainnetHysteresisQuotientFulu,\n\t\tHysteresisUpwardMultiplierFulu: mainnetHysteresisUpwardMultiplierFulu,\n\t\tEVMInflationAddressFulu:        common.MustNewExecutionAddressFromHex(mainnetEVMInflationAddressFulu),\n\t\tEVMInflationPerBlockFulu:       mainnetEVMInflationPerBlockFulu,\n\t}\n\n\tspecData.Config.ConsensusUpdateHeight = mainnetSBTConsensusUpdateHeight\n\tspecData.Config.ConsensusEnableHeight = mainnetSBTConsensusEnableHeight\n\n\treturn specData\n}\n\n// MainnetChainSpec is the ChainSpec for the Berachain mainnet.\nfunc MainnetChainSpec() (chain.Spec, error) {\n\treturn chain.NewSpec(MainnetChainSpecData())\n}\n"
  },
  {
    "path": "config/spec/testnet.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage spec\n\nimport (\n\t\"github.com/berachain/beacon-kit/chain\"\n)\n\n// TestnetChainSpecData is the chain.SpecData for Berachain's public testnet, Bepolia.\nfunc TestnetChainSpecData() *chain.SpecData {\n\tspecData := MainnetChainSpecData()\n\n\t// Testnet uses chain ID of 80069.\n\tspecData.DepositEth1ChainID = chain.TestnetEth1ChainID\n\n\t// Timestamp of the genesis block of Bepolia testnet.\n\tspecData.GenesisTime = 1_739_976_735\n\n\t// Deneb1 fork timing on Bepolia. This is calculated based on the timestamp of the first bepolia\n\t// epoch, block 192, which was used to initiate the fork when beacon-kit forked by epoch instead\n\t// of by timestamp.\n\tspecData.Deneb1ForkTime = 1_740_090_694\n\n\t// Timestamp of the Electra fork on Bepolia.\n\tspecData.ElectraForkTime = 1_746_633_600\n\n\t// Enable stable block time before the Electra1 fork.\n\tspecData.Config.ConsensusUpdateHeight = 7_768_334\n\tspecData.Config.ConsensusEnableHeight = 7_768_335\n\n\t// Timestamp of the Electra1 fork on Bepolia.\n\tspecData.Electra1ForkTime = 1_754_496_000\n\n\t// Timestamp of the Fulu fork on Bepolia.\n\t// TODO: Set to actual fork time before Fulu activation.\n\tspecData.FuluForkTime = 9_999_999_999_999_999\n\n\treturn specData\n}\n\n// TestnetChainSpec is the chain.Spec for Berachain's public testnet.\nfunc TestnetChainSpec() (chain.Spec, error) {\n\treturn chain.NewSpec(TestnetChainSpecData())\n}\n"
  },
  {
    "path": "config/template/template.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage template\n\nconst TomlTemplate = `\n###############################################################################\n###                                BeaconKit                                ###\n###############################################################################\n\n[beacon-kit]\n# ChainSpec is the type of chain spec to use.\nchain-spec = \"{{ .BeaconKit.ChainSpec }}\"\n\n# ChainSpecFilePath is the path to the chain spec file to use.\nchain-spec-file = \"{{ .BeaconKit.ChainSpecFilePath }}\"\n\n# ShutdownTimeout is the maximum time to wait for the node to gracefully\n# shutdown before forcing an exit.\nshutdown-timeout = \"{{ .BeaconKit.ShutdownTimeout }}\"\n\n[beacon-kit.engine]\n# HTTP url of the execution client JSON-RPC endpoint.\nrpc-dial-url = \"{{ .BeaconKit.Engine.RPCDialURL }}\"\n\n# RPC timeout for execution client requests.\nrpc-timeout = \"{{ .BeaconKit.Engine.RPCTimeout }}\"\n\n# Interval for the startup check.\nrpc-startup-check-interval = \"{{ .BeaconKit.Engine.RPCStartupCheckInterval }}\"\n\n# Interval for the JWT refresh.\nrpc-jwt-refresh-interval = \"{{ .BeaconKit.Engine.RPCJWTRefreshInterval }}\"\n\n# Path to the execution client JWT-secret\njwt-secret-path = \"{{.BeaconKit.Engine.JWTSecretPath}}\"\n\n[beacon-kit.logger]\n# TimeFormat is a string that defines the format of the time in the logger.\ntime-format = \"{{.BeaconKit.Logger.TimeFormat}}\"\n\n# LogLevel is the level of logging. Logger will log messages with verbosity up\n# to LogLevel.\nlog-level = \"{{.BeaconKit.Logger.LogLevel}}\"\n\n# Style is the style of the logger.\nstyle = \"{{.BeaconKit.Logger.Style}}\"\n\n[beacon-kit.kzg]\n# Path to the trusted setup path.\ntrusted-setup-path = \"{{.BeaconKit.KZG.TrustedSetupPath}}\"\n\n# KZG implementation to use.\n# Options are \"crate-crypto/go-kzg-4844\".\nimplementation = \"{{.BeaconKit.KZG.Implementation}}\"\n\n[beacon-kit.payload-builder]\n# Enabled determines if the local payload builder is enabled.\n# It should be enabled for validators, but it can be disabled\n# for full nodes.\nenabled = {{ .BeaconKit.PayloadBuilder.Enabled }}\n\n# Post bellatrix, this address will receive the transaction fees produced by any blocks\n# from this node.\nsuggested-fee-recipient = \"{{.BeaconKit.PayloadBuilder.SuggestedFeeRecipient}}\"\n\n# The timeout for local build payload. This should match, or be slightly less\n# than the configured timeout on your execution client. It also must be less than\n# timeout_proposal in the CometBFT configuration.\npayload-timeout = \"{{ .BeaconKit.PayloadBuilder.PayloadTimeout }}\"\n\n[beacon-kit.validator]\n# Graffiti string that will be included in the graffiti field of the beacon block.\ngraffiti = \"{{ .BeaconKit.Validator.Graffiti }}\"\n\n[beacon-kit.block-store-service]\n# AvailabilityWindow is the number of slots to keep in the store.\n# Setting AvailabilityWindow to 0 disables block store and does not allow the node\n# to serve proof or namespace apis from beacon node-api.\navailability-window = \"{{ .BeaconKit.BlockStoreService.AvailabilityWindow }}\"\n\n[beacon-kit.node-api]\n# Enabled determines if the node API is enabled.\nenabled = \"{{ .BeaconKit.NodeAPI.Enabled }}\"\n\n# Address is the address to bind the node API to.\naddress = \"{{ .BeaconKit.NodeAPI.Address }}\"\n\n# Logging determines if the node API logging is enabled.\nlogging = \"{{ .BeaconKit.NodeAPI.Logging }}\"\n`\n"
  },
  {
    "path": "config/viper/parser.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage viper\n\nimport (\n\t\"net/url\"\n\t\"reflect\"\n\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\tbeaconurl \"github.com/berachain/beacon-kit/primitives/net/url\"\n\t\"github.com/mitchellh/mapstructure\"\n\t\"github.com/spf13/cast\"\n)\n\n// NumericToDomainTypeFunc returns a DecodeHookFunc that converts\n// numeric values to a `common.DomainType` (which is a `bytes.B4`).\nfunc NumericToDomainTypeFunc() mapstructure.DecodeHookFunc {\n\treturn func(\n\t\tf reflect.Type,\n\t\tt reflect.Type,\n\t\tdata interface{},\n\t) (interface{}, error) {\n\t\tvar dt common.DomainType\n\t\tif t != reflect.TypeOf(dt) {\n\t\t\treturn data, nil\n\t\t}\n\n\t\tswitch f.Kind() {\n\t\tcase reflect.String:\n\t\t\treturn dt, dt.UnmarshalText([]byte(data.(string))) //nolint:errcheck // Safe to ignore.\n\t\tdefault:\n\t\t\tnum, err := cast.ToUint32E(data)\n\t\t\tif err != nil {\n\t\t\t\treturn common.DomainType{}, err\n\t\t\t}\n\n\t\t\treturn bytes.FromUint32(num), nil\n\t\t}\n\t}\n}\n\n// StringToExecutionAddressFunc returns a DecodeHookFunc that converts\n// string to a `primitives.ExecutionAddresses` by parsing the string.\nfunc StringToExecutionAddressFunc() mapstructure.DecodeHookFunc {\n\treturn stringTo(common.NewExecutionAddressFromHex)\n}\n\n// StringToDialURLFunc returns a DecodeHookFunc that converts\n// string to *url.URL by parsing the string.\nfunc StringToDialURLFunc() mapstructure.DecodeHookFunc {\n\treturn stringTo(\n\t\tfunc(s string) (*url.URL, error) {\n\t\t\turl, err := url.Parse(s)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn url, nil\n\t\t},\n\t)\n}\n\n// StringToConnectionURLFunc returns a DecodeHookFunc that converts\n// string to *beaconurl.ConnectionURL by parsing the string.\nfunc StringToConnectionURLFunc() mapstructure.DecodeHookFunc {\n\treturn stringTo(beaconurl.NewFromRaw)\n}\n\n// stringTo is a helper function for creating DecodeHookFuncs that convert\n// string to a specific type by parsing the string.\nfunc stringTo[T any](\n\tconstructor func(string) (T, error),\n) mapstructure.DecodeHookFunc {\n\treturn func(\n\t\tf reflect.Type,\n\t\tt reflect.Type,\n\t\tdata interface{},\n\t) (interface{}, error) {\n\t\tif f.Kind() != reflect.String {\n\t\t\treturn data, nil\n\t\t}\n\n\t\tvar retType T\n\t\tif t != reflect.TypeOf(retType) {\n\t\t\treturn data, nil\n\t\t}\n\n\t\t// Convert it by parsing\n\t\t//nolint:errcheck // should be safe\n\t\treturn constructor(data.(string))\n\t}\n}\n"
  },
  {
    "path": "consensus/cometbft/cli/commands.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage server\n\nimport (\n\t\"context\"\n\n\t\"github.com/berachain/beacon-kit/cli/commands/server/types\"\n\tclicontext \"github.com/berachain/beacon-kit/cli/context\"\n\tservice \"github.com/berachain/beacon-kit/consensus/cometbft/service\"\n\t\"github.com/berachain/beacon-kit/storage/db\"\n\tcmtcmd \"github.com/cometbft/cometbft/cmd/cometbft/commands\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\tcmtjson \"github.com/cometbft/cometbft/libs/json\"\n\t\"github.com/cometbft/cometbft/node\"\n\t\"github.com/cometbft/cometbft/p2p\"\n\tpvm \"github.com/cometbft/cometbft/privval\"\n\tcmtversion \"github.com/cometbft/cometbft/version\"\n\tdbm \"github.com/cosmos/cosmos-db\"\n\t\"github.com/cosmos/cosmos-sdk/client\"\n\t\"github.com/cosmos/cosmos-sdk/client/flags\"\n\t\"github.com/cosmos/cosmos-sdk/client/grpc/cmtservice\"\n\t\"github.com/cosmos/cosmos-sdk/codec\"\n\tcodectypes \"github.com/cosmos/cosmos-sdk/codec/types\"\n\tcryptocodec \"github.com/cosmos/cosmos-sdk/crypto/codec\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n\t\"github.com/spf13/cobra\"\n\t\"sigs.k8s.io/yaml\"\n)\n\n// Commands add server commands.\nfunc Commands(\n\tappCreator types.AppCreator,\n) *cobra.Command {\n\tcometCmd := &cobra.Command{\n\t\tUse:     \"comet\",\n\t\tAliases: []string{\"cometbft\", \"tendermint\"},\n\t\tShort:   \"CometBFT subcommands\",\n\t}\n\n\tcometCmd.AddCommand(\n\t\tShowNodeIDCmd(),\n\t\tShowValidatorCmd(),\n\t\tShowAddressCmd(),\n\t\tVersionCmd(),\n\t\tcmtcmd.ResetAllCmd,\n\t\tcmtcmd.ResetStateCmd,\n\t\tBootstrapStateCmd(appCreator),\n\t)\n\n\treturn cometCmd\n}\n\n// StatusCommand returns the command to return the status of the network.\nfunc StatusCommand() *cobra.Command {\n\tcmd := &cobra.Command{\n\t\tUse:   \"status\",\n\t\tShort: \"Query remote node for status\",\n\t\tRunE: func(cmd *cobra.Command, _ []string) error {\n\t\t\tclientCtx, err := client.GetClientQueryContext(cmd)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcometRPC, err := clientCtx.GetNode()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tstatus, err := cmtservice.GetNodeStatus(\n\t\t\t\tcontext.Background(),\n\t\t\t\tcometRPC,\n\t\t\t)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\toutput, err := cmtjson.Marshal(status)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t// In order to maintain backwards compatibility, the default json\n\t\t\t// format output\n\t\t\t//#nosec:G703 // its a bet.\n\t\t\toutputFormat, _ := cmd.Flags().GetString(flags.FlagOutput)\n\t\t\tif outputFormat == flags.OutputFormatJSON {\n\t\t\t\tclientCtx = clientCtx.WithOutputFormat(flags.OutputFormatJSON)\n\t\t\t}\n\n\t\t\treturn clientCtx.PrintRaw(output)\n\t\t},\n\t}\n\n\tcmd.Flags().\n\t\tStringP(flags.FlagNode, \"n\", \"tcp://localhost:26657\", \"Node to connect to\")\n\tcmd.Flags().\n\t\tStringP(flags.FlagOutput, \"o\", \"json\", \"Output format (text|json)\")\n\n\treturn cmd\n}\n\n// ShowNodeIDCmd - ported from CometBFT, dump node ID to stdout.\nfunc ShowNodeIDCmd() *cobra.Command {\n\treturn &cobra.Command{\n\t\tUse:   \"show-node-id\",\n\t\tShort: \"Show this node's ID\",\n\t\tRunE: func(cmd *cobra.Command, _ []string) error {\n\t\t\tcfg := clicontext.GetConfigFromCmd(cmd)\n\t\t\tnodeKey, err := p2p.LoadNodeKey(cfg.NodeKeyFile())\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tcmd.Println(nodeKey.ID())\n\t\t\treturn nil\n\t\t},\n\t}\n}\n\n// ShowValidatorCmd - ported from CometBFT, show this node's validator info.\nfunc ShowValidatorCmd() *cobra.Command {\n\tcmd := cobra.Command{\n\t\tUse:   \"show-validator\",\n\t\tShort: \"Show this node's CometBFT validator info\",\n\t\tRunE: func(cmd *cobra.Command, _ []string) error {\n\t\t\tcfg := clicontext.GetConfigFromCmd(cmd)\n\t\t\tprivValidator := pvm.LoadFilePV(\n\t\t\t\tcfg.PrivValidatorKeyFile(),\n\t\t\t\tcfg.PrivValidatorStateFile(),\n\t\t\t)\n\t\t\tpk, err := privValidator.GetPubKey()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tsdkPK, err := cryptocodec.FromCmtPubKeyInterface(pk)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tregistry := codectypes.NewInterfaceRegistry()\n\t\t\tcryptocodec.RegisterInterfaces(registry)\n\t\t\tcdc := codec.NewProtoCodec(registry)\n\n\t\t\tbz, err := cdc.MarshalInterfaceJSON(sdkPK)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tcmd.Println(string(bz))\n\t\t\treturn nil\n\t\t},\n\t}\n\n\treturn &cmd\n}\n\n// ShowAddressCmd - show this node's validator address.\nfunc ShowAddressCmd() *cobra.Command {\n\tcmd := &cobra.Command{\n\t\tUse:   \"show-address\",\n\t\tShort: \"Shows this node's CometBFT validator consensus address\",\n\t\tRunE: func(cmd *cobra.Command, _ []string) error {\n\t\t\tcfg := clicontext.GetConfigFromCmd(cmd)\n\t\t\tprivValidator := pvm.LoadFilePV(\n\t\t\t\tcfg.PrivValidatorKeyFile(),\n\t\t\t\tcfg.PrivValidatorStateFile(),\n\t\t\t)\n\n\t\t\tvalConsAddr := (sdk.ConsAddress)(privValidator.GetAddress())\n\n\t\t\tcmd.Println(valConsAddr.String())\n\t\t\treturn nil\n\t\t},\n\t}\n\n\treturn cmd\n}\n\n// VersionCmd prints CometBFT and ABCI version numbers.\nfunc VersionCmd() *cobra.Command {\n\treturn &cobra.Command{\n\t\tUse:   \"version\",\n\t\tShort: \"Print CometBFT libraries' version\",\n\t\tLong: `Print protocols' and libraries' version numbers against\nwhich this app has been compiled.`,\n\t\tRunE: func(cmd *cobra.Command, _ []string) error {\n\t\t\tbs, err := yaml.Marshal(&struct {\n\t\t\t\tCometBFT      string\n\t\t\t\tABCI          string\n\t\t\t\tBlockProtocol uint64\n\t\t\t\tP2PProtocol   uint64\n\t\t\t}{\n\t\t\t\tCometBFT:      cmtversion.CMTSemVer,\n\t\t\t\tABCI:          cmtversion.ABCIVersion,\n\t\t\t\tBlockProtocol: cmtversion.BlockProtocol,\n\t\t\t\tP2PProtocol:   cmtversion.P2PProtocol,\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tcmd.Println(string(bs))\n\t\t\treturn nil\n\t\t},\n\t}\n}\n\nfunc BootstrapStateCmd(\n\tappCreator types.AppCreator,\n) *cobra.Command {\n\tcmd := &cobra.Command{\n\t\tUse: \"bootstrap-state\",\n\t\tShort: `Bootstrap CometBFT state at an arbitrary block height\nusing a light client`,\n\t\tArgs: cobra.NoArgs,\n\t\tRunE: func(cmd *cobra.Command, _ []string) error {\n\t\t\tlogger := clicontext.GetLoggerFromCmd(cmd)\n\t\t\tcfg := clicontext.GetConfigFromCmd(cmd)\n\t\t\tv := clicontext.GetViperFromCmd(cmd)\n\n\t\t\theight, err := cmd.Flags().GetInt64(\"height\")\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif height == 0 {\n\t\t\t\thome := v.GetString(flags.FlagHome)\n\t\t\t\tvar dbi dbm.DB\n\t\t\t\tdbi, err = db.OpenDB(home, dbm.PebbleDBBackend)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\n\t\t\t\tapp := appCreator(logger, dbi, nil, cfg, v)\n\t\t\t\theight = app.CommitMultiStore().LastCommitID().Version\n\t\t\t}\n\n\t\t\treturn node.BootstrapState(\n\t\t\t\tcmd.Context(),\n\t\t\t\tcfg,\n\t\t\t\tcmtcfg.DefaultDBProvider,\n\t\t\t\tservice.GetGenDocProvider(cfg),\n\t\t\t\tuint64(height), // #nosec G115\n\t\t\t\tnil,\n\t\t\t)\n\t\t},\n\t}\n\n\tcmd.Flags().\n\t\tInt64(\"height\", 0, `Block height to bootstrap state at, if not provided\nit uses the latest block height in app state`)\n\n\treturn cmd\n}\n"
  },
  {
    "path": "consensus/cometbft/service/abci.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n//\n\npackage cometbft\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"time\"\n\n\terrorsmod \"cosmossdk.io/errors\"\n\tcmtabci \"github.com/cometbft/cometbft/abci/types\"\n\tabci \"github.com/cometbft/cometbft/api/cometbft/abci/v1\"\n\tsdkerrors \"github.com/cosmos/cosmos-sdk/types/errors\"\n\tsdkversion \"github.com/cosmos/cosmos-sdk/version\"\n)\n\nvar errInvalidHeight = errors.New(\"invalid height\")\n\nfunc (s *Service) InitChain(\n\t_ context.Context,\n\treq *cmtabci.InitChainRequest,\n) (*cmtabci.InitChainResponse, error) {\n\t// Check if ctx is still good. CometBFT does not check this.\n\tif s.ctx.Err() != nil {\n\t\t// If the context is getting cancelled, we are shutting down.\n\t\treturn &cmtabci.InitChainResponse{}, s.ctx.Err()\n\t}\n\t//nolint:contextcheck // see s.ctx comment for more details\n\treturn s.initChain(s.ctx, req)\n}\n\n// PrepareProposal implements the PrepareProposal ABCI method and returns a\n// ResponsePrepareProposal object to the client.\nfunc (s *Service) PrepareProposal(\n\t_ context.Context,\n\treq *cmtabci.PrepareProposalRequest,\n) (*cmtabci.PrepareProposalResponse, error) {\n\t// Check if ctx is still good. CometBFT does not check this.\n\tif s.ctx.Err() != nil {\n\t\t// If the context is getting cancelled, we are shutting down.\n\t\t// It is ok returning an empty proposal.\n\t\t//nolint:nilerr // explicitly allowing this case\n\t\treturn &cmtabci.PrepareProposalResponse{Txs: req.Txs}, nil\n\t}\n\t//nolint:contextcheck // see s.ctx comment for more details\n\treturn s.prepareProposal(s.ctx, req)\n}\n\nfunc (s *Service) Info(context.Context,\n\t*cmtabci.InfoRequest,\n) (*cmtabci.InfoResponse, error) {\n\tlastCommitID := s.sm.GetCommitMultiStore().LastCommitID()\n\tappVersion := initialAppVersion\n\tif lastCommitID.Version > 0 {\n\t\tvar err error\n\t\tappVersion, err = s.appVersion()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed getting app version: %w\", err)\n\t\t}\n\t}\n\n\treturn &cmtabci.InfoResponse{\n\t\tData:             AppName,\n\t\tVersion:          sdkversion.Version,\n\t\tAppVersion:       appVersion,\n\t\tLastBlockHeight:  lastCommitID.Version,\n\t\tLastBlockAppHash: lastCommitID.Hash,\n\t}, nil\n}\n\n// ProcessProposal implements the ProcessProposal ABCI method and returns a\n// ResponseProcessProposal object to the client.\nfunc (s *Service) ProcessProposal(\n\t_ context.Context,\n\treq *cmtabci.ProcessProposalRequest,\n) (*cmtabci.ProcessProposalResponse, error) {\n\t// Check if ctx is still good. CometBFT does not check this.\n\tif s.ctx.Err() != nil {\n\t\t// Node will panic on context cancel with \"CONSENSUS FAILURE!!!\" due to\n\t\t// returning an error. This is expected. We do not want to accept or\n\t\t// reject a proposal based on incomplete data.\n\t\treturn nil, s.ctx.Err()\n\t}\n\t//nolint:contextcheck // see s.ctx comment for more details\n\treturn s.processProposal(s.ctx, req)\n}\n\nfunc (s *Service) FinalizeBlock(\n\t_ context.Context,\n\treq *cmtabci.FinalizeBlockRequest,\n) (*cmtabci.FinalizeBlockResponse, error) {\n\t// Check if ctx is still good. CometBFT does not check this.\n\tif s.ctx.Err() != nil {\n\t\t// Node will panic on context cancel with \"CONSENSUS FAILURE!!!\" due to error.\n\t\t// We expect this to happen and do not want to finalize any incomplete or invalid state.\n\t\treturn nil, s.ctx.Err()\n\t}\n\t//nolint:contextcheck // see s.ctx comment for more details\n\treturn s.finalizeBlock(s.ctx, req)\n}\n\n// Commit implements the ABCI interface. It will commit all state that exists in\n// the deliver state's multi-store and includes the resulting commit ID in the\n// returned cmtabci.ResponseCommit. Commit will set the check state based on the\n// latest header and reset the deliver state. Also, if a non-zero halt height is\n// defined in config, Commit will execute a deferred function call to check\n// against that height and gracefully halt if it matches the latest committed\n// height.\nfunc (s *Service) Commit(\n\t_ context.Context, req *cmtabci.CommitRequest,\n) (*cmtabci.CommitResponse, error) {\n\t// Check if ctx is still good. CometBFT does not check this.\n\tif s.ctx.Err() != nil {\n\t\t// Node will panic on context cancel with \"CONSENSUS FAILURE!!!\" due to error.\n\t\t// We expect this to happen and do not want to commit any incomplete or invalid state.\n\t\treturn nil, s.ctx.Err()\n\t}\n\n\treturn s.commit(req)\n}\n\n// NOTE: Partially copied from https://github.com/cosmos/cosmos-sdk/blob/960d44842b9e313cbe762068a67a894ac82060ab/baseapp/abci.go#L168\nfunc (s *Service) Query(\n\t_ context.Context,\n\treq *abci.QueryRequest,\n) (*abci.QueryResponse, error) {\n\tresp := new(abci.QueryResponse)\n\n\t// add panic recovery for all queries\n\t//\n\t// Ref: https://github.com/cosmos/cosmos-sdk/pull/8039\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\t*resp = queryResult(errorsmod.Wrapf(sdkerrors.ErrPanic, \"%v\", r))\n\t\t}\n\t}()\n\n\t// when a client did not provide a query height, manually inject the latest\n\tif req.Height == 0 {\n\t\treq.Height = s.lastBlockHeight()\n\t}\n\n\ts.telemetrySink.IncrementCounter(\"beacon_kit.comet.query_count\", \"path\", req.Path)\n\tstartTime := time.Now()\n\tdefer s.telemetrySink.MeasureSince(\n\t\t\"beacon_kit.comet.query_duration\", startTime, \"path\", req.Path,\n\t)\n\n\tpath := splitABCIQueryPath(req.Path)\n\tif len(path) == 0 {\n\t\t*resp = queryResult(errorsmod.Wrap(sdkerrors.ErrUnknownRequest, \"no query path provided\"))\n\t\treturn resp, nil\n\t}\n\n\t// Only \"/store\" prefix for store queries are supported.\n\tif path[0] != \"store\" {\n\t\t*resp = queryResult(errorsmod.Wrap(sdkerrors.ErrNotSupported, \"unsupported query path\"))\n\t\treturn resp, nil\n\t}\n\n\t*resp = s.handleQueryStore(path, req)\n\treturn resp, nil\n}\n\n//\n// NOOP methods\n//\n\nfunc (Service) ListSnapshots(\n\tcontext.Context,\n\t*abci.ListSnapshotsRequest,\n) (*abci.ListSnapshotsResponse, error) {\n\treturn &abci.ListSnapshotsResponse{}, nil\n}\n\nfunc (Service) LoadSnapshotChunk(\n\tcontext.Context,\n\t*abci.LoadSnapshotChunkRequest,\n) (*abci.LoadSnapshotChunkResponse, error) {\n\treturn &abci.LoadSnapshotChunkResponse{}, nil\n}\n\nfunc (Service) OfferSnapshot(\n\tcontext.Context,\n\t*abci.OfferSnapshotRequest,\n) (*abci.OfferSnapshotResponse, error) {\n\treturn &abci.OfferSnapshotResponse{}, nil\n}\n\nfunc (Service) ApplySnapshotChunk(\n\tcontext.Context,\n\t*abci.ApplySnapshotChunkRequest,\n) (*abci.ApplySnapshotChunkResponse, error) {\n\treturn &abci.ApplySnapshotChunkResponse{}, nil\n}\n\nfunc (Service) ExtendVote(\n\tcontext.Context,\n\t*abci.ExtendVoteRequest,\n) (*abci.ExtendVoteResponse, error) {\n\treturn &abci.ExtendVoteResponse{}, nil\n}\n\nfunc (Service) VerifyVoteExtension(\n\tcontext.Context,\n\t*abci.VerifyVoteExtensionRequest,\n) (*abci.VerifyVoteExtensionResponse, error) {\n\treturn &abci.VerifyVoteExtensionResponse{}, nil\n}\n\nfunc (*Service) CheckTx(\n\tcontext.Context,\n\t*abci.CheckTxRequest,\n) (*abci.CheckTxResponse, error) {\n\treturn &abci.CheckTxResponse{}, nil\n}\n"
  },
  {
    "path": "consensus/cometbft/service/abci_utils.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n//\n\npackage cometbft\n\nimport (\n\t\"strings\"\n\n\terrorsmod \"cosmossdk.io/errors\"\n\tstoretypes \"cosmossdk.io/store/types\"\n\tabci \"github.com/cometbft/cometbft/api/cometbft/abci/v1\"\n\tsdkerrors \"github.com/cosmos/cosmos-sdk/types/errors\"\n)\n\n// NOTE: Partially copied from: https://github.com/cosmos/cosmos-sdk/blob/960d44842b9e313cbe762068a67a894ac82060ab/baseapp/abci.go#L1098\nfunc (s *Service) handleQueryStore(path []string, req *abci.QueryRequest) abci.QueryResponse {\n\tqueryable, ok := s.sm.GetCommitMultiStore().(storetypes.Queryable)\n\tif !ok {\n\t\treturn queryResult(\n\t\t\terrorsmod.Wrap(sdkerrors.ErrUnknownRequest, \"multi-store does not support queries\"),\n\t\t)\n\t}\n\n\treq.Path = \"/\" + strings.Join(path[1:], \"/\") // req.Path == \"/beacon\"\n\n\tif req.Height <= 1 && req.Prove {\n\t\treturn queryResult(\n\t\t\terrorsmod.Wrap(\n\t\t\t\tsdkerrors.ErrInvalidRequest,\n\t\t\t\t\"cannot query with proof when height <= 1; please provide a valid height\",\n\t\t\t))\n\t}\n\n\tsdkReq := storetypes.RequestQuery(*req)\n\tresp, err := queryable.Query(&sdkReq)\n\tif err != nil {\n\t\treturn queryResult(err)\n\t}\n\tresp.Height = req.Height\n\n\treturn abci.QueryResponse(*resp)\n}\n\n// NOTE: Copied from here: https://github.com/cosmos/cosmos-sdk/blob/960d44842b9e313cbe762068a67a894ac82060ab/baseapp/errors.go#L37-L46.\n// This was made public in v0.53, under the sdkerrors module.\n// NOTE: the debug parameter has been removed since Service does not expose this functionality.\n//\n// queryResult returns a ResponseQuery from an error. It will try to parse ABCI\n// info from the error.\nfunc queryResult(err error) abci.QueryResponse {\n\tspace, code, log := errorsmod.ABCIInfo(err, false)\n\treturn abci.QueryResponse{\n\t\tCodespace: space,\n\t\tCode:      code,\n\t\tLog:       log,\n\t}\n}\n\n// NOTE: Copied from here: https://github.com/cosmos/cosmos-sdk/blob/960d44842b9e313cbe762068a67a894ac82060ab/baseapp/abci.go#L1153-L1165\n//\n// splitABCIQueryPath splits a string path using the delimiter '/'.\n//\n// e.g. \"this/is/funny\" becomes []string{\"this\", \"is\", \"funny\"}\nfunc splitABCIQueryPath(requestPath string) []string {\n\tpath := strings.Split(requestPath, \"/\")\n\n\t// first element is empty string\n\tif len(path) > 0 && path[0] == \"\" {\n\t\tpath = path[1:]\n\t}\n\n\treturn path\n}\n"
  },
  {
    "path": "consensus/cometbft/service/cache/cache.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n//\n\npackage cache\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/delay\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n\tlru \"github.com/hashicorp/golang-lru/v2\"\n)\n\n// TelemetrySink is an interface for recording metrics.\ntype TelemetrySink interface {\n\t// SetGauge sets a gauge metric to the specified value.\n\tSetGauge(key string, value int64, args ...string)\n}\n\nconst minActivationHeight = 2\n\nfunc IsStateCachingActive(cfg delay.ConfigGetter, height math.Slot) bool {\n\t// We choose to activate caching only after stable block time is activated\n\t// so to avoid rushes of blocks. In any case however caching cannot be activated\n\t// for genesis and first block, which has special handling.\n\tactivationHeight := math.Slot(max(cfg.SbtConsensusEnableHeight(), minActivationHeight)) //#nosec: G115\n\treturn height >= activationHeight\n}\n\nvar (\n\t_ States = (*candidateStates)(nil)\n\n\tErrStateNotFound          = errors.New(\"state not found\")\n\tErrNoFinalState           = errors.New(\"no state marked as final\")\n\tErrFinalStateIsNil        = errors.New(\"state marked as final is nil\")\n\tErrFinalizingUnknownState = errors.New(\"attempt at finalizing unknown state\")\n)\n\n// States is the interface controlling the caching of state and metadata once a block\n// has been succeesfully executed once. States assumes that consensus allows no forks,\n// and that no blocks at height H+1 is ever processed if height H has not been finalized.\ntype States interface {\n\t// SetCached allows caching state and metadata once a block has been executed.\n\t// It should be called for blocks which successfully pass PrepareProposal.\n\t// toCache is simply cached without checks, since CometBFT should guarantee that\n\t// blocks are verified at most once.\n\tSetCached(hash string, toCache *Element)\n\n\t// GetCached allows retrieval of cached state and metadata.\n\t// It should be called by FinalizedBlock to verify whether the block\n\t// has already been executed\n\tGetCached(hash string) (*Element, error)\n\n\t// MarkAsFinal allows marking one of the cached states as the one to be finalized and committed.\n\t// It should be called upon FinalizeBlock to then allow Commit to store the state.\n\t// It errs if we attempt to finalize a state which was not previously cached\n\tMarkAsFinal(hash string) error\n\n\t// GetFinal allows to retrieve state and stateHash marked as final.\n\t// Is should be call by Commit to retrieve the state finalized in FinalizeBlock\n\tGetFinal() (string, *State, error)\n\n\t// Reset allows wiping out all the verified states once one of the has been committed\n\tReset()\n}\n\ntype Element struct {\n\tState      *State\n\tValUpdates transition.ValidatorUpdates\n}\n\ntype candidateStates struct {\n\tstates         *lru.Cache[string, *Element]\n\tfinalStateHash *string\n\tsink           TelemetrySink\n}\n\n// New creates a new States cache with the given maximum size and telemetry sink.\nfunc New(maxSize int, sink TelemetrySink) States {\n\tc, err := lru.New[string, *Element](maxSize)\n\tif err != nil {\n\t\tpanic(fmt.Errorf(\"failed to create candidate states cache: %w\", err))\n\t}\n\treturn &candidateStates{\n\t\tstates:         c,\n\t\tfinalStateHash: nil,\n\t\tsink:           sink,\n\t}\n}\n\nfunc (cs *candidateStates) SetCached(hash string, toCache *Element) {\n\tcs.states.Add(hash, toCache)\n}\n\nfunc (cs *candidateStates) GetCached(hash string) (*Element, error) {\n\tcached, found := cs.states.Get(hash)\n\tif !found {\n\t\treturn nil, ErrStateNotFound\n\t}\n\treturn cached, nil\n}\n\nfunc (cs *candidateStates) MarkAsFinal(hash string) error {\n\tif !cs.states.Contains(hash) {\n\t\treturn ErrFinalizingUnknownState\n\t}\n\tcs.finalStateHash = &hash\n\treturn nil\n}\n\nfunc (cs *candidateStates) GetFinal() (string, *State, error) {\n\tif cs.finalStateHash == nil {\n\t\treturn \"\", nil, ErrNoFinalState\n\t}\n\tcached, found := cs.states.Get(*cs.finalStateHash)\n\tif !found {\n\t\treturn \"\", nil, ErrFinalStateIsNil\n\t}\n\treturn *cs.finalStateHash, cached.State, nil\n}\n\nfunc (cs *candidateStates) Reset() {\n\tcs.sink.SetGauge(\"beacon_kit.comet.cached_states_size_at_reset\", int64(cs.states.Len()))\n\tcs.states.Purge()\n\tcs.finalStateHash = nil\n}\n"
  },
  {
    "path": "consensus/cometbft/service/cache/cache_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage cache_test\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/cache\"\n)\n\nconst maxCachedStates = 10\n\n// mockTelemetrySink is a simple mock for testing.\ntype mockTelemetrySink struct {\n\tlastGaugeKey   string\n\tlastGaugeValue int64\n}\n\nfunc (m *mockTelemetrySink) SetGauge(key string, value int64, _ ...string) {\n\tm.lastGaugeKey = key\n\tm.lastGaugeValue = value\n}\n\nfunc TestCandidateStates_BasicOperations(t *testing.T) {\n\tt.Parallel()\n\tsink := &mockTelemetrySink{}\n\tc := cache.New(maxCachedStates, sink)\n\n\t// Test SetCached and GetCached\n\telem := &cache.Element{State: &cache.State{}}\n\tc.SetCached(\"test-hash\", elem)\n\n\tgot, err := c.GetCached(\"test-hash\")\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error: %v\", err)\n\t}\n\tif got != elem {\n\t\tt.Error(\"retrieved element does not match stored element\")\n\t}\n\n\t// Test GetCached for non-existent key\n\t_, err = c.GetCached(\"non-existent\")\n\tif !errors.Is(err, cache.ErrStateNotFound) {\n\t\tt.Errorf(\"expected ErrStateNotFound, got: %v\", err)\n\t}\n\n\t// Test MarkAsFinal\n\terr = c.MarkAsFinal(\"test-hash\")\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error marking as final: %v\", err)\n\t}\n\n\t// Test MarkAsFinal for non-existent key\n\terr = c.MarkAsFinal(\"non-existent\")\n\tif !errors.Is(err, cache.ErrFinalizingUnknownState) {\n\t\tt.Errorf(\"expected ErrFinalizingUnknownState, got: %v\", err)\n\t}\n\n\t// Test GetFinal\n\thash, state, err := c.GetFinal()\n\tif err != nil {\n\t\tt.Fatalf(\"unexpected error getting final: %v\", err)\n\t}\n\tif hash != \"test-hash\" {\n\t\tt.Errorf(\"expected hash 'test-hash', got: %s\", hash)\n\t}\n\tif state != elem.State {\n\t\tt.Error(\"final state does not match expected state\")\n\t}\n\n\t// Test Reset\n\tc.Reset()\n\n\t// Verify the metric was recorded with correct size (1 element was in cache)\n\tif sink.lastGaugeKey != \"beacon_kit.comet.cached_states_size_at_reset\" {\n\t\tt.Errorf(\"expected gauge key 'beacon_kit.comet.cached_states_size_at_reset', got: %s\", sink.lastGaugeKey)\n\t}\n\tif sink.lastGaugeValue != 1 {\n\t\tt.Errorf(\"expected gauge value 1, got: %d\", sink.lastGaugeValue)\n\t}\n\n\t_, err = c.GetCached(\"test-hash\")\n\tif !errors.Is(err, cache.ErrStateNotFound) {\n\t\tt.Error(\"expected cache to be empty after reset\")\n\t}\n\n\t_, _, err = c.GetFinal()\n\tif !errors.Is(err, cache.ErrNoFinalState) {\n\t\tt.Errorf(\"expected ErrNoFinalState after reset, got: %v\", err)\n\t}\n}\n\nfunc TestCandidateStates_BoundedSize(t *testing.T) {\n\tt.Parallel()\n\tsink := &mockTelemetrySink{}\n\tc := cache.New(maxCachedStates, sink)\n\n\t// Add more entries than maxCachedStates\n\tfor i := range maxCachedStates + 5 {\n\t\thash := fmt.Sprintf(\"hash-%d\", i)\n\t\tc.SetCached(hash, &cache.Element{})\n\t}\n\n\t// Verify oldest entries were evicted (LRU behavior)\n\tfor i := range 5 {\n\t\thash := fmt.Sprintf(\"hash-%d\", i)\n\t\t_, err := c.GetCached(hash)\n\t\tif !errors.Is(err, cache.ErrStateNotFound) {\n\t\t\tt.Errorf(\"expected hash-%d to be evicted, but it was found\", i)\n\t\t}\n\t}\n\n\t// Verify newest entries are still present\n\tfor i := 5; i < maxCachedStates+5; i++ {\n\t\thash := fmt.Sprintf(\"hash-%d\", i)\n\t\t_, err := c.GetCached(hash)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"expected hash-%d to be present, got error: %v\", i, err)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "consensus/cometbft/service/cache/state.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage cache\n\nimport (\n\t\"sync\"\n\n\tstoretypes \"cosmossdk.io/store/types\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n)\n\ntype State struct {\n\tms storetypes.CacheMultiStore\n\n\tmtx sync.RWMutex\n\tctx sdk.Context\n}\n\nfunc NewState(ms storetypes.CacheMultiStore, ctx sdk.Context) *State {\n\treturn &State{\n\t\tms:  ms,\n\t\tctx: ctx,\n\t}\n}\n\n// CacheMultiStore calls and returns a CacheMultiStore on the state's underling\n// CacheMultiStore.\nfunc (st *State) CacheMultiStore() storetypes.CacheMultiStore {\n\treturn st.ms.CacheMultiStore()\n}\n\n// SetContext updates the state's context to the context provided.\nfunc (st *State) SetContext(ctx sdk.Context) {\n\tst.mtx.Lock()\n\tdefer st.mtx.Unlock()\n\tst.ctx = ctx\n}\n\n// Context returns the Context of the state.\nfunc (st *State) Context() sdk.Context {\n\tst.mtx.RLock()\n\tdefer st.mtx.RUnlock()\n\treturn st.ctx\n}\n\nfunc (st *State) Write() {\n\tst.ms.Write()\n}\n"
  },
  {
    "path": "consensus/cometbft/service/commit.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n//\n\npackage cometbft\n\nimport (\n\t\"fmt\"\n\n\t\"cosmossdk.io/store/rootmulti\"\n\tcmtabci \"github.com/cometbft/cometbft/abci/types\"\n)\n\nfunc (s *Service) commit(\n\t*cmtabci.CommitRequest,\n) (*cmtabci.CommitResponse, error) {\n\t_, finalState, err := s.cachedStates.GetFinal()\n\tif err != nil {\n\t\t// This is unexpected since CometBFT should call Commit only\n\t\t// after FinalizeBlock has been called. Panic appeases nilaway.\n\t\tpanic(fmt.Errorf(\"commit: %w\", err))\n\t}\n\n\theader := finalState.Context().BlockHeader()\n\tretainHeight := s.GetBlockRetentionHeight(header.Height)\n\n\trms, ok := s.sm.GetCommitMultiStore().(*rootmulti.Store)\n\tif ok {\n\t\trms.SetCommitHeader(header)\n\t}\n\ts.sm.GetCommitMultiStore().Commit()\n\n\ts.cachedStates.Reset()\n\n\tif s.blockDelay != nil {\n\t\tif err = s.sm.SaveBlockDelay(s.blockDelay.ToBytes()); err != nil {\n\t\t\tpanic(fmt.Errorf(\"failed to save block delay: %w\", err))\n\t\t}\n\t}\n\n\treturn &cmtabci.CommitResponse{\n\t\tRetainHeight: retainHeight,\n\t}, nil\n}\n\n// GetBlockRetentionHeight returns the height for which all blocks below this\n// height\n// are pruned from CometBFT. Given a commitment height and a non-zero local\n// minRetainBlocks configuration, the retentionHeight is the smallest height\n// that\n// satisfies:\n//\n// - Unbonding (safety threshold) time: The block interval in which validators\n// can be economically punished for misbehavior. Blocks in this interval must be\n// auditable e.g. by the light client.\n//\n// - Logical store snapshot interval: The block interval at which the underlying\n// logical store database is persisted to disk, e.g. every 10000 heights. Blocks\n// since the last IAVL snapshot must be available for replay on application\n// restart.\n//\n// - State sync snapshots: Blocks since the oldest available snapshot must be\n// available for state sync nodes to catch up (oldest because a node may be\n// restoring an old snapshot while a new snapshot was taken).\n//\n// - Local (minRetainBlocks) config: Archive nodes may want to retain more or\n// all blocks, e.g. via a local config option min-retain-blocks. There may also\n// be a need to vary retention for other nodes, e.g. sentry nodes which do not\n// need historical blocks.\nfunc (s *Service) GetBlockRetentionHeight(commitHeight int64) int64 {\n\t// pruning is disabled if minRetainBlocks is zero\n\tif s.minRetainBlocks == 0 {\n\t\treturn 0\n\t}\n\n\tminNonZero := func(x, y int64) int64 {\n\t\tswitch {\n\t\tcase x == 0:\n\t\t\treturn y\n\n\t\tcase y == 0:\n\t\t\treturn x\n\n\t\tcase x < y:\n\t\t\treturn x\n\n\t\tdefault:\n\t\t\treturn y\n\t\t}\n\t}\n\n\t// Define retentionHeight as the minimum value that satisfies all non-zero\n\t// constraints. All blocks below (commitHeight-retentionHeight) are pruned\n\t// from CometBFT.\n\tvar retentionHeight int64\n\n\t// Define the number of blocks needed to protect against misbehaving\n\t// validators\n\t// which allows light clients to operate safely. Note, we piggy back of the\n\t// evidence parameters instead of computing an estimated number of blocks\n\t// based\n\t// on the unbonding period and block commitment time as the two should be\n\t// equivalent.\n\tif _, _, err := s.cachedStates.GetFinal(); err != nil {\n\t\treturn 0\n\t}\n\tcp := s.cmtConsensusParams.ToProto()\n\tif cp.Evidence != nil && cp.Evidence.MaxAgeNumBlocks > 0 {\n\t\tretentionHeight = commitHeight - cp.Evidence.MaxAgeNumBlocks\n\t}\n\n\tv := commitHeight - int64(s.minRetainBlocks) // #nosec G115\n\tretentionHeight = minNonZero(retentionHeight, v)\n\n\tif retentionHeight <= 0 {\n\t\t// prune nothing in the case of a non-positive height\n\t\treturn 0\n\t}\n\n\treturn retentionHeight\n}\n"
  },
  {
    "path": "consensus/cometbft/service/configs.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n//\n\npackage cometbft\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/log\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\tcmttypes \"github.com/cometbft/cometbft/types\"\n)\n\nconst ( // appeases mnd\n\t// These timeouts are the ones we tested are necessary\n\t// at minimum to have a smooth network. We enforce that\n\t// these minima are respected.\n\tminTimeoutPropose   = 2000 * time.Millisecond\n\tminTimeoutPrevote   = 2000 * time.Millisecond\n\tminTimeoutPrecommit = 2000 * time.Millisecond\n\n\tmaxBlockSize = 100 * 1024 * 1024\n\n\tprecision    = 505 * time.Millisecond\n\tmessageDelay = 15 * time.Second\n\n\tdefaultMaxNumInboundPeers  = 40\n\tdefaultMaxNumOutboundPeers = 10\n)\n\nvar (\n\tErrInvalidaConfig          = errors.New(\"invalid comet config for BeaconKit\")\n\tErrInvalidaConsensusParams = errors.New(\"invalid comet consensus params for BeaconKit\")\n)\n\n// DefaultConfig returns the default configuration for the CometBFT\n// consensus engine. It overrides a few values based on our own measurements\n// and development level of BeaconKit. Recall that these are node-specific\n// values (although they influence consensus).\n// This should be the only place in the entire BeaconKit codebase where\n// cmtcfg.DefaultConfig() is called.\nfunc DefaultConfig() *cmtcfg.Config {\n\tcfg := cmtcfg.DefaultConfig()\n\n\t// BeaconKit forces PebbleDB as the database backend.\n\tcfg.BaseConfig.DBBackend = \"pebbledb\"\n\n\t// These settings are set by default for performance reasons.\n\tcfg.P2P.MaxNumInboundPeers = defaultMaxNumInboundPeers\n\tcfg.P2P.MaxNumOutboundPeers = defaultMaxNumOutboundPeers\n\n\tcfg.Mempool.Type = \"nop\"\n\tcfg.Mempool.Recheck = false\n\tcfg.Mempool.RecheckTimeout = 0\n\tcfg.Mempool.Broadcast = false\n\tcfg.Mempool.Size = 0\n\tcfg.Mempool.MaxTxBytes = 0\n\tcfg.Mempool.MaxTxsBytes = 0\n\tcfg.Mempool.CacheSize = 0\n\n\t// By default, we set timeouts to the minima we tested\n\tconsensus := cfg.Consensus\n\tconsensus.TimeoutPropose = minTimeoutPropose\n\tconsensus.TimeoutPrevote = minTimeoutPrevote\n\tconsensus.TimeoutPrecommit = minTimeoutPrecommit\n\n\t//nolint:staticcheck // setting to zero because it's deprecated\n\tconsensus.TimeoutCommit = 0\n\n\tcfg.Storage.DiscardABCIResponses = true\n\n\tcfg.TxIndex.Indexer = \"null\"\n\n\tcfg.Instrumentation.Prometheus = true\n\tcfg.Instrumentation.MaxOpenConnections = 800\n\n\t// Disable profiling by default\n\t// cfg.RPC.PprofListenAddress = \"localhost:6060\"\n\n\tif err := cfg.ValidateBasic(); err != nil {\n\t\tpanic(fmt.Errorf(\"invalid comet config: %w\", err))\n\t}\n\n\treturn cfg\n}\n\n// DefaultConsensusParams returns the default consensus parameters\n// shared by every node in the network. Consensus parameters are\n// inscripted in genesis.\nfunc DefaultConsensusParams(consensusKeyAlgo string, cs chain.Spec) *cmttypes.ConsensusParams {\n\tres := cmttypes.DefaultConsensusParams()\n\tres.Validator.PubKeyTypes = []string{consensusKeyAlgo}\n\n\t// set max block size in order to accommodate max blobs size\n\t// This matches current cmttypes.MaxBlockSizeBytes but it's\n\t// explicitly hard coded for safety across deps upgrades.\n\tres.Block.MaxBytes = maxBlockSize\n\n\t// activate pbst and hard code values to\n\t// be safe across dependencies upgrades\n\tres.Feature.PbtsEnableHeight = 1\n\tres.Synchrony.Precision = precision\n\tres.Synchrony.MessageDelay = messageDelay\n\tres.Feature.SBTEnableHeight = cs.SbtConsensusEnableHeight()\n\n\tif err := res.ValidateBasic(); err != nil {\n\t\tpanic(fmt.Errorf(\"invalid default consensus parameters: %w\", err))\n\t}\n\n\treturn res\n}\n\nfunc validateConfig(cfg *cmtcfg.Config) error {\n\tif cfg.Consensus.TimeoutPropose < minTimeoutPropose {\n\t\treturn fmt.Errorf(\"%w, config timeout propose %v, min requested %v\",\n\t\t\tErrInvalidaConfig,\n\t\t\tcfg.Consensus.TimeoutPropose,\n\t\t\tminTimeoutPropose,\n\t\t)\n\t}\n\n\tif cfg.Consensus.TimeoutPrevote < minTimeoutPrevote {\n\t\treturn fmt.Errorf(\"%w, config timeout prevote %v, min requested %v\",\n\t\t\tErrInvalidaConfig,\n\t\t\tcfg.Consensus.TimeoutPrevote,\n\t\t\tminTimeoutPrevote,\n\t\t)\n\t}\n\n\tif cfg.Consensus.TimeoutPrecommit < minTimeoutPrecommit {\n\t\treturn fmt.Errorf(\"%w, config timeout propose %v, min requested %v\",\n\t\t\tErrInvalidaConfig,\n\t\t\tcfg.Consensus.TimeoutPrecommit,\n\t\t\tminTimeoutPrecommit,\n\t\t)\n\t}\n\n\treturn nil\n}\n\nfunc warnAboutConfigs(\n\tcmtCfg *cmtcfg.Config,\n\tlogger log.Logger,\n) {\n\tconnectionsCap := defaultMaxNumInboundPeers + defaultMaxNumOutboundPeers\n\tif cmtCfg.P2P.MaxNumInboundPeers+cmtCfg.P2P.MaxNumOutboundPeers > connectionsCap {\n\t\tlogger.Warn(\n\t\t\t\"excessive peering\",\n\t\t\t\"max_num_inbound_peers\", cmtCfg.P2P.MaxNumInboundPeers,\n\t\t\t\"recommended max_num_inbound_peers\", defaultMaxNumInboundPeers,\n\t\t\t\"max_num_outbound_peers\", cmtCfg.P2P.MaxNumOutboundPeers,\n\t\t\t\"recommended max_num_outbound_peers\", defaultMaxNumOutboundPeers,\n\t\t\t\"recommended connections cap (inbound + outbound)\", connectionsCap,\n\t\t)\n\t}\n}\n\n// extractConsensusParams pull consensus parameters (not config) set in\n// genesis. They are mostly used to (not) update consensus parameters once\n// a block is finalized.\nfunc extractConsensusParams(cmtCfg *cmtcfg.Config) (*cmttypes.ConsensusParams, error) {\n\tgenFunc := GetGenDocProvider(cmtCfg)\n\tgenDoc, err := genFunc()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed pulling consensus params: %w\", err)\n\t}\n\n\t// Todo: add validation for genesis params by chainID\n\tcmtConsensusParams := genDoc.GenesisDoc.ConsensusParams\n\treturn cmtConsensusParams, validateConsensusParams(cmtConsensusParams)\n}\n\nfunc validateConsensusParams(params *cmttypes.ConsensusParams) error {\n\tif params.Block.MaxBytes < maxBlockSize {\n\t\treturn fmt.Errorf(\"%w, param max size %v, requested size %v\",\n\t\t\tErrInvalidaConsensusParams,\n\t\t\tparams.Block.MaxBytes,\n\t\t\tmaxBlockSize,\n\t\t)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "consensus/cometbft/service/configs_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n//\n\npackage cometbft_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\tcometbft \"github.com/berachain/beacon-kit/consensus/cometbft/service\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\tcmttypes \"github.com/cometbft/cometbft/types\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestSBTEnableHeightAlignedWithChainSpecs(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname          string\n\t\tgetChainSpecs func(t *testing.T) chain.Spec\n\t}{\n\t\t{\n\t\t\tname: \"mainnet\",\n\t\t\tgetChainSpecs: func(t *testing.T) chain.Spec {\n\t\t\t\tt.Helper()\n\t\t\t\tcs, err := spec.MainnetChainSpec()\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\treturn cs\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"testnet\",\n\t\t\tgetChainSpecs: func(t *testing.T) chain.Spec {\n\t\t\t\tt.Helper()\n\t\t\t\tcs, err := spec.TestnetChainSpec()\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\treturn cs\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"devnet\",\n\t\t\tgetChainSpecs: func(t *testing.T) chain.Spec {\n\t\t\t\tt.Helper()\n\t\t\t\tcs, err := spec.DevnetChainSpec()\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\treturn cs\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tcs := tt.getChainSpecs(t)\n\n\t\t\tvar cp *cmttypes.ConsensusParams\n\t\t\trequire.NotPanics(t, func() {\n\t\t\t\tcp = cometbft.DefaultConsensusParams(crypto.CometBLSType, cs)\n\t\t\t})\n\n\t\t\t// Make sure that the Enable Height in consensus parameters matches with\n\t\t\t// chain spec one. This is relevant to make sure that consensus parameters\n\t\t\t// are well set when chain spec is modified and genesis is regenerated.\n\t\t\trequire.Equal(t, cp.Feature.SBTEnableHeight, cs.SbtConsensusEnableHeight())\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "consensus/cometbft/service/delay/config.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage delay\n\nimport (\n\t\"math\"\n\t\"time\"\n)\n\nconst (\n\t// maxDelayBetweenBlocks is the maximum delay between two consecutive blocks.\n\t// If the last block time minus the previous block time is greater than\n\t// maxDelayBetweenBlocks, then we reset `FinalizeBlockResponse.NextBlockDelay`\n\t// to default.\n\t//\n\t// This is needed because the network may stall for a long time and we don't\n\t// want to rush in new blocks as the network resumes its operation.\n\tmaxDelayBetweenBlocks = 5 * time.Minute\n\n\t// targetBlockTime is the desired block time.\n\t//\n\t// Note that it CAN'T be lower than the minimal (floor) block time in the\n\t// network, which is comprised of the time to a) propose a new block b)\n\t// gather 2/3+ prevotes c) gather 2/3+ precommits.\n\ttargetBlockTime = 2 * time.Second\n\n\t// Delay to use before the upgrade to SBT.\n\tconstBlockDelay = 500 * time.Millisecond\n\n\t// Height to enable SBT. Changes will be applied in the next block after this\n\tsbtEnableHeight = math.MaxInt64\n\n\t// Height at which consensus params are upgraded to use SBT\n\tsbtConsensusParamUpdate = 0\n\n\t// Until `timeout_commit` is removed from the CometBFT config,\n\t// `FinalizeBlockResponse.NextBlockDelay` can't be exactly 0. If it's set to\n\t// 0, then `timeout_commit` from the config will be used, which is not what\n\t// we want since we're trying to control the block time.\n\tnoDelay = 1 * time.Microsecond\n)\n\ntype ConfigGetter interface {\n\tSbtMaxBlockDelay() time.Duration\n\tSbtTargetBlockTime() time.Duration\n\tSbtConstBlockDelay() time.Duration\n\tSbtConsensusUpdateHeight() int64\n\tSbtConsensusEnableHeight() int64\n}\n\ntype Config struct {\n\tMaxBlockDelay   time.Duration `mapstructure:\"max-block-delay\"`\n\tTargetBlockTime time.Duration `mapstructure:\"target-block-time\"`\n\tConstBlockDelay time.Duration `mapstructure:\"const-block-delay\"`\n\n\t// ConsensusParamUpdate decides the height where we set the ConsensusEnableHeight\n\t// In turn ConsensusEnableHeight, initializes the BlockDelay struct which will then\n\t// be used to calculate block delay in the next height.\n\tConsensusUpdateHeight int64 `mapstructure:\"consensus-update-height\"`\n\tConsensusEnableHeight int64 `mapstructure:\"consensus-enable-height\"`\n}\n\nfunc DefaultConfig() Config {\n\treturn Config{\n\t\tMaxBlockDelay:         maxDelayBetweenBlocks,\n\t\tTargetBlockTime:       targetBlockTime,\n\t\tConstBlockDelay:       constBlockDelay,\n\t\tConsensusUpdateHeight: sbtConsensusParamUpdate,\n\t\tConsensusEnableHeight: sbtEnableHeight,\n\t}\n}\n\nfunc (c Config) SbtMaxBlockDelay() time.Duration {\n\treturn c.MaxBlockDelay\n}\nfunc (c Config) SbtTargetBlockTime() time.Duration {\n\treturn c.TargetBlockTime\n}\nfunc (c Config) SbtConstBlockDelay() time.Duration {\n\treturn c.ConstBlockDelay\n}\nfunc (c Config) SbtConsensusUpdateHeight() int64 {\n\treturn c.ConsensusUpdateHeight\n}\nfunc (c Config) SbtConsensusEnableHeight() int64 {\n\treturn c.ConsensusEnableHeight\n}\n"
  },
  {
    "path": "consensus/cometbft/service/delay/delay.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage delay\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"time\"\n)\n\n// BlockDelay is used to calculate the delay before proposing the next block.\n//\n// The general formula is:\n//\n//\tNextBlockTime = InitialTime + TargetBlockTime * (CurrentHeight - InitialHeight)\n//\n// Initial Time and Height are reset is the chain stops for too long.\ntype BlockDelay struct {\n\t// InitialTime is a checkpoint in time from which we start calculating the\n\t// next block time.\n\tInitialTime time.Time\n\n\t// InitialHeight is a checkpoint in blockchain's height from which we start\n\t// calculating the next block time.\n\tInitialHeight int64\n\n\t// PreviousBlockTime is the time of the previous block.\n\tPreviousBlockTime time.Time\n}\n\n// ComputeNext returns the duration to wait before proposing the next block.\nfunc (d *BlockDelay) ComputeNext(cfg ConfigGetter, curBlockTime time.Time, curBlockHeight int64) time.Duration {\n\t// Reset the initial time and height if the time between blocks is greater\n\t// than MaxDelayBetweenBlocks. This makes the current time and height the\n\t// initial one as if the upgrade happened just now.\n\tif curBlockTime.Sub(d.PreviousBlockTime) > cfg.SbtMaxBlockDelay() {\n\t\td.InitialTime = curBlockTime\n\t\td.InitialHeight = curBlockHeight\n\t\td.PreviousBlockTime = curBlockTime\n\t\treturn cfg.SbtTargetBlockTime()\n\t}\n\n\td.PreviousBlockTime = curBlockTime\n\n\tt := d.InitialTime.Add(cfg.SbtTargetBlockTime() * time.Duration(curBlockHeight-d.InitialHeight))\n\tif curBlockTime.Before(t) {\n\t\tnextBlockDelay := t.Sub(curBlockTime)\n\t\treturn nextBlockDelay\n\t}\n\treturn noDelay\n}\n\n// FromBytes converts the bytes to a blockDelay.\n//\n// Expected format:\n//\n//\tInitialTime (int64) | InitialHeight (int64) | PreviousBlockTime (int64)\n//\t(little endian)\n//\n// It returns ErrBlockDelayFromBytes if it fails to read from the buffer.\nfunc FromBytes(bz []byte) (*BlockDelay, error) {\n\tbuf := bytes.NewReader(bz)\n\tvar initialTime, prevBlockTime int64\n\tvar initialHeight int64\n\n\terr := binary.Read(buf, binary.LittleEndian, &initialTime)\n\tif err != nil {\n\t\treturn nil, &BlockDelayFromBytesError{\n\t\t\tfield: \"InitialTime\",\n\t\t\terr:   err,\n\t\t}\n\t}\n\terr = binary.Read(buf, binary.LittleEndian, &initialHeight)\n\tif err != nil {\n\t\treturn nil, &BlockDelayFromBytesError{\n\t\t\tfield: \"InitialHeight\",\n\t\t\terr:   err,\n\t\t}\n\t}\n\terr = binary.Read(buf, binary.LittleEndian, &prevBlockTime)\n\tif err != nil {\n\t\treturn nil, &BlockDelayFromBytesError{\n\t\t\tfield: \"PreviousBlockTime\",\n\t\t\terr:   err,\n\t\t}\n\t}\n\n\treturn &BlockDelay{\n\t\tInitialTime:       time.Unix(0, initialTime),\n\t\tInitialHeight:     initialHeight,\n\t\tPreviousBlockTime: time.Unix(0, prevBlockTime),\n\t}, nil\n}\n\n// ToBytes converts the blockDelay to bytes.\n//\n// Format:\n//\n//\tInitialTime (int64) | InitialHeight (int64) | PreviousBlockTime (int64)\n//\t(little endian)\n//\n// Panics if it fails to write to the buffer.\nfunc (d *BlockDelay) ToBytes() []byte {\n\tbuf := new(bytes.Buffer)\n\n\terr := binary.Write(buf, binary.LittleEndian, d.InitialTime.UnixNano())\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"failed to write InitialTime: %v\", err))\n\t}\n\terr = binary.Write(buf, binary.LittleEndian, d.InitialHeight)\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"failed to write InitialHeight: %v\", err))\n\t}\n\terr = binary.Write(buf, binary.LittleEndian, d.PreviousBlockTime.UnixNano())\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"failed to write PreviousBlockTime: %v\", err))\n\t}\n\n\treturn buf.Bytes()\n}\n"
  },
  {
    "path": "consensus/cometbft/service/delay/delay_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage delay_test\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/delay\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nvar testCfg = delay.Config{\n\tMaxBlockDelay:   5 * time.Minute,\n\tTargetBlockTime: 2 * time.Second,\n\tConstBlockDelay: 500 * time.Millisecond,\n}\n\nfunc TestBlockDelayFromBytes(t *testing.T) {\n\tt.Parallel()\n\n\td1 := &delay.BlockDelay{\n\t\tInitialTime:       time.Now().Add(-10 * time.Minute),\n\t\tInitialHeight:     5,\n\t\tPreviousBlockTime: time.Now().Add(-5 * time.Minute),\n\t}\n\n\tb := d1.ToBytes()\n\td2, err := delay.FromBytes(b)\n\trequire.NoError(t, err)\n\n\tassert.Equal(t, d1.InitialTime.Unix(), d2.InitialTime.Unix())\n\tassert.Equal(t, d1.InitialHeight, d2.InitialHeight)\n\tassert.Equal(t, d1.PreviousBlockTime.Unix(), d2.PreviousBlockTime.Unix())\n}\n\nfunc TestBlockDelayNext_NoDelay(t *testing.T) {\n\tt.Parallel()\n\n\tgenesisTime := time.Now()\n\tinitialHeight := int64(1)\n\td := &delay.BlockDelay{\n\t\tInitialTime:       genesisTime,\n\t\tInitialHeight:     initialHeight,\n\t\tPreviousBlockTime: genesisTime,\n\t}\n\n\tcurBlockTime := genesisTime.Add(10 * time.Second)\n\tcurBlockHeight := int64(2)\n\n\tdelay := d.ComputeNext(testCfg, curBlockTime, curBlockHeight)\n\n\tassert.Equal(t, 1*time.Microsecond, delay)\n\n\t// InitialTime/Height are not updated, PreviousBlockTime is updated\n\tassert.Equal(t, genesisTime, d.InitialTime)\n\tassert.Equal(t, initialHeight, d.InitialHeight)\n\tassert.Equal(t, curBlockTime, d.PreviousBlockTime)\n}\n\nfunc TestBlockDelayNext_WithDelay(t *testing.T) {\n\tt.Parallel()\n\n\tgenesisTime := time.Now()\n\tinitialHeight := int64(1)\n\td := &delay.BlockDelay{\n\t\tInitialTime:       genesisTime,\n\t\tInitialHeight:     initialHeight,\n\t\tPreviousBlockTime: genesisTime,\n\t}\n\n\tcurBlockTime := genesisTime.Add(2 * time.Second)\n\tcurBlockHeight := int64(3)\n\n\tdelay := d.ComputeNext(testCfg, curBlockTime, curBlockHeight)\n\n\tassert.Equal(t, 2*time.Second, delay)\n\n\t// InitialTime/Height are not updated, PreviousBlockTime is updated\n\tassert.Equal(t, genesisTime, d.InitialTime)\n\tassert.Equal(t, initialHeight, d.InitialHeight)\n\tassert.Equal(t, curBlockTime, d.PreviousBlockTime)\n}\n\nfunc TestBlockDelayNext_ResetOnStall(t *testing.T) {\n\tt.Parallel()\n\n\tgenesisTime := time.Now()\n\tinitialHeight := int64(1)\n\td := &delay.BlockDelay{\n\t\tInitialTime:       genesisTime,\n\t\tInitialHeight:     initialHeight,\n\t\tPreviousBlockTime: genesisTime,\n\t}\n\n\tcurBlockTime := genesisTime.Add(testCfg.MaxBlockDelay + 1*time.Minute)\n\tcurBlockHeight := int64(10)\n\n\tnextBlockDelay := d.ComputeNext(testCfg, curBlockTime, curBlockHeight)\n\n\tassert.Equal(t, d.InitialTime, curBlockTime)\n\tassert.Equal(t, d.InitialHeight, curBlockHeight)\n\tassert.Equal(t, testCfg.TargetBlockTime, nextBlockDelay)\n}\n\nfunc TestBlockDelayNext_Catchup(t *testing.T) {\n\tt.Parallel()\n\n\tgenesisTime := time.Now()\n\tinitialHeight := int64(1)\n\td := &delay.BlockDelay{\n\t\tInitialTime:       genesisTime,\n\t\tInitialHeight:     initialHeight,\n\t\tPreviousBlockTime: genesisTime,\n\t}\n\n\tcurBlockTime := genesisTime.Add(2 * time.Second)\n\tcurBlockHeight := int64(3)\n\n\tdelay := d.ComputeNext(testCfg, curBlockTime, curBlockHeight)\n\n\tassert.Equal(t, 2*time.Second, delay)\n\n\t// Ideal\n\t// height 4 -> 3*2 = 6\n\t// height 5 -> 4*2 = 8\n\t// height 6 -> 5*2 = 10\n\t// height 7 -> 6*2 = 12\n\n\tcurBlockHeight++\n\tcurBlockTime = genesisTime.Add(8 * time.Second)\n\t// T(h4) = 8s\n\t// delay = 1us\n\t// T(h5 = 9s)\n\t// delay = 1us\n\t// T(h6) = 10s\n\t// delay = 1us\n\t// T(h7) = 11s\n\t// delay = 1\n\tdelay = d.ComputeNext(testCfg, curBlockTime, curBlockHeight)\n\tassert.Equal(t, 1*time.Microsecond, delay)\n\n\tfor curBlockHeight++; curBlockHeight < 7; curBlockHeight++ {\n\t\tcurBlockTime = curBlockTime.Add(1 * time.Second)\n\t\tdelay = d.ComputeNext(testCfg, curBlockTime, curBlockHeight)\n\t\tassert.Equal(t, 1*time.Microsecond, delay)\n\t}\n\tcurBlockTime = curBlockTime.Add(1 * time.Second)\n\tdelay = d.ComputeNext(testCfg, curBlockTime, curBlockHeight)\n\n\tassert.Equal(t, 1*time.Second, delay)\n}\n"
  },
  {
    "path": "consensus/cometbft/service/delay/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage delay\n\nimport \"fmt\"\n\n// BlockDelayFromBytesError is returned when the block delay can't be read from\n// the buffer.\ntype BlockDelayFromBytesError struct {\n\tfield string\n\terr   error\n}\n\nfunc (e *BlockDelayFromBytesError) Error() string {\n\treturn fmt.Sprintf(\"%s: %v\", e.field, e.err)\n}\n\nfunc (e *BlockDelayFromBytesError) Unwrap() error {\n\treturn e.err\n}\n"
  },
  {
    "path": "consensus/cometbft/service/encoding/encoding.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage encoding\n\nimport (\n\t\"fmt\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tdatypes \"github.com/berachain/beacon-kit/da/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n)\n\n// ExtractBlobsAndBlockFromRequest extracts the blobs and block from an ABCI\n// request.\nfunc ExtractBlobsAndBlockFromRequest(\n\treq ABCIRequest,\n\tbeaconBlkIndex uint,\n\tblobSidecarsIndex uint,\n\tforkVersion common.Version,\n) (*ctypes.SignedBeaconBlock, datypes.BlobSidecars, error) {\n\tif req == nil {\n\t\treturn nil, nil, ErrNilABCIRequest\n\t}\n\n\tblk, err := UnmarshalBeaconBlockFromABCIRequest(\n\t\treq.GetTxs(),\n\t\tbeaconBlkIndex,\n\t\tforkVersion,\n\t)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tblobs, err := UnmarshalBlobSidecarsFromABCIRequest(\n\t\treq.GetTxs(),\n\t\tblobSidecarsIndex,\n\t)\n\n\treturn blk, blobs, err\n}\n\n// UnmarshalBeaconBlockFromABCIRequest extracts a beacon block from an ABCI\n// request.\nfunc UnmarshalBeaconBlockFromABCIRequest(\n\ttxs [][]byte,\n\tbzIndex uint,\n\tforkVersion common.Version,\n) (*ctypes.SignedBeaconBlock, error) {\n\tvar signedBlk *ctypes.SignedBeaconBlock\n\tlenTxs := uint(len(txs))\n\n\t// Ensure there are transactions in the request and that the request is\n\t// valid.\n\tif txs == nil || lenTxs == 0 {\n\t\treturn signedBlk, ErrNoBeaconBlockInRequest\n\t}\n\tif bzIndex >= lenTxs {\n\t\treturn signedBlk, ErrBzIndexOutOfBounds\n\t}\n\n\t// Extract the beacon block from the ABCI request.\n\tblkBz := txs[bzIndex]\n\tif blkBz == nil {\n\t\treturn signedBlk, ErrNilBeaconBlockInRequest\n\t}\n\n\tblock, err := ctypes.NewEmptySignedBeaconBlockWithVersion(forkVersion)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"attempt at building block with wrong version %s: %w\", forkVersion, err)\n\t}\n\tif err = ssz.Unmarshal(blkBz, block); err != nil {\n\t\treturn nil, err\n\t}\n\treturn block, nil\n}\n\n// UnmarshalBlobSidecarsFromABCIRequest extracts blob sidecars from an ABCI\n// request.\nfunc UnmarshalBlobSidecarsFromABCIRequest(\n\ttxs [][]byte,\n\tbzIndex uint,\n) (datypes.BlobSidecars, error) {\n\tif len(txs) == 0 || bzIndex >= uint(len(txs)) {\n\t\treturn nil, ErrNoBlobSidecarInRequest\n\t}\n\n\tsidecarBz := txs[bzIndex]\n\tif sidecarBz == nil {\n\t\treturn nil, ErrNilBlobSidecarInRequest\n\t}\n\n\tvar sidecars datypes.BlobSidecars\n\tif err := ssz.Unmarshal(sidecarBz, &sidecars); err != nil {\n\t\treturn nil, err\n\t}\n\treturn sidecars, nil\n}\n"
  },
  {
    "path": "consensus/cometbft/service/encoding/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage encoding\n\nimport \"github.com/berachain/beacon-kit/errors\"\n\nvar (\n\t// ErrNilBeaconBlockInRequest is an error for when\n\t// the beacon block in an abci request is nil.\n\tErrNilBeaconBlockInRequest = errors.New(\"nil beacon block in abci request\")\n\n\t// ErrNoBeaconBlockInRequest is an error for when\n\t// there is no beacon block in an abci request.\n\tErrNoBeaconBlockInRequest = errors.New(\"no beacon block in abci request\")\n\n\t// ErrNilBlobSidecarInRequest is an error for when\n\t// the blob sidecar in an abci request is nil.\n\tErrNilBlobSidecarInRequest = errors.New(\"nil blob sidecar in abci request\")\n\n\t// ErrNoBlobSidecarInRequest is an error for when\n\t// there is no blob sidecar in an abci request.\n\tErrNoBlobSidecarInRequest = errors.New(\"no blob sidecar in abci request\")\n\n\t// ErrBzIndexOutOfBounds is an error for when the index\n\t// is out of bounds.\n\tErrBzIndexOutOfBounds = errors.New(\"bzIndex out of bounds\")\n\n\t// ErrNilABCIRequest is an error for when the abci request\n\t// is nil.\n\tErrNilABCIRequest = errors.New(\"nil abci request\")\n\n\t// ErrInvalidType is an error for when the type is invalid.\n\tErrInvalidType = errors.New(\"invalid type\")\n)\n"
  },
  {
    "path": "consensus/cometbft/service/encoding/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage encoding\n\nimport \"time\"\n\n// ABCIRequest represents the interface for an ABCI request.\ntype ABCIRequest interface {\n\t// GetTxs returns the transactions included in the request.\n\tGetTxs() [][]byte\n\tGetTime() time.Time\n}\n"
  },
  {
    "path": "consensus/cometbft/service/finalize_block.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage cometbft\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"time\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/cache\"\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/delay\"\n\tdatypes \"github.com/berachain/beacon-kit/da/types\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n\tcmtabci \"github.com/cometbft/cometbft/abci/types\"\n\t\"github.com/sourcegraph/conc/iter\"\n)\n\nfunc (s *Service) finalizeBlock(\n\tctx context.Context,\n\treq *cmtabci.FinalizeBlockRequest,\n) (*cmtabci.FinalizeBlockResponse, error) {\n\tif err := s.validateFinalizeBlockHeight(req); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Check whether currently block hash is already available. If so\n\t// we may speed up block finalization.\n\thash := string(req.Hash)\n\tswitch cached, err := s.cachedStates.GetCached(hash); {\n\tcase err == nil:\n\t\t// Block with height equal to initial height is special and we can't rely on its cache.\n\t\t// This is because Genesis state is cached but not committed (and purged from s.cachedStates)\n\t\t// We handle the case outside of this switch, via the s.Blockchain.FinalizeBlock below.\n\t\tif req.Height > s.initialHeight {\n\t\t\tif err = s.cachedStates.MarkAsFinal(hash); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed marking state as final, hash %s, height %d: %w\", hash, req.Height, err)\n\t\t\t}\n\n\t\t\tfinalState := cached.State\n\t\t\tvar (\n\t\t\t\tsignedBlk *ctypes.SignedBeaconBlock\n\t\t\t\tsidecars  datypes.BlobSidecars\n\t\t\t)\n\t\t\tsignedBlk, sidecars, err = s.Blockchain.ParseBeaconBlock(req)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"finalize block: failed parsing block: %w\", err)\n\t\t\t}\n\t\t\tblk := signedBlk.GetBeaconBlock()\n\n\t\t\tif err = s.Blockchain.FinalizeSidecars(\n\t\t\t\tfinalState.Context(),\n\t\t\t\treq.SyncingToHeight,\n\t\t\t\tblk,\n\t\t\t\tsidecars,\n\t\t\t); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed finalizing sidecars: %w\", err)\n\t\t\t}\n\t\t\tif err = s.Blockchain.PostFinalizeBlockOps(\n\t\t\t\tfinalState.Context(),\n\t\t\t\tblk,\n\t\t\t); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"finalize block: failed post finalize block ops: %w\", err)\n\t\t\t}\n\t\t\treturn s.calculateFinalizeBlockResponse(req, cached.ValUpdates)\n\t\t}\n\n\tcase errors.Is(err, cache.ErrStateNotFound):\n\t\t// this is a benign error, it just signal it's the first time we see the block being finalized\n\t\t// Keep processing below\n\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"failed checking cached state, hash %s, height %d: %w\", hash, req.Height, err)\n\t}\n\n\t// Block has not been cached already, as it happens when we block sync.\n\t// Normally we would directly process it but first block post initial height\n\t// needs special handling.\n\tvar finalState *cache.State\n\tcachedFinalHash, cachedFinalState, err := s.cachedStates.GetFinal()\n\tswitch {\n\tcase errors.Is(err, cache.ErrNoFinalState):\n\t\thash = string(req.Hash) // not necessary but clarifies intent\n\t\tfinalState = s.resetState(ctx)\n\n\tcase err == nil:\n\t\thash = cachedFinalHash\n\t\tfinalState = cachedFinalState\n\n\t\t// Preserve the CosmosSDK context while using the correct base ctx.\n\t\tfinalState.SetContext(finalState.Context().WithContext(ctx))\n\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"failed checking cached final state, hash %s, height %d: %w\", hash, req.Height, err)\n\t}\n\n\tvalUpdates, err := s.Blockchain.FinalizeBlock(finalState.Context(), req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Cache and mark state as final\n\ts.cachedStates.SetCached(hash, &cache.Element{\n\t\tState:      finalState,\n\t\tValUpdates: valUpdates,\n\t})\n\tif err = s.cachedStates.MarkAsFinal(hash); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed marking state as final, hash %s, height %d: %w\", hash, req.Height, err)\n\t}\n\n\treturn s.calculateFinalizeBlockResponse(req, valUpdates)\n}\n\nfunc (s *Service) nextBlockDelay(req *cmtabci.FinalizeBlockRequest) time.Duration {\n\t// c0. SBT is not enabled => use the old block delay.\n\tif s.cmtConsensusParams.Feature.SBTEnableHeight <= 0 {\n\t\treturn s.delayCfg.SbtConstBlockDelay()\n\t}\n\n\t// c1. current height < SBTEnableHeight => wait for the upgrade.\n\tif req.Height < s.cmtConsensusParams.Feature.SBTEnableHeight {\n\t\treturn s.delayCfg.SbtConstBlockDelay()\n\t}\n\n\t// c2. current height == SBTEnableHeight => initialize the block delay.\n\tif req.Height == s.cmtConsensusParams.Feature.SBTEnableHeight {\n\t\ts.blockDelay = &delay.BlockDelay{\n\t\t\tInitialTime:       req.Time,\n\t\t\tInitialHeight:     req.Height,\n\t\t\tPreviousBlockTime: req.Time,\n\t\t}\n\t\treturn s.delayCfg.SbtConstBlockDelay()\n\t}\n\n\t// c3. current height > SBTEnableHeight\n\t// c3.1\n\t//\n\t// The upgrade was successfully applied and the block delay is set.\n\tif s.blockDelay != nil {\n\t\tprevBlkTime := s.blockDelay.PreviousBlockTime // note it down before ComputeNext changes it\n\t\tdelay := s.blockDelay.ComputeNext(s.delayCfg, req.Time, req.Height)\n\t\ts.logger.Debug(\"Stable block time\",\n\t\t\t\"previous block time\", prevBlkTime.String(),\n\t\t\t\"current block time\", req.Time.String(),\n\t\t\t\"next delay\", delay.String(),\n\t\t)\n\t\treturn delay\n\t}\n\t// c3.2\n\t//\n\t// Looks like we've skipped SBTEnableHeight (probably restoring from the\n\t// snapshot) => panic.\n\tpanic(\n\t\tfmt.Sprintf(\n\t\t\t\"nil block delay at height %d past SBTEnableHeight %d. This is only possible w/ statesync, which is not supported by SBT atm\",\n\t\t\treq.Height,\n\t\t\ts.cmtConsensusParams.Feature.SBTEnableHeight,\n\t\t),\n\t)\n}\n\n// workingHash gets the apphash that will be finalized in commit.\n// These writes will be persisted to the root multi-store\n// (s.smGet.CommitMultiStore()) and flushed to disk  in the\n// Commit phase. This means when the ABCI client requests\n// Commit(), the application state transitions will be flushed\n// to disk and as a result, but we already have an application\n// Merkle root.\nfunc (s *Service) workingHash() []byte {\n\t// Write the FinalizeBlock state into branched storage and commit the\n\t// MultiStore. The write to the FinalizeBlock state writes all state\n\t// transitions to the root MultiStore (s.sm.GetCommitMultiStore())\n\t// so when Commit() is called it persists those values.\n\t_, finalState, err := s.cachedStates.GetFinal()\n\tif err != nil {\n\t\t// this is unexpected since workingHash is called only after\n\t\t// internalFinalizeBlock. Panic appeases nilaway.\n\t\tpanic(fmt.Errorf(\"workingHash: %w\", err))\n\t}\n\tfinalState.Write()\n\n\t// Get the hash of all writes in order to return the apphash to the comet in\n\t// finalizeBlock.\n\tcommitHash := s.sm.GetCommitMultiStore().WorkingHash()\n\ts.logger.Debug(\n\t\t\"hash of all writes\",\n\t\t\"workingHash\",\n\t\tfmt.Sprintf(\"%X\", commitHash),\n\t)\n\n\treturn commitHash\n}\n\nfunc (s *Service) validateFinalizeBlockHeight(req *cmtabci.FinalizeBlockRequest) error {\n\tif req.Height < 1 {\n\t\treturn fmt.Errorf(\n\t\t\t\"finalizeBlock at height %v: %w\",\n\t\t\treq.Height,\n\t\t\terrInvalidHeight,\n\t\t)\n\t}\n\n\tlastBlockHeight := s.lastBlockHeight()\n\n\t// expectedHeight holds the expected height to validate\n\tvar expectedHeight int64\n\tif lastBlockHeight == 0 && s.initialHeight > 1 {\n\t\t// In this case, we're validating the first block of the chain, i.e no\n\t\t// previous commit. The height we're expecting is the initial height.\n\t\texpectedHeight = s.initialHeight\n\t} else {\n\t\t// This case can mean two things:\n\t\t//\n\t\t// - Either there was already a previous commit in the store, in which\n\t\t// case we increment the version from there.\n\t\t// - Or there was no previous commit, in which case we start at version\n\t\t// 1.\n\t\texpectedHeight = lastBlockHeight + 1\n\t}\n\n\tif req.Height != expectedHeight {\n\t\treturn fmt.Errorf(\n\t\t\t\"invalid height: %d; expected: %d\",\n\t\t\treq.Height,\n\t\t\texpectedHeight,\n\t\t)\n\t}\n\n\treturn nil\n}\n\nfunc (s *Service) calculateFinalizeBlockResponse(\n\treq *cmtabci.FinalizeBlockRequest,\n\tvalUpdates transition.ValidatorUpdates,\n) (*cmtabci.FinalizeBlockResponse, error) {\n\t// Update Stable block time related data\n\tif s.cmtConsensusParams.Feature.SBTEnableHeight == 0 && req.Height == s.delayCfg.SbtConsensusUpdateHeight() {\n\t\ts.cmtConsensusParams.Feature.SBTEnableHeight = s.delayCfg.SbtConsensusEnableHeight()\n\t}\n\tnextBlockTime := s.nextBlockDelay(req)\n\n\t// This result format is expected by Comet. That actual execution will happen as part of the state transition.\n\ttxsLen := len(req.Txs)\n\ttxResults := make([]*cmtabci.ExecTxResult, txsLen)\n\tfor i := range txsLen {\n\t\t//nolint:mnd // its okay for now.\n\t\ttxResults[i] = &cmtabci.ExecTxResult{\n\t\t\tCodespace: \"sdk\",\n\t\t\tCode:      2,\n\t\t\tLog:       \"skip decoding\",\n\t\t\tGasWanted: 0,\n\t\t\tGasUsed:   0,\n\t\t}\n\t}\n\n\tformattedValUpdates, err := iter.MapErr(\n\t\tvalUpdates,\n\t\tconvertValidatorUpdate[cmtabci.ValidatorUpdate],\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// update sync to height once FinalizeBlock cannot err anymore.\n\ts.syncingToHeight = req.SyncingToHeight\n\n\tcp := s.cmtConsensusParams.ToProto()\n\treturn &cmtabci.FinalizeBlockResponse{\n\t\tTxResults:             txResults,\n\t\tValidatorUpdates:      formattedValUpdates,\n\t\tConsensusParamUpdates: &cp,\n\t\tAppHash:               s.workingHash(),\n\t\tNextBlockDelay:        nextBlockTime,\n\t}, nil\n}\n"
  },
  {
    "path": "consensus/cometbft/service/genesis.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage cometbft\n\nimport (\n\t\"bytes\"\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\t\"github.com/cometbft/cometbft/node\"\n\tgenutiltypes \"github.com/cosmos/cosmos-sdk/x/genutil/types\"\n)\n\n// DefaultGenesis returns the default genesis state for the application.\nfunc (s *Service) DefaultGenesis(spec chain.Spec) map[string]json.RawMessage {\n\t// Implement the default genesis state for the application.\n\t// This should return a map of module names to their respective default\n\t// genesis states.\n\tgen := make(map[string]json.RawMessage)\n\n\tdefaultGenesis := types.DefaultGenesis(spec.GenesisForkVersion())\n\n\tvar err error\n\tgen[\"beacon\"], err = json.Marshal(defaultGenesis)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn gen\n}\n\n// ValidateGenesis validates the provided genesis state.\nfunc (s *Service) ValidateGenesis(\n\tgenesisState map[string]json.RawMessage,\n) error {\n\t// Implemented the validation logic for the provided genesis state.\n\t// This should validate the genesis state for each module in the\n\t// application.\n\n\t// Validate that required modules are present in genesis. Currently,\n\t// only the beacon module is required.\n\tbeaconGenesisBz, ok := genesisState[\"beacon\"]\n\tif !ok {\n\t\treturn errors.New(\n\t\t\t\"beacon module genesis state is required but was not found\",\n\t\t)\n\t}\n\n\tbeaconGenesis := &types.Genesis{}\n\n\tif err := json.Unmarshal(beaconGenesisBz, &beaconGenesis); err != nil {\n\t\treturn fmt.Errorf(\n\t\t\t\"failed to unmarshal beacon genesis state: %w\",\n\t\t\terr,\n\t\t)\n\t}\n\n\tif !isValidForkVersion(beaconGenesis.GetForkVersion()) {\n\t\treturn fmt.Errorf(\"invalid fork version format: %s\",\n\t\t\tbeaconGenesis.ForkVersion,\n\t\t)\n\t}\n\n\tif err := validateDeposits(beaconGenesis.GetDeposits()); err != nil {\n\t\treturn fmt.Errorf(\"invalid deposits: %w\", err)\n\t}\n\n\tif err := validateExecutionHeader(\n\t\tbeaconGenesis.GetExecutionPayloadHeader(),\n\t); err != nil {\n\t\treturn fmt.Errorf(\"invalid execution payload header: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// validateDeposits performs validation of the provided deposits.\n// It ensures:\n// - At least one deposit is present\n// - No duplicate public keys\n// Returns an error with details if any validation fails.\nfunc validateDeposits(deposits []*types.Deposit) error {\n\tif len(deposits) == 0 {\n\t\treturn errors.New(\"at least one deposit is required\")\n\t}\n\n\tseenPubkeys := make(map[string]struct{})\n\n\t// In genesis, we have 1:1 mapping between deposits and validators. Hence,\n\t// we check for duplicate public key.\n\tfor i, deposit := range deposits {\n\t\tif deposit == nil {\n\t\t\treturn fmt.Errorf(\"deposit %d is nil\", i)\n\t\t}\n\n\t\t// Check for duplicate pubkeys\n\t\tpubkeyHex := hex.EncodeToString(deposit.Pubkey[:])\n\t\tif _, seen := seenPubkeys[pubkeyHex]; seen {\n\t\t\treturn fmt.Errorf(\"duplicate pubkey found in deposit %d\", i)\n\t\t}\n\t\tseenPubkeys[pubkeyHex] = struct{}{}\n\t}\n\n\treturn nil\n}\n\n// maxExtraDataSize defines the maximum allowed size in bytes for the ExtraData\n// field in the execution payload header.\nconst maxExtraDataSize = 32\n\n// validateExecutionHeader validates the provided execution payload header\n// for the genesis block.\nfunc validateExecutionHeader(header *types.ExecutionPayloadHeader) error {\n\tif header == nil {\n\t\treturn errors.New(\"execution payload header cannot be nil\")\n\t}\n\n\t// Check block number to be 0\n\tif header.Number != 0 {\n\t\treturn errors.New(\"block number must be 0 for genesis block\")\n\t}\n\n\tif header.GasLimit == 0 {\n\t\treturn errors.New(\"gas limit cannot be zero\")\n\t}\n\n\tif header.GasUsed != 0 {\n\t\treturn errors.New(\"gas used must be zero for genesis block\")\n\t}\n\n\tif header.BaseFeePerGas == nil {\n\t\treturn errors.New(\"base fee per gas cannot be nil\")\n\t}\n\n\t// Additional Deneb-specific validations for blob gas\n\tif header.BlobGasUsed != 0 {\n\t\treturn errors.New(\n\t\t\t\"blob gas used must be zero for genesis block\",\n\t\t)\n\t}\n\tif header.ExcessBlobGas != 0 {\n\t\treturn errors.New(\n\t\t\t\"excess blob gas must be zero for genesis block\",\n\t\t)\n\t}\n\n\tif header.BlobGasUsed > header.GasLimit {\n\t\treturn fmt.Errorf(\"blob gas used (%d) exceeds gas limit (%d)\",\n\t\t\theader.BlobGasUsed, header.GasLimit,\n\t\t)\n\t}\n\n\t// Validate hash fields are not zero\n\tzeroHash := common.ExecutionHash{}\n\temptyTrieRoot := common.Bytes32(\n\t\tcommon.NewExecutionHashFromHex(\n\t\t\t\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\n\t\t))\n\n\t// For genesis block (when block number is 0), ParentHash must be zero\n\tif !bytes.Equal(header.ParentHash[:], zeroHash[:]) {\n\t\treturn errors.New(\"parent hash must be zero for genesis block\")\n\t}\n\n\tif header.ReceiptsRoot != emptyTrieRoot {\n\t\treturn errors.New(\n\t\t\t\"receipts root must be empty trie root for genesis block\",\n\t\t)\n\t}\n\n\tif bytes.Equal(header.BlockHash[:], zeroHash[:]) {\n\t\treturn errors.New(\"block hash cannot be zero\")\n\t}\n\n\t// Validate prevRandao is zero for genesis\n\tvar zeroBytes32 common.Bytes32\n\tif !bytes.Equal(header.Random[:], zeroBytes32[:]) {\n\t\treturn errors.New(\"prevRandao must be zero for genesis block\")\n\t}\n\n\t// Fee recipient can be zero in genesis block\n\t// No need to validate fee recipient for genesis\n\n\t// We don't validate LogsBloom as it can legitimately be\n\t// all zeros in a genesis block or in blocks with no logs\n\n\t// Extra data length check (max 32 bytes)\n\tif len(header.ExtraData) > maxExtraDataSize {\n\t\treturn fmt.Errorf(\n\t\t\t\"extra data too long: got %d bytes, max 32 bytes\",\n\t\t\tlen(header.ExtraData),\n\t\t)\n\t}\n\n\treturn nil\n}\n\nconst expectedHexLength = 8\n\n// isValidForkVersion returns true if the provided fork version is valid.\n// A valid fork version must:\n// - Start with \"0x\"\n// - Be followed by exactly 8 hexadecimal characters.\nfunc isValidForkVersion(forkVersion common.Version) bool {\n\tforkVersionStr := forkVersion.String()\n\tif !strings.HasPrefix(forkVersionStr, \"0x\") {\n\t\treturn false\n\t}\n\n\t// Remove \"0x\" prefix and verify remaining characters\n\thexPart := strings.TrimPrefix(forkVersionStr, \"0x\")\n\n\t// Should have exactly 8 characters after 0x prefix\n\tif len(hexPart) != expectedHexLength {\n\t\treturn false\n\t}\n\n\t// Verify it's a valid hex number\n\t_, err := hex.DecodeString(hexPart)\n\treturn err == nil\n}\n\n// GetGenDocProvider returns a function which returns the genesis doc from the\n// genesis file.\nfunc GetGenDocProvider(\n\tcfg *cmtcfg.Config,\n) func() (node.ChecksummedGenesisDoc, error) {\n\treturn func() (node.ChecksummedGenesisDoc, error) {\n\t\tappGenesis, err := genutiltypes.AppGenesisFromFile(cfg.GenesisFile())\n\t\tif err != nil {\n\t\t\treturn node.ChecksummedGenesisDoc{\n\t\t\t\tSha256Checksum: []byte{},\n\t\t\t}, err\n\t\t}\n\n\t\tgen, err := appGenesis.ToGenesisDoc()\n\t\tif err != nil {\n\t\t\treturn node.ChecksummedGenesisDoc{\n\t\t\t\tSha256Checksum: []byte{},\n\t\t\t}, err\n\t\t}\n\t\tgenbz, err := gen.AppState.MarshalJSON()\n\t\tif err != nil {\n\t\t\treturn node.ChecksummedGenesisDoc{\n\t\t\t\tSha256Checksum: []byte{},\n\t\t\t}, err\n\t\t}\n\n\t\tbz, err := json.Marshal(genbz)\n\t\tif err != nil {\n\t\t\treturn node.ChecksummedGenesisDoc{\n\t\t\t\tSha256Checksum: []byte{},\n\t\t\t}, err\n\t\t}\n\t\tsum := sha256.Sum256(bz)\n\n\t\treturn node.ChecksummedGenesisDoc{\n\t\t\tGenesisDoc:     gen,\n\t\t\tSha256Checksum: sum[:],\n\t\t}, nil\n\t}\n}\n"
  },
  {
    "path": "consensus/cometbft/service/init_chain.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage cometbft\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/cache\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n\tcmtabci \"github.com/cometbft/cometbft/abci/types\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n\t\"github.com/sourcegraph/conc/iter\"\n)\n\nfunc (s *Service) initChain(\n\tctx context.Context,\n\treq *cmtabci.InitChainRequest,\n) (*cmtabci.InitChainResponse, error) {\n\tif req.ChainId != s.chainID {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"invalid chain-id on InitChain; expected: %s, got: %s\",\n\t\t\ts.chainID,\n\t\t\treq.ChainId,\n\t\t)\n\t}\n\n\t// Enforce that request validators is zero. This is because Berachain derives the validators directly from\n\t// deposits in the genesis file and disregards the validators in genesis file, which is what Comet uses.\n\tif len(req.Validators) != 0 {\n\t\treturn nil, fmt.Errorf(\"expected no validators in initChain request but got %d\", len(req.Validators))\n\t}\n\n\tvar genesisState map[string]json.RawMessage\n\tif err := json.Unmarshal(req.AppStateBytes, &genesisState); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to unmarshal genesis state: %w\", err)\n\t}\n\t// Validate the genesis state.\n\terr := s.ValidateGenesis(genesisState)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ts.logger.Info(\n\t\t\"InitChain\",\n\t\t\"initialHeight\",\n\t\treq.InitialHeight,\n\t\t\"chainID\",\n\t\treq.ChainId,\n\t)\n\n\t// Set the initial height, which will be used to determine if we are\n\t// proposing\n\t// or processing the first block or not.\n\ts.initialHeight = req.InitialHeight\n\tif s.initialHeight == 0 {\n\t\ts.initialHeight = 1\n\t}\n\n\t// if req.InitialHeight is > 1, then we set the initial version on all\n\t// stores\n\tif req.InitialHeight > 1 {\n\t\tif err = s.sm.GetCommitMultiStore().\n\t\t\tSetInitialVersion(req.InitialHeight); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tgenesisHash := \"\"\n\tgenesisFinalState := s.resetState(ctx)\n\ts.cachedStates.SetCached(genesisHash, &cache.Element{\n\t\tState: genesisFinalState,\n\t})\n\tif err = s.cachedStates.MarkAsFinal(genesisHash); err != nil {\n\t\treturn nil, err\n\t}\n\n\t//nolint:contextcheck // ctx already passed via resetState\n\tresValidators, err := s.initChainer(\n\t\tgenesisFinalState.Context(),\n\t\treq.AppStateBytes,\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// NOTE: We don't commit, but FinalizeBlock for block InitialHeight starts\n\t// from\n\t// this FinalizeBlockState.\n\treturn &cmtabci.InitChainResponse{\n\t\tConsensusParams: req.ConsensusParams,\n\t\tValidators:      resValidators,\n\t\tAppHash:         s.sm.GetCommitMultiStore().LastCommitID().Hash,\n\t}, nil\n}\n\n// InitChainer initializes the chain.\nfunc (s *Service) initChainer(\n\tctx sdk.Context,\n\tappStateBytes []byte,\n) ([]cmtabci.ValidatorUpdate, error) {\n\tvar genesisState map[string]json.RawMessage\n\tif err := json.Unmarshal(appStateBytes, &genesisState); err != nil {\n\t\treturn nil, err\n\t}\n\n\tdata := []byte(genesisState[\"beacon\"])\n\tvalUpdates, err := s.Blockchain.ProcessGenesisData(ctx, data)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn iter.MapErr(\n\t\tvalUpdates,\n\t\tconvertValidatorUpdate[cmtabci.ValidatorUpdate],\n\t)\n}\n"
  },
  {
    "path": "consensus/cometbft/service/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage cometbft\n\nimport (\n\t\"time\"\n)\n\n// TelemetrySink is an interface for sending metrics to a telemetry backend.\ntype TelemetrySink interface {\n\t// IncrementCounter increments a counter for the given key.\n\tIncrementCounter(key string, args ...string)\n\t// MeasureSince measures the time since the given time.\n\tMeasureSince(key string, start time.Time, args ...string)\n\t// SetGauge sets a gauge metric to the specified value.\n\tSetGauge(key string, value int64, args ...string)\n}\n"
  },
  {
    "path": "consensus/cometbft/service/log/cmt_logger.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage log\n\nimport (\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\tcmtlog \"github.com/cometbft/cometbft/libs/log\"\n)\n\ntype CometLogger struct {\n\tlog.AdvancedLogger[*phuslu.Logger]\n}\n\nfunc WrapCometLogger(logger *phuslu.Logger) *CometLogger {\n\treturn &CometLogger{\n\t\tAdvancedLogger: logger,\n\t}\n}\n\nfunc (l *CometLogger) With(keyVals ...any) cmtlog.Logger {\n\treturn &CometLogger{\n\t\tAdvancedLogger: l.AdvancedLogger.With(keyVals...),\n\t}\n}\n\nfunc (l *CometLogger) Impl() any {\n\treturn l.AdvancedLogger\n}\n"
  },
  {
    "path": "consensus/cometbft/service/log/sdk_logger.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage log\n\nimport (\n\tsdklog \"cosmossdk.io/log\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n)\n\ntype SDKLogger struct {\n\tlog.AdvancedLogger[*phuslu.Logger]\n}\n\nfunc WrapSDKLogger(logger *phuslu.Logger) *SDKLogger {\n\treturn &SDKLogger{\n\t\tAdvancedLogger: logger,\n\t}\n}\n\nfunc (l *SDKLogger) With(keyVals ...any) sdklog.Logger {\n\treturn &SDKLogger{\n\t\tAdvancedLogger: l.AdvancedLogger.With(keyVals...),\n\t}\n}\n\nfunc (l *SDKLogger) Impl() any {\n\treturn l.AdvancedLogger\n}\n"
  },
  {
    "path": "consensus/cometbft/service/node_api_support.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage cometbft\n\nimport (\n\t\"fmt\"\n\n\terrorsmod \"cosmossdk.io/errors\"\n\tservercmtlog \"github.com/berachain/beacon-kit/consensus/cometbft/service/log\"\n\t\"github.com/berachain/beacon-kit/node-core/types\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n\tsdkerrors \"github.com/cosmos/cosmos-sdk/types/errors\"\n)\n\nvar (\n\tErrAppNotReady = fmt.Errorf(\"%s is not ready; please wait for first block\", AppName)\n\n\t_ types.ConsensusService = (*Service)(nil)\n)\n\n// IsAppReady is used mainly by node-apis to understand the chain state,\n// before loading data\nfunc (s *Service) IsAppReady() error {\n\t// use custom query multi-store if provided\n\tlastBlockHeight := s.sm.GetCommitMultiStore().LatestVersion()\n\tif lastBlockHeight == 0 {\n\t\treturn ErrAppNotReady\n\t}\n\treturn nil\n}\n\n// CreateQueryContext creates a new sdk.Context for a query, taking as args\n// the block height and whether the query needs a proof or not.\nfunc (s *Service) CreateQueryContext(\n\theight int64,\n\tprove bool,\n) (sdk.Context, error) {\n\t// use custom query multi-store if provided\n\tlastBlockHeight := s.sm.GetCommitMultiStore().LatestVersion()\n\tif lastBlockHeight == 0 {\n\t\treturn sdk.Context{}, ErrAppNotReady\n\t}\n\n\tif height > lastBlockHeight {\n\t\treturn sdk.Context{},\n\t\t\terrorsmod.Wrap(\n\t\t\t\tsdkerrors.ErrInvalidHeight,\n\t\t\t\t\"cannot query with height in the future; please provide a valid height\",\n\t\t\t)\n\t}\n\n\t// when a client did not provide a query height, manually inject the latest\n\tif height == 0 {\n\t\theight = lastBlockHeight\n\t}\n\n\tif height <= 1 && prove {\n\t\treturn sdk.Context{},\n\t\t\terrorsmod.Wrap(\n\t\t\t\tsdkerrors.ErrInvalidRequest,\n\t\t\t\t\"cannot query with proof when height <= 1; please provide a valid height\",\n\t\t\t)\n\t}\n\n\tcacheMS, err := s.sm.GetCommitMultiStore().CacheMultiStoreWithVersion(height)\n\tif err != nil {\n\t\treturn sdk.Context{},\n\t\t\terrorsmod.Wrapf(\n\t\t\t\tsdkerrors.ErrNotFound,\n\t\t\t\t\"failed to load state at height %d; %s (latest height: %d)\",\n\t\t\t\theight,\n\t\t\t\terr,\n\t\t\t\tlastBlockHeight,\n\t\t\t)\n\t}\n\n\treturn sdk.NewContext(\n\t\tcacheMS,\n\t\ttrue,\n\t\tservercmtlog.WrapSDKLogger(s.logger),\n\t), nil\n}\n\nfunc (s *Service) GetSyncData() (int64, int64) {\n\treturn s.lastBlockHeight(), s.syncingToHeight\n}\n"
  },
  {
    "path": "consensus/cometbft/service/options.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage cometbft\n\nimport (\n\t\"fmt\"\n\n\tpruningtypes \"cosmossdk.io/store/pruning/types\"\n\tstoretypes \"cosmossdk.io/store/types\"\n)\n\n// File for storing in-package cometbft optional functions,\n// for options that need access to non-exported fields of the Service\n\n// SetPruning sets a pruning option on the multistore associated with the s.\nfunc SetPruning(opts pruningtypes.PruningOptions) func(*Service) {\n\treturn func(bs *Service) {\n\t\tif opts.Strategy == pruningtypes.PruningNothing {\n\t\t\tbs.logger.Warn(\n\t\t\t\t\"enable state pruning to reduce memory footprint considerably\",\n\t\t\t\t\"strategy\", pruningtypes.PruningOptionNothing,\n\t\t\t\t\"recommended strategies\", fmt.Sprintf(\"%s or %s\",\n\t\t\t\t\tpruningtypes.PruningOptionEverything,\n\t\t\t\t\tpruningtypes.PruningOptionDefault,\n\t\t\t\t),\n\t\t\t)\n\t\t}\n\n\t\tbs.sm.GetCommitMultiStore().SetPruning(opts)\n\t}\n}\n\n// SetMinRetainBlocks returns a Service option function that sets the minimum\n// block retention height value when determining which heights to prune during\n// ABCI Commit.\nfunc SetMinRetainBlocks(minRetainBlocks uint64) func(*Service) {\n\treturn func(bs *Service) { bs.setMinRetainBlocks(minRetainBlocks) }\n}\n\n// SetIAVLCacheSize provides a Service option function that sets the size of\n// IAVL cache.\nfunc SetIAVLCacheSize(size int) func(*Service) {\n\treturn func(bs *Service) {\n\t\tbs.sm.GetCommitMultiStore().SetIAVLCacheSize(size)\n\t}\n}\n\n// SetIAVLDisableFastNode enables(false)/disables(true) fast node usage from the\n// IAVL store.\nfunc SetIAVLDisableFastNode(disable bool) func(*Service) {\n\treturn func(bs *Service) {\n\t\tbs.sm.GetCommitMultiStore().SetIAVLDisableFastNode(disable)\n\t}\n}\n\n// SetInterBlockCache provides a Service option function that sets the\n// inter-block cache.\nfunc SetInterBlockCache(cache storetypes.MultiStorePersistentCache) func(*Service) {\n\treturn func(s *Service) {\n\t\ts.setInterBlockCache(cache)\n\t}\n}\n\n// SetChainID sets the chain ID in cometbft.\nfunc SetChainID(chainID string) func(*Service) {\n\treturn func(s *Service) { s.chainID = chainID }\n}\n"
  },
  {
    "path": "consensus/cometbft/service/prepare_proposal.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage cometbft\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/consensus/types\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tcmtabci \"github.com/cometbft/cometbft/abci/types\"\n)\n\nfunc (s *Service) prepareProposal(\n\tctx context.Context,\n\treq *cmtabci.PrepareProposalRequest,\n) (*cmtabci.PrepareProposalResponse, error) {\n\tstartTime := time.Now()\n\tdefer s.telemetrySink.MeasureSince(\n\t\t\"beacon_kit.runtime.prepare_proposal_duration\", startTime)\n\n\t// CometBFT must never call PrepareProposal with a height of 0.\n\tif req.Height < 1 {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"prepareProposal at height %v: %w\",\n\t\t\treq.Height,\n\t\t\terrInvalidHeight,\n\t\t)\n\t}\n\n\t// prepareProposalState is used for PrepareProposal, which is set based on\n\t// the previous block's state. This state is never committed. In case of\n\t// multiple consensus rounds, the state is always reset to the previous\n\t// block's state. Always reset state given that PrepareProposal can timeout\n\t// and be called again in a subsequent round.\n\tprepareProposalState := s.resetState(ctx)\n\t//nolint:contextcheck // ctx already passed via resetState\n\tprepareProposalState.SetContext(\n\t\ts.getContextForProposal(\n\t\t\tprepareProposalState.Context(),\n\t\t\treq.Height,\n\t\t),\n\t)\n\n\tslotData := types.NewSlotData(\n\t\tmath.Slot(req.GetHeight()), // #nosec G115\n\t\tnil,                        // no attestations\n\t\tnil,                        // no slashings\n\t\treq.GetProposerAddress(),\n\t\treq.GetTime(),\n\t)\n\n\t//nolint:contextcheck // ctx already passed via resetState\n\tblkBz, sidecarsBz, err := s.BlockBuilder.BuildBlockAndSidecars(\n\t\tprepareProposalState.Context(),\n\t\tslotData,\n\t)\n\tif err != nil {\n\t\ts.logger.Error(\n\t\t\t\"failed to prepare proposal\",\n\t\t\t\"height\", req.Height,\n\t\t\t\"time\", req.Time,\n\t\t\t\"err\", err,\n\t\t)\n\t\treturn &cmtabci.PrepareProposalResponse{Txs: [][]byte{}}, nil\n\t}\n\n\treturn &cmtabci.PrepareProposalResponse{\n\t\tTxs: [][]byte{blkBz, sidecarsBz},\n\t}, nil\n}\n"
  },
  {
    "path": "consensus/cometbft/service/process_proposal.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage cometbft\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/cache\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tcmtabci \"github.com/cometbft/cometbft/abci/types\"\n)\n\nfunc (s *Service) processProposal(\n\tctx context.Context,\n\treq *cmtabci.ProcessProposalRequest,\n) (*cmtabci.ProcessProposalResponse, error) {\n\tstartTime := time.Now()\n\tdefer s.telemetrySink.MeasureSince(\n\t\t\"beacon_kit.runtime.process_proposal_duration\", startTime)\n\n\t// CometBFT must never call ProcessProposal with a height of 0.\n\tif req.Height < 1 {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"processProposal at height %v: %w\",\n\t\t\treq.Height,\n\t\t\terrInvalidHeight,\n\t\t)\n\t}\n\n\t// processProposalState is used for ProcessProposal, which is set based on\n\t// the previous block's state. This state is never committed. In case of\n\t// multiple consensus rounds, the state is always reset to the previous\n\t// block's state.\n\tprocessProposalState := s.resetState(ctx)\n\n\t//nolint:contextcheck // ctx already passed via resetState\n\tprocessProposalState.SetContext(\n\t\ts.getContextForProposal(\n\t\t\tprocessProposalState.Context(),\n\t\t\treq.Height,\n\t\t),\n\t)\n\n\t// errors to consensus indicate that the node was not able to understand\n\t// whether the block was valid or not. Viceversa, we signal that a block\n\t// is invalid by its status, but we do return nil error in such a case.\n\tvalUpdates, err := s.Blockchain.ProcessProposal(\n\t\tprocessProposalState.Context(),\n\t\treq,\n\t\ts.nodeAddress[:],\n\t)\n\tif err != nil {\n\t\tstatus := cmtabci.PROCESS_PROPOSAL_STATUS_REJECT\n\t\ts.logger.Error(\n\t\t\t\"failed to process proposal\",\n\t\t\t\"height\", req.Height,\n\t\t\t\"time\", req.Time,\n\t\t\t\"hash\", fmt.Sprintf(\"%X\", req.Hash),\n\t\t\t\"err\", err,\n\t\t)\n\t\treturn &cmtabci.ProcessProposalResponse{Status: status}, nil\n\t}\n\n\t// We must not cache execution of the first block post initialHeight\n\t// because its state must be handled in a different way\n\t// TODO: before Stable block time activation we keep caching off\n\t// to make sure chain does not get faster. Once activated, we can\n\t// active as if cache was always active.\n\tif cache.IsStateCachingActive(s.delayCfg, math.Slot(req.Height)) {\n\t\tstateHash := string(req.Hash)\n\t\ttoCache := &cache.Element{\n\t\t\tState:      processProposalState,\n\t\t\tValUpdates: valUpdates,\n\t\t}\n\t\ts.cachedStates.SetCached(stateHash, toCache)\n\t}\n\tstatus := cmtabci.PROCESS_PROPOSAL_STATUS_ACCEPT\n\treturn &cmtabci.ProcessProposalResponse{Status: status}, nil\n}\n"
  },
  {
    "path": "consensus/cometbft/service/service.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage cometbft\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\n\tstoretypes \"cosmossdk.io/store/types\"\n\t\"github.com/berachain/beacon-kit/beacon/blockchain\"\n\t\"github.com/berachain/beacon-kit/beacon/validator\"\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/cache\"\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/delay\"\n\tservercmtlog \"github.com/berachain/beacon-kit/consensus/cometbft/service/log\"\n\tstatem \"github.com/berachain/beacon-kit/consensus/cometbft/service/state\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n\t\"github.com/berachain/beacon-kit/storage\"\n\tabci \"github.com/cometbft/cometbft/api/cometbft/abci/v1\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\tcmtcrypto \"github.com/cometbft/cometbft/crypto\"\n\t\"github.com/cometbft/cometbft/node\"\n\t\"github.com/cometbft/cometbft/p2p\"\n\tpvm \"github.com/cometbft/cometbft/privval\"\n\t\"github.com/cometbft/cometbft/proxy\"\n\tcmttypes \"github.com/cometbft/cometbft/types\"\n\tdbm \"github.com/cosmos/cosmos-db\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n)\n\nconst (\n\tinitialAppVersion uint64 = 0\n\tAppName           string = \"beacond\"\n\tmaxCachedStates          = 10\n)\n\ntype Service struct {\n\tnode        *node.Node\n\tnodeAddress cmtcrypto.Address\n\n\tdelayCfg delay.ConfigGetter\n\n\t// cmtConsensusParams are part of the blockchain state and\n\t// are agreed upon by all validators in the network.\n\tcmtConsensusParams *cmttypes.ConsensusParams\n\n\t// cmtCfg are node-specific settings that influence how\n\t// the consensus engine operates on a particular node.\n\t// Loaded from config file (config.toml), not part of state.\n\tcmtCfg *cmtcfg.Config\n\n\ttelemetrySink TelemetrySink\n\n\tlogger       *phuslu.Logger\n\tsm           *statem.Manager\n\tBlockchain   blockchain.BlockchainI\n\tBlockBuilder validator.BlockBuilderI\n\n\t// cachedStates tracks in memory the post block states\n\t// of blocks which were successfully verified. It allows\n\t// finalizing without re-execution\n\tcachedStates cache.States\n\n\tinterBlockCache storetypes.MultiStorePersistentCache\n\n\t// initialHeight is the initial height at which we start the node\n\tinitialHeight   int64\n\tminRetainBlocks uint64\n\n\tchainID string\n\n\t// ctx is the context passed in for the service. CometBFT currently does\n\t// not support context usage. It passes \"context.TODO()\" to apps that\n\t// implement the ABCI++ interface, and does not provide a context that is\n\t// a child context of the one the node originally provides to comet.\n\t// Thus the app cannot tell when the context as been cancelled or not.\n\t// TODO: We must use this as a workaround for now until CometBFT properly\n\t// generates contexts that inherit from the parent context we provide.\n\tctx context.Context\n\n\t// calculates block delay for the next block\n\t//\n\t// NOTE: may be nil until either InitChain or FinalizeBlock is called.\n\tblockDelay *delay.BlockDelay\n\n\t// syncingToHeight is a helper to track node sync state and support node-apis.\n\tsyncingToHeight int64\n}\n\nfunc NewService(\n\tlogger *phuslu.Logger,\n\tdb dbm.DB,\n\tblockchain blockchain.BlockchainI,\n\tblockBuilder validator.BlockBuilderI,\n\tcs chain.Spec,\n\tcmtCfg *cmtcfg.Config,\n\ttelemetrySink TelemetrySink,\n\toptions ...func(*Service),\n) *Service {\n\tif err := validateConfig(cmtCfg); err != nil {\n\t\tpanic(err)\n\t}\n\tcmtConsensusParams, err := extractConsensusParams(cmtCfg)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// some configs, while legit, causes issues if applied\n\t// carelessly. We warn about them\n\tlog := servercmtlog.WrapSDKLogger(logger)\n\twarnAboutConfigs(cmtCfg, log)\n\n\ts := &Service{\n\t\tlogger:             logger,\n\t\tsm:                 statem.NewManager(db, log),\n\t\tBlockchain:         blockchain,\n\t\tBlockBuilder:       blockBuilder,\n\t\tdelayCfg:           cs,\n\t\tcmtConsensusParams: cmtConsensusParams,\n\t\tcmtCfg:             cmtCfg,\n\t\ttelemetrySink:      telemetrySink,\n\t\tcachedStates:       cache.New(maxCachedStates, telemetrySink),\n\t}\n\n\ts.MountStore(storage.StoreKey, storetypes.StoreTypeIAVL)\n\n\tfor _, option := range options {\n\t\toption(s)\n\t}\n\n\tif s.interBlockCache != nil {\n\t\ts.sm.GetCommitMultiStore().SetInterBlockCache(s.interBlockCache)\n\t}\n\n\t// Load latest height, once all stores have been set\n\tif err = s.sm.LoadLatestVersion(); err != nil {\n\t\tpanic(fmt.Errorf(\"failed loading latest version: %w\", err))\n\t}\n\n\tlastBlockHeight := s.lastBlockHeight()\n\ts.syncingToHeight = lastBlockHeight\n\n\t// Make sure that SBT consensus parameters are duly set when the node restart.\n\t// Note that we can't rely on genesis.json having these parameters set right\n\t// because we introduced stable block time post (mainnet) genesis.\n\tif lastBlockHeight >= s.delayCfg.SbtConsensusUpdateHeight() {\n\t\ts.cmtConsensusParams.Feature.SBTEnableHeight = s.delayCfg.SbtConsensusEnableHeight()\n\t}\n\n\t// Load block delay.\n\t//\n\t// If not found, we will initialize it in FinalizeBlock once SBTEnableHeight\n\t// is reached.\n\tbz, err := s.sm.LoadBlockDelay()\n\tif err != nil {\n\t\tpanic(fmt.Errorf(\"failed loading block delay: %w\", err))\n\t}\n\tif bz != nil {\n\t\ts.blockDelay, err = delay.FromBytes(bz)\n\t\tif err != nil {\n\t\t\tpanic(fmt.Errorf(\"failed decoding block delay: %w\", err))\n\t\t}\n\t}\n\n\t// Clean up any orphaned blob sidecars from incomplete block finalization.\n\tif err = s.Blockchain.PruneOrphanedBlobs(lastBlockHeight); err != nil {\n\t\tpanic(fmt.Errorf(\"failed pruning orphaned blobs: %w\", err))\n\t}\n\n\treturn s\n}\n\n// TODO: Move nodeKey into being created within the function.\nfunc (s *Service) Start(\n\tctx context.Context,\n) error {\n\tcfg := s.cmtCfg\n\tnodeKey, err := p2p.LoadOrGenNodeKey(cfg.NodeKeyFile())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tprivVal, err := pvm.LoadOrGenFilePV(\n\t\tcfg.PrivValidatorKeyFile(),\n\t\tcfg.PrivValidatorStateFile(),\n\t\tnil,\n\t)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ts.ResetAppCtx(ctx)\n\ts.node, err = node.NewNode(\n\t\tctx,\n\t\tcfg,\n\t\tprivVal,\n\t\tnodeKey,\n\t\tproxy.NewLocalClientCreator(s),\n\t\tGetGenDocProvider(cfg),\n\t\tcmtcfg.DefaultDBProvider,\n\t\tnode.DefaultMetricsProvider(cfg.Instrumentation),\n\t\tservercmtlog.WrapCometLogger(s.logger),\n\t)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tpubKey, errPk := s.node.PrivValidator().GetPubKey()\n\tif errPk != nil {\n\t\treturn fmt.Errorf(\"failed retrieving pub key: %w\", err)\n\t}\n\ts.nodeAddress = pubKey.Address()\n\n\tstarted := make(chan struct{})\n\n\t// we start the node in a goroutine since calling Start() can block if genesis\n\t// time is in the future causing us not to handle signals gracefully.\n\tgo func() {\n\t\terr = s.node.Start()\n\t\tstarted <- struct{}{}\n\t}()\n\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn ctx.Err()\n\tcase <-started:\n\t}\n\n\tclose(started)\n\n\treturn err\n}\n\nfunc (s *Service) Stop() error {\n\tvar errs []error\n\n\tif s.node != nil && s.node.IsRunning() {\n\t\ts.logger.Info(\"Stopping CometBFT Node\")\n\t\terr := s.node.Stop()\n\t\tif err != nil {\n\t\t\terrs = append(errs, fmt.Errorf(\"failed to stop CometBFT Node: %w\", err))\n\t\t}\n\t\ts.logger.Info(\"Waiting for CometBFT Node to stop\")\n\t\ts.node.Wait()\n\t}\n\n\ts.logger.Info(\"Closing application.db\")\n\tif err := s.sm.Close(); err != nil {\n\t\terrs = append(errs, fmt.Errorf(\"failed to close application.id: %w\", err))\n\t}\n\treturn errors.Join(errs...)\n}\n\n// ResetAppCtx sets the app ctx for the service. This is used\n// primarily for the mock service.\nfunc (s *Service) ResetAppCtx(ctx context.Context) {\n\ts.ctx = ctx\n}\n\n// SetNodeAddress sets the node address for the service. This is used\n// primarily for the mock service.\nfunc (s *Service) SetNodeAddress(addr cmtcrypto.Address) {\n\ts.nodeAddress = addr\n}\n\n// Name returns the name of the cometbft.\nfunc (s *Service) Name() string {\n\treturn AppName\n}\n\n// CommitMultiStore returns the CommitMultiStore of the cometbft.\n// This needs to be exposed because it is used by commands like Rollback.\nfunc (s *Service) CommitMultiStore() storetypes.CommitMultiStore {\n\treturn s.sm.GetCommitMultiStore()\n}\n\n// GetBlock returns the CometBFT block at the given height.\nfunc (s *Service) GetBlock(height int64) *cmttypes.Block {\n\tif s.node == nil {\n\t\treturn nil\n\t}\n\tblock, _ := s.node.BlockStore().LoadBlock(height)\n\treturn block\n}\n\n// GetSignedHeader returns the CometBFT signed header (header + commit) at the given height.\nfunc (s *Service) GetSignedHeader(height int64) *cmttypes.SignedHeader {\n\tif s.node == nil {\n\t\treturn nil\n\t}\n\tblock, _ := s.node.BlockStore().LoadBlock(height)\n\tif block == nil {\n\t\treturn nil\n\t}\n\tcommit := s.node.BlockStore().LoadBlockCommit(height)\n\tif commit == nil {\n\t\treturn nil\n\t}\n\treturn &cmttypes.SignedHeader{\n\t\tHeader: &block.Header,\n\t\tCommit: commit,\n\t}\n}\n\n// AppVersion returns the application's protocol version.\nfunc (s *Service) AppVersion(_ context.Context) (uint64, error) {\n\treturn s.appVersion()\n}\n\nfunc (s *Service) appVersion() (uint64, error) {\n\tcp := s.cmtConsensusParams.ToProto()\n\treturn cp.Version.App, nil\n}\n\n// MountStore mounts a store to the provided key in the Service multistore,\n// using the default DB.\nfunc (s *Service) MountStore(\n\tkey storetypes.StoreKey,\n\ttyp storetypes.StoreType,\n) {\n\ts.sm.GetCommitMultiStore().MountStoreWithDB(key, typ, nil)\n}\n\n// LastBlockHeight returns the last committed block height.\nfunc (s *Service) lastBlockHeight() int64 {\n\treturn s.sm.GetCommitMultiStore().LastCommitID().Version\n}\n\nfunc (s *Service) setMinRetainBlocks(minRetainBlocks uint64) {\n\ts.minRetainBlocks = minRetainBlocks\n}\n\nfunc (s *Service) setInterBlockCache(\n\tcache storetypes.MultiStorePersistentCache,\n) {\n\ts.interBlockCache = cache\n}\n\n// resetState provides a fresh state which can be used to reset\n// prepareProposal/processProposal/finalizeBlock State.\n// A state is explicitly returned to avoid false positives from\n// nilaway tool.\nfunc (s *Service) resetState(ctx context.Context) *cache.State {\n\tms := s.sm.GetCommitMultiStore().CacheMultiStore()\n\n\tnewCtx := sdk.NewContext(\n\t\tms,\n\t\tfalse,\n\t\tservercmtlog.WrapSDKLogger(s.logger),\n\t).WithContext(ctx)\n\n\treturn cache.NewState(ms, newCtx)\n}\n\n// convertValidatorUpdate abstracts the conversion of a\n// transition.ValidatorUpdate to an appmodulev2.ValidatorUpdate.\n// TODO: this is so hood, bktypes -> sdktypes -> generic is crazy\n// maybe make this some kind of codec/func that can be passed in?\nfunc convertValidatorUpdate[ValidatorUpdateT any](\n\tu **transition.ValidatorUpdate,\n) (ValidatorUpdateT, error) {\n\tvar valUpdate ValidatorUpdateT\n\tupdate := *u\n\tif update == nil {\n\t\treturn valUpdate, errors.New(\"undefined validator update\")\n\t}\n\t//nolint:errcheck // should be safe\n\treturn any(abci.ValidatorUpdate{\n\t\tPubKeyBytes: update.Pubkey[:],\n\t\tPubKeyType:  crypto.CometBLSType,\n\t\tPower:       int64(update.EffectiveBalance.Unwrap()), // #nosec G115 -- this is safe.\n\t}).(ValidatorUpdateT), nil\n}\n\n// getContextForProposal returns the correct Context for PrepareProposal and\n// ProcessProposal. We use finalizeBlockState on the first block to be able to\n// access any state changes made in InitChain.\nfunc (s *Service) getContextForProposal(\n\tctx sdk.Context,\n\theight int64,\n) sdk.Context {\n\tif height != s.initialHeight {\n\t\treturn ctx\n\t}\n\n\t_, finalState, err := s.cachedStates.GetFinal()\n\tif err != nil {\n\t\t// this is unexpected since cometBFT won't call PrepareProposal\n\t\t// on initialHeight. Panic appeases nilaway.\n\t\tpanic(fmt.Errorf(\"getContextForProposal: %w\", err))\n\t}\n\tnewCtx, _ := finalState.Context().CacheContext()\n\t// Preserve the CosmosSDK context while using the correct base ctx.\n\treturn newCtx.WithContext(ctx.Context())\n}\n"
  },
  {
    "path": "consensus/cometbft/service/state/state.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage state\n\nimport (\n\t\"fmt\"\n\n\t\"cosmossdk.io/log\"\n\t\"cosmossdk.io/store\"\n\tstoremetrics \"cosmossdk.io/store/metrics\"\n\tstoretypes \"cosmossdk.io/store/types\"\n\tdbm \"github.com/cosmos/cosmos-db\"\n)\n\ntype Manager struct {\n\tdb  dbm.DB\n\tcms storetypes.CommitMultiStore\n}\n\n// NewManager creates a new Manager.\nfunc NewManager(\n\tdb dbm.DB,\n\tlogger log.Logger,\n\topts ...func(*Manager),\n) *Manager {\n\tsm := &Manager{\n\t\tdb: db,\n\t\tcms: store.NewCommitMultiStore(\n\t\t\tdb,\n\t\t\tlogger,\n\t\t\tstoremetrics.NewNoOpMetrics(),\n\t\t),\n\t}\n\n\tfor _, opt := range opts {\n\t\topt(sm)\n\t}\n\n\t// TODO: Kill KVStoreService and register here.\n\t// sm.cms.MountStoreWithDB(\n\t// \tstoretypes.NewKVStoreKey(\"beacon\"),\n\t// \tstoretypes.StoreTypeIAVL,\n\t// \tdb,\n\t// )\n\n\treturn sm\n}\n\nfunc (sm *Manager) LoadVersion(version int64) error {\n\terr := sm.GetCommitMultiStore().LoadVersion(version)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to load version %d: %w\", version, err)\n\t}\n\n\t// Validate Pruning settings.\n\treturn sm.GetCommitMultiStore().GetPruning().Validate()\n}\n\nfunc (sm *Manager) LoadLatestVersion() error {\n\tif err := sm.cms.LoadLatestVersion(); err != nil {\n\t\treturn fmt.Errorf(\"failed to load latest version: %w\", err)\n\t}\n\n\t// Validator pruning settings.\n\treturn sm.cms.GetPruning().Validate()\n}\n\nfunc (sm *Manager) Close() error {\n\treturn sm.db.Close()\n}\n\n// GetCommitMultiStore returns the CommitMultiStore of the Manager.\nfunc (sm *Manager) GetCommitMultiStore() storetypes.CommitMultiStore {\n\treturn sm.cms\n}\n\n//nolint:gochecknoglobals // unexported key\nvar blockDelayKey = []byte(\"blockDelay\")\n\n// LoadBlockDelay loads the block delay bytes from the database.\n//\n// see next_block_delay.go\nfunc (sm *Manager) LoadBlockDelay() ([]byte, error) {\n\treturn sm.db.Get(blockDelayKey)\n}\n\n// SaveBlockDelay saves the block delay bytes to the database.\n//\n// see next_block_delay.go\nfunc (sm *Manager) SaveBlockDelay(bz []byte) error {\n\treturn sm.db.Set(blockDelayKey, bz)\n}\n"
  },
  {
    "path": "consensus/types/common.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport \"github.com/berachain/beacon-kit/primitives/math\"\n\ntype commonConsensusData struct {\n\t// use to verify block builder\n\tproposerAddress []byte\n\n\t// used to build next block and validate current payload timestamp\n\tconsensusTime math.U64\n}\n\n// GetProposerAddress returns the address of the validator\n// selected by consensus to propose the block.\nfunc (c *commonConsensusData) GetProposerAddress() []byte {\n\treturn c.proposerAddress\n}\n\n// GetConsensusTime returns the timestamp of current consensus request.\n// It is used to build next payload and to validate currentpayload.\nfunc (c *commonConsensusData) GetConsensusTime() math.U64 {\n\treturn c.consensusTime\n}\n"
  },
  {
    "path": "consensus/types/consensus_block.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\ntype ConsensusBlock struct {\n\tblk *types.BeaconBlock\n\n\t// some consensus data useful to build and verify the block\n\t*commonConsensusData\n}\n\n// New creates a new ConsensusBlock instance.\nfunc NewConsensusBlock(\n\tbeaconBlock *types.BeaconBlock,\n\tproposerAddress []byte,\n\tconsensusTime time.Time,\n) *ConsensusBlock {\n\treturn &ConsensusBlock{\n\t\tblk: beaconBlock,\n\t\tcommonConsensusData: &commonConsensusData{\n\t\t\tproposerAddress: proposerAddress,\n\t\t\tconsensusTime:   math.U64(consensusTime.Unix()), // #nosec G115\n\t\t},\n\t}\n}\n\nfunc (b *ConsensusBlock) GetBeaconBlock() *types.BeaconBlock {\n\treturn b.blk\n}\n"
  },
  {
    "path": "consensus/types/slot_data.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"time\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// SlotData represents the data to be used to propose a block.\ntype SlotData struct {\n\t// slot is the slot number of the incoming slot.\n\tslot math.Slot\n\t// attestationData is the attestation data of the incoming slot.\n\tattestationData []*ctypes.AttestationData\n\t// slashingInfo is the slashing info of the incoming slot.\n\tslashingInfo []*ctypes.SlashingInfo\n\n\t// some consensus data useful to build and verify the block\n\t*commonConsensusData\n}\n\n// NewSlotData creates a new SlotData instance.\nfunc NewSlotData(\n\tslot math.Slot,\n\tattestationData []*ctypes.AttestationData,\n\tslashingInfo []*ctypes.SlashingInfo,\n\tproposerAddress []byte,\n\tconsensusTime time.Time,\n) *SlotData {\n\treturn &SlotData{\n\t\tslot:            slot,\n\t\tattestationData: attestationData,\n\t\tslashingInfo:    slashingInfo,\n\t\tcommonConsensusData: &commonConsensusData{\n\t\t\tproposerAddress: proposerAddress,\n\t\t\tconsensusTime:   math.U64(consensusTime.Unix()), // #nosec G115\n\t\t},\n\t}\n}\n\n// GetSlot retrieves the slot of the SlotData.\nfunc (b *SlotData) GetSlot() math.Slot {\n\treturn b.slot\n}\n\n// GetAttestationData retrieves the attestation data of the SlotData.\nfunc (b *SlotData) GetAttestationData() []*ctypes.AttestationData {\n\treturn b.attestationData\n}\n\n// GetSlashingInfo retrieves the slashing info of the SlotData.\nfunc (b *SlotData) GetSlashingInfo() []*ctypes.SlashingInfo {\n\treturn b.slashingInfo\n}\n\n// SetAttestationData sets the attestation data of the SlotData.\nfunc (b *SlotData) SetAttestationData(\n\tattestationData []*ctypes.AttestationData,\n) {\n\tb.attestationData = attestationData\n}\n\n// SetSlashingInfo sets the slashing info of the SlotData.\nfunc (b *SlotData) SetSlashingInfo(\n\tslashingInfo []*ctypes.SlashingInfo,\n) {\n\tb.slashingInfo = slashingInfo\n}\n"
  },
  {
    "path": "consensus-types/types/attestation_data.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tfastssz \"github.com/ferranbt/fastssz\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// AttestationDataSize is the size of the AttestationData object in bytes.\n// 8 bytes for Slot + 8 bytes for Index + 32 bytes for BeaconBlockRoot.\nconst AttestationDataSize = 48\n\nvar (\n\t_ ssz.StaticObject                    = (*AttestationData)(nil)\n\t_ constraints.SSZMarshallableRootable = (*AttestationData)(nil)\n)\n\n// AttestationData represents an attestation data.\ntype AttestationData struct {\n\t// Slot is the slot number of the attestation data.\n\tSlot math.U64 `json:\"slot\"`\n\t// Index is the index of the validator.\n\tIndex math.U64 `json:\"index\"`\n\t// BeaconBlockRoot is the root of the beacon block.\n\tBeaconBlockRoot common.Root `json:\"beaconBlockRoot\"`\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// SizeSSZ returns the size of the AttestationData object in SSZ encoding.\nfunc (*AttestationData) SizeSSZ(*ssz.Sizer) uint32 {\n\treturn AttestationDataSize\n}\n\n// DefineSSZ defines the SSZ encoding for the AttestationData object.\nfunc (a *AttestationData) DefineSSZ(codec *ssz.Codec) {\n\tssz.DefineUint64(codec, &a.Slot)\n\tssz.DefineUint64(codec, &a.Index)\n\tssz.DefineStaticBytes(codec, &a.BeaconBlockRoot)\n}\n\n// HashTreeRoot computes the SSZ hash tree root of the AttestationData object.\nfunc (a *AttestationData) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(a)\n}\n\n// MarshalSSZ marshals the AttestationData object to SSZ format.\nfunc (a *AttestationData) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(a))\n\treturn buf, ssz.EncodeToBytes(buf, a)\n}\n\nfunc (*AttestationData) ValidateAfterDecodingSSZ() error { return nil }\n\n/* -------------------------------------------------------------------------- */\n/*                                   FastSSZ                                  */\n/* -------------------------------------------------------------------------- */\n\n// MarshalSSZTo marshals the AttestationData object into a pre-allocated byte\n// slice.\nfunc (a *AttestationData) MarshalSSZTo(dst []byte) ([]byte, error) {\n\tbz, err := a.MarshalSSZ()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdst = append(dst, bz...)\n\treturn dst, err\n}\n\n// HashTreeRootWith ssz hashes the AttestationData object with a hasher.\nfunc (a *AttestationData) HashTreeRootWith(hh fastssz.HashWalker) error {\n\tindx := hh.Index()\n\n\t// Field (0) 'Slot'\n\thh.PutUint64(uint64(a.Slot))\n\n\t// Field (1) 'Index'\n\thh.PutUint64(uint64(a.Index))\n\n\t// Field (2) 'BeaconBlockRoot'\n\thh.PutBytes(a.BeaconBlockRoot[:])\n\n\thh.Merkleize(indx)\n\treturn nil\n}\n\n// GetTree ssz hashes the AttestationData object.\nfunc (a *AttestationData) GetTree() (*fastssz.Node, error) {\n\treturn fastssz.ProofTree(a)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                             Getters and Setters                            */\n/* -------------------------------------------------------------------------- */\n\n// GetSlot returns the slot of the attestation data.\nfunc (a *AttestationData) GetSlot() math.U64 {\n\treturn a.Slot\n}\n\n// GetIndex returns the index of the attestation data.\nfunc (a *AttestationData) GetIndex() math.U64 {\n\treturn a.Index\n}\n\n// GetBeaconBlockRoot returns the beacon block root of the attestation data.\nfunc (a *AttestationData) GetBeaconBlockRoot() common.Root {\n\treturn a.BeaconBlockRoot\n}\n"
  },
  {
    "path": "consensus-types/types/attestation_data_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc generateAttestationData() *types.AttestationData {\n\treturn &types.AttestationData{\n\t\tSlot:  12345,\n\t\tIndex: 67890,\n\t\tBeaconBlockRoot: [32]byte{\n\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,\n\t\t},\n\t}\n}\n\nfunc TestAttestationData_MarshalSSZ_UnmarshalSSZ(t *testing.T) {\n\tt.Parallel()\n\ttestCases := []struct {\n\t\tname     string\n\t\tdata     *types.AttestationData\n\t\texpected *types.AttestationData\n\t\terr      error\n\t}{\n\t\t{\n\t\t\tname:     \"Valid AttestationData\",\n\t\t\tdata:     generateAttestationData(),\n\t\t\texpected: generateAttestationData(),\n\t\t\terr:      nil,\n\t\t},\n\t\t{\n\t\t\tname: \"Empty AttestationData\",\n\t\t\tdata: &types.AttestationData{\n\t\t\t\tSlot:            0,\n\t\t\t\tIndex:           0,\n\t\t\t\tBeaconBlockRoot: [32]byte{},\n\t\t\t},\n\t\t\texpected: &types.AttestationData{\n\t\t\t\tSlot:            0,\n\t\t\t\tIndex:           0,\n\t\t\t\tBeaconBlockRoot: [32]byte{},\n\t\t\t},\n\t\t\terr: nil,\n\t\t},\n\t\t{\n\t\t\tname:     \"Invalid Buffer Size\",\n\t\t\tdata:     generateAttestationData(),\n\t\t\texpected: nil,\n\t\t\terr:      io.ErrUnexpectedEOF,\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tdata, err := tc.data.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.NotNil(t, data)\n\n\t\t\tunmarshalled := new(types.AttestationData)\n\t\t\tif tc.name == \"Invalid Buffer Size\" {\n\t\t\t\terr = ssz.Unmarshal(data[:32], unmarshalled)\n\t\t\t\trequire.ErrorIs(t, err, tc.err)\n\t\t\t} else {\n\t\t\t\terr = ssz.Unmarshal(data, unmarshalled)\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tc.expected, unmarshalled)\n\n\t\t\t\tvar buf []byte\n\t\t\t\tbuf, err = tc.data.MarshalSSZTo(buf)\n\t\t\t\trequire.NoError(t, err)\n\n\t\t\t\t// The two byte slices should be equal\n\t\t\t\trequire.Equal(t, data, buf)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestAttestationData_GetTree(t *testing.T) {\n\tt.Parallel()\n\tdata := generateAttestationData()\n\n\ttree, err := data.GetTree()\n\trequire.NoError(t, err)\n\trequire.NotNil(t, tree)\n\n\texpectedRoot := data.HashTreeRoot()\n\n\t// Compare the tree root with the expected root\n\tactualRoot := tree.Hash()\n\trequire.Equal(t, string(expectedRoot[:]), string(actualRoot))\n}\n\nfunc TestAttestationData_Getters(t *testing.T) {\n\tt.Parallel()\n\tdata := generateAttestationData()\n\tbeaconBlockRoot := common.Root{\n\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,\n\t}\n\n\trequire.NotNil(t, data)\n\n\trequire.Equal(t, math.U64(12345), data.GetSlot())\n\trequire.Equal(t, math.U64(67890), data.GetIndex())\n\trequire.Equal(t, beaconBlockRoot, data.GetBeaconBlockRoot())\n}\n"
  },
  {
    "path": "consensus-types/types/attester_slashings.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//nolint:dupl // separate file for ease of future implementation\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// Compile-time assertions to ensure AttesterSlashing implements necessary interfaces.\nvar (\n\t_ ssz.StaticObject                    = (*AttesterSlashing)(nil)\n\t_ constraints.SSZMarshallableRootable = (*AttesterSlashing)(nil)\n\t_ common.UnusedEnforcer               = (*AttesterSlashings)(nil)\n)\n\ntype (\n\tAttesterSlashing  = common.UnusedType\n\tAttesterSlashings []*AttesterSlashing\n)\n\n// SizeSSZ returns the SSZ encoded size in bytes for the AttesterSlashings.\nfunc (ass AttesterSlashings) SizeSSZ(siz *ssz.Sizer, _ bool) uint32 {\n\treturn ssz.SizeSliceOfStaticObjects(siz, ass)\n}\n\n// DefineSSZ defines the SSZ encoding for the AttesterSlashings object.\nfunc (ass AttesterSlashings) DefineSSZ(c *ssz.Codec) {\n\tc.DefineDecoder(func(*ssz.Decoder) {\n\t\tssz.DefineSliceOfStaticObjectsContent(c, (*[]*AttesterSlashing)(&ass), constants.MaxAttesterSlashings)\n\t})\n\tc.DefineEncoder(func(*ssz.Encoder) {\n\t\tssz.DefineSliceOfStaticObjectsContent(c, (*[]*AttesterSlashing)(&ass), constants.MaxAttesterSlashings)\n\t})\n\tc.DefineHasher(func(*ssz.Hasher) {\n\t\tssz.DefineSliceOfStaticObjectsOffset(c, (*[]*AttesterSlashing)(&ass), constants.MaxAttesterSlashings)\n\t})\n}\n\n// HashTreeRoot returns the hash tree root of the AttesterSlashings.\nfunc (ass AttesterSlashings) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(ass)\n}\n\n// EnforceUnused return true if the length of the AttestererSlashings is 0.\n// As long as this type remains unimplemented and unvalidated by consensus,\n// we must enforce that it contains no data.\nfunc (ass AttesterSlashings) EnforceUnused() error {\n\tif len(ass) != 0 {\n\t\treturn errors.New(\"AttesterSlashings must be unused\")\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "consensus-types/types/attestions.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//nolint:dupl // separate file for ease of future implementation\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// Compile-time assertions to ensure Attestation implements necessary interfaces.\nvar (\n\t_ ssz.StaticObject                    = (*Attestation)(nil)\n\t_ constraints.SSZMarshallableRootable = (*Attestation)(nil)\n\t_ common.UnusedEnforcer               = (*Attestations)(nil)\n)\n\ntype (\n\tAttestation  = common.UnusedType\n\tAttestations []*Attestation\n)\n\n// SizeSSZ returns the SSZ encoded size in bytes for the Attestations.\nfunc (as Attestations) SizeSSZ(siz *ssz.Sizer, _ bool) uint32 {\n\treturn ssz.SizeSliceOfStaticObjects(siz, as)\n}\n\n// DefineSSZ defines the SSZ encoding for the Attestations object.\nfunc (as Attestations) DefineSSZ(c *ssz.Codec) {\n\tc.DefineDecoder(func(*ssz.Decoder) {\n\t\tssz.DefineSliceOfStaticObjectsContent(c, (*[]*Attestation)(&as), constants.MaxAttestations)\n\t})\n\tc.DefineEncoder(func(*ssz.Encoder) {\n\t\tssz.DefineSliceOfStaticObjectsContent(c, (*[]*Attestation)(&as), constants.MaxAttestations)\n\t})\n\tc.DefineHasher(func(*ssz.Hasher) {\n\t\tssz.DefineSliceOfStaticObjectsOffset(c, (*[]*Attestation)(&as), constants.MaxAttestations)\n\t})\n}\n\n// HashTreeRoot returns the hash tree root of the Attestations.\nfunc (as Attestations) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(as)\n}\n\n// EnforceUnused return true if the length of the Attestations is 0.\n// As long as this type remains unimplemented and unvalidated by consensus,\n// we must enforce that it contains no data.\nfunc (as Attestations) EnforceUnused() error {\n\tif len(as) != 0 {\n\t\treturn errors.New(\"Attestations must be unused\")\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "consensus-types/types/block.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// Compile-time assertions to ensure BeaconBlock implements necessary interfaces.\nvar (\n\t_ ssz.DynamicObject                            = (*BeaconBlock)(nil)\n\t_ constraints.SSZVersionedMarshallableRootable = (*BeaconBlock)(nil)\n)\n\n// BeaconBlock represents a block in the beacon chain.\ntype BeaconBlock struct {\n\tconstraints.Versionable `json:\"-\"`\n\n\t// Slot represents the position of the block in the chain.\n\tSlot math.Slot `json:\"slot\"`\n\t// ProposerIndex is the index of the validator who proposed the block.\n\tProposerIndex math.ValidatorIndex `json:\"proposer_index\"`\n\t// ParentRoot is the hash of the parent block\n\tParentRoot common.Root `json:\"parent_root\"`\n\t// StateRoot is the hash of the state at the block.\n\tStateRoot common.Root `json:\"state_root\"`\n\t// Body is the body of the BeaconBlock, containing the block's operations.\n\tBody *BeaconBlockBody `json:\"body\"`\n}\n\n// NewBeaconBlockWithVersion assembles a new beacon block from the given parameters.\nfunc NewBeaconBlockWithVersion(\n\tslot math.Slot,\n\tproposerIndex math.ValidatorIndex,\n\tparentBlockRoot common.Root,\n\tforkVersion common.Version,\n) (*BeaconBlock, error) {\n\tswitch forkVersion {\n\tcase version.Deneb(), version.Deneb1(), version.Electra(), version.Electra1(), version.Fulu():\n\t\tblock := NewEmptyBeaconBlockWithVersion(forkVersion)\n\t\tblock.Slot = slot\n\t\tblock.ProposerIndex = proposerIndex\n\t\tblock.ParentRoot = parentBlockRoot\n\n\t\t// StateRoot is left empty as it is not ready at this time.\n\t\tblock.StateRoot = common.Root{}\n\t\treturn block, nil\n\tdefault:\n\t\t// We return block here to appease nilaway.\n\t\tblock := &BeaconBlock{}\n\t\terr := errors.Wrap(ErrForkVersionNotSupported, fmt.Sprintf(\"fork %d\", forkVersion))\n\t\treturn block, err\n\t}\n}\n\nfunc NewEmptyBeaconBlockWithVersion(version common.Version) *BeaconBlock {\n\treturn &BeaconBlock{\n\t\tVersionable: NewVersionable(version),\n\t\tBody:        NewEmptyBeaconBlockBodyWithVersion(version),\n\t}\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// SizeSSZ returns the size of the BeaconBlock object in SSZ encoding.\nfunc (b *BeaconBlock) SizeSSZ(siz *ssz.Sizer, fixed bool) uint32 {\n\t//nolint:mnd // todo fix.\n\tvar size = uint32(8 + 8 + 32 + 32 + 4)\n\tif fixed {\n\t\treturn size\n\t}\n\tsize += ssz.SizeDynamicObject(siz, b.Body)\n\treturn size\n}\n\n// DefineSSZ defines the SSZ encoding for the BeaconBlock object.\nfunc (b *BeaconBlock) DefineSSZ(codec *ssz.Codec) {\n\t// Define the static data (fields and dynamic offsets)\n\tssz.DefineUint64(codec, &b.Slot)\n\tssz.DefineUint64(codec, &b.ProposerIndex)\n\tssz.DefineStaticBytes(codec, &b.ParentRoot)\n\tssz.DefineStaticBytes(codec, &b.StateRoot)\n\tssz.DefineDynamicObjectOffset(codec, &b.Body)\n\n\t// Define the dynamic data (fields)\n\tssz.DefineDynamicObjectContent(codec, &b.Body)\n}\n\n// MarshalSSZ marshals the BeaconBlock object to SSZ format.\nfunc (b *BeaconBlock) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(b))\n\treturn buf, ssz.EncodeToBytes(buf, b)\n}\n\nfunc (b *BeaconBlock) ValidateAfterDecodingSSZ() error {\n\treturn b.Body.ValidateAfterDecodingSSZ()\n}\n\n// HashTreeRoot computes the Merkleization of the BeaconBlock object.\nfunc (b *BeaconBlock) HashTreeRoot() common.Root {\n\treturn ssz.HashConcurrent(b)\n}\n\n// GetSlot retrieves the slot of the BeaconBlockBase.\nfunc (b *BeaconBlock) GetSlot() math.Slot {\n\treturn b.Slot\n}\n\n// GetProposerIndex retrieves the proposer index.\nfunc (b *BeaconBlock) GetProposerIndex() math.ValidatorIndex {\n\treturn b.ProposerIndex\n}\n\n// GetParentBlockRoot retrieves the parent block root of the BeaconBlockBase.\nfunc (b *BeaconBlock) GetParentBlockRoot() common.Root {\n\treturn b.ParentRoot\n}\n\n// SetParentBlockRoot sets the parent block root of the BeaconBlockBase.\nfunc (b *BeaconBlock) SetParentBlockRoot(parentBlockRoot common.Root) {\n\tb.ParentRoot = parentBlockRoot\n}\n\n// GetStateRoot retrieves the state root of the BeaconBlock.\nfunc (b *BeaconBlock) GetStateRoot() common.Root {\n\treturn b.StateRoot\n}\n\n// SetStateRoot sets the state root of the BeaconBlock.\nfunc (b *BeaconBlock) SetStateRoot(root common.Root) {\n\tb.StateRoot = root\n}\n\n// GetBody retrieves the body of the BeaconBlock.\nfunc (b *BeaconBlock) GetBody() *BeaconBlockBody {\n\treturn b.Body\n}\n\n// GetHeader builds a BeaconBlockHeader from the BeaconBlock.\nfunc (b *BeaconBlock) GetHeader() *BeaconBlockHeader {\n\treturn &BeaconBlockHeader{\n\t\tSlot:            b.Slot,\n\t\tProposerIndex:   b.ProposerIndex,\n\t\tParentBlockRoot: b.ParentRoot,\n\t\tStateRoot:       b.StateRoot,\n\t\tBodyRoot:        b.GetBody().HashTreeRoot(),\n\t}\n}\n\n// GetTimestamp retrieves the timestamp of the BeaconBlock from\n// the ExecutionPayload.\nfunc (b *BeaconBlock) GetTimestamp() math.U64 {\n\treturn b.Body.ExecutionPayload.Timestamp\n}\n"
  },
  {
    "path": "consensus-types/types/block_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"testing\"\n\t\"testing/quick\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/berachain/beacon-kit/testing/utils\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestBeaconBlockForDeneb(t *testing.T) {\n\tt.Parallel()\n\tdeneb1 := version.Deneb1()\n\tblock, err := types.NewBeaconBlockWithVersion(\n\t\tmath.Slot(10),\n\t\tmath.ValidatorIndex(5),\n\t\tcommon.Root{1, 2, 3, 4, 5}, // parent root\n\t\tdeneb1,\n\t)\n\trequire.NoError(t, err)\n\trequire.NotNil(t, block)\n\trequire.Equal(t, deneb1, block.GetForkVersion())\n\trequire.Equal(t, deneb1, block.GetBody().GetForkVersion())\n\trequire.Equal(t, deneb1, block.GetBody().GetExecutionPayload().GetForkVersion())\n}\n\nfunc TestBeaconBlock(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tblock := utils.GenerateValidBeaconBlock(t, v)\n\n\t\trequire.NotNil(t, block.Body)\n\t\trequire.Equal(t, math.U64(10), block.GetTimestamp())\n\t\trequire.Equal(t, v, block.GetForkVersion())\n\t\trequire.NotNil(t, block)\n\n\t\t// Set a new state root and test the SetStateRoot and GetBody methods\n\t\tnewStateRoot := [32]byte{1, 1, 1, 1, 1}\n\t\tblock.SetStateRoot(newStateRoot)\n\t\trequire.Equal(t, newStateRoot, [32]byte(block.StateRoot))\n\n\t\t// Test the GetHeader method\n\t\theader := block.GetHeader()\n\t\trequire.NotNil(t, header)\n\t\trequire.Equal(t, block.Slot, header.Slot)\n\t\trequire.Equal(t, block.ProposerIndex, header.ProposerIndex)\n\t\trequire.Equal(t, block.ParentRoot, header.ParentBlockRoot)\n\t\trequire.Equal(t, block.StateRoot, header.StateRoot)\n\t\trequire.Equal(t, newStateRoot, [32]byte(block.GetStateRoot()))\n\t})\n}\n\nfunc TestBeaconBlock_MarshalUnmarshalSSZ(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tblock := utils.GenerateValidBeaconBlock(t, v)\n\n\t\tsszBlock, err := block.MarshalSSZ()\n\t\trequire.NoError(t, err)\n\t\trequire.NotNil(t, sszBlock)\n\n\t\tunmarshalledBlock := types.NewEmptyBeaconBlockWithVersion(v)\n\t\terr = ssz.Unmarshal(sszBlock, unmarshalledBlock)\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, block, unmarshalledBlock)\n\t})\n}\n\nfunc TestBeaconBlock_HashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tblock := utils.GenerateValidBeaconBlock(t, v)\n\t\thashRoot := block.HashTreeRoot()\n\t\trequire.NotNil(t, hashRoot)\n\t})\n}\n\nfunc TestBeaconBlock_IsNil(t *testing.T) {\n\tt.Parallel()\n\tvar block *types.BeaconBlock\n\trequire.Nil(t, block)\n}\n\nfunc TestNewWithVersion(t *testing.T) {\n\tt.Parallel()\n\tslot := math.Slot(10)\n\tproposerIndex := math.ValidatorIndex(5)\n\tparentBlockRoot := common.Root{1, 2, 3, 4, 5}\n\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tblock, err := types.NewBeaconBlockWithVersion(\n\t\t\tslot, proposerIndex, parentBlockRoot, v,\n\t\t)\n\t\trequire.NoError(t, err)\n\t\trequire.NotNil(t, block)\n\n\t\t// Check the block's fields\n\t\trequire.NotNil(t, block)\n\t\trequire.Equal(t, slot, block.GetSlot())\n\t\trequire.Equal(t, proposerIndex, block.GetProposerIndex())\n\t\trequire.Equal(t, parentBlockRoot, block.GetParentBlockRoot())\n\t\trequire.Equal(t, v, block.GetForkVersion())\n\t})\n}\n\nfunc TestNewWithVersionInvalidForkVersion(t *testing.T) {\n\tt.Parallel()\n\tslot := math.Slot(10)\n\tproposerIndex := math.ValidatorIndex(5)\n\tparentBlockRoot := common.Root{1, 2, 3, 4, 5}\n\n\t_, err := types.NewBeaconBlockWithVersion(\n\t\tslot,\n\t\tproposerIndex,\n\t\tparentBlockRoot,\n\t\tcommon.Version{100, 0, 0, 0},\n\t) // 100 is an invalid fork version\n\trequire.ErrorIs(t, err, types.ErrForkVersionNotSupported)\n}\n\nfunc TestPropertyBlockRootAndBlockHeaderRootEquivalence(t *testing.T) {\n\tt.Parallel()\n\tqc := &quick.Config{MaxCount: 100}\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tf := func(\n\t\t\tslot math.Slot,\n\t\t\tproposerIdx math.ValidatorIndex,\n\t\t\tparentBlockRoot common.Root,\n\t\t) bool {\n\t\t\tblk, err := types.NewBeaconBlockWithVersion(\n\t\t\t\tslot,\n\t\t\t\tproposerIdx,\n\t\t\t\tparentBlockRoot,\n\t\t\t\tv,\n\t\t\t)\n\t\t\trequire.NoError(t, err)\n\t\t\treturn blk.GetHeader().HashTreeRoot().Equals(blk.HashTreeRoot())\n\t\t}\n\t\trequire.NoError(t, quick.Check(f, qc))\n\t})\n}\n"
  },
  {
    "path": "consensus-types/types/bls_to_execution_changes.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//nolint:dupl // separate file for ease of future implementation\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// Compile-time assertions to ensure BlsToExecutionChange implements necessary interfaces.\nvar (\n\t_ ssz.StaticObject                    = (*BlsToExecutionChange)(nil)\n\t_ constraints.SSZMarshallableRootable = (*BlsToExecutionChange)(nil)\n\t_ common.UnusedEnforcer               = (*BlsToExecutionChanges)(nil)\n)\n\ntype (\n\tBlsToExecutionChange  = common.UnusedType\n\tBlsToExecutionChanges []*BlsToExecutionChange\n)\n\n// SizeSSZ returns the SSZ encoded size in bytes for the BlsToExecutionChanges.\nfunc (bs BlsToExecutionChanges) SizeSSZ(siz *ssz.Sizer, _ bool) uint32 {\n\treturn ssz.SizeSliceOfStaticObjects(siz, bs)\n}\n\n// DefineSSZ defines the SSZ encoding for the BlsToExecutionChanges object.\nfunc (bs BlsToExecutionChanges) DefineSSZ(c *ssz.Codec) {\n\tc.DefineDecoder(func(*ssz.Decoder) {\n\t\tssz.DefineSliceOfStaticObjectsContent(c, (*[]*BlsToExecutionChange)(&bs), constants.MaxBlsToExecutionChanges)\n\t})\n\tc.DefineEncoder(func(*ssz.Encoder) {\n\t\tssz.DefineSliceOfStaticObjectsContent(c, (*[]*BlsToExecutionChange)(&bs), constants.MaxBlsToExecutionChanges)\n\t})\n\tc.DefineHasher(func(*ssz.Hasher) {\n\t\tssz.DefineSliceOfStaticObjectsOffset(c, (*[]*BlsToExecutionChange)(&bs), constants.MaxBlsToExecutionChanges)\n\t})\n}\n\n// HashTreeRoot returns the hash tree root of the BlsToExecutionChanges.\nfunc (bs BlsToExecutionChanges) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(bs)\n}\n\n// EnforceUnused return true if the length of the BlsToExecutionChanges is 0.\n// As long as this type remains unimplemented and unvalidated by consensus,\n// we must enforce that it contains no data.\nfunc (bs BlsToExecutionChanges) EnforceUnused() error {\n\tif len(bs) != 0 {\n\t\treturn errors.New(\"BlsToExecutionChanges must be unused\")\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "consensus-types/types/body.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/karalabe/ssz\"\n)\n\nconst (\n\t// BodyLengthDeneb is the number of fields in the BeaconBlockBody struct for Deneb.\n\tBodyLengthDeneb uint64 = 12\n\n\t// BodyLengthElectra is the number of fields in the BeaconBlockBody struct for Electra.\n\tBodyLengthElectra uint64 = 13\n\n\t// KZGPosition is the position of BlobKzgCommitments in the block body.\n\tKZGPosition uint64 = 11\n\n\t// KZGGeneralizedIndex is the index of the KZG commitment root's parent.\n\t//     (1 << log2ceil(KZGPosition)) | KZGPosition.\n\tKZGGeneralizedIndex = 27\n\n\t// KZGRootIndex is the merkle index of BlobKzgCommitments' root\n\t// in the merkle tree built from the block body.\n\t//     2 * KZGGeneralizedIndex.\n\tKZGRootIndex = KZGGeneralizedIndex * 2\n\n\t// KZGInclusionProofDepth is the\n\t//     Log2Floor(KZGGeneralizedIndex) +\n\t//     Log2Ceil(MaxBlobCommitmentsPerBlock) + 1\n\tKZGInclusionProofDepth = 17\n\n\t// KZGOffset is the offset of the KZG commitments in the serialized block body.\n\tKZGOffset = KZGRootIndex * constants.MaxBlobCommitmentsPerBlock\n)\n\n// Compile-time assertions to ensure BeaconBlockBody implements necessary interfaces.\nvar (\n\t_ ssz.DynamicObject                            = (*BeaconBlockBody)(nil)\n\t_ constraints.SSZVersionedMarshallableRootable = (*BeaconBlockBody)(nil)\n)\n\n// BeaconBlockBody represents the body of a beacon block.\ntype BeaconBlockBody struct {\n\t// Must be available within the object to satisfy signature required for SizeSSZ and DefineSSZ.\n\tconstraints.Versionable `json:\"-\"`\n\n\t// RandaoReveal is the reveal of the RANDAO.\n\tRandaoReveal crypto.BLSSignature\n\t// Eth1Data is the data from the Eth1 chain.\n\tEth1Data *Eth1Data\n\t// Graffiti is for a fun message or meme.\n\tGraffiti [32]byte\n\t// proposerSlashings is unused but left for compatibility.\n\tproposerSlashings []*ProposerSlashing\n\t// attesterSlashings is unused but left for compatibility.\n\tattesterSlashings []*AttesterSlashing\n\t// attestations is unused but left for compatibility.\n\tattestations []*Attestation\n\t// Deposits is the list of deposits included in the body.\n\tDeposits []*Deposit\n\t// voluntaryExits is unused but left for compatibility.\n\tvoluntaryExits []*VoluntaryExit\n\t// syncAggregate is unused but left for compatibility.\n\tsyncAggregate *SyncAggregate\n\t// ExecutionPayload is the execution payload of the body.\n\tExecutionPayload *ExecutionPayload\n\t// blsToExecutionChanges is unused but left for compatibility.\n\tblsToExecutionChanges []*BlsToExecutionChange\n\t// BlobKzgCommitments is the list of KZG commitments for the EIP-4844 blobs.\n\tBlobKzgCommitments []eip4844.KZGCommitment\n\t// executionRequests is introduced in Electra. We keep this private so that it must go through Getter/Setter\n\t// which does a forkVersion check.\n\texecutionRequests *ExecutionRequests\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// SizeSSZ returns the size of the BeaconBlockBody in SSZ.\nfunc (b *BeaconBlockBody) SizeSSZ(siz *ssz.Sizer, fixed bool) uint32 {\n\tvar size = 96 + 72 + 32 + 4 + 4 + 4 + 4 + 4 + b.syncAggregate.SizeSSZ(siz) + 4 + 4 + 4\n\tincludeExecRequest := version.EqualsOrIsAfter(b.GetForkVersion(), version.Electra())\n\tif includeExecRequest {\n\t\t// Add 4 for the offset of dynamic field ExecutionRequests\n\t\tsize += constants.SSZOffsetSize\n\t}\n\n\tif fixed {\n\t\treturn size\n\t}\n\n\tsize += ssz.SizeSliceOfStaticObjects(siz, b.proposerSlashings)\n\tsize += ssz.SizeSliceOfStaticObjects(siz, b.attesterSlashings)\n\tsize += ssz.SizeSliceOfStaticObjects(siz, b.attestations)\n\tsize += ssz.SizeSliceOfStaticObjects(siz, b.Deposits)\n\tsize += ssz.SizeSliceOfStaticObjects(siz, b.voluntaryExits)\n\tsize += ssz.SizeDynamicObject(siz, b.ExecutionPayload)\n\tsize += ssz.SizeSliceOfStaticObjects(siz, b.blsToExecutionChanges)\n\tsize += ssz.SizeSliceOfStaticBytes(siz, b.BlobKzgCommitments)\n\tif includeExecRequest {\n\t\tsize += ssz.SizeDynamicObject(siz, b.executionRequests)\n\t}\n\treturn size\n}\n\n// DefineSSZ defines the SSZ serialization of the BeaconBlockBody.\n//\n//nolint:mnd // TODO: get from accessible chainspec field params\nfunc (b *BeaconBlockBody) DefineSSZ(codec *ssz.Codec) {\n\t// Define the static data (fields and dynamic offsets)\n\tssz.DefineStaticBytes(codec, &b.RandaoReveal)\n\tssz.DefineStaticObject(codec, &b.Eth1Data)\n\tssz.DefineStaticBytes(codec, &b.Graffiti)\n\tssz.DefineSliceOfStaticObjectsOffset(codec, &b.proposerSlashings, constants.MaxProposerSlashings)\n\tssz.DefineSliceOfStaticObjectsOffset(codec, &b.attesterSlashings, constants.MaxAttesterSlashings)\n\tssz.DefineSliceOfStaticObjectsOffset(codec, &b.attestations, constants.MaxAttestations)\n\tssz.DefineSliceOfStaticObjectsOffset(codec, &b.Deposits, constants.MaxDeposits)\n\tssz.DefineSliceOfStaticObjectsOffset(codec, &b.voluntaryExits, constants.MaxVoluntaryExits)\n\tssz.DefineStaticObject(codec, &b.syncAggregate)\n\tssz.DefineDynamicObjectOffset(codec, &b.ExecutionPayload)\n\tssz.DefineSliceOfStaticObjectsOffset(codec, &b.blsToExecutionChanges, constants.MaxBlsToExecutionChanges)\n\tssz.DefineSliceOfStaticBytesOffset(codec, &b.BlobKzgCommitments, 4096)\n\tincludeExecRequest := version.EqualsOrIsAfter(b.GetForkVersion(), version.Electra())\n\tif includeExecRequest {\n\t\tssz.DefineDynamicObjectOffset(codec, &b.executionRequests)\n\t}\n\n\t// Define the dynamic data (fields)\n\tssz.DefineSliceOfStaticObjectsContent(codec, &b.proposerSlashings, constants.MaxProposerSlashings)\n\tssz.DefineSliceOfStaticObjectsContent(codec, &b.attesterSlashings, constants.MaxAttesterSlashings)\n\tssz.DefineSliceOfStaticObjectsContent(codec, &b.attestations, constants.MaxAttestations)\n\tssz.DefineSliceOfStaticObjectsContent(codec, &b.Deposits, constants.MaxDeposits)\n\tssz.DefineSliceOfStaticObjectsContent(codec, &b.voluntaryExits, constants.MaxVoluntaryExits)\n\tssz.DefineDynamicObjectContent(codec, &b.ExecutionPayload)\n\tssz.DefineSliceOfStaticObjectsContent(codec, &b.blsToExecutionChanges, constants.MaxBlsToExecutionChanges)\n\tssz.DefineSliceOfStaticBytesContent(codec, &b.BlobKzgCommitments, 4096)\n\tif includeExecRequest {\n\t\tssz.DefineDynamicObjectContent(codec, &b.executionRequests)\n\t}\n}\n\n// MarshalSSZ serializes the BeaconBlockBody to SSZ-encoded bytes.\nfunc (b *BeaconBlockBody) MarshalSSZ() ([]byte, error) {\n\terr := common.EnforceAllUnused(\n\t\tb.GetProposerSlashings(),\n\t\tb.GetAttesterSlashings(),\n\t\tb.GetAttestations(),\n\t\tb.GetVoluntaryExits(),\n\t\tb.GetSyncAggregate(),\n\t\tb.GetBlsToExecutionChanges(),\n\t)\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\tbuf := make([]byte, ssz.Size(b))\n\treturn buf, ssz.EncodeToBytes(buf, b)\n}\n\nfunc NewEmptyBeaconBlockBodyWithVersion(version common.Version) *BeaconBlockBody {\n\treturn &BeaconBlockBody{\n\t\tVersionable:      NewVersionable(version),\n\t\tEth1Data:         NewEmptyEth1Data(),\n\t\tExecutionPayload: NewEmptyExecutionPayloadWithVersion(version),\n\t\tsyncAggregate:    &SyncAggregate{},\n\t}\n}\n\nfunc (b *BeaconBlockBody) ValidateAfterDecodingSSZ() error {\n\terrUnused := common.EnforceAllUnused(\n\t\tb.GetProposerSlashings(),\n\t\tb.GetAttesterSlashings(),\n\t\tb.GetAttestations(),\n\t\tb.GetVoluntaryExits(),\n\t\tb.GetSyncAggregate(),\n\t\tb.GetBlsToExecutionChanges(),\n\t)\n\treturn errors.Join(\n\t\tb.ExecutionPayload.ValidateAfterDecodingSSZ(),\n\t\terrUnused,\n\t)\n}\n\n// HashTreeRoot returns the SSZ hash tree root of the BeaconBlockBody.\nfunc (b *BeaconBlockBody) HashTreeRoot() common.Root {\n\treturn ssz.HashConcurrent(b)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                              Getters/Setters                               */\n/* -------------------------------------------------------------------------- */\n\n// GetTopLevelRoots returns the top-level roots of the BeaconBlockBody.\nfunc (b *BeaconBlockBody) GetTopLevelRoots() ([]common.Root, error) {\n\ttlrs := []common.Root{\n\t\tcommon.Root(b.GetRandaoReveal().HashTreeRoot()),\n\t\tb.Eth1Data.HashTreeRoot(),\n\t\tcommon.Root(b.GetGraffiti().HashTreeRoot()),\n\t\tb.GetProposerSlashings().HashTreeRoot(),\n\t\tb.GetAttesterSlashings().HashTreeRoot(),\n\t\tb.GetAttestations().HashTreeRoot(),\n\t\tb.GetDeposits().HashTreeRoot(),\n\t\tb.GetVoluntaryExits().HashTreeRoot(),\n\t\tb.syncAggregate.HashTreeRoot(),\n\t\tb.GetExecutionPayload().HashTreeRoot(),\n\t\tb.GetBlsToExecutionChanges().HashTreeRoot(),\n\t\t// KzgCommitments intentionally left blank - included separately for inclusion proof\n\t\t{},\n\t}\n\tif version.EqualsOrIsAfter(b.GetForkVersion(), version.Electra()) {\n\t\ter, err := b.GetExecutionRequests()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ttlrs = append(tlrs, er.HashTreeRoot())\n\t}\n\n\t// Ensure that the length returned is correct according to the fork version.\n\tif uint64(len(tlrs)) != b.Length() {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"top-level roots length (%d) does not match expected body length (%d)\",\n\t\t\tlen(tlrs), b.Length(),\n\t\t)\n\t}\n\n\treturn tlrs, nil\n}\n\n// Length returns the number of fields in the BeaconBlockBody struct\n// according to the fork version.\nfunc (b *BeaconBlockBody) Length() uint64 {\n\tif version.IsBefore(b.GetForkVersion(), version.Electra()) {\n\t\treturn BodyLengthDeneb\n\t}\n\treturn BodyLengthElectra\n}\n\nfunc (b *BeaconBlockBody) GetRandaoReveal() crypto.BLSSignature {\n\treturn b.RandaoReveal\n}\n\nfunc (b *BeaconBlockBody) SetRandaoReveal(reveal crypto.BLSSignature) {\n\tb.RandaoReveal = reveal\n}\n\nfunc (b *BeaconBlockBody) GetEth1Data() *Eth1Data {\n\treturn b.Eth1Data\n}\n\nfunc (b *BeaconBlockBody) SetEth1Data(eth1Data *Eth1Data) {\n\tb.Eth1Data = eth1Data\n}\n\nfunc (b *BeaconBlockBody) GetGraffiti() common.Bytes32 {\n\treturn b.Graffiti\n}\n\nfunc (b *BeaconBlockBody) SetGraffiti(graffiti common.Bytes32) {\n\tb.Graffiti = graffiti\n}\n\nfunc (b *BeaconBlockBody) GetProposerSlashings() ProposerSlashings {\n\treturn b.proposerSlashings\n}\n\nfunc (b *BeaconBlockBody) SetProposerSlashings(ps ProposerSlashings) {\n\tb.proposerSlashings = ps\n}\n\nfunc (b *BeaconBlockBody) GetAttesterSlashings() AttesterSlashings {\n\treturn b.attesterSlashings\n}\n\nfunc (b *BeaconBlockBody) SetAttesterSlashings(ps AttesterSlashings) {\n\tb.attesterSlashings = ps\n}\n\nfunc (b *BeaconBlockBody) GetVoluntaryExits() VoluntaryExits {\n\treturn b.voluntaryExits\n}\n\nfunc (b *BeaconBlockBody) SetVoluntaryExits(exits VoluntaryExits) {\n\tb.voluntaryExits = exits\n}\n\nfunc (b *BeaconBlockBody) GetDeposits() Deposits {\n\treturn b.Deposits\n}\n\nfunc (b *BeaconBlockBody) SetDeposits(deposits Deposits) {\n\tb.Deposits = deposits\n}\n\nfunc (b *BeaconBlockBody) GetAttestations() Attestations {\n\treturn b.attestations\n}\n\nfunc (b *BeaconBlockBody) SetAttestations(attestations Attestations) {\n\tb.attestations = attestations\n}\n\nfunc (b *BeaconBlockBody) GetSyncAggregate() *SyncAggregate {\n\treturn b.syncAggregate\n}\n\nfunc (b *BeaconBlockBody) SetSyncAggregate(syncAggregate *SyncAggregate) {\n\tb.syncAggregate = syncAggregate\n}\n\nfunc (b *BeaconBlockBody) GetExecutionPayload() *ExecutionPayload {\n\treturn b.ExecutionPayload\n}\n\nfunc (b *BeaconBlockBody) SetExecutionPayload(executionData *ExecutionPayload) {\n\tb.ExecutionPayload = executionData\n}\n\nfunc (b *BeaconBlockBody) GetBlsToExecutionChanges() BlsToExecutionChanges {\n\treturn b.blsToExecutionChanges\n}\n\nfunc (b *BeaconBlockBody) SetBlsToExecutionChanges(blsChanges BlsToExecutionChanges) {\n\tb.blsToExecutionChanges = blsChanges\n}\n\nfunc (b *BeaconBlockBody) GetBlobKzgCommitments() eip4844.KZGCommitments[common.ExecutionHash] {\n\treturn b.BlobKzgCommitments\n}\n\nfunc (b *BeaconBlockBody) SetBlobKzgCommitments(commitments eip4844.KZGCommitments[common.ExecutionHash]) {\n\tb.BlobKzgCommitments = commitments\n}\n\nfunc (b *BeaconBlockBody) GetExecutionRequests() (*ExecutionRequests, error) {\n\tif version.IsBefore(b.GetForkVersion(), version.Electra()) {\n\t\treturn nil, errors.Wrapf(ErrFieldNotSupportedOnFork, \"block version %d\", b.GetForkVersion())\n\t}\n\tif b.executionRequests == nil {\n\t\treturn nil, errors.New(\"retrieved execution requests is nil\")\n\t}\n\treturn b.executionRequests, nil\n}\n\nfunc (b *BeaconBlockBody) SetExecutionRequests(executionRequest *ExecutionRequests) error {\n\tif executionRequest == nil {\n\t\treturn errors.New(\"cannot set execution requests to nil\")\n\t}\n\tif version.IsBefore(b.GetForkVersion(), version.Electra()) {\n\t\treturn errors.Wrapf(ErrFieldNotSupportedOnFork, \"block version %d\", b.GetForkVersion())\n\t}\n\tb.executionRequests = executionRequest\n\treturn nil\n}\n"
  },
  {
    "path": "consensus-types/types/body_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\tsszutil \"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/math/log\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/karalabe/ssz\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc generateBeaconBlockBody(t *testing.T, v common.Version) types.BeaconBlockBody {\n\tversionable := types.NewVersionable(v)\n\tbody := types.BeaconBlockBody{\n\t\tVersionable:  versionable,\n\t\tRandaoReveal: [96]byte{1, 2, 3},\n\t\tEth1Data:     &types.Eth1Data{},\n\t\tGraffiti:     [32]byte{4, 5, 6},\n\t\tDeposits:     []*types.Deposit{},\n\t\tExecutionPayload: &types.ExecutionPayload{\n\t\t\tVersionable:   versionable,\n\t\t\tBaseFeePerGas: math.NewU256(0),\n\t\t},\n\t\tBlobKzgCommitments: []eip4844.KZGCommitment{},\n\t}\n\tbody.SetProposerSlashings(types.ProposerSlashings{})\n\tbody.SetAttesterSlashings(types.AttesterSlashings{})\n\tbody.SetAttestations(types.Attestations{})\n\tbody.SetSyncAggregate(&types.SyncAggregate{})\n\tbody.SetVoluntaryExits(types.VoluntaryExits{})\n\tbody.SetBlsToExecutionChanges(types.BlsToExecutionChanges{})\n\tif version.EqualsOrIsAfter(v, version.Electra()) {\n\t\trequire.NoError(t, body.SetExecutionRequests(&types.ExecutionRequests{}))\n\t}\n\treturn body\n}\n\nfunc TestBeaconBlockBodyBase(t *testing.T) {\n\tt.Parallel()\n\tbody := types.BeaconBlockBody{\n\t\tRandaoReveal: [96]byte{1, 2, 3},\n\t\tEth1Data:     &types.Eth1Data{},\n\t\tGraffiti:     [32]byte{4, 5, 6},\n\t\tDeposits:     []*types.Deposit{},\n\t}\n\n\trequire.Equal(t, bytes.B96{1, 2, 3}, body.GetRandaoReveal())\n\trequire.NotNil(t, body.GetEth1Data())\n\n\tnewGraffiti := [32]byte{7, 8, 9}\n\tbody.SetGraffiti(newGraffiti)\n\n\trequire.Equal(t, newGraffiti, [32]byte(body.GetGraffiti()))\n\trequire.NotNil(t, body.GetDeposits())\n}\n\nfunc TestBeaconBlockBody(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tversionable := types.NewVersionable(v)\n\t\tbody := types.BeaconBlockBody{\n\t\t\tVersionable:  versionable,\n\t\t\tRandaoReveal: [96]byte{1, 2, 3},\n\t\t\tEth1Data:     &types.Eth1Data{},\n\t\t\tGraffiti:     [32]byte{4, 5, 6},\n\t\t\tDeposits:     []*types.Deposit{},\n\t\t\tExecutionPayload: &types.ExecutionPayload{\n\t\t\t\tVersionable:   versionable,\n\t\t\t\tBaseFeePerGas: math.NewU256(0),\n\t\t\t},\n\t\t\tBlobKzgCommitments: []eip4844.KZGCommitment{},\n\t\t}\n\t\trequire.NotNil(t, body.GetExecutionPayload())\n\t\trequire.NotNil(t, body.GetBlobKzgCommitments())\n\t\tif version.EqualsOrIsAfter(v, version.Electra()) {\n\t\t\trequire.Equal(t, types.BodyLengthElectra, body.Length())\n\t\t} else {\n\t\t\trequire.Equal(t, types.BodyLengthDeneb, body.Length())\n\t\t}\n\t})\n}\n\nfunc TestBeaconBlockBody_SetBlobKzgCommitments(t *testing.T) {\n\tt.Parallel()\n\tbody := types.BeaconBlockBody{}\n\tcommitments := eip4844.KZGCommitments[common.ExecutionHash]{}\n\tbody.SetBlobKzgCommitments(commitments)\n\n\trequire.Equal(t, commitments, body.GetBlobKzgCommitments())\n}\n\nfunc TestBeaconBlockBody_SetRandaoReveal(t *testing.T) {\n\tt.Parallel()\n\tbody := types.BeaconBlockBody{}\n\trandaoReveal := crypto.BLSSignature{1, 2, 3}\n\tbody.SetRandaoReveal(randaoReveal)\n\n\trequire.Equal(t, randaoReveal, body.GetRandaoReveal())\n}\n\nfunc TestBeaconBlockBody_SetEth1Data(t *testing.T) {\n\tt.Parallel()\n\tbody := types.BeaconBlockBody{}\n\teth1Data := &types.Eth1Data{}\n\tbody.SetEth1Data(eth1Data)\n\n\trequire.Equal(t, eth1Data, body.GetEth1Data())\n}\n\nfunc TestBeaconBlockBody_SetDeposits(t *testing.T) {\n\tt.Parallel()\n\tbody := types.BeaconBlockBody{}\n\tdeposits := types.Deposits{}\n\tbody.SetDeposits(deposits)\n\n\trequire.Equal(t, deposits, body.GetDeposits())\n}\n\nfunc TestBeaconBlockBody_MarshalSSZ(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tbody := types.BeaconBlockBody{\n\t\t\tVersionable:        types.NewVersionable(v),\n\t\t\tRandaoReveal:       [96]byte{1, 2, 3},\n\t\t\tEth1Data:           &types.Eth1Data{},\n\t\t\tGraffiti:           [32]byte{4, 5, 6},\n\t\t\tDeposits:           []*types.Deposit{},\n\t\t\tExecutionPayload:   &types.ExecutionPayload{},\n\t\t\tBlobKzgCommitments: []eip4844.KZGCommitment{},\n\t\t}\n\t\tdata, err := body.MarshalSSZ()\n\n\t\trequire.NoError(t, err)\n\t\trequire.NotNil(t, data)\n\t})\n}\n\nfunc TestBeaconBlockBody_GetTopLevelRoots(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tbody := generateBeaconBlockBody(t, v)\n\t\troots, err := body.GetTopLevelRoots()\n\t\trequire.NoError(t, err)\n\t\trequire.NotNil(t, roots)\n\t\tif version.EqualsOrIsAfter(v, version.Electra()) {\n\t\t\trequire.Equal(t, types.BodyLengthElectra, uint64(len(roots)))\n\t\t} else {\n\t\t\trequire.Equal(t, types.BodyLengthDeneb, uint64(len(roots)))\n\t\t}\n\t})\n}\n\nfunc TestBeaconBlockBody_Empty(t *testing.T) {\n\tt.Parallel()\n\tbody := types.BeaconBlockBody{}\n\trequire.NotNil(t, body)\n}\n\n// Ensure that the ProposerSlashings field cannot be unmarshaled with data in it,\n// enforcing that it's unused.\nfunc TestBeaconBlockBody_UnusedProposerSlashingsEnforcement(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tblockBody := types.BeaconBlockBody{\n\t\t\tVersionable: types.NewVersionable(v),\n\t\t}\n\t\tunused := common.UnusedType(1)\n\t\tblockBody.SetProposerSlashings(types.ProposerSlashings{&unused})\n\t\t_, err := blockBody.MarshalSSZ()\n\t\trequire.Error(t, err)\n\n\t\tbuf := make([]byte, ssz.Size(&blockBody))\n\t\terr = ssz.EncodeToBytes(buf, &blockBody)\n\t\trequire.NoError(t, err)\n\n\t\tunmarshalledBody := types.NewEmptyBeaconBlockBodyWithVersion(v)\n\t\terr = sszutil.Unmarshal(buf, unmarshalledBody)\n\t\trequire.ErrorContains(t, err, \"must be unused\")\n\t})\n}\n\n// Ensure that the AttesterSlashings field cannot be unmarshaled with data in it,\n// enforcing that it's unused.\nfunc TestBeaconBlockBody_UnusedAttesterSlashingsEnforcement(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tblockBody := types.BeaconBlockBody{\n\t\t\tVersionable: types.NewVersionable(v),\n\t\t}\n\t\tunused := common.UnusedType(1)\n\t\tblockBody.SetAttesterSlashings(types.AttesterSlashings{&unused})\n\t\t_, err := blockBody.MarshalSSZ()\n\t\trequire.Error(t, err)\n\n\t\tbuf := make([]byte, ssz.Size(&blockBody))\n\t\terr = ssz.EncodeToBytes(buf, &blockBody)\n\t\trequire.NoError(t, err)\n\n\t\tunmarshalledBody := types.NewEmptyBeaconBlockBodyWithVersion(v)\n\t\terr = sszutil.Unmarshal(buf, unmarshalledBody)\n\t\trequire.ErrorContains(t, err, \"must be unused\")\n\t})\n}\n\n// Ensure that the Attestations field cannot be unmarshaled with data in it,\n// enforcing that it's unused.\nfunc TestBeaconBlockBody_UnusedAttestationsEnforcement(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tblockBody := types.BeaconBlockBody{\n\t\t\tVersionable: types.NewVersionable(v),\n\t\t}\n\t\tunused := common.UnusedType(1)\n\t\tblockBody.SetAttestations(types.Attestations{&unused})\n\t\t_, err := blockBody.MarshalSSZ()\n\t\trequire.Error(t, err)\n\n\t\tbuf := make([]byte, ssz.Size(&blockBody))\n\t\terr = ssz.EncodeToBytes(buf, &blockBody)\n\t\trequire.NoError(t, err)\n\n\t\tunmarshalledBody := types.NewEmptyBeaconBlockBodyWithVersion(v)\n\t\terr = sszutil.Unmarshal(buf, unmarshalledBody)\n\t\trequire.ErrorContains(t, err, \"must be unused\")\n\t})\n}\n\n// Ensure that the VoluntaryExits field cannot be unmarshaled with data in it,\n// enforcing that it's unused.\nfunc TestBeaconBlockBody_UnusedVoluntaryExitsEnforcement(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tblockBody := types.BeaconBlockBody{\n\t\t\tVersionable: types.NewVersionable(v),\n\t\t}\n\t\tunused := common.UnusedType(1)\n\t\tblockBody.SetVoluntaryExits(types.VoluntaryExits{&unused})\n\t\t_, err := blockBody.MarshalSSZ()\n\t\trequire.Error(t, err)\n\n\t\tbuf := make([]byte, ssz.Size(&blockBody))\n\t\terr = ssz.EncodeToBytes(buf, &blockBody)\n\t\trequire.NoError(t, err)\n\n\t\tunmarshalledBody := types.NewEmptyBeaconBlockBodyWithVersion(v)\n\t\terr = sszutil.Unmarshal(buf, unmarshalledBody)\n\t\trequire.ErrorContains(t, err, \"must be unused\")\n\t})\n}\n\n// Ensure that the BlsToExecutionChanges field cannot be unmarshaled with data in it,\n// enforcing that it's unused.\nfunc TestBeaconBlockBody_UnusedBlsToExecutionChangesEnforcement(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tblockBody := types.BeaconBlockBody{\n\t\t\tVersionable: types.NewVersionable(v),\n\t\t}\n\t\tunused := common.UnusedType(1)\n\t\tblockBody.SetBlsToExecutionChanges(types.BlsToExecutionChanges{&unused})\n\t\t_, err := blockBody.MarshalSSZ()\n\t\trequire.Error(t, err)\n\n\t\tbuf := make([]byte, ssz.Size(&blockBody))\n\t\terr = ssz.EncodeToBytes(buf, &blockBody)\n\t\trequire.NoError(t, err)\n\n\t\tunmarshalledBody := types.NewEmptyBeaconBlockBodyWithVersion(v)\n\t\terr = sszutil.Unmarshal(buf, unmarshalledBody)\n\t\trequire.ErrorContains(t, err, \"must be unused\")\n\t})\n}\n\nfunc TestBeaconBlockBody_RoundTrip_HashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tbody := generateBeaconBlockBody(t, v)\n\t\tdata, err := body.MarshalSSZ()\n\t\trequire.NoError(t, err)\n\t\trequire.NotNil(t, data)\n\n\t\tunmarshalledBody := types.NewEmptyBeaconBlockBodyWithVersion(v)\n\t\terr = sszutil.Unmarshal(data, unmarshalledBody)\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, body.HashTreeRoot(), unmarshalledBody.HashTreeRoot())\n\t})\n}\n\n// This test explains the calculation of the KZG commitment' inclusion proof depth.\nfunc Test_KZGCommitmentInclusionProofDepth(t *testing.T) {\n\tt.Parallel()\n\tmaxUint8 := uint64(^uint8(0))\n\tcs, err := spec.DevnetChainSpec()\n\trequire.NoError(t, err)\n\n\t// Depth of the partial BeaconBlockBody merkle tree. This is partial\n\t// because we only include as much as we need to prove the inclusion of\n\t// the KZG commitments.\n\tblockBodyMerkleDepth := uint64(log.ILog2Floor(uint64(types.KZGGeneralizedIndex)))\n\trequire.Less(t, blockBodyMerkleDepth, maxUint8)\n\n\t// The depth of the merkle tree of the KZG Commitments, including the +1\n\t// for the length mixin.\n\tcommitmentProofMerkleDepth := uint64(log.ILog2Ceil(cs.MaxBlobCommitmentsPerBlock())) + 1\n\trequire.Less(t, commitmentProofMerkleDepth, maxUint8)\n\n\t// InclusionProofDepth is the combined depth of all of these things.\n\texpectedInclusionProofDepth := blockBodyMerkleDepth + commitmentProofMerkleDepth\n\trequire.Less(t, expectedInclusionProofDepth, maxUint8)\n\n\t// Grab the inclusionProofDepth from beacon-kit.\n\tactualInclusionProofDepth := types.KZGInclusionProofDepth\n\trequire.Less(t, uint64(actualInclusionProofDepth), maxUint8)\n\n\trequire.Equal(t, uint8(expectedInclusionProofDepth), uint8(actualInclusionProofDepth))\n}\n"
  },
  {
    "path": "consensus-types/types/consolidation_request.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\tsszutil \"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/karalabe/ssz\"\n)\n\nconst sszConsolidationRequestSize = 116\n\n// Compile-time check to ensure ConsolidationRequest implements the necessary interfaces.\nvar (\n\t_ ssz.StaticObject            = (*ConsolidationRequest)(nil)\n\t_ constraints.SSZMarshallable = (*ConsolidationRequest)(nil)\n)\n\n// ConsolidationRequest is introduced in Pectra but not used by us.\n// We keep it so we can maintain parity tests with other SSZ implementations.\ntype ConsolidationRequest struct {\n\tSourceAddress common.ExecutionAddress\n\tSourcePubKey  crypto.BLSPubkey\n\tTargetPubKey  crypto.BLSPubkey\n}\n\n/* -------------------------------------------------------------------------- */\n/*                       Consolidation Request SSZ                            */\n/* -------------------------------------------------------------------------- */\n\nfunc (c *ConsolidationRequest) ValidateAfterDecodingSSZ() error {\n\treturn nil\n}\n\nfunc (c *ConsolidationRequest) DefineSSZ(codec *ssz.Codec) {\n\tssz.DefineStaticBytes(codec, &c.SourceAddress)\n\tssz.DefineStaticBytes(codec, &c.SourcePubKey)\n\tssz.DefineStaticBytes(codec, &c.TargetPubKey)\n}\n\nfunc (c *ConsolidationRequest) SizeSSZ(_ *ssz.Sizer) uint32 {\n\treturn sszConsolidationRequestSize\n}\n\nfunc (c *ConsolidationRequest) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(c))\n\treturn buf, ssz.EncodeToBytes(buf, c)\n}\n\n// HashTreeRoot returns the hash tree root of the Deposits.\nfunc (c *ConsolidationRequest) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(c)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                       Consolidation Requests SSZ                           */\n/* -------------------------------------------------------------------------- */\n\n// Compile-time check to ensure ConsolidationRequests implements the necessary interfaces.\nvar _ constraints.SSZMarshaler = (*ConsolidationRequests)(nil)\n\n// ConsolidationRequests is used for SSZ unmarshalling a list of ConsolidationRequest\ntype ConsolidationRequests []*ConsolidationRequest\n\n// MarshalSSZ marshals the ConsolidationRequests object to SSZ format by encoding each consolidation request individually.\nfunc (cr ConsolidationRequests) MarshalSSZ() ([]byte, error) {\n\treturn sszutil.MarshalItemsEIP7685(cr)\n}\n\n// ValidateAfterDecodingSSZ validates the ConsolidationRequests object after decoding.\nfunc (cr ConsolidationRequests) ValidateAfterDecodingSSZ() error {\n\tif len(cr) > constants.MaxConsolidationRequestsPerPayload {\n\t\treturn fmt.Errorf(\n\t\t\t\"invalid number of consolidation requests, got %d max %d\",\n\t\t\tlen(cr), constants.MaxConsolidationRequestsPerPayload,\n\t\t)\n\t}\n\treturn nil\n}\n\n// DecodeConsolidationRequests decodes SSZ data by decoding each request individually.\nfunc DecodeConsolidationRequests(data []byte) (ConsolidationRequests, error) {\n\tmaxSize := constants.MaxConsolidationRequestsPerPayload * sszConsolidationRequestSize\n\tif len(data) > maxSize {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"invalid consolidation requests SSZ size, requests should not be more than the \"+\n\t\t\t\t\"max per payload, got %d max %d\", len(data), maxSize,\n\t\t)\n\t}\n\tif len(data) < sszConsolidationRequestSize {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"invalid consolidation requests SSZ size, got %d expected at least %d\",\n\t\t\tlen(data), sszConsolidationRequestSize,\n\t\t)\n\t}\n\tif len(data)%sszConsolidationRequestSize != 0 {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"invalid data length: %d is not a multiple of consolidation request size %d\",\n\t\t\tlen(data), sszConsolidationRequestSize,\n\t\t)\n\t}\n\n\t// Use the EIP-7685 unmarshalItems helper.\n\treturn sszutil.UnmarshalItemsEIP7685(\n\t\tdata,\n\t\tsszConsolidationRequestSize,\n\t\tfunc() *ConsolidationRequest { return new(ConsolidationRequest) },\n\t)\n}\n"
  },
  {
    "path": "consensus-types/types/consolidation_request_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\tenginev1 \"github.com/prysmaticlabs/prysm/v5/proto/engine/v1\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestConsolidationRequest_ValidValuesSSZ(t *testing.T) {\n\tt.Parallel()\n\ttestCases := []struct {\n\t\tname                 string\n\t\tconsolidationRequest *types.ConsolidationRequest\n\t}{\n\t\t{\n\t\t\tname: \"basic\",\n\t\t\tconsolidationRequest: &types.ConsolidationRequest{\n\t\t\t\t// 20-byte execution address for SourceAddress\n\t\t\t\tSourceAddress: common.ExecutionAddress{\n\t\t\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t\t},\n\t\t\t\t// 48-byte public key for SourcePubKey\n\t\t\t\tSourcePubKey: crypto.BLSPubkey{\n\t\t\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t\t\t21, 22, 23, 24, 25, 26, 27, 28, 29, 30,\n\t\t\t\t\t31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n\t\t\t\t\t41, 42, 43, 44, 45, 46, 47, 48,\n\t\t\t\t},\n\t\t\t\t// 48-byte public key for TargetPubKey\n\t\t\t\tTargetPubKey: crypto.BLSPubkey{\n\t\t\t\t\t48, 47, 46, 45, 44, 43, 42, 41, 40, 39,\n\t\t\t\t\t38, 37, 36, 35, 34, 33, 32, 31, 30, 29,\n\t\t\t\t\t28, 27, 26, 25, 24, 23, 22, 21, 20, 19,\n\t\t\t\t\t18, 17, 16, 15, 14, 13, 12, 11, 10, 9,\n\t\t\t\t\t8, 7, 6, 5, 4, 3, 2, 1,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"max values\",\n\t\t\tconsolidationRequest: &types.ConsolidationRequest{\n\t\t\t\tSourceAddress: common.ExecutionAddress{\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t},\n\t\t\t\tSourcePubKey: crypto.BLSPubkey{\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t},\n\t\t\t\tTargetPubKey: crypto.BLSPubkey{\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"random-ish values\",\n\t\t\tconsolidationRequest: &types.ConsolidationRequest{\n\t\t\t\tSourceAddress: common.ExecutionAddress{\n\t\t\t\t\t7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\n\t\t\t\t\t17, 18, 19, 20, 21, 22, 23, 24, 25, 26,\n\t\t\t\t},\n\t\t\t\tSourcePubKey: crypto.BLSPubkey{\n\t\t\t\t\t7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\n\t\t\t\t\t17, 18, 19, 20, 21, 22, 23, 24, 25, 26,\n\t\t\t\t\t27, 28, 29, 30, 31, 32, 33, 34, 35, 36,\n\t\t\t\t\t37, 38, 39, 40, 41, 42, 43, 44, 45, 46,\n\t\t\t\t\t47, 48, 49, 50, 51, 52, 53, 54,\n\t\t\t\t},\n\t\t\t\tTargetPubKey: crypto.BLSPubkey{\n\t\t\t\t\t14, 15, 16, 17, 18, 19, 20, 21, 22, 23,\n\t\t\t\t\t24, 25, 26, 27, 28, 29, 30, 31, 32, 33,\n\t\t\t\t\t34, 35, 36, 37, 38, 39, 40, 41, 42, 43,\n\t\t\t\t\t44, 45, 46, 47, 48, 49, 50, 51, 52, 53,\n\t\t\t\t\t54, 55, 56, 57, 58, 59, 60, 61,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\t// Marshal the original consolidation request.\n\t\t\tcrBytes, err := tc.consolidationRequest.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\n\t\t\t// Unmarshal into a Prysm consolidation request.\n\t\t\tvar prysmCR enginev1.ConsolidationRequest\n\t\t\terr = prysmCR.UnmarshalSSZ(crBytes)\n\t\t\trequire.NoError(t, err)\n\n\t\t\tprysmHTR, err := prysmCR.HashTreeRoot()\n\t\t\trequire.NoError(t, err)\n\t\t\tcrHTR := tc.consolidationRequest.HashTreeRoot()\n\n\t\t\t// Compare the HashTreeRoots. This effectively tests that all fields were encoded correctly.\n\t\t\trequire.Equal(t, crHTR[:], prysmHTR[:])\n\n\t\t\t// Marshal the Prysm consolidation request.\n\t\t\tprysmCRBytes, err := prysmCR.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\n\t\t\t// Unmarshal back into a new ConsolidationRequest.\n\t\t\tvar recomputedCR types.ConsolidationRequest\n\t\t\terr = ssz.Unmarshal(prysmCRBytes, &recomputedCR)\n\t\t\trequire.NoError(t, err)\n\n\t\t\t// Compare that the original and recomputed consolidation requests match.\n\t\t\trequire.Equal(t, *tc.consolidationRequest, recomputedCR)\n\t\t})\n\t}\n}\n\n//nolint:paralleltest // Invalid SSZ values cannot be run in parallel due to zeroalloc, which is global shared memory.\nfunc TestConsolidationRequest_InvalidValuesUnmarshalSSZ(t *testing.T) {\n\t// Build a valid consolidation request to get a baseline valid payload.\n\tvalidConsolidation := &types.ConsolidationRequest{\n\t\tSourceAddress: common.ExecutionAddress{\n\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t},\n\t\tSourcePubKey: crypto.BLSPubkey{\n\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t21, 22, 23, 24, 25, 26, 27, 28, 29, 30,\n\t\t\t31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n\t\t\t41, 42, 43, 44, 45, 46, 47, 48,\n\t\t},\n\t\tTargetPubKey: crypto.BLSPubkey{\n\t\t\t48, 47, 46, 45, 44, 43, 42, 41, 40, 39,\n\t\t\t38, 37, 36, 35, 34, 33, 32, 31, 30, 29,\n\t\t\t28, 27, 26, 25, 24, 23, 22, 21, 20, 19,\n\t\t\t18, 17, 16, 15, 14, 13, 12, 11, 10, 9,\n\t\t\t8, 7, 6, 5, 4, 3, 2, 1,\n\t\t},\n\t}\n\tvalidBytes, err := validConsolidation.MarshalSSZ()\n\trequire.NoError(t, err)\n\n\t// Build a slice of invalid payloads.\n\tinvalidPayloads := [][]byte{\n\t\tnil,                       // nil slice\n\t\t{},                        // empty slice\n\t\t[]byte(\"this is not ssz\"), // arbitrary non-SSZ data\n\t\t{0x00, 0x01, 0x02},        // too short to be valid\n\t\t// A truncated valid payload.\n\t\tfunc() []byte {\n\t\t\tif len(validBytes) > 5 {\n\t\t\t\treturn validBytes[:len(validBytes)-5]\n\t\t\t}\n\t\t\treturn validBytes\n\t\t}(),\n\t\t// A valid payload with extra trailing bytes.\n\t\tfunc() []byte {\n\t\t\textra := []byte{0xAA, 0xBB, 0xCC, 0xDD}\n\t\t\treturn append(validBytes, extra...)\n\t\t}(),\n\t}\n\n\tfor i, payload := range invalidPayloads {\n\t\ti, payload := i, payload // capture loop variables\n\t\tt.Run(fmt.Sprintf(\"invalidConsolidation_%d\", i), func(t *testing.T) {\n\t\t\t// Ensure that calling UnmarshalSSZ does not panic and returns an error.\n\t\t\trequire.NotPanics(t, func() {\n\t\t\t\tvar c types.ConsolidationRequest\n\t\t\t\terr = ssz.Unmarshal(payload, &c)\n\t\t\t\trequire.Error(t, err, \"expected error for payload %v\", payload)\n\t\t\t})\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "consensus-types/types/deposit.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tfastssz \"github.com/ferranbt/fastssz\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// depositSize is the size of the SSZ encoding of a Deposit.\nconst depositSize = 192 // 48 + 32 + 8 + 96 + 8\n\n// Compile-time assertions to ensure Deposit implements necessary interfaces.\nvar (\n\t_ ssz.StaticObject                    = (*Deposit)(nil)\n\t_ constraints.SSZMarshallableRootable = (*Deposit)(nil)\n)\n\n// Deposit into the consensus layer from the deposit contract in the execution\n// layer.\ntype Deposit struct {\n\t// Public key of the validator specified in the deposit.\n\tPubkey crypto.BLSPubkey `json:\"pubkey\"`\n\t// A staking credentials with\n\t// 1 byte prefix + 11 bytes padding + 20 bytes address = 32 bytes.\n\tCredentials WithdrawalCredentials `json:\"credentials\"`\n\t// Deposit amount in gwei.\n\tAmount math.Gwei `json:\"amount\"`\n\t// Signature of the deposit data.\n\tSignature crypto.BLSSignature `json:\"signature\"`\n\t// Index of the deposit in the deposit contract.\n\tIndex uint64 `json:\"index\"`\n}\n\nfunc NewEmptyDeposit() *Deposit {\n\treturn &Deposit{}\n}\n\n// Equals returns true if the Deposit is equal to the other.\nfunc (d *Deposit) Equals(o *Deposit) bool {\n\treturn d.Pubkey == o.Pubkey &&\n\t\td.Credentials == o.Credentials &&\n\t\td.Amount == o.Amount &&\n\t\td.Signature == o.Signature &&\n\t\td.Index == o.Index\n}\n\n// VerifySignature verifies the deposit data and signature.\nfunc (d *Deposit) VerifySignature(\n\tforkData *ForkData,\n\tdomainType common.DomainType,\n\tsignatureVerificationFn func(\n\t\tpubkey crypto.BLSPubkey, message []byte, signature crypto.BLSSignature,\n\t) error,\n) error {\n\treturn (&DepositMessage{\n\t\tPubkey:      d.Pubkey,\n\t\tCredentials: d.Credentials,\n\t\tAmount:      d.Amount,\n\t}).VerifyCreateValidator(\n\t\tforkData, d.Signature,\n\t\tdomainType, signatureVerificationFn,\n\t)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// DefineSSZ defines the SSZ encoding for the Deposit object.\nfunc (d *Deposit) DefineSSZ(c *ssz.Codec) {\n\tssz.DefineStaticBytes(c, &d.Pubkey)\n\tssz.DefineStaticBytes(c, &d.Credentials)\n\tssz.DefineUint64(c, &d.Amount)\n\tssz.DefineStaticBytes(c, &d.Signature)\n\tssz.DefineUint64(c, &d.Index)\n}\n\n// MarshalSSZ marshals the Deposit object to SSZ format.\nfunc (d *Deposit) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(d))\n\treturn buf, ssz.EncodeToBytes(buf, d)\n}\n\nfunc (*Deposit) ValidateAfterDecodingSSZ() error { return nil }\n\n// SizeSSZ returns the SSZ encoded size of the Deposit object.\nfunc (d *Deposit) SizeSSZ(*ssz.Sizer) uint32 {\n\treturn depositSize\n}\n\n// HashTreeRoot computes the Merkleization of the Deposit object.\nfunc (d *Deposit) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(d)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   FastSSZ                                  */\n/* -------------------------------------------------------------------------- */\n\n// MarshalSSZTo marshals the Deposit object into a pre-allocated byte slice.\nfunc (d *Deposit) MarshalSSZTo(dst []byte) ([]byte, error) {\n\tbz, err := d.MarshalSSZ()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdst = append(dst, bz...)\n\treturn dst, nil\n}\n\n// HashTreeRootWith ssz hashes the Deposit object with a hasher.\nfunc (d *Deposit) HashTreeRootWith(hh fastssz.HashWalker) error {\n\tindx := hh.Index()\n\n\t// Field (0) 'Pubkey'\n\thh.PutBytes(d.Pubkey[:])\n\n\t// Field (1) 'Credentials'\n\thh.PutBytes(d.Credentials[:])\n\n\t// Field (2) 'Amount'\n\thh.PutUint64(uint64(d.Amount))\n\n\t// Field (3) 'Signature'\n\thh.PutBytes(d.Signature[:])\n\n\t// Field (4) 'Index'\n\thh.PutUint64(d.Index)\n\n\thh.Merkleize(indx)\n\treturn nil\n}\n\n// GetTree ssz hashes the Deposit object.\nfunc (d *Deposit) GetTree() (*fastssz.Node, error) {\n\treturn fastssz.ProofTree(d)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                             Getters and Setters                            */\n/* -------------------------------------------------------------------------- */\n\n// GetAmount returns the deposit amount in gwei.\nfunc (d *Deposit) GetAmount() math.Gwei {\n\treturn d.Amount\n}\n\n// GetPubkey returns the public key of the validator specified in the deposit.\nfunc (d *Deposit) GetPubkey() crypto.BLSPubkey {\n\treturn d.Pubkey\n}\n\n// GetIndex returns the index of the deposit in the deposit contract.\nfunc (d *Deposit) GetIndex() math.U64 {\n\treturn math.U64(d.Index)\n}\n\n// GetSignature returns the signature of the deposit data.\nfunc (d *Deposit) GetSignature() crypto.BLSSignature {\n\treturn d.Signature\n}\n\n// GetWithdrawalCredentials returns the staking credentials of the deposit.\nfunc (d *Deposit) GetWithdrawalCredentials() WithdrawalCredentials {\n\treturn d.Credentials\n}\n\n// HasEth1WithdrawalCredentials as defined in the Ethereum 2.0 specification:\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/validator.md#eth1_address_withdrawal_prefix\nfunc (d *Deposit) HasEth1WithdrawalCredentials() bool {\n\treturn d.Credentials.IsValidEth1WithdrawalCredentials()\n}\n"
  },
  {
    "path": "consensus-types/types/deposit_message.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// DepositMessage represents a deposit message as defined in the Ethereum 2.0\n// specification.\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#depositmessage\ntype DepositMessage struct {\n\t// Public key of the validator specified in the deposit.\n\tPubkey crypto.BLSPubkey `json:\"pubkey\"`\n\t// A staking credentials with\n\t// 1 byte prefix + 11 bytes padding + 20 bytes address = 32 bytes.\n\tCredentials WithdrawalCredentials `json:\"credentials\"`\n\t// Deposit amount in gwei.\n\tAmount math.Gwei `json:\"amount\"`\n}\n\n// CreateAndSignDepositMessage constructs and signs a deposit message.\nfunc CreateAndSignDepositMessage(\n\tforkData *ForkData,\n\tdomainType common.DomainType,\n\tsigner crypto.BLSSigner,\n\tcredentials WithdrawalCredentials,\n\tamount math.Gwei,\n) (*DepositMessage, crypto.BLSSignature, error) {\n\tdomain := forkData.ComputeDomain(domainType)\n\tdepositMessage := &DepositMessage{\n\t\tPubkey:      signer.PublicKey(),\n\t\tCredentials: credentials,\n\t\tAmount:      amount,\n\t}\n\tsigningRoot := ComputeSigningRoot(depositMessage, domain)\n\tsignature, err := signer.Sign(signingRoot[:])\n\tif err != nil {\n\t\treturn nil, crypto.BLSSignature{}, err\n\t}\n\n\treturn depositMessage, signature, nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// SizeSSZ returns the size of the DepositMessage object in SSZ encoding.\nfunc (*DepositMessage) SizeSSZ(*ssz.Sizer) uint32 {\n\t//nolint:mnd // 48 + 32 + 8 = 88.\n\treturn 88\n}\n\n// DefineSSZ defines the SSZ encoding for the DepositMessage object.\nfunc (dm *DepositMessage) DefineSSZ(codec *ssz.Codec) {\n\tssz.DefineStaticBytes(codec, &dm.Pubkey)\n\tssz.DefineStaticBytes(codec, &dm.Credentials)\n\tssz.DefineUint64(codec, &dm.Amount)\n}\n\n// HashTreeRoot computes the SSZ hash tree root of the DepositMessage object.\nfunc (dm *DepositMessage) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(dm)\n}\n\n// MarshalSSZTo marshals the DepositMessage object to SSZ format into the\n// provided\n// buffer.\nfunc (dm *DepositMessage) MarshalSSZTo(buf []byte) ([]byte, error) {\n\treturn buf, ssz.EncodeToBytes(buf, dm)\n}\n\n// MarshalSSZ marshals the DepositMessage object to SSZ format.\nfunc (dm *DepositMessage) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(dm))\n\treturn dm.MarshalSSZTo(buf)\n}\n\n// UnmarshalSSZ unmarshals the DepositMessage object from SSZ format.\nfunc (dm *DepositMessage) UnmarshalSSZ(buf []byte) error {\n\treturn ssz.DecodeFromBytes(buf, dm)\n}\n\n// VerifyCreateValidator verifies the deposit data when attempting to create a\n// new validator from a given deposit.\nfunc (dm *DepositMessage) VerifyCreateValidator(\n\tforkData *ForkData,\n\tsignature crypto.BLSSignature,\n\tdomainType common.DomainType,\n\tsignatureVerificationFn func(\n\t\tpubkey crypto.BLSPubkey, message []byte, signature crypto.BLSSignature,\n\t) error,\n) error {\n\tsigningRoot := ComputeSigningRoot(\n\t\tdm, forkData.ComputeDomain(domainType))\n\tif err := signatureVerificationFn(\n\t\tdm.Pubkey, signingRoot[:], signature,\n\t); err != nil {\n\t\treturn errors.Join(err, ErrDepositMessage)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "consensus-types/types/deposit_message_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"io\"\n\t\"testing\"\n\n\ttypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto/mocks\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tkaralabessz \"github.com/karalabe/ssz\"\n\t\"github.com/stretchr/testify/mock\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestCreateAndSignDepositMessage(t *testing.T) {\n\tt.Parallel()\n\tforkData := &types.ForkData{\n\t\tCurrentVersion:        common.Version{0x00, 0x00, 0x00, 0x04},\n\t\tGenesisValidatorsRoot: common.Root{0x00, 0x00, 0x00, 0x00},\n\t}\n\n\tdomainType := common.DomainType{\n\t\t0x01, 0x00, 0x00, 0x00,\n\t}\n\n\tmocksSigner := &mocks.Blssigner{}\n\tmocksSigner.On(\"PublicKey\").Return(crypto.BLSPubkey{})\n\tmocksSigner.On(\"Sign\", mock.Anything).Return(crypto.BLSSignature{}, nil)\n\n\tcredentials := types.WithdrawalCredentials{}\n\tamount := math.Gwei(32)\n\n\tdepositMessage, signature, err := types.CreateAndSignDepositMessage(\n\t\tforkData, domainType, mocksSigner, credentials, amount,\n\t)\n\n\trequire.NoError(t, err)\n\trequire.NotNil(t, depositMessage)\n\trequire.NotNil(t, signature)\n}\n\nfunc TestDepositMessage_MarshalUnmarshalSSZ(t *testing.T) {\n\tt.Parallel()\n\toriginal := &types.DepositMessage{\n\t\tPubkey:      crypto.BLSPubkey{},\n\t\tCredentials: types.WithdrawalCredentials{},\n\t\tAmount:      math.Gwei(1000),\n\t}\n\n\tdata, err := original.MarshalSSZ()\n\trequire.NoError(t, err)\n\trequire.NotNil(t, data)\n\tvar unmarshalled types.DepositMessage\n\terr = unmarshalled.UnmarshalSSZ(data)\n\n\trequire.NoError(t, err)\n\trequire.Equal(t, original, &unmarshalled)\n}\n\nfunc TestDepositMessage_MarshalSSZTo(t *testing.T) {\n\tt.Parallel()\n\toriginal := &types.DepositMessage{\n\t\tPubkey:      crypto.BLSPubkey{},\n\t\tCredentials: types.WithdrawalCredentials{},\n\t\tAmount:      math.Gwei(1000),\n\t}\n\n\tbuf := make([]byte, karalabessz.Size(original))\n\tdata, err := original.MarshalSSZTo(buf)\n\trequire.NoError(t, err)\n\n\tvar unmarshalled types.DepositMessage\n\terr = unmarshalled.UnmarshalSSZ(data)\n\trequire.NoError(t, err)\n\trequire.Equal(t, original, &unmarshalled)\n}\n\nfunc TestDepositMessage_UnmarshalSSZ_ErrSize(t *testing.T) {\n\tt.Parallel()\n\tbuf := make([]byte, 10) // size less than 88\n\n\tvar unmarshalledDepositMessage types.DepositMessage\n\terr := unmarshalledDepositMessage.UnmarshalSSZ(buf)\n\n\trequire.ErrorIs(t, err, io.ErrUnexpectedEOF)\n}\n\nfunc TestDepositMessage_VerifyCreateValidator_Error(t *testing.T) {\n\tt.Parallel()\n\toriginal := &types.DepositMessage{\n\t\tPubkey:      crypto.BLSPubkey{},\n\t\tCredentials: types.WithdrawalCredentials{},\n\t\tAmount:      math.Gwei(1000),\n\t}\n\n\tforkData := &types.ForkData{\n\t\tCurrentVersion:        common.Version{0, 0, 0, 0},\n\t\tGenesisValidatorsRoot: common.Root{},\n\t}\n\n\tsignature := crypto.BLSSignature{}\n\n\t// Define a signature verification function that always returns an error\n\tsignatureVerificationFn := func(\n\t\t_ crypto.BLSPubkey, _ []byte, _ crypto.BLSSignature,\n\t) error {\n\t\treturn errors.New(\"signature verification failed\")\n\t}\n\tdomainType := common.DomainType{\n\t\t0x01, 0x00, 0x00, 0x00,\n\t}\n\n\terr := original.VerifyCreateValidator(\n\t\tforkData, signature, domainType, signatureVerificationFn,\n\t)\n\n\trequire.ErrorIs(t, err, types.ErrDepositMessage)\n}\n"
  },
  {
    "path": "consensus-types/types/deposit_request.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n)\n\n// DepositRequest is introduced in EIP6110 which is currently not processed.\ntype DepositRequest = Deposit\n\n// Compile-time check to ensure DepositRequests implements the necessary interfaces.\nvar _ constraints.SSZMarshaler = (*DepositRequests)(nil)\n\n// DepositRequests is used for SSZ unmarshalling a list of DepositRequest\ntype DepositRequests []*DepositRequest\n\n// MarshalSSZ marshals the Deposits object to SSZ format by encoding each deposit individually.\nfunc (dr DepositRequests) MarshalSSZ() ([]byte, error) {\n\treturn ssz.MarshalItemsEIP7685(dr)\n}\n\n// ValidateAfterDecodingSSZ validates the DepositRequests object after decoding.\nfunc (dr DepositRequests) ValidateAfterDecodingSSZ() error {\n\tif len(dr) > constants.MaxDepositRequestsPerPayload {\n\t\treturn fmt.Errorf(\n\t\t\t\"invalid number of deposit requests, got %d max %d\",\n\t\t\tlen(dr), constants.MaxDepositRequestsPerPayload,\n\t\t)\n\t}\n\treturn nil\n}\n\n// DecodeDepositRequests decodes SSZ data by decoding each request individually.\nfunc DecodeDepositRequests(data []byte) (DepositRequests, error) {\n\tmaxSize := constants.MaxDepositRequestsPerPayload * depositSize\n\tif len(data) > maxSize {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"invalid deposit requests SSZ size, requests should not be more than the max per \"+\n\t\t\t\t\"payload, got %d max %d\", len(data), maxSize,\n\t\t)\n\t}\n\tif len(data) < depositSize {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"invalid deposit requests SSZ size, got %d expected at least %d\",\n\t\t\tlen(data), depositSize,\n\t\t)\n\t}\n\n\t// Use the EIP-7685 unmarshalItems helper.\n\treturn ssz.UnmarshalItemsEIP7685(\n\t\tdata,\n\t\tdepositSize,\n\t\tfunc() *DepositRequest { return new(DepositRequest) },\n\t)\n}\n"
  },
  {
    "path": "consensus-types/types/deposit_request_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/ethereum/go-ethereum/common/hexutil\"\n\t\"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil\"\n\tenginev1 \"github.com/prysmaticlabs/prysm/v5/proto/engine/v1\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestDepositRequest_ValidValuesSSZ(t *testing.T) {\n\tt.Parallel()\n\ttestCases := []struct {\n\t\tname           string\n\t\tdepositRequest *types.DepositRequest\n\t}{\n\t\t{\n\t\t\tname: \"basic\",\n\t\t\tdepositRequest: &types.DepositRequest{\n\t\t\t\t// 48-byte public key\n\t\t\t\tPubkey: crypto.BLSPubkey{\n\t\t\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t\t\t21, 22, 23, 24, 25, 26, 27, 28, 29, 30,\n\t\t\t\t\t31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n\t\t\t\t\t41, 42, 43, 44, 45, 46, 47, 48,\n\t\t\t\t},\n\t\t\t\t// 32-byte withdrawal credentials\n\t\t\t\tCredentials: [32]byte{\n\t\t\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t\t\t21, 22, 23, 24, 25, 26, 27, 28, 29, 30,\n\t\t\t\t\t31, 32,\n\t\t\t\t},\n\t\t\t\tAmount: 1000,\n\t\t\t\t// 96-byte BLS signature\n\t\t\t\tSignature: crypto.BLSSignature{\n\t\t\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t\t\t21, 22, 23, 24, 25, 26, 27, 28, 29, 30,\n\t\t\t\t\t31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n\t\t\t\t\t41, 42, 43, 44, 45, 46, 47, 48, 49, 50,\n\t\t\t\t\t51, 52, 53, 54, 55, 56, 57, 58, 59, 60,\n\t\t\t\t\t61, 62, 63, 64, 65, 66, 67, 68, 69, 70,\n\t\t\t\t\t71, 72, 73, 74, 75, 76, 77, 78, 79, 80,\n\t\t\t\t\t81, 82, 83, 84, 85, 86, 87, 88, 89, 90,\n\t\t\t\t\t91, 92, 93, 94, 95, 96,\n\t\t\t\t},\n\t\t\t\tIndex: 1,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"zero amount\",\n\t\t\tdepositRequest: &types.DepositRequest{\n\t\t\t\tPubkey: crypto.BLSPubkey{\n\t\t\t\t\t10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\n\t\t\t\t\t20, 21, 22, 23, 24, 25, 26, 27, 28, 29,\n\t\t\t\t\t30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\n\t\t\t\t\t40, 41, 42, 43, 44, 45, 46, 47, 48,\n\t\t\t\t},\n\t\t\t\tCredentials: [32]byte{\n\t\t\t\t\t10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\n\t\t\t\t\t20, 21, 22, 23, 24, 25, 26, 27, 28, 29,\n\t\t\t\t\t30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\n\t\t\t\t\t40, 41,\n\t\t\t\t},\n\t\t\t\tAmount: 0,\n\t\t\t\tSignature: crypto.BLSSignature{\n\t\t\t\t\t10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\n\t\t\t\t\t20, 21, 22, 23, 24, 25, 26, 27, 28, 29,\n\t\t\t\t\t30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\n\t\t\t\t\t40, 41, 42, 43, 44, 45, 46, 47, 48, 49,\n\t\t\t\t\t50, 51, 52, 53, 54, 55, 56, 57, 58, 59,\n\t\t\t\t\t60, 61, 62, 63, 64, 65, 66, 67, 68, 69,\n\t\t\t\t\t70, 71, 72, 73, 74, 75, 76, 77, 78, 79,\n\t\t\t\t\t80, 81, 82, 83, 84, 85, 86, 87, 88, 89,\n\t\t\t\t\t90, 91, 92, 93, 94, 95, 96,\n\t\t\t\t},\n\t\t\t\tIndex: 2,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"max values\",\n\t\t\tdepositRequest: &types.DepositRequest{\n\t\t\t\tPubkey: crypto.BLSPubkey{\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t},\n\t\t\t\tCredentials: [32]byte{\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255,\n\t\t\t\t},\n\t\t\t\tAmount: 1<<64 - 1,\n\t\t\t\tSignature: crypto.BLSSignature{\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255,\n\t\t\t\t},\n\t\t\t\tIndex: 3,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"random-ish values\",\n\t\t\tdepositRequest: &types.DepositRequest{\n\t\t\t\tPubkey: crypto.BLSPubkey{\n\t\t\t\t\t7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\n\t\t\t\t\t17, 18, 19, 20, 21, 22, 23, 24, 25, 26,\n\t\t\t\t\t27, 28, 29, 30, 31, 32, 33, 34, 35, 36,\n\t\t\t\t\t37, 38, 39, 40, 41, 42, 43, 44, 45, 46,\n\t\t\t\t\t47, 48, 49, 50, 51, 52, 53, 54,\n\t\t\t\t},\n\t\t\t\tCredentials: [32]byte{\n\t\t\t\t\t7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\n\t\t\t\t\t17, 18, 19, 20, 21, 22, 23, 24, 25, 26,\n\t\t\t\t\t27, 28, 29, 30, 31, 32, 33, 34, 35, 36,\n\t\t\t\t\t37, 38,\n\t\t\t\t},\n\t\t\t\tAmount: 54321,\n\t\t\t\tSignature: crypto.BLSSignature{\n\t\t\t\t\t7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\n\t\t\t\t\t17, 18, 19, 20, 21, 22, 23, 24, 25, 26,\n\t\t\t\t\t27, 28, 29, 30, 31, 32, 33, 34, 35, 36,\n\t\t\t\t\t37, 38, 39, 40, 41, 42, 43, 44, 45, 46,\n\t\t\t\t\t47, 48, 49, 50, 51, 52, 53, 54, 55, 56,\n\t\t\t\t\t57, 58, 59, 60, 61, 62, 63, 64, 65, 66,\n\t\t\t\t\t67, 68, 69, 70, 71, 72, 73, 74, 75, 76,\n\t\t\t\t\t77, 78, 79, 80, 81, 82, 83, 84, 85, 86,\n\t\t\t\t\t87, 88, 89, 90, 91, 92, 93, 94, 95, 96,\n\t\t\t\t},\n\t\t\t\tIndex: 4,\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\t// Marshal the original deposit request.\n\t\t\tdepositRequestBytes, err := tc.depositRequest.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\n\t\t\t// Unmarshal into a Prysm deposit request.\n\t\t\tvar prysmDeposit enginev1.DepositRequest\n\t\t\terr = prysmDeposit.UnmarshalSSZ(depositRequestBytes)\n\t\t\trequire.NoError(t, err)\n\n\t\t\t// Compare the HashTreeRoots: first compute the HTRs.\n\t\t\tprysmHTR, err := prysmDeposit.HashTreeRoot()\n\t\t\trequire.NoError(t, err)\n\t\t\tdepositHTR := tc.depositRequest.HashTreeRoot()\n\t\t\t// Compare the HashTreeRoots to ensure all fields were correctly interpreted.\n\t\t\trequire.Equal(t, depositHTR[:], prysmHTR[:])\n\n\t\t\t// Marshal the Prysm deposit request.\n\t\t\tprysmDepositBytes, err := prysmDeposit.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\n\t\t\t// Unmarshal back into a new DepositRequest.\n\t\t\tvar recomputedDepositRequest types.DepositRequest\n\t\t\terr = ssz.Unmarshal(prysmDepositBytes, &recomputedDepositRequest)\n\t\t\trequire.NoError(t, err)\n\n\t\t\t// Compare that the original and recomputed deposit requests match.\n\t\t\trequire.Equal(t, *tc.depositRequest, recomputedDepositRequest)\n\t\t})\n\t}\n}\n\n//nolint:paralleltest // Invalid SSZ values cannot be run in parallel due to zeroalloc, which is global shared memory.\nfunc TestDepositRequest_InvalidValuesUnmarshalSSZ(t *testing.T) {\n\t// Build a valid deposit request and marshal it to obtain a baseline valid payload.\n\tvalidDeposit := &types.DepositRequest{\n\t\t// 48-byte public key\n\t\tPubkey: crypto.BLSPubkey{\n\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t21, 22, 23, 24, 25, 26, 27, 28, 29, 30,\n\t\t\t31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n\t\t\t41, 42, 43, 44, 45, 46, 47, 48,\n\t\t},\n\t\t// 32-byte withdrawal credentials\n\t\tCredentials: [32]byte{\n\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t21, 22, 23, 24, 25, 26, 27, 28, 29, 30,\n\t\t\t31, 32,\n\t\t},\n\t\tAmount: 1000,\n\t\t// 96-byte BLS signature\n\t\tSignature: crypto.BLSSignature{\n\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t21, 22, 23, 24, 25, 26, 27, 28, 29, 30,\n\t\t\t31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n\t\t\t41, 42, 43, 44, 45, 46, 47, 48, 49, 50,\n\t\t\t51, 52, 53, 54, 55, 56, 57, 58, 59, 60,\n\t\t\t61, 62, 63, 64, 65, 66, 67, 68, 69, 70,\n\t\t\t71, 72, 73, 74, 75, 76, 77, 78, 79, 80,\n\t\t\t81, 82, 83, 84, 85, 86, 87, 88, 89, 90,\n\t\t\t91, 92, 93, 94, 95, 96,\n\t\t},\n\t\tIndex: 1,\n\t}\n\tvalidBytes, err := validDeposit.MarshalSSZ()\n\trequire.NoError(t, err)\n\n\t// Build a slice of invalid payloads.\n\tinvalidPayloads := [][]byte{\n\t\tnil,                       // nil slice\n\t\t{},                        // empty slice\n\t\t[]byte(\"this is not ssz\"), // arbitrary non-SSZ data\n\t\t{0x00, 0x01, 0x02},        // too short to be valid\n\t\t// A truncated valid payload.\n\t\tfunc() []byte {\n\t\t\tif len(validBytes) > 5 {\n\t\t\t\treturn validBytes[:len(validBytes)-5]\n\t\t\t}\n\t\t\treturn validBytes\n\t\t}(),\n\t\t// A valid payload with extra trailing bytes.\n\t\tfunc() []byte {\n\t\t\textra := []byte{0xAA, 0xBB, 0xCC, 0xDD}\n\t\t\treturn append(validBytes, extra...)\n\t\t}(),\n\t}\n\n\t// Iterate over each invalid payload.\n\tfor i, payload := range invalidPayloads {\n\t\ti, payload := i, payload // capture range variables\n\t\tt.Run(fmt.Sprintf(\"invalidPayload_%d\", i), func(t *testing.T) {\n\t\t\trequire.NotPanics(t, func() {\n\t\t\t\tvar d types.DepositRequest\n\t\t\t\terr = ssz.Unmarshal(payload, &d)\n\t\t\t\t// We expect an error for every invalid payload.\n\t\t\t\trequire.Error(t, err, \"expected error for payload %v\", payload)\n\t\t\t})\n\t\t})\n\t}\n}\n\nfunc TestDepositRequests_ValidValuesSSZ(t *testing.T) {\n\tt.Parallel()\n\ttestCases := []struct {\n\t\tname           string\n\t\tdepositRequest types.DepositRequests\n\t}{\n\t\t{\n\t\t\tname: \"basic\",\n\t\t\tdepositRequest: []*types.DepositRequest{\n\t\t\t\t{\n\t\t\t\t\t// 48-byte public key\n\t\t\t\t\tPubkey: crypto.BLSPubkey{\n\t\t\t\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t\t\t\t21, 22, 23, 24, 25, 26, 27, 28, 29, 30,\n\t\t\t\t\t\t31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n\t\t\t\t\t\t41, 42, 43, 44, 45, 46, 47, 48,\n\t\t\t\t\t},\n\t\t\t\t\t// 32-byte withdrawal credentials\n\t\t\t\t\tCredentials: [32]byte{\n\t\t\t\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t\t\t\t21, 22, 23, 24, 25, 26, 27, 28, 29, 30,\n\t\t\t\t\t\t31, 32,\n\t\t\t\t\t},\n\t\t\t\t\tAmount: 1000,\n\t\t\t\t\t// 96-byte BLS signature\n\t\t\t\t\tSignature: crypto.BLSSignature{\n\t\t\t\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t\t\t\t21, 22, 23, 24, 25, 26, 27, 28, 29, 30,\n\t\t\t\t\t\t31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n\t\t\t\t\t\t41, 42, 43, 44, 45, 46, 47, 48, 49, 50,\n\t\t\t\t\t\t51, 52, 53, 54, 55, 56, 57, 58, 59, 60,\n\t\t\t\t\t\t61, 62, 63, 64, 65, 66, 67, 68, 69, 70,\n\t\t\t\t\t\t71, 72, 73, 74, 75, 76, 77, 78, 79, 80,\n\t\t\t\t\t\t81, 82, 83, 84, 85, 86, 87, 88, 89, 90,\n\t\t\t\t\t\t91, 92, 93, 94, 95, 96,\n\t\t\t\t\t},\n\t\t\t\t\tIndex: 1,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\t// Marshal the original deposit request.\n\t\t\tdepositRequestBytes, err := tc.depositRequest.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\n\t\t\t// Unmarshal back into a new DepositRequest.\n\t\t\trecomputedDepositRequest, err := types.DecodeDepositRequests(depositRequestBytes)\n\t\t\trequire.NoError(t, err)\n\n\t\t\t// Compare that the original and recomputed deposit requests match.\n\t\t\trequire.Equal(t, tc.depositRequest, recomputedDepositRequest)\n\t\t})\n\t}\n}\n\n// Tests below are adapted from Prysm\n// https://github.com/prysmaticlabs/prysm/blob/develop/proto/engine/v1/electra_test.go#L198-L240\n\nconst depositRequestsSSZHex = \"0x706b000000000000000000000000000000000000000000000000000000000000000000000000000000000\" +\n\t\"0000000000077630000000000000000000000000000000000000000000000000000000000007b00000000000000736967000000000000000\" +\n\t\"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\" +\n\t\"00000000000000000000000000000000000000000000000000000000000c801000000000000706b000000000000000000000000000000000\" +\n\t\"0000000000000000000000000000000000000000000000000000000000077630000000000000000000000000000000000000000000000000\" +\n\t\"000000000009001000000000000736967000000000000000000000000000000000000000000000000000000000000000000000000000000\" +\n\t\"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020\" +\n\t\"00000000000000\"\n\nfunc TestUnmarshalItems_OK(t *testing.T) {\n\tt.Parallel()\n\tdrb, err := hexutil.Decode(depositRequestsSSZHex)\n\trequire.NoError(t, err)\n\texampleRequest := &types.DepositRequest{}\n\tdepositRequests, err := ssz.UnmarshalItemsEIP7685(\n\t\tdrb,\n\t\tint(exampleRequest.SizeSSZ(nil)),\n\t\tfunc() *types.DepositRequest { return &types.DepositRequest{} })\n\trequire.NoError(t, err)\n\n\texampleRequest1 := &types.DepositRequest{\n\t\tPubkey:      crypto.BLSPubkey(bytesutil.PadTo([]byte(\"pk\"), 48)),\n\t\tCredentials: types.WithdrawalCredentials(bytesutil.PadTo([]byte(\"wc\"), 32)),\n\t\tAmount:      123,\n\t\tSignature:   crypto.BLSSignature(bytesutil.PadTo([]byte(\"sig\"), 96)),\n\t\tIndex:       456,\n\t}\n\texampleRequest2 := &types.DepositRequest{\n\t\tPubkey:      crypto.BLSPubkey(bytesutil.PadTo([]byte(\"pk\"), 48)),\n\t\tCredentials: types.WithdrawalCredentials(bytesutil.PadTo([]byte(\"wc\"), 32)),\n\t\tAmount:      400,\n\t\tSignature:   crypto.BLSSignature(bytesutil.PadTo([]byte(\"sig\"), 96)),\n\t\tIndex:       32,\n\t}\n\trequire.Equal(t, []*types.DepositRequest{exampleRequest1, exampleRequest2}, depositRequests)\n}\n\nfunc TestMarshalItems_OK(t *testing.T) {\n\tt.Parallel()\n\texampleRequest1 := &types.DepositRequest{\n\t\tPubkey:      crypto.BLSPubkey(bytesutil.PadTo([]byte(\"pk\"), 48)),\n\t\tCredentials: types.WithdrawalCredentials(bytesutil.PadTo([]byte(\"wc\"), 32)),\n\t\tAmount:      123,\n\t\tSignature:   crypto.BLSSignature(bytesutil.PadTo([]byte(\"sig\"), 96)),\n\t\tIndex:       456,\n\t}\n\texampleRequest2 := &types.DepositRequest{\n\t\tPubkey:      crypto.BLSPubkey(bytesutil.PadTo([]byte(\"pk\"), 48)),\n\t\tCredentials: types.WithdrawalCredentials(bytesutil.PadTo([]byte(\"wc\"), 32)),\n\t\tAmount:      400,\n\t\tSignature:   crypto.BLSSignature(bytesutil.PadTo([]byte(\"sig\"), 96)),\n\t\tIndex:       32,\n\t}\n\tdrbs, err := ssz.MarshalItemsEIP7685([]*types.DepositRequest{exampleRequest1, exampleRequest2})\n\trequire.NoError(t, err)\n\trequire.Equal(t, depositRequestsSSZHex, hexutil.Encode(drbs))\n}\n"
  },
  {
    "path": "consensus-types/types/deposit_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tfastssz \"github.com/ferranbt/fastssz\"\n\tkaralabessz \"github.com/karalabe/ssz\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// generateValidDeposit generates a valid deposit for testing purposes.\nfunc generateValidDeposit() *types.Deposit {\n\tvar pubKey crypto.BLSPubkey\n\tvar signature crypto.BLSSignature\n\tvar credentials types.WithdrawalCredentials\n\tamount := math.Gwei(32)\n\tindex := uint64(1)\n\n\treturn &types.Deposit{\n\t\tPubkey:      pubKey,\n\t\tCredentials: credentials,\n\t\tAmount:      amount,\n\t\tSignature:   signature,\n\t\tIndex:       index,\n\t}\n}\n\nfunc TestDeposit_Equals(t *testing.T) {\n\tt.Parallel()\n\t// Create base deposit\n\tdeposit1 := generateValidDeposit()\n\n\t// Test equal deposits\n\tdeposit2 := &types.Deposit{\n\t\tPubkey:      deposit1.Pubkey,\n\t\tCredentials: deposit1.Credentials,\n\t\tAmount:      deposit1.Amount,\n\t\tSignature:   deposit1.Signature,\n\t\tIndex:       deposit1.Index,\n\t}\n\trequire.True(t, deposit1.Equals(deposit2))\n\n\t// Test different pubkey\n\tdifferentPubkey := deposit2\n\tdifferentPubkey.Pubkey[0] = 0x01\n\trequire.False(t, deposit1.Equals(differentPubkey))\n\n\t// Test different credentials\n\tdifferentCreds := deposit2\n\tdifferentCreds.Credentials[0] = 0x01\n\trequire.False(t, deposit1.Equals(differentCreds))\n\n\t// Test different amount\n\tdifferentAmount := deposit2\n\tdifferentAmount.Amount = math.Gwei(16)\n\trequire.False(t, deposit1.Equals(differentAmount))\n\n\t// Test different signature\n\tdifferentSig := deposit2\n\tdifferentSig.Signature[0] = 0x01\n\trequire.False(t, deposit1.Equals(differentSig))\n\n\t// Test different index\n\tdifferentIndex := deposit2\n\tdifferentIndex.Index = 2\n\trequire.False(t, deposit1.Equals(differentIndex))\n}\n\nfunc TestDeposit_MarshalUnmarshalSSZ(t *testing.T) {\n\tt.Parallel()\n\toriginalDeposit := generateValidDeposit()\n\n\t// Marshal the original deposit to SSZ\n\tsszDeposit, err := originalDeposit.MarshalSSZ()\n\trequire.NoError(t, err)\n\trequire.NotNil(t, sszDeposit)\n\n\tunmarshalledDeposit := new(types.Deposit)\n\terr = ssz.Unmarshal(sszDeposit, unmarshalledDeposit)\n\trequire.NoError(t, err)\n\trequire.Equal(t, originalDeposit, unmarshalledDeposit)\n}\n\nfunc TestDeposit_MarshalSSZTo(t *testing.T) {\n\tt.Parallel()\n\tdeposit := generateValidDeposit()\n\tbuf := make([]byte, karalabessz.Size(deposit))\n\ttarget, err := deposit.MarshalSSZTo(buf)\n\trequire.NoError(t, err)\n\trequire.NotNil(t, target)\n}\n\nfunc TestDeposit_HashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\tdeposit := generateValidDeposit()\n\trequire.NotPanics(t, func() {\n\t\t_ = deposit.HashTreeRoot()\n\t})\n}\n\nfunc TestDeposit_SizeSSZ(t *testing.T) {\n\tt.Parallel()\n\tdeposit := generateValidDeposit()\n\n\trequire.Equal(t, uint32(192), karalabessz.Size(deposit))\n}\n\nfunc TestDeposit_HashTreeRootWith(t *testing.T) {\n\tt.Parallel()\n\tdeposit := generateValidDeposit()\n\trequire.NotNil(t, deposit)\n\thasher := fastssz.NewHasher()\n\trequire.NotNil(t, hasher)\n\terr := deposit.HashTreeRootWith(hasher)\n\trequire.NoError(t, err)\n}\n\nfunc TestDeposit_GetTree(t *testing.T) {\n\tt.Parallel()\n\tdeposit := generateValidDeposit()\n\t_, err := deposit.GetTree()\n\trequire.NoError(t, err)\n}\n\nfunc TestDeposit_UnmarshalSSZ_ErrSize(t *testing.T) {\n\tt.Parallel()\n\t// Create a byte slice of incorrect size\n\tbuf := make([]byte, 10) // size less than 192\n\n\tvar unmarshalledDeposit types.Deposit\n\terr := ssz.Unmarshal(buf, &unmarshalledDeposit)\n\trequire.ErrorIs(t, err, io.ErrUnexpectedEOF)\n}\n\nfunc TestDeposit_VerifySignature(t *testing.T) {\n\tt.Parallel()\n\tdeposit := generateValidDeposit()\n\n\tforkData := &types.ForkData{\n\t\tCurrentVersion:        common.Version{0x00, 0x00, 0x00, 0x04},\n\t\tGenesisValidatorsRoot: common.Root{0x00, 0x00, 0x00, 0x00},\n\t}\n\n\tsignatureVerificationFn := func(\n\t\t_ crypto.BLSPubkey, _ []byte, _ crypto.BLSSignature,\n\t) error {\n\t\treturn nil\n\t}\n\n\terrVerify := deposit.VerifySignature(forkData, common.DomainType{\n\t\t0x01, 0x00, 0x00, 0x00,\n\t}, signatureVerificationFn)\n\trequire.NoError(t, errVerify)\n}\n\nfunc TestDeposit_Getters(t *testing.T) {\n\tt.Parallel()\n\tdeposit := generateValidDeposit()\n\n\trequire.Equal(t, deposit.Pubkey, deposit.GetPubkey())\n\trequire.Equal(t, deposit.Credentials, deposit.GetWithdrawalCredentials())\n\trequire.Equal(t, deposit.Amount, deposit.GetAmount())\n\trequire.Equal(t, deposit.Signature, deposit.GetSignature())\n\trequire.Equal(t, math.U64(deposit.Index), deposit.GetIndex())\n}\n"
  },
  {
    "path": "consensus-types/types/deposits.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//nolint:dupl // False positive detected.\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// Deposits is a type alias for a SSZ list of Deposit containers.\ntype Deposits []*Deposit\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// SizeSSZ returns the SSZ encoded size in bytes for the Deposits.\nfunc (ds Deposits) SizeSSZ(siz *ssz.Sizer, _ bool) uint32 {\n\treturn ssz.SizeSliceOfStaticObjects(siz, ([]*Deposit)(ds))\n}\n\n// DefineSSZ defines the SSZ encoding for the Deposits object.\n// TODO: get from accessible chainspec field params.\nfunc (ds Deposits) DefineSSZ(c *ssz.Codec) {\n\tc.DefineDecoder(func(*ssz.Decoder) {\n\t\tssz.DefineSliceOfStaticObjectsContent(c, (*[]*Deposit)(&ds), constants.MaxDeposits)\n\t})\n\tc.DefineEncoder(func(*ssz.Encoder) {\n\t\tssz.DefineSliceOfStaticObjectsContent(c, (*[]*Deposit)(&ds), constants.MaxDeposits)\n\t})\n\tc.DefineHasher(func(*ssz.Hasher) {\n\t\tssz.DefineSliceOfStaticObjectsOffset(c, (*[]*Deposit)(&ds), constants.MaxDeposits)\n\t})\n}\n\n// HashTreeRoot returns the hash tree root of the Deposits.\nfunc (ds Deposits) HashTreeRoot() common.Root {\n\t// TODO: determine if using HashConcurrent optimizes performance.\n\treturn ssz.HashSequential(ds)\n}\n"
  },
  {
    "path": "consensus-types/types/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport \"github.com/berachain/beacon-kit/errors\"\n\nvar (\n\t// ErrDepositMessage is an error for when the deposit signature doesn't\n\t// match.\n\tErrDepositMessage = errors.New(\"invalid deposit message\")\n\n\t// ErrInvalidWithdrawalCredentials is an error for when the.\n\tErrInvalidWithdrawalCredentials = errors.New(\n\t\t\"invalid withdrawal credentials\",\n\t)\n\n\t// ErrForkVersionNotSupported is an error for when the fork\n\t// version is not supported.\n\tErrForkVersionNotSupported = errors.New(\"fork version not supported\")\n\n\t// ErrNilValue is an error for when a getter returns nil on a value\n\t// It should generally not occur unless we have a bug in our code and is used for defensive programming.\n\tErrNilValue = errors.New(\"unexpected nil value\")\n\n\t// ErrInclusionProofDepthExceeded is an error for when the\n\t// KZG_COMMITMENT_INCLUSION_PROOF_DEPTH calculation overflows.\n\tErrInclusionProofDepthExceeded = errors.New(\"inclusion proof depth exceeded\")\n\n\t// ErrNilPayloadHeader is an error for when the payload header is nil.\n\tErrNilPayloadHeader = errors.New(\"nil payload header\")\n\n\t// ErrInvalidValidatorStatus is an error for when the validator status is invalid.\n\tErrInvalidValidatorStatus = errors.New(\"invalid validator status\")\n\n\t// ErrFieldNotSupportedOnFork occurs when attempting to retrieve a field on a fork on which it is not supported\n\tErrFieldNotSupportedOnFork = errors.New(\"field not supported on fork\")\n)\n"
  },
  {
    "path": "consensus-types/types/eth1data.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tfastssz \"github.com/ferranbt/fastssz\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// Eth1DataSize is the size of the Eth1Data object in bytes.\n// 32 bytes for DepositRoot + 8 bytes for DepositCount + 8 bytes for BlockHash.\nconst Eth1DataSize = 72\n\nvar (\n\t_ ssz.StaticObject                    = (*Eth1Data)(nil)\n\t_ constraints.SSZMarshallableRootable = (*Eth1Data)(nil)\n)\n\ntype Eth1Data struct {\n\t// DepositRoot is the root of the deposit tree.\n\tDepositRoot common.Root `json:\"depositRoot\"`\n\t// DepositCount is the number of deposits in the deposit tree.\n\tDepositCount math.U64 `json:\"depositCount\"`\n\t// BlockHash is the hash of the block corresponding to the Eth1Data.\n\tBlockHash common.ExecutionHash `json:\"blockHash\"`\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                 Constructor                                */\n/* -------------------------------------------------------------------------- */\n\nfunc NewEth1Data(depositRoot common.Root) *Eth1Data {\n\treturn &Eth1Data{\n\t\tDepositRoot: depositRoot,\n\t}\n}\n\nfunc NewEmptyEth1Data() *Eth1Data {\n\treturn &Eth1Data{}\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// SizeSSZ returns the size of the Eth1Data object in SSZ encoding.\nfunc (*Eth1Data) SizeSSZ(*ssz.Sizer) uint32 {\n\treturn Eth1DataSize\n}\n\n// DefineSSZ defines the SSZ encoding for the Eth1Data object.\nfunc (e *Eth1Data) DefineSSZ(codec *ssz.Codec) {\n\tssz.DefineStaticBytes(codec, &e.DepositRoot)\n\tssz.DefineUint64(codec, &e.DepositCount)\n\tssz.DefineStaticBytes(codec, &e.BlockHash)\n}\n\n// HashTreeRoot computes the SSZ hash tree root of the Eth1Data object.\nfunc (e *Eth1Data) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(e)\n}\n\n// MarshalSSZ marshals the Eth1Data object to SSZ format.\nfunc (e *Eth1Data) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(e))\n\treturn buf, ssz.EncodeToBytes(buf, e)\n}\n\nfunc (*Eth1Data) ValidateAfterDecodingSSZ() error { return nil }\n\n// MarshalSSZTo marshals the Eth1Data object into a pre-allocated byte slice.\nfunc (e *Eth1Data) MarshalSSZTo(dst []byte) ([]byte, error) {\n\tbz, err := e.MarshalSSZ()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn append(dst, bz...), err\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   FastSSZ                                  */\n/* -------------------------------------------------------------------------- */\n\n// HashTreeRootWith ssz hashes the Eth1Data object with a hasher.\nfunc (e *Eth1Data) HashTreeRootWith(hh fastssz.HashWalker) error {\n\tindx := hh.Index()\n\n\t// Field (0) 'DepositRoot'\n\thh.PutBytes(e.DepositRoot[:])\n\n\t// Field (1) 'DepositCount'\n\thh.PutUint64(uint64(e.DepositCount))\n\n\t// Field (2) 'BlockHash'\n\thh.PutBytes(e.BlockHash[:])\n\n\thh.Merkleize(indx)\n\treturn nil\n}\n\n// GetTree ssz hashes the Eth1Data object.\nfunc (e *Eth1Data) GetTree() (*fastssz.Node, error) {\n\treturn fastssz.ProofTree(e)\n}\n\n// GetDepositCount returns the deposit count.\nfunc (e *Eth1Data) GetDepositCount() math.U64 {\n\treturn e.DepositCount\n}\n"
  },
  {
    "path": "consensus-types/types/eth1data_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\tkaralabessz \"github.com/karalabe/ssz\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestEth1Data_Serialization(t *testing.T) {\n\tt.Parallel()\n\toriginal := types.NewEth1Data(common.Root{})\n\tdata, err := original.MarshalSSZ()\n\trequire.NoError(t, err)\n\trequire.NotNil(t, data)\n\n\tunmarshalled := new(types.Eth1Data)\n\terr = ssz.Unmarshal(data, unmarshalled)\n\trequire.NoError(t, err)\n\trequire.Equal(t, original, unmarshalled)\n\n\tvar buf []byte\n\tbuf, err = original.MarshalSSZTo(buf)\n\trequire.NoError(t, err)\n\n\t// The two byte slices should be equal\n\trequire.Equal(t, data, buf)\n}\n\nfunc TestEth1Data_UnmarshalError(t *testing.T) {\n\tt.Parallel()\n\n\tvar unmarshalled types.Eth1Data\n\terr := ssz.Unmarshal([]byte{}, &unmarshalled)\n\trequire.ErrorIs(t, err, io.ErrUnexpectedEOF)\n}\n\nfunc TestEth1Data_SizeSSZ(t *testing.T) {\n\tt.Parallel()\n\teth1Data := types.NewEth1Data(common.Root{})\n\tsize := karalabessz.Size(eth1Data)\n\trequire.Equal(t, uint32(72), size)\n}\n\nfunc TestEth1Data_HashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\teth1Data := types.NewEth1Data(common.Root{})\n\n\trequire.NotPanics(t, func() {\n\t\t_ = eth1Data.HashTreeRoot()\n\t})\n}\n\nfunc TestEth1Data_GetTree(t *testing.T) {\n\tt.Parallel()\n\teth1Data := types.NewEth1Data(common.Root{})\n\ttree, err := eth1Data.GetTree()\n\n\trequire.NoError(t, err)\n\trequire.NotNil(t, tree)\n}\n\nfunc TestEth1Data_GetDepositCount(t *testing.T) {\n\tt.Parallel()\n\teth1Data := &types.Eth1Data{\n\t\tDepositRoot:  common.Root{},\n\t\tDepositCount: 10,\n\t\tBlockHash:    common.ExecutionHash{},\n\t}\n\n\tcount := eth1Data.GetDepositCount()\n\n\trequire.Equal(t, uint64(10), count.Unwrap())\n}\n"
  },
  {
    "path": "consensus-types/types/execution_requests.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\tsszutil \"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// 3 since three dynamic objects (Deposits, Withdrawals, Consolidations)\nconst dynamicFieldsInExecutionRequests = 3\n\n// Compile-time check to ensure ExecutionRequests implements the necessary interfaces.\nvar (\n\t_ ssz.DynamicObject                   = (*ExecutionRequests)(nil)\n\t_ constraints.SSZMarshallableRootable = (*ExecutionRequests)(nil)\n)\n\n// EncodedExecutionRequest is the result of GetExecutionRequestsList which is spec defined.\ntype EncodedExecutionRequest = bytes.Bytes\n\ntype ExecutionRequests struct {\n\tDeposits       []*DepositRequest\n\tWithdrawals    []*WithdrawalRequest\n\tConsolidations []*ConsolidationRequest\n}\n\nfunc (e *ExecutionRequests) ValidateAfterDecodingSSZ() error {\n\treturn errors.Join(\n\t\tDepositRequests(e.Deposits).ValidateAfterDecodingSSZ(),\n\t\tWithdrawalRequests(e.Withdrawals).ValidateAfterDecodingSSZ(),\n\t\tConsolidationRequests(e.Consolidations).ValidateAfterDecodingSSZ(),\n\t)\n}\n\n// GetExecutionRequestsList introduced in pectra from the consensus spec\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/electra/beacon-chain.md#new-get_execution_requests_list\nfunc GetExecutionRequestsList(er *ExecutionRequests) ([]EncodedExecutionRequest, error) {\n\tif er == nil {\n\t\treturn nil, errors.New(\"nil execution requests\")\n\t}\n\tresult := make([]EncodedExecutionRequest, 0)\n\n\t// Process deposit requests if non-empty.\n\tif len(er.Deposits) > 0 {\n\t\tdepositBytes, err := sszutil.MarshalItemsEIP7685(er.Deposits)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcombined := append([]byte{constants.DepositRequestType}, depositBytes...)\n\t\tresult = append(result, combined)\n\t}\n\n\t// Process withdrawal requests if non-empty.\n\tif len(er.Withdrawals) > 0 {\n\t\twithdrawalBytes, err := sszutil.MarshalItemsEIP7685(er.Withdrawals)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcombined := append([]byte{constants.WithdrawalRequestType}, withdrawalBytes...)\n\t\tresult = append(result, combined)\n\t}\n\n\t// Process consolidation requests if non-empty.\n\tif len(er.Consolidations) > 0 {\n\t\tconsolidationBytes, err := sszutil.MarshalItemsEIP7685(er.Consolidations)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcombined := append([]byte{constants.ConsolidationRequestType}, consolidationBytes...)\n\t\tresult = append(result, combined)\n\t}\n\n\treturn result, nil\n}\n\n// DecodeExecutionRequests is used to decode the result from GetPayload into an ExecutionRequests.\nfunc DecodeExecutionRequests(encodedRequests [][]byte) (*ExecutionRequests, error) {\n\tvar (\n\t\tresult   ExecutionRequests\n\t\tprevType *uint8\n\t\terr      error\n\t)\n\n\t// Iterate over each encoded request group.\n\tfor _, encoded := range encodedRequests {\n\t\tif len(encoded) < 1 {\n\t\t\treturn nil, errors.New(\"invalid execution request, length less than 1\")\n\t\t}\n\t\t// The first byte indicates the request type.\n\t\treqType := encoded[0]\n\n\t\t// Enforce that request types are in strictly increasing order.\n\t\tif prevType != nil && *prevType >= reqType {\n\t\t\treturn nil, errors.New(\"requests should be in sorted order and unique\")\n\t\t}\n\t\tprevType = &reqType\n\n\t\t// The remaining bytes are the SSZ serialization for this group.\n\t\tdata := encoded[1:]\n\n\t\t// Switch based on the request type.\n\t\tswitch reqType {\n\t\tcase constants.DepositRequestType:\n\t\t\tif result.Deposits, err = DecodeDepositRequests(data); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\tcase constants.WithdrawalRequestType:\n\t\t\tif result.Withdrawals, err = DecodeWithdrawalRequests(data); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\tcase constants.ConsolidationRequestType:\n\t\t\tif result.Consolidations, err = DecodeConsolidationRequests(data); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"unsupported request type %d\", reqType)\n\t\t}\n\t}\n\n\treturn &result, nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                       Execution Requests SSZ                               */\n/* -------------------------------------------------------------------------- */\n\nfunc (e *ExecutionRequests) DefineSSZ(codec *ssz.Codec) {\n\tssz.DefineSliceOfStaticObjectsOffset(codec, &e.Deposits, constants.MaxDepositRequestsPerPayload)\n\tssz.DefineSliceOfStaticObjectsOffset(codec, &e.Withdrawals, constants.MaxWithdrawalRequestsPerPayload)\n\tssz.DefineSliceOfStaticObjectsOffset(codec, &e.Consolidations, constants.MaxConsolidationRequestsPerPayload)\n\n\tssz.DefineSliceOfStaticObjectsContent(codec, &e.Deposits, constants.MaxDepositRequestsPerPayload)\n\tssz.DefineSliceOfStaticObjectsContent(codec, &e.Withdrawals, constants.MaxWithdrawalRequestsPerPayload)\n\tssz.DefineSliceOfStaticObjectsContent(codec, &e.Consolidations, constants.MaxConsolidationRequestsPerPayload)\n}\n\nfunc (e *ExecutionRequests) SizeSSZ(siz *ssz.Sizer, fixed bool) uint32 {\n\tsize := constants.SSZOffsetSize * dynamicFieldsInExecutionRequests\n\tif fixed {\n\t\treturn size\n\t}\n\tsize += ssz.SizeSliceOfStaticObjects(siz, e.Deposits)\n\tsize += ssz.SizeSliceOfStaticObjects(siz, e.Withdrawals)\n\tsize += ssz.SizeSliceOfStaticObjects(siz, e.Consolidations)\n\treturn size\n}\n\nfunc (e *ExecutionRequests) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(e))\n\treturn buf, ssz.EncodeToBytes(buf, e)\n}\n\n// HashTreeRoot returns the hash tree root of the Deposits.\nfunc (e *ExecutionRequests) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(e)\n}\n"
  },
  {
    "path": "consensus-types/types/execution_requests_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/ethereum/go-ethereum/common/hexutil\"\n\t\"github.com/prysmaticlabs/prysm/v5/config/params\"\n\t\"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil\"\n\tenginev1 \"github.com/prysmaticlabs/prysm/v5/proto/engine/v1\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestExecutionRequests_ValidValuesSSZ(t *testing.T) {\n\tt.Parallel()\n\t// Create a few helper instances to reuse in test cases.\n\t// You can reuse your existing tests' values for deposit, withdrawal, and consolidation.\n\tdepositBasic := &types.DepositRequest{\n\t\t// 48-byte public key\n\t\tPubkey: crypto.BLSPubkey{\n\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t21, 22, 23, 24, 25, 26, 27, 28, 29, 30,\n\t\t\t31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n\t\t\t41, 42, 43, 44, 45, 46, 47, 48,\n\t\t},\n\t\tCredentials: [32]byte{\n\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t21, 22, 23, 24, 25, 26, 27, 28, 29, 30,\n\t\t\t31, 32,\n\t\t},\n\t\tAmount: 1000,\n\t\tSignature: crypto.BLSSignature{1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t21, 22, 23, 24, 25, 26, 27, 28, 29, 30,\n\t\t\t31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n\t\t\t41, 42, 43, 44, 45, 46, 47, 48, 49, 50,\n\t\t\t51, 52, 53, 54, 55, 56, 57, 58, 59, 60,\n\t\t\t61, 62, 63, 64, 65, 66, 67, 68, 69, 70,\n\t\t\t71, 72, 73, 74, 75, 76, 77, 78, 79, 80,\n\t\t\t81, 82, 83, 84, 85, 86, 87, 88, 89, 90,\n\t\t\t91, 92, 93, 94, 95, 96,\n\t\t},\n\t\tIndex: 1,\n\t}\n\n\twithdrawalBasic := &types.WithdrawalRequest{\n\t\tSourceAddress: common.ExecutionAddress{\n\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t},\n\t\tValidatorPubKey: crypto.BLSPubkey{\n\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t21, 22, 23, 24, 25, 26, 27, 28, 29, 30,\n\t\t\t31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n\t\t\t41, 42, 43, 44, 45, 46, 47, 48,\n\t\t},\n\t\tAmount: 1000,\n\t}\n\n\tconsolidationBasic := &types.ConsolidationRequest{\n\t\tSourceAddress: common.ExecutionAddress{\n\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t},\n\t\tSourcePubKey: crypto.BLSPubkey{\n\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t21, 22, 23, 24, 25, 26, 27, 28, 29, 30,\n\t\t\t31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n\t\t\t41, 42, 43, 44, 45, 46, 47, 48,\n\t\t},\n\t\tTargetPubKey: crypto.BLSPubkey{\n\t\t\t48, 47, 46, 45, 44, 43, 42, 41, 40, 39,\n\t\t\t38, 37, 36, 35, 34, 33, 32, 31, 30, 29,\n\t\t\t28, 27, 26, 25, 24, 23, 22, 21, 20, 19,\n\t\t\t18, 17, 16, 15, 14, 13, 12, 11, 10, 9,\n\t\t\t8, 7, 6, 5, 4, 3, 2, 1,\n\t\t},\n\t}\n\n\t// Define test cases. We vary the content of each slice.\n\ttestCases := []struct {\n\t\tname              string\n\t\texecutionRequests *types.ExecutionRequests\n\t}{\n\t\t{\n\t\t\tname: \"all basic\",\n\t\t\texecutionRequests: &types.ExecutionRequests{\n\t\t\t\tDeposits:       []*types.DepositRequest{depositBasic},\n\t\t\t\tWithdrawals:    []*types.WithdrawalRequest{withdrawalBasic},\n\t\t\t\tConsolidations: []*types.ConsolidationRequest{consolidationBasic},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"empty slices\",\n\t\t\texecutionRequests: &types.ExecutionRequests{\n\t\t\t\tDeposits:       []*types.DepositRequest{},\n\t\t\t\tWithdrawals:    []*types.WithdrawalRequest{},\n\t\t\t\tConsolidations: []*types.ConsolidationRequest{},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"multiple entries\",\n\t\t\texecutionRequests: &types.ExecutionRequests{\n\t\t\t\tDeposits:       []*types.DepositRequest{depositBasic, depositBasic},\n\t\t\t\tWithdrawals:    []*types.WithdrawalRequest{withdrawalBasic, withdrawalBasic, withdrawalBasic},\n\t\t\t\tConsolidations: []*types.ConsolidationRequest{consolidationBasic, consolidationBasic},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"random-ish values\",\n\t\t\texecutionRequests: &types.ExecutionRequests{\n\t\t\t\tDeposits: []*types.DepositRequest{\n\t\t\t\t\t{\n\t\t\t\t\t\tPubkey: crypto.BLSPubkey{\n\t\t\t\t\t\t\t7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\n\t\t\t\t\t\t\t17, 18, 19, 20, 21, 22, 23, 24, 25, 26,\n\t\t\t\t\t\t\t27, 28, 29, 30, 31, 32, 33, 34, 35, 36,\n\t\t\t\t\t\t\t37, 38, 39, 40, 41, 42, 43, 44, 45, 46,\n\t\t\t\t\t\t\t47, 48, 49, 50, 51, 52, 53, 54,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tCredentials: [32]byte{\n\t\t\t\t\t\t\t7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\n\t\t\t\t\t\t\t17, 18, 19, 20, 21, 22, 23, 24, 25, 26,\n\t\t\t\t\t\t\t27, 28, 29, 30, 31, 32, 33, 34, 35, 36,\n\t\t\t\t\t\t\t37, 38,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tAmount: 54321,\n\t\t\t\t\t\tSignature: crypto.BLSSignature{\n\t\t\t\t\t\t\t7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\n\t\t\t\t\t\t\t17, 18, 19, 20, 21, 22, 23, 24, 25, 26,\n\t\t\t\t\t\t\t27, 28, 29, 30, 31, 32, 33, 34, 35, 36,\n\t\t\t\t\t\t\t37, 38, 39, 40, 41, 42, 43, 44, 45, 46,\n\t\t\t\t\t\t\t47, 48, 49, 50, 51, 52, 53, 54, 55, 56,\n\t\t\t\t\t\t\t57, 58, 59, 60, 61, 62, 63, 64, 65, 66,\n\t\t\t\t\t\t\t67, 68, 69, 70, 71, 72, 73, 74, 75, 76,\n\t\t\t\t\t\t\t77, 78, 79, 80, 81, 82, 83, 84, 85, 86,\n\t\t\t\t\t\t\t87, 88, 89, 90, 91, 92, 93, 94, 95, 96,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tIndex: 4,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tWithdrawals: []*types.WithdrawalRequest{\n\t\t\t\t\t{\n\t\t\t\t\t\tSourceAddress: common.ExecutionAddress{\n\t\t\t\t\t\t\t7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\n\t\t\t\t\t\t\t17, 18, 19, 20, 21, 22, 23, 24, 25, 26,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tValidatorPubKey: crypto.BLSPubkey{\n\t\t\t\t\t\t\t7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\n\t\t\t\t\t\t\t17, 18, 19, 20, 21, 22, 23, 24, 25, 26,\n\t\t\t\t\t\t\t27, 28, 29, 30, 31, 32, 33, 34, 35, 36,\n\t\t\t\t\t\t\t37, 38, 39, 40, 41, 42, 43, 44, 45, 46,\n\t\t\t\t\t\t\t47, 48, 49, 50, 51, 52, 53, 54,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tAmount: 54321,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tConsolidations: []*types.ConsolidationRequest{\n\t\t\t\t\t{\n\t\t\t\t\t\tSourceAddress: common.ExecutionAddress{\n\t\t\t\t\t\t\t7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\n\t\t\t\t\t\t\t17, 18, 19, 20, 21, 22, 23, 24, 25, 26,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tSourcePubKey: crypto.BLSPubkey{\n\t\t\t\t\t\t\t7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\n\t\t\t\t\t\t\t17, 18, 19, 20, 21, 22, 23, 24, 25, 26,\n\t\t\t\t\t\t\t27, 28, 29, 30, 31, 32, 33, 34, 35, 36,\n\t\t\t\t\t\t\t37, 38, 39, 40, 41, 42, 43, 44, 45, 46,\n\t\t\t\t\t\t\t47, 48, 49, 50, 51, 52, 53, 54,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tTargetPubKey: crypto.BLSPubkey{\n\t\t\t\t\t\t\t14, 15, 16, 17, 18, 19, 20, 21, 22, 23,\n\t\t\t\t\t\t\t24, 25, 26, 27, 28, 29, 30, 31, 32, 33,\n\t\t\t\t\t\t\t34, 35, 36, 37, 38, 39, 40, 41, 42, 43,\n\t\t\t\t\t\t\t44, 45, 46, 47, 48, 49, 50, 51, 52, 53,\n\t\t\t\t\t\t\t54, 55, 56, 57, 58, 59, 60, 61,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\t// Marshal the original ExecutionRequests.\n\t\t\texecReqBytes, err := tc.executionRequests.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\n\t\t\t// Unmarshal into a Prysm ExecutionRequests.\n\t\t\tvar prysmER enginev1.ExecutionRequests\n\t\t\terr = prysmER.UnmarshalSSZ(execReqBytes)\n\t\t\trequire.NoError(t, err)\n\n\t\t\tprysmHTR, err := prysmER.HashTreeRoot()\n\t\t\trequire.NoError(t, err)\n\t\t\texecReqHTR := tc.executionRequests.HashTreeRoot()\n\n\t\t\t// Compare the HashTreeRoots to ensure encoding was correct.\n\t\t\trequire.Equal(t, execReqHTR[:], prysmHTR[:])\n\n\t\t\t// Marshal the Prysm ExecutionRequests.\n\t\t\tprysmERBytes, err := prysmER.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\n\t\t\t// Unmarshal back into a new ExecutionRequests.\n\t\t\tvar recomputedER types.ExecutionRequests\n\t\t\terr = ssz.Unmarshal(prysmERBytes, &recomputedER)\n\t\t\trequire.NoError(t, err)\n\n\t\t\t// Compare that the original and recomputed ExecutionRequests match.\n\t\t\trequire.Equal(t, *tc.executionRequests, recomputedER)\n\t\t})\n\t}\n}\n\n// TestExecutionRequests_InvalidValuesUnmarshalSSZ ensures that Unmarshal must never panic.\n//\n//nolint:paralleltest // Invalid SSZ values cannot be run in parallel due to zeroalloc, which is global shared memory.\nfunc TestExecutionRequests_InvalidValuesUnmarshalSSZ(t *testing.T) {\n\t// Define several invalid payloads.\n\tinvalidPayloads := [][]byte{\n\t\tnil,                    // nil slice\n\t\t{},                     // empty slice\n\t\t[]byte(\"invalid data\"), // arbitrary string data\n\t\t{0x00, 0x01},           // too short to be valid\n\t\t// A random 50-byte slice (likely invalid)\n\t\tfunc() []byte {\n\t\t\tb := make([]byte, 50)\n\t\t\tfor i := range b {\n\t\t\t\tb[i] = byte((i * 3) % 256)\n\t\t\t}\n\t\t\treturn b\n\t\t}(),\n\t\t// A truncated valid payload: marshal a valid empty ExecutionRequests and drop last 4 bytes.\n\t\tfunc() []byte {\n\t\t\ter := types.ExecutionRequests{\n\t\t\t\tDeposits:       []*types.DepositRequest{},\n\t\t\t\tWithdrawals:    []*types.WithdrawalRequest{},\n\t\t\t\tConsolidations: []*types.ConsolidationRequest{},\n\t\t\t}\n\t\t\tvalidBytes, err := er.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\t\t\tif len(validBytes) > 4 {\n\t\t\t\treturn validBytes[:len(validBytes)-4]\n\t\t\t}\n\t\t\treturn validBytes\n\t\t}(),\n\t\t// A valid payload with extra trailing bytes.\n\t\tfunc() []byte {\n\t\t\ter := types.ExecutionRequests{\n\t\t\t\tDeposits:       []*types.DepositRequest{},\n\t\t\t\tWithdrawals:    []*types.WithdrawalRequest{},\n\t\t\t\tConsolidations: []*types.ConsolidationRequest{},\n\t\t\t}\n\t\t\tvalidBytes, err := er.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\t\t\t// Append extra bytes that should make the payload invalid.\n\t\t\textra := []byte{0xFF, 0xEE, 0xDD, 0xCC}\n\t\t\treturn append(validBytes, extra...)\n\t\t}(),\n\t}\n\n\tfor i, payload := range invalidPayloads {\n\t\ti, payload := i, payload // capture loop variables\n\t\tt.Run(fmt.Sprintf(\"invalidPayload_%d\", i), func(t *testing.T) {\n\t\t\tvar er types.ExecutionRequests\n\t\t\t// Ensure that calling UnmarshalSSZ with an invalid payload does not panic\n\t\t\t// and returns a non-nil error.\n\t\t\trequire.NotPanics(t, func() {\n\t\t\t\terr := ssz.Unmarshal(payload, &er)\n\t\t\t\trequire.Error(t, err, \"Expected error for payload %v\", payload)\n\t\t\t})\n\t\t})\n\t}\n}\n\n// Tests below are adapted from Prysm\n// https://github.com/prysmaticlabs/prysm/blob/develop/proto/engine/v1/electra_test.go#L15-L196\n\nfunc TestDecodeExecutionRequests(t *testing.T) {\n\tt.Parallel()\n\tt.Run(\"All requests decode successfully\", func(t *testing.T) {\n\t\tdepositRequestBytes, err := hexutil.Decode(\"0x610000000000000000000000000000000000000000000000000000000\" +\n\t\t\t\"000000000000000000000000000000000000000\" +\n\t\t\t\"620000000000000000000000000000000000000000000000000000000000000000\" +\n\t\t\t\"40597307000000630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\" +\n\t\t\t\"00000000000000000000000000000000000000\" +\n\t\t\t\"00000000000000000000000000000000000000000000000000000000000000000000000000000000\")\n\t\trequire.NoError(t, err)\n\t\twithdrawalRequestBytes, err := hexutil.Decode(\"0x6400000000000000000000000000000000000000\" +\n\t\t\t\"6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040597307000000\")\n\t\trequire.NoError(t, err)\n\t\tconsolidationRequestBytes, err := hexutil.Decode(\"0x6600000000000000000000000000000000000000\" +\n\t\t\t\"670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\" +\n\t\t\t\"680000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\")\n\t\trequire.NoError(t, err)\n\t\tebe := &enginev1.ExecutionBundleElectra{\n\t\t\tExecutionRequests: [][]byte{append([]byte{uint8(enginev1.DepositRequestType)}, depositRequestBytes...),\n\t\t\t\tappend([]byte{uint8(enginev1.WithdrawalRequestType)}, withdrawalRequestBytes...),\n\t\t\t\tappend([]byte{uint8(enginev1.ConsolidationRequestType)}, consolidationRequestBytes...)},\n\t\t}\n\t\trequests, err := types.DecodeExecutionRequests(ebe.GetExecutionRequests())\n\t\trequire.NoError(t, err)\n\t\trequire.Len(t, requests.Deposits, 1)\n\t\trequire.Len(t, requests.Withdrawals, 1)\n\t\trequire.Len(t, requests.Consolidations, 1)\n\t})\n\tt.Run(\"Excluded requests still decode successfully when one request is missing\", func(t *testing.T) {\n\t\tdepositRequestBytes, err := hexutil.Decode(\"0x610000000000000000000000000000000000000000000000000000000\" +\n\t\t\t\"000000000000000000000000000000000000000\" +\n\t\t\t\"620000000000000000000000000000000000000000000000000000000000000000\" +\n\t\t\t\"405973070000006300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\" +\n\t\t\t\"0000000000000000000000000000000000000\" +\n\t\t\t\"00000000000000000000000000000000000000000000000000000000000000000000000000000000\")\n\t\trequire.NoError(t, err)\n\t\tconsolidationRequestBytes, err := hexutil.Decode(\"0x6600000000000000000000000000000000000000\" +\n\t\t\t\"670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\" +\n\t\t\t\"680000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\")\n\t\trequire.NoError(t, err)\n\t\tebe := &enginev1.ExecutionBundleElectra{\n\t\t\tExecutionRequests: [][]byte{\n\t\t\t\tappend([]byte{uint8(enginev1.DepositRequestType)}, depositRequestBytes...),\n\t\t\t\tappend([]byte{uint8(enginev1.ConsolidationRequestType)}, consolidationRequestBytes...),\n\t\t\t},\n\t\t}\n\t\trequests, err := types.DecodeExecutionRequests(ebe.GetExecutionRequests())\n\t\trequire.NoError(t, err)\n\t\trequire.Len(t, requests.Deposits, 1)\n\t\trequire.Empty(t, requests.Withdrawals)\n\t\trequire.Len(t, requests.Consolidations, 1)\n\t})\n\tt.Run(\"Decode execution requests should fail if ordering is not sorted\", func(t *testing.T) {\n\t\tdepositRequestBytes, err := hexutil.Decode(\"0x61000000000000000000000000000000000000000000000000000000000\" +\n\t\t\t\"0000000000000000000000000000000000000\" +\n\t\t\t\"620000000000000000000000000000000000000000000000000000000000000000\" +\n\t\t\t\"405973070000006300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\" +\n\t\t\t\"0000000000000000000000000000000000000\" +\n\t\t\t\"00000000000000000000000000000000000000000000000000000000000000000000000000000000\")\n\t\trequire.NoError(t, err)\n\t\tconsolidationRequestBytes, err := hexutil.Decode(\"0x6600000000000000000000000000000000000000\" +\n\t\t\t\"670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\" +\n\t\t\t\"680000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\")\n\t\trequire.NoError(t, err)\n\t\tebe := &enginev1.ExecutionBundleElectra{\n\t\t\tExecutionRequests: [][]byte{\n\t\t\t\tappend([]byte{uint8(enginev1.ConsolidationRequestType)}, consolidationRequestBytes...),\n\t\t\t\tappend([]byte{uint8(enginev1.DepositRequestType)}, depositRequestBytes...),\n\t\t\t},\n\t\t}\n\t\t_, err = types.DecodeExecutionRequests(ebe.GetExecutionRequests())\n\t\trequire.ErrorContains(t, err, \"requests should be in sorted order and unique\")\n\t})\n\tt.Run(\"Requests should error if the request type is shorter than 1 byte\", func(t *testing.T) {\n\t\tconsolidationRequestBytes, err := hexutil.Decode(\"0x6600000000000000000000000000000000000000\" +\n\t\t\t\"670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\" +\n\t\t\t\"680000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\")\n\t\trequire.NoError(t, err)\n\t\tebe := &enginev1.ExecutionBundleElectra{\n\t\t\tExecutionRequests: [][]byte{\n\t\t\t\tappend([]byte{}, []byte{}...),\n\t\t\t\tappend([]byte{uint8(enginev1.ConsolidationRequestType)}, consolidationRequestBytes...),\n\t\t\t},\n\t\t}\n\t\t_, err = types.DecodeExecutionRequests(ebe.GetExecutionRequests())\n\t\trequire.ErrorContains(t, err, \"invalid execution request, length less than 1\")\n\t})\n\tt.Run(\"a duplicate request should fail\", func(t *testing.T) {\n\t\twithdrawalRequestBytes, err := hexutil.Decode(\"0x6400000000000000000000000000000000000000\" +\n\t\t\t\"6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040597307000000\")\n\t\trequire.NoError(t, err)\n\t\twithdrawalRequestBytes2, err := hexutil.Decode(\"0x6400000000000000000000000000000000000000\" +\n\t\t\t\"6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040597307000000\")\n\t\trequire.NoError(t, err)\n\t\tebe := &enginev1.ExecutionBundleElectra{\n\t\t\tExecutionRequests: [][]byte{\n\t\t\t\tappend([]byte{uint8(enginev1.WithdrawalRequestType)}, withdrawalRequestBytes...),\n\t\t\t\tappend([]byte{uint8(enginev1.WithdrawalRequestType)}, withdrawalRequestBytes2...),\n\t\t\t},\n\t\t}\n\t\t_, err = types.DecodeExecutionRequests(ebe.GetExecutionRequests())\n\t\trequire.ErrorContains(t, err, \"requests should be in sorted order and unique\")\n\t})\n\tt.Run(\"a duplicate withdrawals ( non 0 request type )request should fail\", func(t *testing.T) {\n\t\tdepositRequestBytes, err := hexutil.Decode(\"0x61000000000000000000000000000000000000000000000000000000\" +\n\t\t\t\"0000000000000000000000000000000000000000\" +\n\t\t\t\"620000000000000000000000000000000000000000000000000000000000000000\" +\n\t\t\t\"4059730700000063000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\" +\n\t\t\t\"000000000000000000000000000000000000000\" +\n\t\t\t\"00000000000000000000000000000000000000000000000000000000000000000000000000000000\")\n\t\trequire.NoError(t, err)\n\t\tdepositRequestBytes2, err := hexutil.Decode(\"0x61000000000000000000000000000000000000000000000000000000\" +\n\t\t\t\"0000000000000000000000000000000000000000\" +\n\t\t\t\"620000000000000000000000000000000000000000000000000000000000000000\" +\n\t\t\t\"405973070000006300000000000000000000000000000000000000000000000000000000000000000000000000000000000000\" +\n\t\t\t\"0000000000000000000000000000000000000000\" +\n\t\t\t\"00000000000000000000000000000000000000000000000000000000000000000000000000000000\")\n\t\trequire.NoError(t, err)\n\t\tebe := &enginev1.ExecutionBundleElectra{\n\t\t\tExecutionRequests: [][]byte{\n\t\t\t\tappend([]byte{uint8(enginev1.DepositRequestType)}, depositRequestBytes...),\n\t\t\t\tappend([]byte{uint8(enginev1.DepositRequestType)}, depositRequestBytes2...),\n\t\t\t},\n\t\t}\n\t\t_, err = types.DecodeExecutionRequests(ebe.GetExecutionRequests())\n\t\trequire.ErrorContains(t, err, \"requests should be in sorted order and unique\")\n\t})\n\tt.Run(\"If a request type is provided, but the request list is shorter than the ssz of 1 request we error\", func(t *testing.T) {\n\t\tconsolidationRequestBytes, err := hexutil.Decode(\"0x6600000000000000000000000000000000000000\" +\n\t\t\t\"670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\" +\n\t\t\t\"680000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\")\n\t\trequire.NoError(t, err)\n\t\tebe := &enginev1.ExecutionBundleElectra{\n\t\t\tExecutionRequests: [][]byte{\n\t\t\t\tappend([]byte{uint8(enginev1.DepositRequestType)}, []byte{}...),\n\t\t\t\tappend([]byte{uint8(enginev1.ConsolidationRequestType)}, consolidationRequestBytes...),\n\t\t\t},\n\t\t}\n\t\t_, err = types.DecodeExecutionRequests(ebe.GetExecutionRequests())\n\t\trequire.ErrorContains(t, err, \"invalid deposit requests SSZ size, got 0 expected at least 192\")\n\t})\n\tt.Run(\"If deposit requests are over the max allowed per payload then we should error\", func(t *testing.T) {\n\t\trequests := make([]*enginev1.DepositRequest, constants.MaxDepositRequestsPerPayload+1)\n\t\tfor i := range requests {\n\t\t\trequests[i] = &enginev1.DepositRequest{\n\t\t\t\tPubkey:                bytesutil.PadTo([]byte(\"pk\"), 48),\n\t\t\t\tWithdrawalCredentials: bytesutil.PadTo([]byte(\"wc\"), 32),\n\t\t\t\tAmount:                123,\n\t\t\t\tSignature:             bytesutil.PadTo([]byte(\"sig\"), 96),\n\t\t\t\tIndex:                 456,\n\t\t\t}\n\t\t}\n\t\tby, err := ssz.MarshalItemsEIP7685(requests)\n\t\trequire.NoError(t, err)\n\t\tebe := &enginev1.ExecutionBundleElectra{\n\t\t\tExecutionRequests: [][]byte{\n\t\t\t\tappend([]byte{uint8(enginev1.DepositRequestType)}, by...),\n\t\t\t},\n\t\t}\n\t\t_, err = types.DecodeExecutionRequests(ebe.GetExecutionRequests())\n\t\trequire.ErrorContains(t, err, \"invalid deposit requests SSZ size, requests should not be more than the max per payload\")\n\t})\n\tt.Run(\"If withdrawal requests are over the max allowed per payload then we should error\", func(t *testing.T) {\n\t\trequests := make([]*enginev1.WithdrawalRequest, params.BeaconConfig().MaxWithdrawalRequestsPerPayload+1)\n\t\tfor i := range requests {\n\t\t\trequests[i] = &enginev1.WithdrawalRequest{\n\t\t\t\tSourceAddress:   bytesutil.PadTo([]byte(\"sa\"), 20),\n\t\t\t\tValidatorPubkey: bytesutil.PadTo([]byte(\"pk\"), 48),\n\t\t\t\tAmount:          55555,\n\t\t\t}\n\t\t}\n\t\tby, err := ssz.MarshalItemsEIP7685(requests)\n\t\trequire.NoError(t, err)\n\t\tebe := &enginev1.ExecutionBundleElectra{\n\t\t\tExecutionRequests: [][]byte{\n\t\t\t\tappend([]byte{uint8(enginev1.WithdrawalRequestType)}, by...),\n\t\t\t},\n\t\t}\n\t\t_, err = types.DecodeExecutionRequests(ebe.GetExecutionRequests())\n\t\trequire.ErrorContains(t, err, \"invalid withdrawal requests SSZ size, requests should not be more than the max per payload\")\n\t})\n\tt.Run(\"If consolidation requests are over the max allowed per payload then we should error\", func(t *testing.T) {\n\t\trequests := make([]*enginev1.ConsolidationRequest, params.BeaconConfig().MaxConsolidationsRequestsPerPayload+1)\n\t\tfor i := range requests {\n\t\t\trequests[i] = &enginev1.ConsolidationRequest{\n\t\t\t\tSourceAddress: bytesutil.PadTo([]byte(\"sa\"), 20),\n\t\t\t\tSourcePubkey:  bytesutil.PadTo([]byte(\"pk\"), 48),\n\t\t\t\tTargetPubkey:  bytesutil.PadTo([]byte(\"pk\"), 48),\n\t\t\t}\n\t\t}\n\t\tby, err := ssz.MarshalItemsEIP7685(requests)\n\t\trequire.NoError(t, err)\n\t\tebe := &enginev1.ExecutionBundleElectra{\n\t\t\tExecutionRequests: [][]byte{\n\t\t\t\tappend([]byte{uint8(enginev1.ConsolidationRequestType)}, by...),\n\t\t\t},\n\t\t}\n\t\t_, err = types.DecodeExecutionRequests(ebe.GetExecutionRequests())\n\t\trequire.ErrorContains(t, err, \"invalid consolidation requests SSZ size, requests should not be more than the max per payload\")\n\t})\n}\n\nfunc TestGetExecutionRequestsList(t *testing.T) {\n\tt.Parallel()\n\tt.Run(\"Empty execution requests should return an empty response and not nil\", func(t *testing.T) {\n\t\tebe := &types.ExecutionRequests{}\n\t\tb, err := types.GetExecutionRequestsList(ebe)\n\t\trequire.NoError(t, err)\n\t\trequire.NotNil(t, b)\n\t\trequire.Empty(t, b)\n\t})\n}\n"
  },
  {
    "path": "consensus-types/types/fork.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tfastssz \"github.com/ferranbt/fastssz\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// ForkSize is the size of the Fork object in bytes.\n// 4 bytes for PreviousVersion + 4 bytes for CurrentVersion + 8 bytes for Epoch.\nconst ForkSize = 16\n\nvar (\n\t_ ssz.StaticObject                    = (*Fork)(nil)\n\t_ constraints.SSZMarshallableRootable = (*Fork)(nil)\n)\n\n// Fork as defined in the Ethereum 2.0 specification:\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#fork\ntype Fork struct {\n\t// PreviousVersion is the last version before the fork.\n\tPreviousVersion common.Version `json:\"previous_version\"`\n\t// CurrentVersion is the first version after the fork.\n\tCurrentVersion common.Version `json:\"current_version\"`\n\t// Epoch is the epoch at which the fork occurred.\n\tEpoch math.Epoch `json:\"epoch\"`\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                 Constructor                                */\n/* -------------------------------------------------------------------------- */\n\n// New creates a new fork.\nfunc NewFork(\n\tpreviousVersion common.Version,\n\tcurrentVersion common.Version,\n\tepoch math.Epoch,\n) *Fork {\n\treturn &Fork{\n\t\tPreviousVersion: previousVersion,\n\t\tCurrentVersion:  currentVersion,\n\t\tEpoch:           epoch,\n\t}\n}\n\nfunc NewEmptyFork() *Fork {\n\treturn &Fork{}\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// SizeSSZ returns the SSZ encoded size of the Fork object in bytes.\nfunc (f *Fork) SizeSSZ(*ssz.Sizer) uint32 {\n\treturn ForkSize\n}\n\n// DefineSSZ defines the SSZ encoding for the Fork object.\nfunc (f *Fork) DefineSSZ(codec *ssz.Codec) {\n\tssz.DefineStaticBytes(codec, &f.PreviousVersion)\n\tssz.DefineStaticBytes(codec, &f.CurrentVersion)\n\tssz.DefineUint64(codec, &f.Epoch)\n}\n\n// MarshalSSZ marshals the Fork object to SSZ format.\nfunc (f *Fork) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(f))\n\treturn buf, ssz.EncodeToBytes(buf, f)\n}\n\nfunc (*Fork) ValidateAfterDecodingSSZ() error { return nil }\n\n// HashTreeRoot computes the SSZ hash tree root of the Fork object.\nfunc (f *Fork) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(f)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   FastSSZ                                  */\n/* -------------------------------------------------------------------------- */\n\n// MarshalSSZTo ssz marshals the Fork object to a target array.\nfunc (f *Fork) MarshalSSZTo(buf []byte) ([]byte, error) {\n\tbz, err := f.MarshalSSZ()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn append(buf, bz...), nil\n}\n\n// HashTreeRootWith ssz hashes the Fork object with a hasher.\nfunc (f *Fork) HashTreeRootWith(hh fastssz.HashWalker) error {\n\tindx := hh.Index()\n\n\t// Field (0) 'PreviousVersion'\n\thh.PutBytes(f.PreviousVersion[:])\n\n\t// Field (1) 'CurrentVersion'\n\thh.PutBytes(f.CurrentVersion[:])\n\n\t// Field (2) 'Epoch'\n\thh.PutUint64(uint64(f.Epoch))\n\n\thh.Merkleize(indx)\n\treturn nil\n}\n\n// GetTree ssz hashes the Fork object.\nfunc (f *Fork) GetTree() (*fastssz.Node, error) {\n\treturn fastssz.ProofTree(f)\n}\n"
  },
  {
    "path": "consensus-types/types/fork_data.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// Compile-time assertions to ensure ForkData implements necessary interfaces.\nvar (\n\t_ ssz.StaticObject                    = (*ForkData)(nil)\n\t_ constraints.SSZMarshallableRootable = (*ForkData)(nil)\n)\n\n// ForkData as defined in the Ethereum 2.0 specification:\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#forkdata\ntype ForkData struct {\n\t// CurrentVersion is the current version of the fork.\n\tCurrentVersion common.Version\n\t// GenesisValidatorsRoot is the root of the genesis validators.\n\tGenesisValidatorsRoot common.Root\n}\n\n// NewForkData creates a new ForkData struct.\nfunc NewForkData(\n\tcurrentVersion common.Version, genesisValidatorsRoot common.Root,\n) *ForkData {\n\treturn &ForkData{\n\t\tCurrentVersion:        currentVersion,\n\t\tGenesisValidatorsRoot: genesisValidatorsRoot,\n\t}\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// SizeSSZ returns the size of the SigningData object in SSZ encoding.\nfunc (*ForkData) SizeSSZ(*ssz.Sizer) uint32 {\n\t//nolint:mnd // 32+4 = 36.\n\treturn 36\n}\n\n// DefineSSZ defines the SSZ encoding for the ForkData object.\nfunc (fd *ForkData) DefineSSZ(codec *ssz.Codec) {\n\tssz.DefineStaticBytes(codec, &fd.CurrentVersion)\n\tssz.DefineStaticBytes(codec, &fd.GenesisValidatorsRoot)\n}\n\n// HashTreeRoot computes the SSZ hash tree root of the ForkData object.\nfunc (fd *ForkData) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(fd)\n}\n\n// MarshalSSZTo marshals the ForkData object to SSZ format into the provided\n// buffer.\nfunc (fd *ForkData) MarshalSSZTo(buf []byte) ([]byte, error) {\n\treturn buf, ssz.EncodeToBytes(buf, fd)\n}\n\n// MarshalSSZ marshals the ForkData object to SSZ format.\nfunc (fd *ForkData) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(fd))\n\treturn fd.MarshalSSZTo(buf)\n}\n\nfunc (*ForkData) ValidateAfterDecodingSSZ() error { return nil }\n\n// ComputeDomain as defined in the Ethereum 2.0 specification.\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#compute_domain\nfunc (fd *ForkData) ComputeDomain(\n\tdomainType common.DomainType,\n) common.Domain {\n\tforkDataRoot := fd.HashTreeRoot()\n\treturn common.Domain(\n\t\tappend(\n\t\t\tdomainType[:],\n\t\t\tforkDataRoot[:28]...),\n\t)\n}\n\n// ComputeRandaoSigningRoot computes the randao signing root.\nfunc (fd *ForkData) ComputeRandaoSigningRoot(\n\tdomainType common.DomainType,\n\tepoch math.Epoch,\n) common.Root {\n\treturn ComputeSigningRootUInt64(\n\t\tepoch.Unwrap(),\n\t\tfd.ComputeDomain(domainType),\n\t)\n}\n"
  },
  {
    "path": "consensus-types/types/fork_data_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tkaralabessz \"github.com/karalabe/ssz\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestForkData_Serialization(t *testing.T) {\n\tt.Parallel()\n\toriginal := &types.ForkData{\n\t\tCurrentVersion:        common.Version{},\n\t\tGenesisValidatorsRoot: common.Root{},\n\t}\n\n\tdata, err := original.MarshalSSZ()\n\trequire.NoError(t, err)\n\trequire.NotNil(t, data)\n\n\tunmarshalled := new(types.ForkData)\n\terr = ssz.Unmarshal(data, unmarshalled)\n\trequire.NoError(t, err)\n\n\trequire.Equal(t, original, unmarshalled)\n}\n\nfunc TestForkData_Unmarshal(t *testing.T) {\n\tt.Parallel()\n\tunmarshalled := new(types.ForkData)\n\terr := ssz.Unmarshal([]byte{}, unmarshalled)\n\trequire.ErrorIs(t, err, io.ErrUnexpectedEOF)\n}\n\nfunc TestForkData_SizeSSZ(t *testing.T) {\n\tt.Parallel()\n\tforkData := &types.ForkData{\n\t\tCurrentVersion:        common.Version{},\n\t\tGenesisValidatorsRoot: common.Root{},\n\t}\n\n\tsize := karalabessz.Size(forkData)\n\trequire.Equal(t, uint32(36), size)\n}\n\nfunc TestForkData_HashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\tforkData := &types.ForkData{\n\t\tCurrentVersion:        common.Version{},\n\t\tGenesisValidatorsRoot: common.Root{},\n\t}\n\trequire.NotPanics(t, func() {\n\t\t_ = forkData.HashTreeRoot()\n\t})\n}\n\nfunc TestForkData_ComputeDomain(t *testing.T) {\n\tt.Parallel()\n\tforkData := &types.ForkData{\n\t\tCurrentVersion:        common.Version{},\n\t\tGenesisValidatorsRoot: common.Root{},\n\t}\n\tdomainType := common.DomainType{\n\t\t0x01, 0x00, 0x00, 0x00,\n\t}\n\trequire.NotPanics(t, func() {\n\t\t_ = forkData.ComputeDomain(domainType)\n\t})\n}\n\nfunc TestForkData_ComputeRandaoSigningRoot(t *testing.T) {\n\tt.Parallel()\n\tfd := &types.ForkData{\n\t\tCurrentVersion:        common.Version{},\n\t\tGenesisValidatorsRoot: common.Root{},\n\t}\n\n\tdomainType := common.DomainType{0, 0, 0, 0}\n\tepoch := math.Epoch(1)\n\n\trequire.NotPanics(t, func() {\n\t\tfd.ComputeRandaoSigningRoot(domainType, epoch)\n\t})\n}\n\nfunc TestNewForkData(t *testing.T) {\n\tt.Parallel()\n\tcurrentVersion := common.Version{}\n\tgenesisValidatorsRoot := common.Root{}\n\n\tforkData := types.NewForkData(currentVersion, genesisValidatorsRoot)\n\n\trequire.Equal(t, currentVersion, forkData.CurrentVersion)\n\trequire.Equal(t, genesisValidatorsRoot, forkData.GenesisValidatorsRoot)\n}\n\nfunc TestNew(t *testing.T) {\n\tt.Parallel()\n\tcurrentVersion := common.Version{}\n\tgenesisValidatorsRoot := common.Root{}\n\n\tnewForkData := types.NewForkData(currentVersion, genesisValidatorsRoot)\n\n\trequire.Equal(t, currentVersion, newForkData.CurrentVersion)\n\trequire.Equal(t, genesisValidatorsRoot, newForkData.GenesisValidatorsRoot)\n}\n"
  },
  {
    "path": "consensus-types/types/fork_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tkaralabessz \"github.com/karalabe/ssz\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestFork_Serialization(t *testing.T) {\n\tt.Parallel()\n\toriginal := types.NewFork(\n\t\tcommon.Version{1, 2, 3, 4},\n\t\tcommon.Version{5, 6, 7, 8},\n\t\tmath.Epoch(1000),\n\t)\n\n\tdata, err := original.MarshalSSZ()\n\trequire.NotNil(t, data)\n\trequire.NoError(t, err)\n\n\tunmarshalled := new(types.Fork)\n\terr = ssz.Unmarshal(data, unmarshalled)\n\trequire.NoError(t, err)\n\trequire.Equal(t, original, unmarshalled)\n\n\tvar buf []byte\n\tbuf, err = original.MarshalSSZTo(buf)\n\trequire.NoError(t, err)\n\n\t// The two byte slices should be equal\n\trequire.Equal(t, data, buf)\n}\n\nfunc TestFork_SizeSSZ(t *testing.T) {\n\tt.Parallel()\n\tfork := &types.Fork{\n\t\tPreviousVersion: common.Version{1, 2, 3, 4},\n\t\tCurrentVersion:  common.Version{5, 6, 7, 8},\n\t\tEpoch:           math.Epoch(1000),\n\t}\n\n\tsize := karalabessz.Size(fork)\n\trequire.Equal(t, uint32(16), size)\n}\n\nfunc TestFork_HashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\tfork := &types.Fork{\n\t\tPreviousVersion: common.Version{1, 2, 3, 4},\n\t\tCurrentVersion:  common.Version{5, 6, 7, 8},\n\t\tEpoch:           math.Epoch(1000),\n\t}\n\n\trequire.NotPanics(t, func() {\n\t\t_ = fork.HashTreeRoot()\n\t})\n}\n\nfunc TestFork_GetTree(t *testing.T) {\n\tt.Parallel()\n\tfork := &types.Fork{\n\t\tPreviousVersion: common.Version{1, 2, 3, 4},\n\t\tCurrentVersion:  common.Version{5, 6, 7, 8},\n\t\tEpoch:           math.Epoch(1000),\n\t}\n\n\ttree, err := fork.GetTree()\n\trequire.NoError(t, err)\n\trequire.NotNil(t, tree)\n}\n\nfunc TestFork_UnmarshalSSZ_ErrSize(t *testing.T) {\n\tt.Parallel()\n\tbuf := make([]byte, 10) // size less than 16\n\n\tunmarshalled := new(types.Fork)\n\terr := ssz.Unmarshal(buf, unmarshalled)\n\trequire.ErrorIs(t, err, io.ErrUnexpectedEOF)\n}\n"
  },
  {
    "path": "consensus-types/types/genesis.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"fmt\"\n\t\"math/big\"\n\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\nconst (\n\tdefaultGasLimit      = math.U64(30000000)\n\tdefaultBaseFeePerGas = int64(3906250)\n)\n\n// Genesis is a struct that contains the genesis information\n// need to start the beacon chain.\ntype Genesis struct {\n\t// ForkVersion is the fork version of the genesis slot.\n\tForkVersion common.Version `json:\"fork_version\"`\n\n\t// Deposits represents the deposits in the genesis. Deposits are\n\t// used to initialize the validator set.\n\tDeposits []*Deposit `json:\"deposits\"`\n\n\t// ExecutionPayloadHeader is the header of the execution payload\n\t// in the genesis.\n\tExecutionPayloadHeader *ExecutionPayloadHeader `json:\"execution_payload_header\"`\n}\n\n// GetForkVersion returns the fork version in the genesis.\nfunc (g *Genesis) GetForkVersion() common.Version {\n\treturn g.ForkVersion\n}\n\n// GetDeposits returns the deposits in the genesis.\nfunc (g *Genesis) GetDeposits() []*Deposit {\n\treturn g.Deposits\n}\n\n// GetExecutionPayloadHeader returns the execution payload header.\nfunc (g *Genesis) GetExecutionPayloadHeader() *ExecutionPayloadHeader {\n\treturn g.ExecutionPayloadHeader\n}\n\n// UnmarshalJSON for Genesis.\nfunc (g *Genesis) UnmarshalJSON(\n\tdata []byte,\n) error {\n\ttype genesisMarshalable[Deposit any] struct {\n\t\tForkVersion            common.Version  `json:\"fork_version\"`\n\t\tDeposits               []*Deposit      `json:\"deposits\"`\n\t\tExecutionPayloadHeader json.RawMessage `json:\"execution_payload_header\"`\n\t}\n\tvar g2 genesisMarshalable[Deposit]\n\tif err := json.Unmarshal(data, &g2); err != nil {\n\t\treturn err\n\t}\n\n\tpayloadHeader := NewEmptyExecutionPayloadHeaderWithVersion(g2.ForkVersion)\n\tif err := json.Unmarshal(g2.ExecutionPayloadHeader, payloadHeader); err != nil {\n\t\treturn err\n\t}\n\n\tg.Deposits = g2.Deposits\n\tg.ForkVersion = g2.ForkVersion\n\tg.ExecutionPayloadHeader = payloadHeader\n\treturn nil\n}\n\n// DefaultGenesis returns the default genesis.\nfunc DefaultGenesis(v common.Version) *Genesis {\n\tdefaultHeader, err := DefaultGenesisExecutionPayloadHeader(v)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treturn &Genesis{\n\t\tForkVersion:            v,\n\t\tDeposits:               make([]*Deposit, 0),\n\t\tExecutionPayloadHeader: defaultHeader,\n\t}\n}\n\n// DefaultGenesisExecutionPayloadHeader returns a default ExecutionPayloadHeader.\nfunc DefaultGenesisExecutionPayloadHeader(v common.Version) (*ExecutionPayloadHeader, error) {\n\tstateRoot, err := bytes.ToBytes32(\n\t\thex.MustToBytes(\n\t\t\t\"0x12965ab9cbe2d2203f61d23636eb7e998f167cb79d02e452f532535641e35bcc\",\n\t\t),\n\t)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed generating state root: %w\", err)\n\t}\n\n\treceiptsRoot, err := bytes.ToBytes32(\n\t\thex.MustToBytes(\n\t\t\t\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\n\t\t),\n\t)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed generating receipts root: %w\", err)\n\t}\n\n\tbaseFeePerGas, err := math.NewU256FromBigInt(\n\t\tbig.NewInt(defaultBaseFeePerGas),\n\t)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed setting base fee per gas: %w\", err)\n\t}\n\n\treturn &ExecutionPayloadHeader{\n\t\tVersionable:   NewVersionable(v),\n\t\tParentHash:    common.ExecutionHash{},\n\t\tFeeRecipient:  common.ExecutionAddress{},\n\t\tStateRoot:     stateRoot,\n\t\tReceiptsRoot:  receiptsRoot,\n\t\tLogsBloom:     [256]byte{},\n\t\tRandom:        common.Bytes32{},\n\t\tNumber:        0,\n\t\tGasLimit:      defaultGasLimit,\n\t\tGasUsed:       0,\n\t\tTimestamp:     0,\n\t\tExtraData:     make([]byte, constants.ExtraDataLength),\n\t\tBaseFeePerGas: baseFeePerGas,\n\t\tBlockHash: common.NewExecutionHashFromHex(\n\t\t\t\"0xcfff92cd918a186029a847b59aca4f83d3941df5946b06bca8de0861fc5d0850\",\n\t\t),\n\t\tTransactionsRoot: engineprimitives.Transactions(nil).\n\t\t\tHashTreeRoot(),\n\t\tWithdrawalsRoot: engineprimitives.Withdrawals(nil).HashTreeRoot(),\n\t\tBlobGasUsed:     0,\n\t\tExcessBlobGas:   0,\n\t}, nil\n}\n"
  },
  {
    "path": "consensus-types/types/genesis_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//nolint:lll // long strings.\npackage types_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestDefaultGenesis(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tg := types.DefaultGenesis(v)\n\t\tif !version.Equals(g.ForkVersion, v) {\n\t\t\tt.Errorf(\n\t\t\t\t\"Expected fork version %v, but got %v\",\n\t\t\t\tv,\n\t\t\t\tg.ForkVersion,\n\t\t\t)\n\t\t}\n\n\t\tif len(g.Deposits) != 0 {\n\t\t\tt.Errorf(\"Expected no deposits, but got %v\", len(g.Deposits))\n\t\t}\n\t\t// add assertions for ExecutionPayloadHeader\n\t\trequire.NotNil(t, g.ExecutionPayloadHeader,\n\t\t\t\"Expected ExecutionPayloadHeader to be non-nil\")\n\t\trequire.Equal(t, common.ExecutionHash{},\n\t\t\tg.ExecutionPayloadHeader.GetParentHash(),\n\t\t\t\"Unexpected ParentHash\")\n\t\trequire.Equal(t, common.ExecutionAddress{},\n\t\t\tg.ExecutionPayloadHeader.GetFeeRecipient(),\n\t\t\t\"Unexpected FeeRecipient\")\n\t\trequire.Equal(t, math.U64(30000000),\n\t\t\tg.ExecutionPayloadHeader.GetGasLimit(),\n\t\t\t\"Unexpected GasLimit\")\n\t\trequire.Equal(t, math.U64(0),\n\t\t\tg.ExecutionPayloadHeader.GetGasUsed(),\n\t\t\t\"Unexpected GasUsed\")\n\t\trequire.Equal(t, math.U64(0),\n\t\t\tg.ExecutionPayloadHeader.GetTimestamp(),\n\t\t\t\"Unexpected Timestamp\")\n\t})\n}\n\nfunc TestDefaultGenesisExecutionPayloadHeader(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\theader, err := types.DefaultGenesisExecutionPayloadHeader(v)\n\t\trequire.NoError(t, err)\n\t\trequire.NotNil(t, header)\n\t})\n}\n\nfunc TestGenesisGetForkVersion(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tg := types.DefaultGenesis(v)\n\t\tforkVersion := g.GetForkVersion()\n\t\trequire.Equal(t, v, forkVersion)\n\t})\n}\n\nfunc TestGenesisGetDeposits(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tg := types.DefaultGenesis(v)\n\t\tdeposits := g.GetDeposits()\n\t\trequire.Empty(t, deposits)\n\t})\n}\n\nfunc TestGenesisGetExecutionPayloadHeader(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tg := types.DefaultGenesis(v)\n\t\theader := g.GetExecutionPayloadHeader()\n\t\trequire.NotNil(t, header)\n\t})\n}\n\nfunc TestDefaultGenesisPanics(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\trequire.NotPanics(t, func() {\n\t\t\ttypes.DefaultGenesis(v)\n\t\t})\n\t})\n}\n\nfunc TestGenesisUnmarshalJSON(t *testing.T) {\n\tt.Parallel()\n\tt.Helper()\n\ttestCases := []struct {\n\t\tname                string\n\t\tjsonInput           string\n\t\texpectedError       bool\n\t\texpectedFork        bytes.B4\n\t\texpectedDepositsLen int\n\t}{\n\t\t{\n\t\t\tname: \"Valid JSON with empty deposits\",\n\t\t\tjsonInput: `{\n\t\t\t\t  \"fork_version\": \"0x04000000\",\n\t\t\t\t  \"deposits\": [],\n\t\t\t\t  \"execution_payload_header\": {\n\t\t\t\t\t\"parentHash\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"feeRecipient\": \"0x0000000000000000000000000000000000000000\",\n\t\t\t\t\t\"stateRoot\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"receiptsRoot\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"logsBloom\": \"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"prevRandao\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"blockNumber\": \"0x0\",\n\t\t\t\t\t\"gasLimit\": \"0x0\",\n\t\t\t\t\t\"gasUsed\": \"0x0\",\n\t\t\t\t\t\"timestamp\": \"0x0\",\n\t\t\t\t\t\"extraData\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"baseFeePerGas\": \"0x0\",\n\t\t\t\t\t\"blockHash\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"transactionsRoot\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"withdrawalsRoot\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"blobGasUsed\": \"0x0\",\n\t\t\t\t\t\"excessBlobGas\": \"0x0\"\n\t\t\t\t  }\n\t\t\t\t}`,\n\t\t\texpectedError:       false,\n\t\t\texpectedFork:        bytes.B4{0x4, 0x0, 0x0, 0x0},\n\t\t\texpectedDepositsLen: 0,\n\t\t},\n\t\t{\n\t\t\tname: \"Valid JSON with non-empty deposits\",\n\t\t\tjsonInput: `{\n\t\t\t\t  \"fork_version\": \"0x04000000\",\n\t\t\t\t  \"deposits\": [{\"key\": \"value\"}],\n\t\t\t\t  \"execution_payload_header\": {\n\t\t\t\t\t\"parentHash\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"feeRecipient\": \"0x0000000000000000000000000000000000000000\",\n\t\t\t\t\t\"stateRoot\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"receiptsRoot\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"logsBloom\": \"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"prevRandao\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"blockNumber\": \"0x0\",\n\t\t\t\t\t\"gasLimit\": \"0x0\",\n\t\t\t\t\t\"gasUsed\": \"0x0\",\n\t\t\t\t\t\"timestamp\": \"0x0\",\n\t\t\t\t\t\"extraData\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"baseFeePerGas\": \"0x0\",\n\t\t\t\t\t\"blockHash\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"transactionsRoot\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"withdrawalsRoot\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"blobGasUsed\": \"0x0\",\n\t\t\t\t\t\"excessBlobGas\": \"0x0\"\n\t\t\t\t  }\n\t\t\t\t}`,\n\t\t\texpectedError:       false,\n\t\t\texpectedFork:        bytes.B4{0x4, 0x0, 0x0, 0x0},\n\t\t\texpectedDepositsLen: 1,\n\t\t},\n\t\t{\n\t\t\tname: \"Invalid JSON input\",\n\t\t\tjsonInput: `{\n\t\t\t\t\"fork_version\": 12345,\n\t\t\t\t\"deposits\": [],\n\t\t\t\t\"execution_payload_header\": {\n\t\t\t\t}\n\t\t\t}`,\n\t\t\texpectedError: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Missing fields in JSON input\",\n\t\t\tjsonInput: `{\n\t\t\t\t  \"fork_version\": \"0x04000000\",\n\t\t\t\t  \"deposits\": [{\"key\": \"value\"}],\n\t\t\t\t  \"execution_payload_header\": {\n\t\t\t\t\t\"parentHash\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"feeRecipient\": \"0x0000000000000000000000000000000000000000\",\n\t\t\t\t\t\"stateRoot\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"receiptsRoot\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"logsBloom\": \"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"prevRandao\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"gasLimit\": \"0x1c9c380\",\n\t\t\t\t\t\"gasUsed\": \"0x0\",\n\t\t\t\t\t\"timestamp\": \"0x0\",\n\t\t\t\t\t\"extraData\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"baseFeePerGas\": \"0x3b9aca\",\n\t\t\t\t\t\"blockHash\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"transactionsRoot\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"withdrawalsRoot\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\t\t\t\"blobGasUsed\": \"0x0\",\n\t\t\t\t\t\"excessBlobGas\": \"0x0\"\n\t\t\t\t  }\n\t\t\t\t}`,\n\t\t\texpectedError: true,\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\t\t\t\tg := types.DefaultGenesis(v)\n\t\t\t\terr := g.UnmarshalJSON([]byte(tc.jsonInput))\n\t\t\t\tif tc.expectedError {\n\t\t\t\t\trequire.Error(t, err, \"Expected error but got none\")\n\t\t\t\t} else {\n\t\t\t\t\trequire.NoError(t, err, \"Unexpected error\")\n\t\t\t\t\trequire.Equal(t, tc.expectedFork, g.ForkVersion, \"Unexpected ForkVersion\")\n\t\t\t\t\trequire.Len(t, g.Deposits, tc.expectedDepositsLen, \"Unexpected number of deposits\")\n\t\t\t\t\trequire.NotNil(t, g.ExecutionPayloadHeader, \"Expected ExecutionPayloadHeader to be non-nil\")\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "consensus-types/types/header.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tfastssz \"github.com/ferranbt/fastssz\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// BeaconBlockHeaderSize is the size of the BeaconBlockHeader object in bytes.\n//\n// Total size: Slot (8) + ProposerIndex (8) +\n// ParentBlockRoot (32) + StateRoot (32) + BodyRoot (32).\nconst BeaconBlockHeaderSize = 112\n\nvar (\n\t_ ssz.StaticObject                    = (*BeaconBlockHeader)(nil)\n\t_ constraints.SSZMarshallableRootable = (*BeaconBlockHeader)(nil)\n)\n\n// BeaconBlockHeader represents the base of a beacon block header.\ntype BeaconBlockHeader struct {\n\t// Slot represents the position of the block in the chain.\n\tSlot math.Slot `json:\"slot\"`\n\t// ProposerIndex is the index of the validator who proposed the block.\n\tProposerIndex math.ValidatorIndex `json:\"proposer_index\"`\n\t// ParentBlockRoot is the hash of the parent block\n\tParentBlockRoot common.Root `json:\"parent_block_root\"`\n\t// StateRoot is the hash of the state at the block.\n\tStateRoot common.Root `json:\"state_root\"`\n\t// BodyRoot is the root of the block body.\n\tBodyRoot common.Root `json:\"body_root\"`\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                 Constructor                                */\n/* -------------------------------------------------------------------------- */\n\n// NewBeaconBlockHeader creates a new BeaconBlockHeader.\nfunc NewBeaconBlockHeader(\n\tslot math.Slot,\n\tproposerIndex math.ValidatorIndex,\n\tparentBlockRoot common.Root,\n\tstateRoot common.Root,\n\tbodyRoot common.Root,\n) *BeaconBlockHeader {\n\treturn &BeaconBlockHeader{\n\t\tSlot:            slot,\n\t\tProposerIndex:   proposerIndex,\n\t\tParentBlockRoot: parentBlockRoot,\n\t\tStateRoot:       stateRoot,\n\t\tBodyRoot:        bodyRoot,\n\t}\n}\n\nfunc NewEmptyBeaconBlockHeader() *BeaconBlockHeader {\n\treturn &BeaconBlockHeader{}\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// SizeSSZ returns the size of the BeaconBlockHeader object in SSZ encoding.\nfunc (b *BeaconBlockHeader) SizeSSZ(*ssz.Sizer) uint32 {\n\treturn BeaconBlockHeaderSize\n}\n\n// DefineSSZ defines the SSZ encoding for the BeaconBlockHeader object.\nfunc (b *BeaconBlockHeader) DefineSSZ(codec *ssz.Codec) {\n\tssz.DefineUint64(codec, &b.Slot)\n\tssz.DefineUint64(codec, &b.ProposerIndex)\n\tssz.DefineStaticBytes(codec, &b.ParentBlockRoot)\n\tssz.DefineStaticBytes(codec, &b.StateRoot)\n\tssz.DefineStaticBytes(codec, &b.BodyRoot)\n}\n\n// MarshalSSZ marshals the BeaconBlockBody object to SSZ format.\nfunc (b *BeaconBlockHeader) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(b))\n\treturn buf, ssz.EncodeToBytes(buf, b)\n}\n\nfunc (*BeaconBlockHeader) ValidateAfterDecodingSSZ() error { return nil }\n\n// HashTreeRoot computes the SSZ hash tree root of the BeaconBlockHeader object.\nfunc (b *BeaconBlockHeader) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(b)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   FastSSZ                                  */\n/* -------------------------------------------------------------------------- */\n\n// MarshalSSZTo marshals the BeaconBlockHeader object to SSZ format.\nfunc (b *BeaconBlockHeader) MarshalSSZTo(dst []byte) ([]byte, error) {\n\tbz, err := b.MarshalSSZ()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdst = append(dst, bz...)\n\treturn dst, nil\n}\n\n// HashTreeRootWith ssz hashes the BeaconBlockHeader object with a hasher.\nfunc (b *BeaconBlockHeader) HashTreeRootWith(\n\thh fastssz.HashWalker,\n) error {\n\tindx := hh.Index()\n\n\t// Field (0) 'Slot'\n\thh.PutUint64(uint64(b.Slot))\n\n\t// Field (1) 'ProposerIndex'\n\thh.PutUint64(uint64(b.ProposerIndex))\n\n\t// Field (2) 'ParentBlockRoot'\n\thh.PutBytes(b.ParentBlockRoot[:])\n\n\t// Field (3) 'StateRoot'\n\thh.PutBytes(b.StateRoot[:])\n\n\t// Field (4) 'BodyRoot'\n\thh.PutBytes(b.BodyRoot[:])\n\n\thh.Merkleize(indx)\n\treturn nil\n}\n\n// GetTree ssz hashes the BeaconBlockHeader object.\nfunc (b *BeaconBlockHeader) GetTree() (*fastssz.Node, error) {\n\treturn fastssz.ProofTree(b)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                            Getters and Setters                             */\n/* -------------------------------------------------------------------------- */\n\n// Equals returns true if the Withdrawal is equal to the other.\nfunc (b *BeaconBlockHeader) Equals(rhs *BeaconBlockHeader) bool {\n\tswitch {\n\tcase b == nil && rhs == nil:\n\t\treturn true\n\tcase b != nil && rhs != nil:\n\t\treturn b.Slot == rhs.Slot &&\n\t\t\tb.ProposerIndex == rhs.ProposerIndex &&\n\t\t\tb.ParentBlockRoot == rhs.ParentBlockRoot &&\n\t\t\tb.StateRoot == rhs.StateRoot &&\n\t\t\tb.BodyRoot == rhs.BodyRoot\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// GetSlot retrieves the slot of the BeaconBlockHeader.\nfunc (b *BeaconBlockHeader) GetSlot() math.Slot {\n\treturn b.Slot\n}\n\n// SetSlot sets the slot of the BeaconBlockHeader.\nfunc (b *BeaconBlockHeader) SetSlot(slot math.Slot) {\n\tb.Slot = slot\n}\n\n// GetProposerIndex retrieves the proposer index of the BeaconBlockHeader.\nfunc (b *BeaconBlockHeader) GetProposerIndex() math.ValidatorIndex {\n\treturn b.ProposerIndex\n}\n\n// SetProposerIndex sets the proposer index of the BeaconBlockHeader.\nfunc (b *BeaconBlockHeader) SetProposerIndex(\n\tproposerIndex math.ValidatorIndex,\n) {\n\tb.ProposerIndex = proposerIndex\n}\n\n// GetParentBlockRoot retrieves the parent block root of the BeaconBlockHeader.\nfunc (b *BeaconBlockHeader) GetParentBlockRoot() common.Root {\n\treturn b.ParentBlockRoot\n}\n\n// SetParentBlockRoot sets the parent block root of the BeaconBlockHeader.\nfunc (b *BeaconBlockHeader) SetParentBlockRoot(parentBlockRoot common.Root) {\n\tb.ParentBlockRoot = parentBlockRoot\n}\n\n// GetStateRoot retrieves the state root of the BeaconBlockHeader.\nfunc (b *BeaconBlockHeader) GetStateRoot() common.Root {\n\treturn b.StateRoot\n}\n\n// SetStateRoot sets the state root of the BeaconBlockHeader.\nfunc (b *BeaconBlockHeader) SetStateRoot(stateRoot common.Root) {\n\tb.StateRoot = stateRoot\n}\n\n// GetBodyRoot retrieves the body root of the BeaconBlockHeader.\nfunc (b *BeaconBlockHeader) GetBodyRoot() common.Root {\n\treturn b.BodyRoot\n}\n\n// SetBodyRoot sets the body root of the BeaconBlockHeader.\nfunc (b *BeaconBlockHeader) SetBodyRoot(bodyRoot common.Root) {\n\tb.BodyRoot = bodyRoot\n}\n"
  },
  {
    "path": "consensus-types/types/header_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tkaralabessz \"github.com/karalabe/ssz\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestBeaconBlockHeader_Equals(t *testing.T) {\n\tt.Parallel()\n\tvar (\n\t\tslot            = math.Slot(100)\n\t\tvalIdx          = math.ValidatorIndex(200)\n\t\tparentBlockRoot = common.Root{1}\n\t\tstateRoot       = common.Root{2}\n\t\tbodyRoot        = common.Root{3}\n\n\t\tlhs = types.NewBeaconBlockHeader(\n\t\t\tslot, valIdx, parentBlockRoot, stateRoot, bodyRoot,\n\t\t)\n\t)\n\n\ttests := []struct {\n\t\tname string\n\t\trhs  *types.BeaconBlockHeader\n\t\twant bool\n\t}{\n\t\t{\n\t\t\tname: \"equal\",\n\t\t\trhs: types.NewBeaconBlockHeader(\n\t\t\t\tslot, valIdx, parentBlockRoot, stateRoot, bodyRoot,\n\t\t\t),\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname: \"slot differs\",\n\t\t\trhs: types.NewBeaconBlockHeader(\n\t\t\t\t2*slot, valIdx, parentBlockRoot, stateRoot, bodyRoot,\n\t\t\t),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tname: \"validator index differs\",\n\t\t\trhs: types.NewBeaconBlockHeader(\n\t\t\t\tslot, 2*valIdx, parentBlockRoot, stateRoot, bodyRoot,\n\t\t\t),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tname: \"parent block root differs\",\n\t\t\trhs: types.NewBeaconBlockHeader(\n\t\t\t\tslot, valIdx, common.Root{0xff}, stateRoot, bodyRoot,\n\t\t\t),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tname: \"state root differs\",\n\t\t\trhs: types.NewBeaconBlockHeader(\n\t\t\t\tslot, valIdx, parentBlockRoot, common.Root{0xff}, bodyRoot,\n\t\t\t),\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tname: \"body root differs\",\n\t\t\trhs: types.NewBeaconBlockHeader(\n\t\t\t\tslot, valIdx, parentBlockRoot, stateRoot, common.Root{0xff},\n\t\t\t),\n\t\t\twant: false,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot1 := lhs.Equals(tt.rhs)\n\t\t\trequire.Equal(t, tt.want, got1)\n\n\t\t\t// check commutativity as well\n\t\t\tgot2 := tt.rhs.Equals(lhs)\n\t\t\trequire.Equal(t, got1, got2)\n\n\t\t\t// copies stays equal/disequal\n\t\t\trhsCopy := &types.BeaconBlockHeader{}\n\t\t\t*rhsCopy = *tt.rhs\n\t\t\tgot3 := rhsCopy.Equals(lhs)\n\t\t\trequire.Equal(t, got1, got3)\n\t\t})\n\t}\n}\n\nfunc TestBeaconBlockHeader_Serialization(t *testing.T) {\n\tt.Parallel()\n\toriginal := types.NewBeaconBlockHeader(\n\t\tmath.Slot(100),\n\t\tmath.ValidatorIndex(200),\n\t\tcommon.Root{},\n\t\tcommon.Root{},\n\t\tcommon.Root{},\n\t)\n\n\tdata, err := original.MarshalSSZ()\n\trequire.NoError(t, err)\n\trequire.NotNil(t, data)\n\n\tunmarshalled := new(types.BeaconBlockHeader)\n\terr = ssz.Unmarshal(data, unmarshalled)\n\trequire.NoError(t, err)\n\trequire.Equal(t, original, unmarshalled)\n\n\tvar buf []byte\n\tbuf, err = original.MarshalSSZTo(buf)\n\trequire.NoError(t, err)\n\n\t// The two byte slices should be equal\n\trequire.Equal(t, data, buf)\n}\n\nfunc TestBeaconBlockHeader_SizeSSZ(t *testing.T) {\n\tt.Parallel()\n\theader := types.NewBeaconBlockHeader(\n\t\tmath.Slot(100),\n\t\tmath.ValidatorIndex(200),\n\t\tcommon.Root{},\n\t\tcommon.Root{},\n\t\tcommon.Root{},\n\t)\n\n\tsize := karalabessz.Size(header)\n\trequire.Equal(t, uint32(112), size)\n}\n\nfunc TestBeaconBlockHeader_HashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\theader := types.NewBeaconBlockHeader(\n\t\tmath.Slot(100),\n\t\tmath.ValidatorIndex(200),\n\t\tcommon.Root{},\n\t\tcommon.Root{},\n\t\tcommon.Root{},\n\t)\n\n\t_ = header.HashTreeRoot()\n}\n\nfunc TestBeaconBlockHeader_GetTree(t *testing.T) {\n\tt.Parallel()\n\theader := types.NewBeaconBlockHeader(\n\t\tmath.Slot(100),\n\t\tmath.ValidatorIndex(200),\n\t\tcommon.Root{},\n\t\tcommon.Root{},\n\t\tcommon.Root{},\n\t)\n\n\ttree, err := header.GetTree()\n\n\trequire.NoError(t, err)\n\trequire.NotNil(t, tree)\n}\n\nfunc TestBeaconBlockHeader_SetStateRoot(t *testing.T) {\n\tt.Parallel()\n\theader := types.NewBeaconBlockHeader(\n\t\tmath.Slot(100),\n\t\tmath.ValidatorIndex(200),\n\t\tcommon.Root{},\n\t\tcommon.Root{},\n\t\tcommon.Root{},\n\t)\n\n\tnewStateRoot := common.Root{}\n\theader.SetStateRoot(newStateRoot)\n\n\trequire.Equal(t, newStateRoot, header.GetStateRoot())\n}\n\nfunc TestBeaconBlockHeader_SetSlot(t *testing.T) {\n\tt.Parallel()\n\theader := types.NewBeaconBlockHeader(\n\t\tmath.Slot(100),\n\t\tmath.ValidatorIndex(200),\n\t\tcommon.Root{},\n\t\tcommon.Root{},\n\t\tcommon.Root{},\n\t)\n\n\tnewSlot := math.Slot(101)\n\theader.SetSlot(newSlot)\n\n\trequire.Equal(t, newSlot, header.GetSlot())\n}\n\nfunc TestBeaconBlockHeader_SetProposerIndex(t *testing.T) {\n\tt.Parallel()\n\theader := types.NewBeaconBlockHeader(\n\t\tmath.Slot(100),\n\t\tmath.ValidatorIndex(200),\n\t\tcommon.Root{},\n\t\tcommon.Root{},\n\t\tcommon.Root{},\n\t)\n\n\tnewProposerIndex := math.ValidatorIndex(201)\n\theader.SetProposerIndex(newProposerIndex)\n\trequire.Equal(t, newProposerIndex, header.GetProposerIndex())\n}\n\nfunc TestBeaconBlockHeader_SetParentBlockRoot(t *testing.T) {\n\tt.Parallel()\n\theader := types.NewBeaconBlockHeader(\n\t\tmath.Slot(100),\n\t\tmath.ValidatorIndex(200),\n\t\tcommon.Root{},\n\t\tcommon.Root{},\n\t\tcommon.Root{},\n\t)\n\n\tnewParentBlockRoot := common.Root{}\n\theader.SetParentBlockRoot(newParentBlockRoot)\n\n\trequire.Equal(t, newParentBlockRoot, header.GetParentBlockRoot())\n}\n\nfunc TestBeaconBlockHeader_SetBodyRoot(t *testing.T) {\n\tt.Parallel()\n\theader := types.NewBeaconBlockHeader(\n\t\tmath.Slot(100),\n\t\tmath.ValidatorIndex(200),\n\t\tcommon.Root{},\n\t\tcommon.Root{},\n\t\tcommon.Root{},\n\t)\n\n\tnewBodyRoot := common.Root{}\n\theader.SetBodyRoot(newBodyRoot)\n\n\trequire.Equal(t, newBodyRoot, header.GetBodyRoot())\n}\n\nfunc TestBeaconBlockHeader_UnmarshalSSZ_ErrSize(t *testing.T) {\n\tt.Parallel()\n\tbuf := make([]byte, 100) // Incorrect size\n\n\tunmarshalled := new(types.BeaconBlockHeader)\n\terr := ssz.Unmarshal(buf, unmarshalled)\n\trequire.ErrorIs(t, err, io.ErrUnexpectedEOF)\n}\n"
  },
  {
    "path": "consensus-types/types/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport \"github.com/berachain/beacon-kit/primitives/common\"\n\ntype ProposerDomain interface {\n\t// DomainTypeProposer returns the domain for proposer signatures.\n\tDomainTypeProposer() common.DomainType\n}\n"
  },
  {
    "path": "consensus-types/types/mocks/blobs_bundle.mock.go",
    "content": "// Code generated by mockery v2.49.0. DO NOT EDIT.\n\npackage mocks\n\nimport (\n\tbytes \"github.com/berachain/beacon-kit/primitives/bytes\"\n\teip4844 \"github.com/berachain/beacon-kit/primitives/eip4844\"\n\n\tmock \"github.com/stretchr/testify/mock\"\n)\n\n// BlobsBundle is an autogenerated mock type for the BlobsBundle type\ntype BlobsBundle struct {\n\tmock.Mock\n}\n\ntype BlobsBundle_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *BlobsBundle) EXPECT() *BlobsBundle_Expecter {\n\treturn &BlobsBundle_Expecter{mock: &_m.Mock}\n}\n\n// GetBlobs provides a mock function with given fields:\nfunc (_m *BlobsBundle) GetBlobs() []*eip4844.Blob {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetBlobs\")\n\t}\n\n\tvar r0 []*eip4844.Blob\n\tif rf, ok := ret.Get(0).(func() []*eip4844.Blob); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).([]*eip4844.Blob)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// BlobsBundle_GetBlobs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBlobs'\ntype BlobsBundle_GetBlobs_Call struct {\n\t*mock.Call\n}\n\n// GetBlobs is a helper method to define mock.On call\nfunc (_e *BlobsBundle_Expecter) GetBlobs() *BlobsBundle_GetBlobs_Call {\n\treturn &BlobsBundle_GetBlobs_Call{Call: _e.mock.On(\"GetBlobs\")}\n}\n\nfunc (_c *BlobsBundle_GetBlobs_Call) Run(run func()) *BlobsBundle_GetBlobs_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *BlobsBundle_GetBlobs_Call) Return(_a0 []*eip4844.Blob) *BlobsBundle_GetBlobs_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *BlobsBundle_GetBlobs_Call) RunAndReturn(run func() []*eip4844.Blob) *BlobsBundle_GetBlobs_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// GetCommitments provides a mock function with given fields:\nfunc (_m *BlobsBundle) GetCommitments() []eip4844.KZGCommitment {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetCommitments\")\n\t}\n\n\tvar r0 []eip4844.KZGCommitment\n\tif rf, ok := ret.Get(0).(func() []eip4844.KZGCommitment); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).([]eip4844.KZGCommitment)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// BlobsBundle_GetCommitments_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCommitments'\ntype BlobsBundle_GetCommitments_Call struct {\n\t*mock.Call\n}\n\n// GetCommitments is a helper method to define mock.On call\nfunc (_e *BlobsBundle_Expecter) GetCommitments() *BlobsBundle_GetCommitments_Call {\n\treturn &BlobsBundle_GetCommitments_Call{Call: _e.mock.On(\"GetCommitments\")}\n}\n\nfunc (_c *BlobsBundle_GetCommitments_Call) Run(run func()) *BlobsBundle_GetCommitments_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *BlobsBundle_GetCommitments_Call) Return(_a0 []eip4844.KZGCommitment) *BlobsBundle_GetCommitments_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *BlobsBundle_GetCommitments_Call) RunAndReturn(run func() []eip4844.KZGCommitment) *BlobsBundle_GetCommitments_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// GetProofs provides a mock function with given fields:\nfunc (_m *BlobsBundle) GetProofs() []bytes.B48 {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetProofs\")\n\t}\n\n\tvar r0 []bytes.B48\n\tif rf, ok := ret.Get(0).(func() []bytes.B48); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).([]bytes.B48)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// BlobsBundle_GetProofs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetProofs'\ntype BlobsBundle_GetProofs_Call struct {\n\t*mock.Call\n}\n\n// GetProofs is a helper method to define mock.On call\nfunc (_e *BlobsBundle_Expecter) GetProofs() *BlobsBundle_GetProofs_Call {\n\treturn &BlobsBundle_GetProofs_Call{Call: _e.mock.On(\"GetProofs\")}\n}\n\nfunc (_c *BlobsBundle_GetProofs_Call) Run(run func()) *BlobsBundle_GetProofs_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *BlobsBundle_GetProofs_Call) Return(_a0 []bytes.B48) *BlobsBundle_GetProofs_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *BlobsBundle_GetProofs_Call) RunAndReturn(run func() []bytes.B48) *BlobsBundle_GetProofs_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewBlobsBundle creates a new instance of BlobsBundle. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewBlobsBundle(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *BlobsBundle {\n\tmock := &BlobsBundle{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "consensus-types/types/mocks/built_execution_payload_env.mock.go",
    "content": "// Code generated by mockery v2.53.5. DO NOT EDIT.\n\npackage mocks\n\nimport (\n\ttypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\tmath \"github.com/berachain/beacon-kit/primitives/math\"\n\tmock \"github.com/stretchr/testify/mock\"\n)\n\n// BuiltExecutionPayloadEnv is an autogenerated mock type for the BuiltExecutionPayloadEnv type\ntype BuiltExecutionPayloadEnv struct {\n\tmock.Mock\n}\n\ntype BuiltExecutionPayloadEnv_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *BuiltExecutionPayloadEnv) EXPECT() *BuiltExecutionPayloadEnv_Expecter {\n\treturn &BuiltExecutionPayloadEnv_Expecter{mock: &_m.Mock}\n}\n\n// GetBlobsBundle provides a mock function with no fields\nfunc (_m *BuiltExecutionPayloadEnv) GetBlobsBundle() engineprimitives.BlobsBundle {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetBlobsBundle\")\n\t}\n\n\tvar r0 engineprimitives.BlobsBundle\n\tif rf, ok := ret.Get(0).(func() engineprimitives.BlobsBundle); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(engineprimitives.BlobsBundle)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// BuiltExecutionPayloadEnv_GetBlobsBundle_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBlobsBundle'\ntype BuiltExecutionPayloadEnv_GetBlobsBundle_Call struct {\n\t*mock.Call\n}\n\n// GetBlobsBundle is a helper method to define mock.On call\nfunc (_e *BuiltExecutionPayloadEnv_Expecter) GetBlobsBundle() *BuiltExecutionPayloadEnv_GetBlobsBundle_Call {\n\treturn &BuiltExecutionPayloadEnv_GetBlobsBundle_Call{Call: _e.mock.On(\"GetBlobsBundle\")}\n}\n\nfunc (_c *BuiltExecutionPayloadEnv_GetBlobsBundle_Call) Run(run func()) *BuiltExecutionPayloadEnv_GetBlobsBundle_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *BuiltExecutionPayloadEnv_GetBlobsBundle_Call) Return(_a0 engineprimitives.BlobsBundle) *BuiltExecutionPayloadEnv_GetBlobsBundle_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *BuiltExecutionPayloadEnv_GetBlobsBundle_Call) RunAndReturn(run func() engineprimitives.BlobsBundle) *BuiltExecutionPayloadEnv_GetBlobsBundle_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// GetBlockValue provides a mock function with no fields\nfunc (_m *BuiltExecutionPayloadEnv) GetBlockValue() *math.U256 {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetBlockValue\")\n\t}\n\n\tvar r0 *math.U256\n\tif rf, ok := ret.Get(0).(func() *math.U256); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(*math.U256)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// BuiltExecutionPayloadEnv_GetBlockValue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBlockValue'\ntype BuiltExecutionPayloadEnv_GetBlockValue_Call struct {\n\t*mock.Call\n}\n\n// GetBlockValue is a helper method to define mock.On call\nfunc (_e *BuiltExecutionPayloadEnv_Expecter) GetBlockValue() *BuiltExecutionPayloadEnv_GetBlockValue_Call {\n\treturn &BuiltExecutionPayloadEnv_GetBlockValue_Call{Call: _e.mock.On(\"GetBlockValue\")}\n}\n\nfunc (_c *BuiltExecutionPayloadEnv_GetBlockValue_Call) Run(run func()) *BuiltExecutionPayloadEnv_GetBlockValue_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *BuiltExecutionPayloadEnv_GetBlockValue_Call) Return(_a0 *math.U256) *BuiltExecutionPayloadEnv_GetBlockValue_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *BuiltExecutionPayloadEnv_GetBlockValue_Call) RunAndReturn(run func() *math.U256) *BuiltExecutionPayloadEnv_GetBlockValue_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// GetEncodedExecutionRequests provides a mock function with no fields\nfunc (_m *BuiltExecutionPayloadEnv) GetEncodedExecutionRequests() []types.EncodedExecutionRequest {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetEncodedExecutionRequests\")\n\t}\n\n\tvar r0 []types.EncodedExecutionRequest\n\tif rf, ok := ret.Get(0).(func() []types.EncodedExecutionRequest); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).([]types.EncodedExecutionRequest)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// BuiltExecutionPayloadEnv_GetEncodedExecutionRequests_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetEncodedExecutionRequests'\ntype BuiltExecutionPayloadEnv_GetEncodedExecutionRequests_Call struct {\n\t*mock.Call\n}\n\n// GetEncodedExecutionRequests is a helper method to define mock.On call\nfunc (_e *BuiltExecutionPayloadEnv_Expecter) GetEncodedExecutionRequests() *BuiltExecutionPayloadEnv_GetEncodedExecutionRequests_Call {\n\treturn &BuiltExecutionPayloadEnv_GetEncodedExecutionRequests_Call{Call: _e.mock.On(\"GetEncodedExecutionRequests\")}\n}\n\nfunc (_c *BuiltExecutionPayloadEnv_GetEncodedExecutionRequests_Call) Run(run func()) *BuiltExecutionPayloadEnv_GetEncodedExecutionRequests_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *BuiltExecutionPayloadEnv_GetEncodedExecutionRequests_Call) Return(_a0 []types.EncodedExecutionRequest) *BuiltExecutionPayloadEnv_GetEncodedExecutionRequests_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *BuiltExecutionPayloadEnv_GetEncodedExecutionRequests_Call) RunAndReturn(run func() []types.EncodedExecutionRequest) *BuiltExecutionPayloadEnv_GetEncodedExecutionRequests_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// GetExecutionPayload provides a mock function with no fields\nfunc (_m *BuiltExecutionPayloadEnv) GetExecutionPayload() *types.ExecutionPayload {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetExecutionPayload\")\n\t}\n\n\tvar r0 *types.ExecutionPayload\n\tif rf, ok := ret.Get(0).(func() *types.ExecutionPayload); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(*types.ExecutionPayload)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// BuiltExecutionPayloadEnv_GetExecutionPayload_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetExecutionPayload'\ntype BuiltExecutionPayloadEnv_GetExecutionPayload_Call struct {\n\t*mock.Call\n}\n\n// GetExecutionPayload is a helper method to define mock.On call\nfunc (_e *BuiltExecutionPayloadEnv_Expecter) GetExecutionPayload() *BuiltExecutionPayloadEnv_GetExecutionPayload_Call {\n\treturn &BuiltExecutionPayloadEnv_GetExecutionPayload_Call{Call: _e.mock.On(\"GetExecutionPayload\")}\n}\n\nfunc (_c *BuiltExecutionPayloadEnv_GetExecutionPayload_Call) Run(run func()) *BuiltExecutionPayloadEnv_GetExecutionPayload_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *BuiltExecutionPayloadEnv_GetExecutionPayload_Call) Return(_a0 *types.ExecutionPayload) *BuiltExecutionPayloadEnv_GetExecutionPayload_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *BuiltExecutionPayloadEnv_GetExecutionPayload_Call) RunAndReturn(run func() *types.ExecutionPayload) *BuiltExecutionPayloadEnv_GetExecutionPayload_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// ShouldOverrideBuilder provides a mock function with no fields\nfunc (_m *BuiltExecutionPayloadEnv) ShouldOverrideBuilder() bool {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for ShouldOverrideBuilder\")\n\t}\n\n\tvar r0 bool\n\tif rf, ok := ret.Get(0).(func() bool); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tr0 = ret.Get(0).(bool)\n\t}\n\n\treturn r0\n}\n\n// BuiltExecutionPayloadEnv_ShouldOverrideBuilder_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ShouldOverrideBuilder'\ntype BuiltExecutionPayloadEnv_ShouldOverrideBuilder_Call struct {\n\t*mock.Call\n}\n\n// ShouldOverrideBuilder is a helper method to define mock.On call\nfunc (_e *BuiltExecutionPayloadEnv_Expecter) ShouldOverrideBuilder() *BuiltExecutionPayloadEnv_ShouldOverrideBuilder_Call {\n\treturn &BuiltExecutionPayloadEnv_ShouldOverrideBuilder_Call{Call: _e.mock.On(\"ShouldOverrideBuilder\")}\n}\n\nfunc (_c *BuiltExecutionPayloadEnv_ShouldOverrideBuilder_Call) Run(run func()) *BuiltExecutionPayloadEnv_ShouldOverrideBuilder_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *BuiltExecutionPayloadEnv_ShouldOverrideBuilder_Call) Return(_a0 bool) *BuiltExecutionPayloadEnv_ShouldOverrideBuilder_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *BuiltExecutionPayloadEnv_ShouldOverrideBuilder_Call) RunAndReturn(run func() bool) *BuiltExecutionPayloadEnv_ShouldOverrideBuilder_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewBuiltExecutionPayloadEnv creates a new instance of BuiltExecutionPayloadEnv. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewBuiltExecutionPayloadEnv(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *BuiltExecutionPayloadEnv {\n\tmock := &BuiltExecutionPayloadEnv{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "consensus-types/types/mocks/new_payload_request.mock.go",
    "content": "// Code generated by mockery v2.53.5. DO NOT EDIT.\n\npackage mocks\n\nimport (\n\ttypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tcommon \"github.com/berachain/beacon-kit/primitives/common\"\n\tcrypto \"github.com/berachain/beacon-kit/primitives/crypto\"\n\tmock \"github.com/stretchr/testify/mock\"\n)\n\n// NewPayloadRequest is an autogenerated mock type for the NewPayloadRequest type\ntype NewPayloadRequest struct {\n\tmock.Mock\n}\n\ntype NewPayloadRequest_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *NewPayloadRequest) EXPECT() *NewPayloadRequest_Expecter {\n\treturn &NewPayloadRequest_Expecter{mock: &_m.Mock}\n}\n\n// GetEncodedExecutionRequests provides a mock function with no fields\nfunc (_m *NewPayloadRequest) GetEncodedExecutionRequests() ([]types.EncodedExecutionRequest, error) {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetEncodedExecutionRequests\")\n\t}\n\n\tvar r0 []types.EncodedExecutionRequest\n\tvar r1 error\n\tif rf, ok := ret.Get(0).(func() ([]types.EncodedExecutionRequest, error)); ok {\n\t\treturn rf()\n\t}\n\tif rf, ok := ret.Get(0).(func() []types.EncodedExecutionRequest); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).([]types.EncodedExecutionRequest)\n\t\t}\n\t}\n\n\tif rf, ok := ret.Get(1).(func() error); ok {\n\t\tr1 = rf()\n\t} else {\n\t\tr1 = ret.Error(1)\n\t}\n\n\treturn r0, r1\n}\n\n// NewPayloadRequest_GetEncodedExecutionRequests_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetEncodedExecutionRequests'\ntype NewPayloadRequest_GetEncodedExecutionRequests_Call struct {\n\t*mock.Call\n}\n\n// GetEncodedExecutionRequests is a helper method to define mock.On call\nfunc (_e *NewPayloadRequest_Expecter) GetEncodedExecutionRequests() *NewPayloadRequest_GetEncodedExecutionRequests_Call {\n\treturn &NewPayloadRequest_GetEncodedExecutionRequests_Call{Call: _e.mock.On(\"GetEncodedExecutionRequests\")}\n}\n\nfunc (_c *NewPayloadRequest_GetEncodedExecutionRequests_Call) Run(run func()) *NewPayloadRequest_GetEncodedExecutionRequests_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *NewPayloadRequest_GetEncodedExecutionRequests_Call) Return(_a0 []types.EncodedExecutionRequest, _a1 error) *NewPayloadRequest_GetEncodedExecutionRequests_Call {\n\t_c.Call.Return(_a0, _a1)\n\treturn _c\n}\n\nfunc (_c *NewPayloadRequest_GetEncodedExecutionRequests_Call) RunAndReturn(run func() ([]types.EncodedExecutionRequest, error)) *NewPayloadRequest_GetEncodedExecutionRequests_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// GetExecutionPayload provides a mock function with no fields\nfunc (_m *NewPayloadRequest) GetExecutionPayload() *types.ExecutionPayload {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetExecutionPayload\")\n\t}\n\n\tvar r0 *types.ExecutionPayload\n\tif rf, ok := ret.Get(0).(func() *types.ExecutionPayload); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(*types.ExecutionPayload)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// NewPayloadRequest_GetExecutionPayload_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetExecutionPayload'\ntype NewPayloadRequest_GetExecutionPayload_Call struct {\n\t*mock.Call\n}\n\n// GetExecutionPayload is a helper method to define mock.On call\nfunc (_e *NewPayloadRequest_Expecter) GetExecutionPayload() *NewPayloadRequest_GetExecutionPayload_Call {\n\treturn &NewPayloadRequest_GetExecutionPayload_Call{Call: _e.mock.On(\"GetExecutionPayload\")}\n}\n\nfunc (_c *NewPayloadRequest_GetExecutionPayload_Call) Run(run func()) *NewPayloadRequest_GetExecutionPayload_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *NewPayloadRequest_GetExecutionPayload_Call) Return(_a0 *types.ExecutionPayload) *NewPayloadRequest_GetExecutionPayload_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *NewPayloadRequest_GetExecutionPayload_Call) RunAndReturn(run func() *types.ExecutionPayload) *NewPayloadRequest_GetExecutionPayload_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// GetForkVersion provides a mock function with no fields\nfunc (_m *NewPayloadRequest) GetForkVersion() common.Version {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetForkVersion\")\n\t}\n\n\tvar r0 common.Version\n\tif rf, ok := ret.Get(0).(func() common.Version); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(common.Version)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// NewPayloadRequest_GetForkVersion_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetForkVersion'\ntype NewPayloadRequest_GetForkVersion_Call struct {\n\t*mock.Call\n}\n\n// GetForkVersion is a helper method to define mock.On call\nfunc (_e *NewPayloadRequest_Expecter) GetForkVersion() *NewPayloadRequest_GetForkVersion_Call {\n\treturn &NewPayloadRequest_GetForkVersion_Call{Call: _e.mock.On(\"GetForkVersion\")}\n}\n\nfunc (_c *NewPayloadRequest_GetForkVersion_Call) Run(run func()) *NewPayloadRequest_GetForkVersion_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *NewPayloadRequest_GetForkVersion_Call) Return(_a0 common.Version) *NewPayloadRequest_GetForkVersion_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *NewPayloadRequest_GetForkVersion_Call) RunAndReturn(run func() common.Version) *NewPayloadRequest_GetForkVersion_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// GetParentBeaconBlockRoot provides a mock function with no fields\nfunc (_m *NewPayloadRequest) GetParentBeaconBlockRoot() common.Root {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetParentBeaconBlockRoot\")\n\t}\n\n\tvar r0 common.Root\n\tif rf, ok := ret.Get(0).(func() common.Root); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(common.Root)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// NewPayloadRequest_GetParentBeaconBlockRoot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetParentBeaconBlockRoot'\ntype NewPayloadRequest_GetParentBeaconBlockRoot_Call struct {\n\t*mock.Call\n}\n\n// GetParentBeaconBlockRoot is a helper method to define mock.On call\nfunc (_e *NewPayloadRequest_Expecter) GetParentBeaconBlockRoot() *NewPayloadRequest_GetParentBeaconBlockRoot_Call {\n\treturn &NewPayloadRequest_GetParentBeaconBlockRoot_Call{Call: _e.mock.On(\"GetParentBeaconBlockRoot\")}\n}\n\nfunc (_c *NewPayloadRequest_GetParentBeaconBlockRoot_Call) Run(run func()) *NewPayloadRequest_GetParentBeaconBlockRoot_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *NewPayloadRequest_GetParentBeaconBlockRoot_Call) Return(_a0 common.Root) *NewPayloadRequest_GetParentBeaconBlockRoot_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *NewPayloadRequest_GetParentBeaconBlockRoot_Call) RunAndReturn(run func() common.Root) *NewPayloadRequest_GetParentBeaconBlockRoot_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// GetParentProposerPubkey provides a mock function with no fields\nfunc (_m *NewPayloadRequest) GetParentProposerPubkey() *crypto.BLSPubkey {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetParentProposerPubkey\")\n\t}\n\n\tvar r0 *crypto.BLSPubkey\n\tif rf, ok := ret.Get(0).(func() *crypto.BLSPubkey); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(*crypto.BLSPubkey)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// NewPayloadRequest_GetParentProposerPubkey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetParentProposerPubkey'\ntype NewPayloadRequest_GetParentProposerPubkey_Call struct {\n\t*mock.Call\n}\n\n// GetParentProposerPubkey is a helper method to define mock.On call\nfunc (_e *NewPayloadRequest_Expecter) GetParentProposerPubkey() *NewPayloadRequest_GetParentProposerPubkey_Call {\n\treturn &NewPayloadRequest_GetParentProposerPubkey_Call{Call: _e.mock.On(\"GetParentProposerPubkey\")}\n}\n\nfunc (_c *NewPayloadRequest_GetParentProposerPubkey_Call) Run(run func()) *NewPayloadRequest_GetParentProposerPubkey_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *NewPayloadRequest_GetParentProposerPubkey_Call) Return(_a0 *crypto.BLSPubkey) *NewPayloadRequest_GetParentProposerPubkey_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *NewPayloadRequest_GetParentProposerPubkey_Call) RunAndReturn(run func() *crypto.BLSPubkey) *NewPayloadRequest_GetParentProposerPubkey_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// GetVersionedHashes provides a mock function with no fields\nfunc (_m *NewPayloadRequest) GetVersionedHashes() []common.ExecutionHash {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetVersionedHashes\")\n\t}\n\n\tvar r0 []common.ExecutionHash\n\tif rf, ok := ret.Get(0).(func() []common.ExecutionHash); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).([]common.ExecutionHash)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// NewPayloadRequest_GetVersionedHashes_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetVersionedHashes'\ntype NewPayloadRequest_GetVersionedHashes_Call struct {\n\t*mock.Call\n}\n\n// GetVersionedHashes is a helper method to define mock.On call\nfunc (_e *NewPayloadRequest_Expecter) GetVersionedHashes() *NewPayloadRequest_GetVersionedHashes_Call {\n\treturn &NewPayloadRequest_GetVersionedHashes_Call{Call: _e.mock.On(\"GetVersionedHashes\")}\n}\n\nfunc (_c *NewPayloadRequest_GetVersionedHashes_Call) Run(run func()) *NewPayloadRequest_GetVersionedHashes_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *NewPayloadRequest_GetVersionedHashes_Call) Return(_a0 []common.ExecutionHash) *NewPayloadRequest_GetVersionedHashes_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *NewPayloadRequest_GetVersionedHashes_Call) RunAndReturn(run func() []common.ExecutionHash) *NewPayloadRequest_GetVersionedHashes_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// HasValidVersionedAndBlockHashes provides a mock function with no fields\nfunc (_m *NewPayloadRequest) HasValidVersionedAndBlockHashes() error {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for HasValidVersionedAndBlockHashes\")\n\t}\n\n\tvar r0 error\n\tif rf, ok := ret.Get(0).(func() error); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tr0 = ret.Error(0)\n\t}\n\n\treturn r0\n}\n\n// NewPayloadRequest_HasValidVersionedAndBlockHashes_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'HasValidVersionedAndBlockHashes'\ntype NewPayloadRequest_HasValidVersionedAndBlockHashes_Call struct {\n\t*mock.Call\n}\n\n// HasValidVersionedAndBlockHashes is a helper method to define mock.On call\nfunc (_e *NewPayloadRequest_Expecter) HasValidVersionedAndBlockHashes() *NewPayloadRequest_HasValidVersionedAndBlockHashes_Call {\n\treturn &NewPayloadRequest_HasValidVersionedAndBlockHashes_Call{Call: _e.mock.On(\"HasValidVersionedAndBlockHashes\")}\n}\n\nfunc (_c *NewPayloadRequest_HasValidVersionedAndBlockHashes_Call) Run(run func()) *NewPayloadRequest_HasValidVersionedAndBlockHashes_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *NewPayloadRequest_HasValidVersionedAndBlockHashes_Call) Return(_a0 error) *NewPayloadRequest_HasValidVersionedAndBlockHashes_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *NewPayloadRequest_HasValidVersionedAndBlockHashes_Call) RunAndReturn(run func() error) *NewPayloadRequest_HasValidVersionedAndBlockHashes_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewNewPayloadRequest creates a new instance of NewPayloadRequest. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewNewPayloadRequest(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *NewPayloadRequest {\n\tmock := &NewPayloadRequest{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "consensus-types/types/mocks/proposer_domain.mock.go",
    "content": "// Code generated by mockery v2.53.5. DO NOT EDIT.\n\npackage mocks\n\nimport (\n\tcommon \"github.com/berachain/beacon-kit/primitives/common\"\n\tmock \"github.com/stretchr/testify/mock\"\n)\n\n// ProposerDomain is an autogenerated mock type for the ProposerDomain type\ntype ProposerDomain struct {\n\tmock.Mock\n}\n\ntype ProposerDomain_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *ProposerDomain) EXPECT() *ProposerDomain_Expecter {\n\treturn &ProposerDomain_Expecter{mock: &_m.Mock}\n}\n\n// DomainTypeProposer provides a mock function with no fields\nfunc (_m *ProposerDomain) DomainTypeProposer() common.DomainType {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for DomainTypeProposer\")\n\t}\n\n\tvar r0 common.DomainType\n\tif rf, ok := ret.Get(0).(func() common.DomainType); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(common.DomainType)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// ProposerDomain_DomainTypeProposer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DomainTypeProposer'\ntype ProposerDomain_DomainTypeProposer_Call struct {\n\t*mock.Call\n}\n\n// DomainTypeProposer is a helper method to define mock.On call\nfunc (_e *ProposerDomain_Expecter) DomainTypeProposer() *ProposerDomain_DomainTypeProposer_Call {\n\treturn &ProposerDomain_DomainTypeProposer_Call{Call: _e.mock.On(\"DomainTypeProposer\")}\n}\n\nfunc (_c *ProposerDomain_DomainTypeProposer_Call) Run(run func()) *ProposerDomain_DomainTypeProposer_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *ProposerDomain_DomainTypeProposer_Call) Return(_a0 common.DomainType) *ProposerDomain_DomainTypeProposer_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *ProposerDomain_DomainTypeProposer_Call) RunAndReturn(run func() common.DomainType) *ProposerDomain_DomainTypeProposer_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewProposerDomain creates a new instance of ProposerDomain. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewProposerDomain(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *ProposerDomain {\n\tmock := &ProposerDomain{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "consensus-types/types/mocks/unused_enforcer.mock.go",
    "content": "// Code generated by mockery v2.49.0. DO NOT EDIT.\n\npackage mocks\n\nimport mock \"github.com/stretchr/testify/mock\"\n\n// UnusedEnforcer is an autogenerated mock type for the UnusedEnforcer type\ntype UnusedEnforcer struct {\n\tmock.Mock\n}\n\ntype UnusedEnforcer_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *UnusedEnforcer) EXPECT() *UnusedEnforcer_Expecter {\n\treturn &UnusedEnforcer_Expecter{mock: &_m.Mock}\n}\n\n// EnforceUnused provides a mock function with given fields:\nfunc (_m *UnusedEnforcer) EnforceUnused() error {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for EnforceUnused\")\n\t}\n\n\tvar r0 error\n\tif rf, ok := ret.Get(0).(func() error); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tr0 = ret.Error(0)\n\t}\n\n\treturn r0\n}\n\n// UnusedEnforcer_EnforceUnused_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EnforceUnused'\ntype UnusedEnforcer_EnforceUnused_Call struct {\n\t*mock.Call\n}\n\n// EnforceUnused is a helper method to define mock.On call\nfunc (_e *UnusedEnforcer_Expecter) EnforceUnused() *UnusedEnforcer_EnforceUnused_Call {\n\treturn &UnusedEnforcer_EnforceUnused_Call{Call: _e.mock.On(\"EnforceUnused\")}\n}\n\nfunc (_c *UnusedEnforcer_EnforceUnused_Call) Run(run func()) *UnusedEnforcer_EnforceUnused_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *UnusedEnforcer_EnforceUnused_Call) Return(_a0 error) *UnusedEnforcer_EnforceUnused_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *UnusedEnforcer_EnforceUnused_Call) RunAndReturn(run func() error) *UnusedEnforcer_EnforceUnused_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewUnusedEnforcer creates a new instance of UnusedEnforcer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewUnusedEnforcer(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *UnusedEnforcer {\n\tmock := &UnusedEnforcer{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "consensus-types/types/payload.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\tfastssz \"github.com/ferranbt/fastssz\"\n\t\"github.com/karalabe/ssz\"\n)\n\nconst (\n\t// ExecutionPayloadStaticSize is the static size of the ExecutionPayload.\n\tExecutionPayloadStaticSize uint32 = 528\n\n\t// ExtraDataSize is the size of ExtraData in bytes.\n\tExtraDataSize = 32\n)\n\n// Compile-time assertions to ensure ExecutionPayload implements necessary interfaces.\nvar (\n\t_ ssz.DynamicObject                            = (*ExecutionPayload)(nil)\n\t_ constraints.SSZVersionedMarshallableRootable = (*ExecutionPayload)(nil)\n)\n\n// ExecutionPayload represents the payload of an execution block.\ntype ExecutionPayload struct {\n\tconstraints.Versionable `json:\"-\"`\n\n\t// ParentHash is the hash of the parent block.\n\tParentHash common.ExecutionHash `json:\"parentHash\"`\n\t// FeeRecipient is the address of the fee recipient.\n\tFeeRecipient common.ExecutionAddress `json:\"feeRecipient\"`\n\t// StateRoot is the root of the state trie.\n\tStateRoot common.Bytes32 `json:\"stateRoot\"`\n\t// ReceiptsRoot is the root of the receipts trie.\n\tReceiptsRoot common.Bytes32 `json:\"receiptsRoot\"`\n\t// LogsBloom is the bloom filter for the logs.\n\tLogsBloom bytes.B256 `json:\"logsBloom\"`\n\t// Random is the prevRandao value.\n\tRandom common.Bytes32 `json:\"prevRandao\"`\n\t// Number is the block number.\n\tNumber math.U64 `json:\"blockNumber\"`\n\t// GasLimit is the gas limit for the block.\n\tGasLimit math.U64 `json:\"gasLimit\"`\n\t// GasUsed is the amount of gas used in the block.\n\tGasUsed math.U64 `json:\"gasUsed\"`\n\t// Timestamp is the timestamp of the block.\n\tTimestamp math.U64 `json:\"timestamp\"`\n\t// ExtraData is the extra data of the block.\n\tExtraData bytes.Bytes `json:\"extraData\"`\n\t// BaseFeePerGas is the base fee per gas.\n\tBaseFeePerGas *math.U256 `json:\"baseFeePerGas\"`\n\t// BlockHash is the hash of the block.\n\tBlockHash common.ExecutionHash `json:\"blockHash\"`\n\t// Transactions is the list of transactions in the block.\n\tTransactions engineprimitives.Transactions `json:\"transactions\"`\n\t// Withdrawals is the list of withdrawals in the block.\n\tWithdrawals []*engineprimitives.Withdrawal `json:\"withdrawals\"`\n\t// BlobGasUsed is the amount of blob gas used in the block.\n\tBlobGasUsed math.U64 `json:\"blobGasUsed\"`\n\t// ExcessBlobGas is the amount of excess blob gas in the block.\n\tExcessBlobGas math.U64 `json:\"excessBlobGas\"`\n}\n\nfunc NewEmptyExecutionPayloadWithVersion(forkVersion common.Version) *ExecutionPayload {\n\tep := &ExecutionPayload{\n\t\tVersionable:   NewVersionable(forkVersion),\n\t\tBaseFeePerGas: &math.U256{},\n\t}\n\n\t// For any fork version Capella onwards, non-nil withdrawals are required.\n\tif version.EqualsOrIsAfter(forkVersion, version.Capella()) {\n\t\tep.Withdrawals = make([]*engineprimitives.Withdrawal, 0)\n\t}\n\treturn ep\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// SizeSSZ returns either the static size of the object if fixed == true, or\n// the total size otherwise.\nfunc (p *ExecutionPayload) SizeSSZ(siz *ssz.Sizer, fixed bool) uint32 {\n\tvar size = ExecutionPayloadStaticSize\n\tif fixed {\n\t\treturn size\n\t}\n\tsize += ssz.SizeDynamicBytes(siz, p.ExtraData)\n\tsize += ssz.SizeSliceOfDynamicBytes(siz, p.Transactions)\n\tsize += ssz.SizeSliceOfStaticObjects(siz, p.Withdrawals)\n\treturn size\n}\n\n// DefineSSZ defines how an object is encoded/decoded.\n//\n//nolint:mnd // TODO: get from accessible chainspec field params\nfunc (p *ExecutionPayload) DefineSSZ(codec *ssz.Codec) {\n\t// Define the static data (fields and dynamic offsets)\n\tssz.DefineStaticBytes(codec, &p.ParentHash)\n\tssz.DefineStaticBytes(codec, &p.FeeRecipient)\n\tssz.DefineStaticBytes(codec, &p.StateRoot)\n\tssz.DefineStaticBytes(codec, &p.ReceiptsRoot)\n\tssz.DefineStaticBytes(codec, &p.LogsBloom)\n\tssz.DefineStaticBytes(codec, &p.Random)\n\tssz.DefineUint64(codec, &p.Number)\n\tssz.DefineUint64(codec, &p.GasLimit)\n\tssz.DefineUint64(codec, &p.GasUsed)\n\tssz.DefineUint64(codec, &p.Timestamp)\n\tssz.DefineDynamicBytesOffset(codec, (*[]byte)(&p.ExtraData), 32)\n\tssz.DefineUint256(codec, &p.BaseFeePerGas)\n\tssz.DefineStaticBytes(codec, &p.BlockHash)\n\tssz.DefineSliceOfDynamicBytesOffset(\n\t\tcodec,\n\t\t(*[][]byte)(&p.Transactions),\n\t\tconstants.MaxTxsPerPayload,\n\t\tconstants.MaxBytesPerTx,\n\t)\n\tssz.DefineSliceOfStaticObjectsOffset(codec, &p.Withdrawals, 16)\n\tssz.DefineUint64(codec, &p.BlobGasUsed)\n\tssz.DefineUint64(codec, &p.ExcessBlobGas)\n\n\t// Define the dynamic data (fields)\n\tssz.DefineDynamicBytesContent(codec, (*[]byte)(&p.ExtraData), 32)\n\tssz.DefineSliceOfDynamicBytesContent(\n\t\tcodec,\n\t\t(*[][]byte)(&p.Transactions),\n\t\tconstants.MaxTxsPerPayload,\n\t\tconstants.MaxBytesPerTx,\n\t)\n\tssz.DefineSliceOfStaticObjectsContent(codec, &p.Withdrawals, 16)\n\n\t// Note that at this state we don't have any guarantee that\n\t// p.Withdrawal is not nil, which we require Capella onwards\n\t// (empty list of withdrawals are fine). We ensure non-nillness\n\t// in ValidateAfterDecodingSSZ.\n}\n\n// MarshalSSZ serializes the ExecutionPayload object into a slice of bytes.\nfunc (p *ExecutionPayload) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(p))\n\treturn buf, ssz.EncodeToBytes(buf, p)\n}\n\nfunc (p *ExecutionPayload) ValidateAfterDecodingSSZ() error {\n\t// For any fork version Capella onwards, non-nil withdrawals are required.\n\tif p.Withdrawals == nil && version.EqualsOrIsAfter(p.GetForkVersion(), version.Capella()) {\n\t\tp.Withdrawals = make([]*engineprimitives.Withdrawal, 0)\n\t}\n\treturn nil\n}\n\n// HashTreeRoot returns the hash tree root of the ExecutionPayload.\nfunc (p *ExecutionPayload) HashTreeRoot() common.Root {\n\treturn ssz.HashConcurrent(p)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   FastSSZ                                  */\n/* -------------------------------------------------------------------------- */\n\n// MarshalSSZTo serializes the ExecutionPayload object into a writer.\nfunc (p *ExecutionPayload) MarshalSSZTo(dst []byte) ([]byte, error) {\n\tbz, err := p.MarshalSSZ()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdst = append(dst, bz...)\n\treturn dst, nil\n}\n\n// HashTreeRootWith ssz hashes the ExecutionPayload object with a hasher.\n//\n//nolint:mnd // will be deprecated eventually.\nfunc (p *ExecutionPayload) HashTreeRootWith(hh fastssz.HashWalker) error {\n\tindx := hh.Index()\n\n\t// Field (0) 'ParentHash'\n\thh.PutBytes(p.ParentHash[:])\n\n\t// Field (1) 'FeeRecipient'\n\thh.PutBytes(p.FeeRecipient[:])\n\n\t// Field (2) 'StateRoot'\n\thh.PutBytes(p.StateRoot[:])\n\n\t// Field (3) 'ReceiptsRoot'\n\thh.PutBytes(p.ReceiptsRoot[:])\n\n\t// Field (4) 'LogsBloom'\n\thh.PutBytes(p.LogsBloom[:])\n\n\t// Field (5) 'Random'\n\thh.PutBytes(p.Random[:])\n\n\t// Field (6) 'Number'\n\thh.PutUint64(uint64(p.Number))\n\n\t// Field (7) 'GasLimit'\n\thh.PutUint64(uint64(p.GasLimit))\n\n\t// Field (8) 'GasUsed'\n\thh.PutUint64(uint64(p.GasUsed))\n\n\t// Field (9) 'Timestamp'\n\thh.PutUint64(uint64(p.Timestamp))\n\n\t// Field (10) 'ExtraData'\n\t{\n\t\telemIndx := hh.Index()\n\t\tbyteLen := uint64(len(p.ExtraData))\n\t\tif byteLen > 32 {\n\t\t\treturn fastssz.ErrIncorrectListSize\n\t\t}\n\t\thh.Append(p.ExtraData)\n\t\thh.MerkleizeWithMixin(elemIndx, byteLen, (32+31)/32)\n\t}\n\n\t// Field (11) 'BaseFeePerGas'\n\tbz, err := p.BaseFeePerGas.MarshalSSZ()\n\tif err != nil {\n\t\treturn err\n\t}\n\thh.PutBytes(bz)\n\n\t// Field (12) 'BlockHash'\n\thh.PutBytes(p.BlockHash[:])\n\n\t// Field (13) 'Transactions'\n\t{\n\t\tsubIndx := hh.Index()\n\t\tnum := uint64(len(p.Transactions))\n\t\tif num > 1048576 {\n\t\t\treturn fastssz.ErrIncorrectListSize\n\t\t}\n\t\tfor _, elem := range p.Transactions {\n\t\t\t{\n\t\t\t\telemIndx := hh.Index()\n\t\t\t\tbyteLen := uint64(len(elem))\n\t\t\t\tif byteLen > 1073741824 {\n\t\t\t\t\treturn fastssz.ErrIncorrectListSize\n\t\t\t\t}\n\t\t\t\thh.AppendBytes32(elem)\n\t\t\t\thh.MerkleizeWithMixin(elemIndx, byteLen, (1073741824+31)/32)\n\t\t\t}\n\t\t}\n\t\thh.MerkleizeWithMixin(subIndx, num, 1048576)\n\t}\n\n\t// Field (14) 'Withdrawals'\n\t{\n\t\tsubIndx := hh.Index()\n\t\tnum := uint64(len(p.Withdrawals))\n\t\tif num > 16 {\n\t\t\treturn fastssz.ErrIncorrectListSize\n\t\t}\n\t\tfor _, elem := range p.Withdrawals {\n\t\t\tif err = elem.HashTreeRootWith(hh); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\thh.MerkleizeWithMixin(subIndx, num, 16)\n\t}\n\n\t// Field (15) 'BlobGasUsed'\n\thh.PutUint64(uint64(p.BlobGasUsed))\n\n\t// Field (16) 'ExcessBlobGas'\n\thh.PutUint64(uint64(p.ExcessBlobGas))\n\n\thh.Merkleize(indx)\n\treturn nil\n}\n\n// GetTree ssz hashes the ExecutionPayload object.\nfunc (p *ExecutionPayload) GetTree() (*fastssz.Node, error) {\n\treturn fastssz.ProofTree(p)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    JSON                                    */\n/* -------------------------------------------------------------------------- */\n\n// MarshalJSON marshals as JSON.\nfunc (p ExecutionPayload) MarshalJSON() ([]byte, error) {\n\ttype ExecutionPayload struct {\n\t\tParentHash    common.ExecutionHash           `json:\"parentHash\"`\n\t\tFeeRecipient  common.ExecutionAddress        `json:\"feeRecipient\"`\n\t\tStateRoot     bytes.B32                      `json:\"stateRoot\"`\n\t\tReceiptsRoot  bytes.B32                      `json:\"receiptsRoot\"`\n\t\tLogsBloom     bytes.B256                     `json:\"logsBloom\"`\n\t\tRandom        bytes.B32                      `json:\"prevRandao\"`\n\t\tNumber        math.U64                       `json:\"blockNumber\"`\n\t\tGasLimit      math.U64                       `json:\"gasLimit\"`\n\t\tGasUsed       math.U64                       `json:\"gasUsed\"`\n\t\tTimestamp     math.U64                       `json:\"timestamp\"`\n\t\tExtraData     bytes.Bytes                    `json:\"extraData\"`\n\t\tBaseFeePerGas *math.U256Hex                  `json:\"baseFeePerGas\"`\n\t\tBlockHash     common.ExecutionHash           `json:\"blockHash\"`\n\t\tTransactions  []bytes.Bytes                  `json:\"transactions\"`\n\t\tWithdrawals   []*engineprimitives.Withdrawal `json:\"withdrawals\"`\n\t\tBlobGasUsed   math.U64                       `json:\"blobGasUsed\"`\n\t\tExcessBlobGas math.U64                       `json:\"excessBlobGas\"`\n\t}\n\tvar enc ExecutionPayload\n\tenc.ParentHash = p.ParentHash\n\tenc.FeeRecipient = p.FeeRecipient\n\tenc.StateRoot = p.StateRoot\n\tenc.ReceiptsRoot = p.ReceiptsRoot\n\tenc.LogsBloom = p.LogsBloom\n\tenc.Random = p.Random\n\tenc.Number = p.Number\n\tenc.GasLimit = p.GasLimit\n\tenc.GasUsed = p.GasUsed\n\tenc.Timestamp = p.Timestamp\n\tenc.ExtraData = p.ExtraData\n\tenc.BaseFeePerGas = (*math.U256Hex)(p.BaseFeePerGas)\n\tenc.BlockHash = p.BlockHash\n\tenc.Transactions = make([]bytes.Bytes, len(p.Transactions))\n\tfor k, v := range p.Transactions {\n\t\tenc.Transactions[k] = v\n\t}\n\tenc.Withdrawals = p.Withdrawals\n\tenc.BlobGasUsed = p.BlobGasUsed\n\tenc.ExcessBlobGas = p.ExcessBlobGas\n\treturn json.Marshal(&enc)\n}\n\n// UnmarshalJSON unmarshals from JSON.\n//\n//nolint:funlen // todo fix.\nfunc (p *ExecutionPayload) UnmarshalJSON(input []byte) error {\n\ttype ExecutionPayload struct {\n\t\tParentHash    *common.ExecutionHash          `json:\"parentHash\"`\n\t\tFeeRecipient  *common.ExecutionAddress       `json:\"feeRecipient\"`\n\t\tStateRoot     *bytes.B32                     `json:\"stateRoot\"`\n\t\tReceiptsRoot  *bytes.B32                     `json:\"receiptsRoot\"`\n\t\tLogsBloom     *bytes.B256                    `json:\"logsBloom\"`\n\t\tRandom        *bytes.B32                     `json:\"prevRandao\"`\n\t\tNumber        *math.U64                      `json:\"blockNumber\"`\n\t\tGasLimit      *math.U64                      `json:\"gasLimit\"`\n\t\tGasUsed       *math.U64                      `json:\"gasUsed\"`\n\t\tTimestamp     *math.U64                      `json:\"timestamp\"`\n\t\tExtraData     *bytes.Bytes                   `json:\"extraData\"`\n\t\tBaseFeePerGas *math.U256Hex                  `json:\"baseFeePerGas\"`\n\t\tBlockHash     *common.ExecutionHash          `json:\"blockHash\"`\n\t\tTransactions  []bytes.Bytes                  `json:\"transactions\"`\n\t\tWithdrawals   []*engineprimitives.Withdrawal `json:\"withdrawals\"`\n\t\tBlobGasUsed   *math.U64                      `json:\"blobGasUsed\"`\n\t\tExcessBlobGas *math.U64                      `json:\"excessBlobGas\"`\n\t}\n\tvar dec ExecutionPayload\n\tif err := json.Unmarshal(input, &dec); err != nil {\n\t\treturn err\n\t}\n\tif dec.ParentHash == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'parentHash' for ExecutionPayload\",\n\t\t)\n\t}\n\tp.ParentHash = *dec.ParentHash\n\tif dec.FeeRecipient == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'feeRecipient' for ExecutionPayload\",\n\t\t)\n\t}\n\tp.FeeRecipient = *dec.FeeRecipient\n\tif dec.StateRoot == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'stateRoot' for ExecutionPayload\",\n\t\t)\n\t}\n\tp.StateRoot = *dec.StateRoot\n\tif dec.ReceiptsRoot == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'receiptsRoot' for ExecutionPayload\",\n\t\t)\n\t}\n\tp.ReceiptsRoot = *dec.ReceiptsRoot\n\tif dec.LogsBloom == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'logsBloom' for ExecutionPayload\",\n\t\t)\n\t}\n\tp.LogsBloom = *dec.LogsBloom\n\tif dec.Random == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'prevRandao' for ExecutionPayload\",\n\t\t)\n\t}\n\tp.Random = *dec.Random\n\tif dec.Number == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'blockNumber' for ExecutionPayload\",\n\t\t)\n\t}\n\tp.Number = *dec.Number\n\tif dec.GasLimit == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'gasLimit' for ExecutionPayload\",\n\t\t)\n\t}\n\tp.GasLimit = *dec.GasLimit\n\tif dec.GasUsed == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'gasUsed' for ExecutionPayload\",\n\t\t)\n\t}\n\tp.GasUsed = *dec.GasUsed\n\tif dec.Timestamp == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'timestamp' for ExecutionPayload\",\n\t\t)\n\t}\n\tp.Timestamp = *dec.Timestamp\n\tif dec.ExtraData == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'extraData' for ExecutionPayload\",\n\t\t)\n\t}\n\tp.ExtraData = *dec.ExtraData\n\tif dec.BaseFeePerGas == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'baseFeePerGas' for ExecutionPayload\",\n\t\t)\n\t}\n\tp.BaseFeePerGas = (*math.U256)(dec.BaseFeePerGas)\n\tif dec.BlockHash == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'blockHash' for ExecutionPayload\",\n\t\t)\n\t}\n\tp.BlockHash = *dec.BlockHash\n\tif dec.Transactions == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'transactions' for ExecutionPayload\",\n\t\t)\n\t}\n\tp.Transactions = make([][]byte, len(dec.Transactions))\n\tfor k, v := range dec.Transactions {\n\t\tp.Transactions[k] = v\n\t}\n\tif dec.Withdrawals != nil {\n\t\tp.Withdrawals = dec.Withdrawals\n\t}\n\tif dec.BlobGasUsed != nil {\n\t\tp.BlobGasUsed = *dec.BlobGasUsed\n\t}\n\tif dec.ExcessBlobGas != nil {\n\t\tp.ExcessBlobGas = *dec.ExcessBlobGas\n\t}\n\treturn nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   Getters                                  */\n/* -------------------------------------------------------------------------- */\n\n// IsBlinded checks if the ExecutionPayload is blinded.\nfunc (p *ExecutionPayload) IsBlinded() bool {\n\treturn false\n}\n\n// GetParentHash returns the parent hash of the ExecutionPayload.\nfunc (p *ExecutionPayload) GetParentHash() common.ExecutionHash {\n\treturn p.ParentHash\n}\n\n// GetFeeRecipient returns the fee recipient address of the ExecutionPayload.\nfunc (p *ExecutionPayload) GetFeeRecipient() common.ExecutionAddress {\n\treturn p.FeeRecipient\n}\n\n// GetStateRoot returns the state root of the ExecutionPayload.\nfunc (p *ExecutionPayload) GetStateRoot() common.Bytes32 {\n\treturn p.StateRoot\n}\n\n// GetReceiptsRoot returns the receipts root of the ExecutionPayload.\nfunc (p *ExecutionPayload) GetReceiptsRoot() common.Bytes32 {\n\treturn p.ReceiptsRoot\n}\n\n// GetLogsBloom returns the logs bloom of the ExecutionPayload.\nfunc (p *ExecutionPayload) GetLogsBloom() bytes.B256 {\n\treturn p.LogsBloom\n}\n\n// GetPrevRandao returns the previous Randao value of the ExecutionPayload.\nfunc (p *ExecutionPayload) GetPrevRandao() common.Bytes32 {\n\treturn p.Random\n}\n\n// GetNumber returns the block number of the ExecutionPayload.\nfunc (p *ExecutionPayload) GetNumber() math.U64 {\n\treturn p.Number\n}\n\n// GetGasLimit returns the gas limit of the ExecutionPayload.\nfunc (p *ExecutionPayload) GetGasLimit() math.U64 {\n\treturn p.GasLimit\n}\n\n// GetGasUsed returns the gas used of the ExecutionPayload.\nfunc (p *ExecutionPayload) GetGasUsed() math.U64 {\n\treturn p.GasUsed\n}\n\n// GetTimestamp returns the timestamp of the ExecutionPayload.\nfunc (p *ExecutionPayload) GetTimestamp() math.U64 {\n\treturn p.Timestamp\n}\n\n// GetExtraData returns the extra data of the ExecutionPayload.\nfunc (p *ExecutionPayload) GetExtraData() []byte {\n\treturn p.ExtraData\n}\n\n// GetBaseFeePerGas returns the base fee per gas of the ExecutionPayload.\nfunc (p *ExecutionPayload) GetBaseFeePerGas() *math.U256 {\n\treturn p.BaseFeePerGas\n}\n\n// GetBlockHash returns the block hash of the ExecutionPayload.\nfunc (p *ExecutionPayload) GetBlockHash() common.ExecutionHash {\n\treturn p.BlockHash\n}\n\n// GetTransactions returns the transactions of the ExecutionPayload.\nfunc (p *ExecutionPayload) GetTransactions() engineprimitives.Transactions {\n\treturn p.Transactions\n}\n\n// GetWithdrawals returns the withdrawals of the ExecutionPayload.\nfunc (p *ExecutionPayload) GetWithdrawals() engineprimitives.Withdrawals {\n\treturn p.Withdrawals\n}\n\n// GetBlobGasUsed returns the blob gas used of the ExecutionPayload.\nfunc (p *ExecutionPayload) GetBlobGasUsed() math.U64 {\n\treturn p.BlobGasUsed\n}\n\n// GetExcessBlobGas returns the excess blob gas of the ExecutionPayload.\nfunc (p *ExecutionPayload) GetExcessBlobGas() math.U64 {\n\treturn p.ExcessBlobGas\n}\n\n// ToHeader converts the ExecutionPayload to an ExecutionPayloadHeader.\nfunc (p *ExecutionPayload) ToHeader() (*ExecutionPayloadHeader, error) {\n\tswitch p.GetForkVersion() {\n\tcase version.Deneb(), version.Deneb1(), version.Electra(), version.Electra1(), version.Fulu():\n\t\treturn &ExecutionPayloadHeader{\n\t\t\tVersionable:      p.Versionable,\n\t\t\tParentHash:       p.GetParentHash(),\n\t\t\tFeeRecipient:     p.GetFeeRecipient(),\n\t\t\tStateRoot:        p.GetStateRoot(),\n\t\t\tReceiptsRoot:     p.GetReceiptsRoot(),\n\t\t\tLogsBloom:        p.GetLogsBloom(),\n\t\t\tRandom:           p.GetPrevRandao(),\n\t\t\tNumber:           p.GetNumber(),\n\t\t\tGasLimit:         p.GetGasLimit(),\n\t\t\tGasUsed:          p.GetGasUsed(),\n\t\t\tTimestamp:        p.GetTimestamp(),\n\t\t\tExtraData:        p.GetExtraData(),\n\t\t\tBaseFeePerGas:    p.GetBaseFeePerGas(),\n\t\t\tBlockHash:        p.GetBlockHash(),\n\t\t\tTransactionsRoot: p.GetTransactions().HashTreeRoot(),\n\t\t\tWithdrawalsRoot:  p.GetWithdrawals().HashTreeRoot(),\n\t\t\tBlobGasUsed:      p.GetBlobGasUsed(),\n\t\t\tExcessBlobGas:    p.GetExcessBlobGas(),\n\t\t}, nil\n\tdefault:\n\t\treturn nil, errors.New(\"unknown fork version\")\n\t}\n}\n"
  },
  {
    "path": "consensus-types/types/payload_env.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// BuiltExecutionPayloadEnv is an interface for the execution payload envelope.\n//\n// TODO: move interface definition to packages where it is used.\ntype BuiltExecutionPayloadEnv interface {\n\t// GetExecutionPayload retrieves the associated execution payload.\n\tGetExecutionPayload() *ExecutionPayload\n\t// GetBlockValue returns the Wei value of the block in the execution payload.\n\tGetBlockValue() *math.U256\n\t// GetBlobsBundle fetches the associated BlobsBundleV1 if available.\n\tGetBlobsBundle() engineprimitives.BlobsBundle\n\t// GetEncodedExecutionRequests fetches the associated execution requests if available\n\tGetEncodedExecutionRequests() []EncodedExecutionRequest\n\t// ShouldOverrideBuilder indicates if the builder should be overridden.\n\tShouldOverrideBuilder() bool\n}\n\n// executionPayloadEnvelope is a struct that holds the execution payload and\n// its associated data.\ntype executionPayloadEnvelope[BlobsBundleT engineprimitives.BlobsBundle] struct {\n\tExecutionPayload  *ExecutionPayload         `json:\"executionPayload\"`\n\tBlockValue        *math.U256                `json:\"blockValue\"`\n\tBlobsBundle       BlobsBundleT              `json:\"blobsBundle\"`\n\tExecutionRequests []EncodedExecutionRequest `json:\"executionRequests\"`\n\tOverride          bool                      `json:\"shouldOverrideBuilder\"`\n}\n\n// NewEmptyExecutionPayloadEnvelope returns an empty executionPayloadEnvelope\n// for the given fork version.\nfunc NewEmptyExecutionPayloadEnvelope[\n\tBlobsBundleT engineprimitives.BlobsBundle,\n](forkVersion common.Version) BuiltExecutionPayloadEnv {\n\treturn &executionPayloadEnvelope[BlobsBundleT]{\n\t\tExecutionPayload: NewEmptyExecutionPayloadWithVersion(forkVersion),\n\t}\n}\n\nfunc NewExecutionPayloadEnvelope[\n\tBlobsBundleT engineprimitives.BlobsBundle,\n](\n\tpayload *ExecutionPayload,\n\tblobs BlobsBundleT,\n\texecutionRequests []EncodedExecutionRequest,\n) BuiltExecutionPayloadEnv {\n\treturn &executionPayloadEnvelope[BlobsBundleT]{\n\t\tExecutionPayload:  payload,\n\t\tBlobsBundle:       blobs,\n\t\tExecutionRequests: executionRequests,\n\t}\n}\n\n// GetExecutionPayload returns the execution payload of the\n// executionPayloadEnvelope.\nfunc (e *executionPayloadEnvelope[BlobsBundleT]) GetExecutionPayload() *ExecutionPayload {\n\treturn e.ExecutionPayload\n}\n\n// GetBlockValue returns the block value of the executionPayloadEnvelope.\nfunc (e *executionPayloadEnvelope[BlobsBundleT]) GetBlockValue() *math.U256 {\n\treturn e.BlockValue\n}\n\n// GetBlobsBundle returns the blobs bundle of the executionPayloadEnvelope.\nfunc (e *executionPayloadEnvelope[BlobsBundleT]) GetBlobsBundle() engineprimitives.BlobsBundle {\n\treturn e.BlobsBundle\n}\n\n// GetEncodedExecutionRequests returns the encoded Execution Requests\nfunc (e *executionPayloadEnvelope[BlobsBundleT]) GetEncodedExecutionRequests() []EncodedExecutionRequest {\n\treturn e.ExecutionRequests\n}\n\n// ShouldOverrideBuilder returns whether the builder should be overridden.\nfunc (e *executionPayloadEnvelope[BlobsBundleT]) ShouldOverrideBuilder() bool {\n\treturn e.Override\n}\n"
  },
  {
    "path": "consensus-types/types/payload_header.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tfastssz \"github.com/ferranbt/fastssz\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// ExecutionPayloadHeaderStaticSize is the static size of the ExecutionPayloadHeader.\nconst ExecutionPayloadHeaderStaticSize uint32 = 584\n\n// Compile-time assertions to ensure ExecutionPayloadHeader implements necessary interfaces.\nvar (\n\t_ ssz.DynamicObject                            = (*ExecutionPayloadHeader)(nil)\n\t_ constraints.SSZVersionedMarshallableRootable = (*ExecutionPayloadHeader)(nil)\n)\n\n// ExecutionPayloadHeader represents the payload header of an execution block.\ntype ExecutionPayloadHeader struct {\n\t// NOTE: This version is not required but left in for backwards compatibility.\n\t//\n\t// A recommended alternative to `GetForkVersion()` on this struct would be to use the chain\n\t// spec's `ActiveForkVersionForTimestamp()` on the value of `GetTimestamp()`.\n\t//\n\t// This version should still be set to the correct value to avoid potential inconsistencies.\n\tconstraints.Versionable\n\n\t// Contents\n\t//\n\t// ParentHash is the hash of the parent block.\n\tParentHash common.ExecutionHash `json:\"parentHash\"`\n\t// FeeRecipient is the address of the fee recipient.\n\tFeeRecipient common.ExecutionAddress `json:\"feeRecipient\"`\n\t// StateRoot is the root of the state trie.\n\tStateRoot common.Bytes32 `json:\"stateRoot\"`\n\t// ReceiptsRoot is the root of the receipts trie.\n\tReceiptsRoot common.Bytes32 `json:\"receiptsRoot\"`\n\t// LogsBloom is the bloom filter for the logs.\n\tLogsBloom bytes.B256 `json:\"logsBloom\"`\n\t// Random is the prevRandao value.\n\tRandom common.Bytes32 `json:\"prevRandao\"`\n\t// Number is the block number.\n\tNumber math.U64 `json:\"blockNumber\"`\n\t// GasLimit is the gas limit for the block.\n\tGasLimit math.U64 `json:\"gasLimit\"`\n\t// GasUsed is the amount of gas used in the block.\n\tGasUsed math.U64 `json:\"gasUsed\"`\n\t// Timestamp is the timestamp of the block.\n\tTimestamp math.U64 `json:\"timestamp\"`\n\t// ExtraData is the extra data of the block.\n\tExtraData bytes.Bytes `json:\"extraData\"`\n\t// BaseFeePerGas is the base fee per gas.\n\tBaseFeePerGas *math.U256 `json:\"baseFeePerGas\"`\n\t// BlockHash is the hash of the block.\n\tBlockHash common.ExecutionHash `json:\"blockHash\"`\n\t// TransactionsRoot is the root of the transaction trie.\n\tTransactionsRoot common.Root `json:\"transactionsRoot\"`\n\t// WithdrawalsRoot is the root of the withdrawals trie.\n\tWithdrawalsRoot common.Root `json:\"withdrawalsRoot\"`\n\t// BlobGasUsed is the amount of blob gas used in the block.\n\tBlobGasUsed math.U64 `json:\"blobGasUsed\"`\n\t// ExcessBlobGas is the amount of excess blob gas in the block.\n\tExcessBlobGas math.U64 `json:\"excessBlobGas\"`\n}\n\nfunc NewEmptyExecutionPayloadHeaderWithVersion(version common.Version) *ExecutionPayloadHeader {\n\treturn &ExecutionPayloadHeader{\n\t\tVersionable:   NewVersionable(version),\n\t\tBaseFeePerGas: &math.U256{},\n\t}\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// SizeSSZ returns either the static size of the object if fixed == true, or\n// the total size otherwise.\nfunc (h *ExecutionPayloadHeader) SizeSSZ(siz *ssz.Sizer, fixed bool) uint32 {\n\tsize := ExecutionPayloadHeaderStaticSize\n\tif fixed {\n\t\treturn size\n\t}\n\tsize += ssz.SizeDynamicBytes(siz, h.ExtraData)\n\n\treturn size\n}\n\n// DefineSSZ defines how an object is encoded/decoded.\nfunc (h *ExecutionPayloadHeader) DefineSSZ(codec *ssz.Codec) {\n\t// Define the static data (fields and dynamic offsets)\n\tssz.DefineStaticBytes(codec, &h.ParentHash)\n\tssz.DefineStaticBytes(codec, &h.FeeRecipient)\n\tssz.DefineStaticBytes(codec, &h.StateRoot)\n\tssz.DefineStaticBytes(codec, &h.ReceiptsRoot)\n\tssz.DefineStaticBytes(codec, &h.LogsBloom)\n\tssz.DefineStaticBytes(codec, &h.Random)\n\tssz.DefineUint64(codec, &h.Number)\n\tssz.DefineUint64(codec, &h.GasLimit)\n\tssz.DefineUint64(codec, &h.GasUsed)\n\tssz.DefineUint64(codec, &h.Timestamp)\n\t//nolint:mnd // TODO: get from accessible chainspec field params\n\tssz.DefineDynamicBytesOffset(codec, (*[]byte)(&h.ExtraData), 32)\n\tssz.DefineUint256(codec, &h.BaseFeePerGas)\n\tssz.DefineStaticBytes(codec, &h.BlockHash)\n\tssz.DefineStaticBytes(codec, &h.TransactionsRoot)\n\tssz.DefineStaticBytes(codec, &h.WithdrawalsRoot)\n\tssz.DefineUint64(codec, &h.BlobGasUsed)\n\tssz.DefineUint64(codec, &h.ExcessBlobGas)\n\n\t// Define the dynamic data (fields)\n\t//nolint:mnd // TODO: get from accessible chainspec field params\n\tssz.DefineDynamicBytesContent(codec, (*[]byte)(&h.ExtraData), 32)\n}\n\n// MarshalSSZ serializes the ExecutionPayloadHeader object into a slice of\n// bytes.\nfunc (h *ExecutionPayloadHeader) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(h))\n\treturn buf, ssz.EncodeToBytes(buf, h)\n}\n\nfunc (*ExecutionPayloadHeader) ValidateAfterDecodingSSZ() error { return nil }\n\n// HashTreeRootSSZ returns the hash tree root of the ExecutionPayloadHeader.\nfunc (h *ExecutionPayloadHeader) HashTreeRoot() common.Root {\n\treturn ssz.HashConcurrent(h)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   FastSSZ                                  */\n/* -------------------------------------------------------------------------- */\n\n// MarshalSSZTo ssz marshals the ExecutionPayloadHeaderDeneb object to a target\n// array.\nfunc (h *ExecutionPayloadHeader) MarshalSSZTo(dst []byte) ([]byte, error) {\n\tbz, err := h.MarshalSSZ()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdst = append(dst, bz...)\n\treturn dst, nil\n}\n\n// HashTreeRootWith ssz hashes the ExecutionPayloadHeaderDeneb object with a\n// hasher\n//\n//nolint:mnd // from fastssz.\nfunc (h *ExecutionPayloadHeader) HashTreeRootWith(hh fastssz.HashWalker) error {\n\tindx := hh.Index()\n\n\t// Field (0) 'ParentHash'\n\thh.PutBytes(h.ParentHash[:])\n\n\t// Field (1) 'FeeRecipient'\n\thh.PutBytes(h.FeeRecipient[:])\n\n\t// Field (2) 'StateRoot'\n\thh.PutBytes(h.StateRoot[:])\n\n\t// Field (3) 'ReceiptsRoot'\n\thh.PutBytes(h.ReceiptsRoot[:])\n\n\t// Field (4) 'LogsBloom'\n\tif size := len(h.LogsBloom); size != 256 {\n\t\treturn fastssz.ErrBytesLengthFn(\n\t\t\t\"ExecutionPayloadHeaderDeneb.LogsBloom\",\n\t\t\tsize,\n\t\t\t256,\n\t\t)\n\t}\n\thh.PutBytes(h.LogsBloom[:])\n\n\t// Field (5) 'Random'\n\thh.PutBytes(h.Random[:])\n\n\t// Field (6) 'Number'\n\thh.PutUint64(uint64(h.Number))\n\n\t// Field (7) 'GasLimit'\n\thh.PutUint64(uint64(h.GasLimit))\n\n\t// Field (8) 'GasUsed'\n\thh.PutUint64(uint64(h.GasUsed))\n\n\t// Field (9) 'Timestamp'\n\thh.PutUint64(uint64(h.Timestamp))\n\n\t// Field (10) 'ExtraData'\n\t{\n\t\telemIndx := hh.Index()\n\t\tbyteLen := uint64(len(h.ExtraData))\n\t\tif byteLen > 32 {\n\t\t\treturn fastssz.ErrIncorrectListSize\n\t\t}\n\t\thh.Append(h.ExtraData)\n\t\thh.MerkleizeWithMixin(elemIndx, byteLen, (32+31)/32)\n\t}\n\n\t// Field (11) 'BaseFeePerGas'\n\tbz, err := h.BaseFeePerGas.MarshalSSZ()\n\tif err != nil {\n\t\treturn err\n\t}\n\thh.PutBytes(bz)\n\n\t// Field (12) 'BlockHash'\n\thh.PutBytes(h.BlockHash[:])\n\n\t// Field (13) 'TransactionsRoot'\n\thh.PutBytes(h.TransactionsRoot[:])\n\n\t// Field (14) 'WithdrawalsRoot'\n\thh.PutBytes(h.WithdrawalsRoot[:])\n\n\t// Field (15) 'BlobGasUsed'\n\thh.PutUint64(uint64(h.BlobGasUsed))\n\n\t// Field (16) 'ExcessBlobGas'\n\thh.PutUint64(uint64(h.ExcessBlobGas))\n\n\thh.Merkleize(indx)\n\treturn nil\n}\n\n// GetTree ssz hashes the ExecutionPayloadHeaderDeneb object.\nfunc (h *ExecutionPayloadHeader) GetTree() (*fastssz.Node, error) {\n\treturn fastssz.ProofTree(h)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    JSON                                    */\n/* -------------------------------------------------------------------------- */\n\n// MarshalJSON marshals as JSON.\nfunc (h ExecutionPayloadHeader) MarshalJSON() ([]byte, error) {\n\ttype ExecutionPayloadHeader struct {\n\t\tParentHash       common.ExecutionHash    `json:\"parentHash\"`\n\t\tFeeRecipient     common.ExecutionAddress `json:\"feeRecipient\"`\n\t\tStateRoot        bytes.B32               `json:\"stateRoot\"`\n\t\tReceiptsRoot     bytes.B32               `json:\"receiptsRoot\"`\n\t\tLogsBloom        bytes.B256              `json:\"logsBloom\"`\n\t\tRandom           bytes.B32               `json:\"prevRandao\"`\n\t\tNumber           math.U64                `json:\"blockNumber\"`\n\t\tGasLimit         math.U64                `json:\"gasLimit\"`\n\t\tGasUsed          math.U64                `json:\"gasUsed\"`\n\t\tTimestamp        math.U64                `json:\"timestamp\"`\n\t\tExtraData        bytes.Bytes             `json:\"extraData\"`\n\t\tBaseFeePerGas    *math.U256              `json:\"baseFeePerGas\"`\n\t\tBlockHash        common.ExecutionHash    `json:\"blockHash\"`\n\t\tTransactionsRoot common.Root             `json:\"transactionsRoot\"`\n\t\tWithdrawalsRoot  common.Root             `json:\"withdrawalsRoot\"`\n\t\tBlobGasUsed      math.U64                `json:\"blobGasUsed\"`\n\t\tExcessBlobGas    math.U64                `json:\"excessBlobGas\"`\n\t}\n\tvar enc ExecutionPayloadHeader\n\tenc.ParentHash = h.ParentHash\n\tenc.FeeRecipient = h.FeeRecipient\n\tenc.StateRoot = h.StateRoot\n\tenc.ReceiptsRoot = h.ReceiptsRoot\n\tenc.LogsBloom = h.LogsBloom\n\tenc.Random = h.Random\n\tenc.Number = h.Number\n\tenc.GasLimit = h.GasLimit\n\tenc.GasUsed = h.GasUsed\n\tenc.Timestamp = h.Timestamp\n\tenc.ExtraData = h.ExtraData\n\tenc.BaseFeePerGas = h.BaseFeePerGas\n\tenc.BlockHash = h.BlockHash\n\tenc.TransactionsRoot = h.TransactionsRoot\n\tenc.WithdrawalsRoot = h.WithdrawalsRoot\n\tenc.BlobGasUsed = h.BlobGasUsed\n\tenc.ExcessBlobGas = h.ExcessBlobGas\n\treturn json.Marshal(&enc)\n}\n\n// UnmarshalJSON unmarshals from JSON.\n//\n//nolint:funlen // codegen.\nfunc (h *ExecutionPayloadHeader) UnmarshalJSON(input []byte) error {\n\ttype ExecutionPayloadHeader struct {\n\t\tParentHash       *common.ExecutionHash    `json:\"parentHash\"`\n\t\tFeeRecipient     *common.ExecutionAddress `json:\"feeRecipient\"`\n\t\tStateRoot        *bytes.B32               `json:\"stateRoot\"`\n\t\tReceiptsRoot     *bytes.B32               `json:\"receiptsRoot\"`\n\t\tLogsBloom        *bytes.B256              `json:\"logsBloom\"`\n\t\tRandom           *bytes.B32               `json:\"prevRandao\"`\n\t\tNumber           *math.U64                `json:\"blockNumber\"`\n\t\tGasLimit         *math.U64                `json:\"gasLimit\"`\n\t\tGasUsed          *math.U64                `json:\"gasUsed\"`\n\t\tTimestamp        *math.U64                `json:\"timestamp\"`\n\t\tExtraData        *bytes.Bytes             `json:\"extraData\"`\n\t\tBaseFeePerGas    *math.U256               `json:\"baseFeePerGas\"`\n\t\tBlockHash        *common.ExecutionHash    `json:\"blockHash\"`\n\t\tTransactionsRoot *common.Root             `json:\"transactionsRoot\"`\n\t\tWithdrawalsRoot  *common.Root             `json:\"withdrawalsRoot\"`\n\t\tBlobGasUsed      *math.U64                `json:\"blobGasUsed\"`\n\t\tExcessBlobGas    *math.U64                `json:\"excessBlobGas\"`\n\t}\n\tvar dec ExecutionPayloadHeader\n\tif err := json.Unmarshal(input, &dec); err != nil {\n\t\treturn err\n\t}\n\tif dec.ParentHash == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'parentHash' for ExecutionPayloadHeader\",\n\t\t)\n\t}\n\th.ParentHash = *dec.ParentHash\n\tif dec.FeeRecipient == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'feeRecipient' for ExecutionPayloadHeader\",\n\t\t)\n\t}\n\th.FeeRecipient = *dec.FeeRecipient\n\tif dec.StateRoot == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'stateRoot' for ExecutionPayloadHeader\",\n\t\t)\n\t}\n\th.StateRoot = *dec.StateRoot\n\tif dec.ReceiptsRoot == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'receiptsRoot' for ExecutionPayloadHeader\",\n\t\t)\n\t}\n\th.ReceiptsRoot = *dec.ReceiptsRoot\n\tif dec.LogsBloom == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'logsBloom' for ExecutionPayloadHeader\",\n\t\t)\n\t}\n\th.LogsBloom = *dec.LogsBloom\n\tif dec.Random == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'prevRandao' for ExecutionPayloadHeader\",\n\t\t)\n\t}\n\th.Random = *dec.Random\n\tif dec.Number == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'blockNumber' for ExecutionPayloadHeader\",\n\t\t)\n\t}\n\th.Number = *dec.Number\n\tif dec.GasLimit == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'gasLimit' for ExecutionPayloadHeader\",\n\t\t)\n\t}\n\th.GasLimit = *dec.GasLimit\n\tif dec.GasUsed == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'gasUsed' for ExecutionPayloadHeader\",\n\t\t)\n\t}\n\th.GasUsed = *dec.GasUsed\n\tif dec.Timestamp == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'timestamp' for ExecutionPayloadHeader\",\n\t\t)\n\t}\n\th.Timestamp = *dec.Timestamp\n\tif dec.ExtraData == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'extraData' for ExecutionPayloadHeader\",\n\t\t)\n\t}\n\n\t// TODO: This is required for the API to be symmetric? But it's not really\n\t// clear if\n\t// this matters.\n\tif len(*dec.ExtraData) != 0 {\n\t\th.ExtraData = *dec.ExtraData\n\t}\n\n\tif dec.BaseFeePerGas == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'baseFeePerGas' for ExecutionPayloadHeader\",\n\t\t)\n\t}\n\th.BaseFeePerGas = dec.BaseFeePerGas\n\tif dec.BlockHash == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'blockHash' for ExecutionPayloadHeader\",\n\t\t)\n\t}\n\th.BlockHash = *dec.BlockHash\n\tif dec.TransactionsRoot == nil {\n\t\treturn errors.New(\n\t\t\t\"missing required field 'transactionsRoot' for ExecutionPayloadHeader\",\n\t\t)\n\t}\n\th.TransactionsRoot = *dec.TransactionsRoot\n\tif dec.WithdrawalsRoot != nil {\n\t\th.WithdrawalsRoot = *dec.WithdrawalsRoot\n\t}\n\tif dec.BlobGasUsed != nil {\n\t\th.BlobGasUsed = *dec.BlobGasUsed\n\t}\n\tif dec.ExcessBlobGas != nil {\n\t\th.ExcessBlobGas = *dec.ExcessBlobGas\n\t}\n\treturn nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   Getters                                  */\n/* -------------------------------------------------------------------------- */\n\n// GetParentHash returns the parent hash of the ExecutionPayloadHeader.\nfunc (h *ExecutionPayloadHeader) GetParentHash() common.ExecutionHash {\n\treturn h.ParentHash\n}\n\n// GetFeeRecipient returns the fee recipient address of the ExecutionPayloadHeader.\nfunc (h *ExecutionPayloadHeader) GetFeeRecipient() common.ExecutionAddress {\n\treturn h.FeeRecipient\n}\n\n// GetStateRoot returns the state root of the ExecutionPayloadHeader.\nfunc (h *ExecutionPayloadHeader) GetStateRoot() common.Bytes32 {\n\treturn h.StateRoot\n}\n\n// GetReceiptsRoot returns the receipts root of the ExecutionPayloadHeader.\nfunc (h *ExecutionPayloadHeader) GetReceiptsRoot() common.Bytes32 {\n\treturn h.ReceiptsRoot\n}\n\n// GetLogsBloom returns the logs bloom of the ExecutionPayloadHeader.\nfunc (h *ExecutionPayloadHeader) GetLogsBloom() bytes.B256 {\n\treturn h.LogsBloom\n}\n\n// GetPrevRandao returns the previous Randao value of the\n// ExecutionPayloadHeader.\nfunc (h *ExecutionPayloadHeader) GetPrevRandao() common.Bytes32 {\n\treturn h.Random\n}\n\n// GetNumber returns the block number of the ExecutionPayloadHeader.\nfunc (h *ExecutionPayloadHeader) GetNumber() math.U64 {\n\treturn h.Number\n}\n\n// GetGasLimit returns the gas limit of the ExecutionPayloadHeader.\nfunc (h *ExecutionPayloadHeader) GetGasLimit() math.U64 {\n\treturn h.GasLimit\n}\n\n// GetGasUsed returns the gas used of the ExecutionPayloadHeader.\nfunc (h *ExecutionPayloadHeader) GetGasUsed() math.U64 {\n\treturn h.GasUsed\n}\n\n// GetTimestamp returns the timestamp of the ExecutionPayloadHeader.\nfunc (h *ExecutionPayloadHeader) GetTimestamp() math.U64 {\n\treturn h.Timestamp\n}\n\n// GetExtraData returns the extra data of the ExecutionPayloadHeader.\nfunc (h *ExecutionPayloadHeader) GetExtraData() []byte {\n\treturn h.ExtraData\n}\n\n// GetBaseFeePerGas returns the base fee per gas of the\n// ExecutionPayloadHeader.\nfunc (h *ExecutionPayloadHeader) GetBaseFeePerGas() *math.U256 {\n\treturn h.BaseFeePerGas\n}\n\n// GetBlockHash returns the block hash of the ExecutionPayloadHeader.\nfunc (h *ExecutionPayloadHeader) GetBlockHash() common.ExecutionHash {\n\treturn h.BlockHash\n}\n\n// GetTransactionsRoot returns the transactions root of the\n// ExecutionPayloadHeader.\nfunc (h *ExecutionPayloadHeader) GetTransactionsRoot() common.Root {\n\treturn h.TransactionsRoot\n}\n\n// GetWithdrawalsRoot returns the withdrawals root of the\n// ExecutionPayloadHeader.\nfunc (h *ExecutionPayloadHeader) GetWithdrawalsRoot() common.Root {\n\treturn h.WithdrawalsRoot\n}\n\n// GetBlobGasUsed returns the blob gas used of the ExecutionPayloadHeader.\nfunc (h *ExecutionPayloadHeader) GetBlobGasUsed() math.U64 {\n\treturn h.BlobGasUsed\n}\n\n// GetExcessBlobGas returns the excess blob gas of the\n// ExecutionPayloadHeader.\nfunc (h *ExecutionPayloadHeader) GetExcessBlobGas() math.U64 {\n\treturn h.ExcessBlobGas\n}\n"
  },
  {
    "path": "consensus-types/types/payload_header_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n\tsszutil \"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\tfastssz \"github.com/ferranbt/fastssz\"\n\t\"github.com/karalabe/ssz\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// generateExecutionPayloadHeader generates an ExecutionPayloadHeader.\nfunc generateExecutionPayloadHeader(version common.Version) *types.ExecutionPayloadHeader {\n\treturn &types.ExecutionPayloadHeader{\n\t\tVersionable:      types.NewVersionable(version),\n\t\tParentHash:       common.ExecutionHash{},\n\t\tFeeRecipient:     common.ExecutionAddress{},\n\t\tStateRoot:        bytes.B32{},\n\t\tReceiptsRoot:     bytes.B32{},\n\t\tLogsBloom:        bytes.B256{},\n\t\tRandom:           bytes.B32{},\n\t\tNumber:           math.U64(0),\n\t\tGasLimit:         math.U64(0),\n\t\tGasUsed:          math.U64(0),\n\t\tTimestamp:        math.U64(0),\n\t\tExtraData:        nil,\n\t\tBaseFeePerGas:    &math.U256{},\n\t\tBlockHash:        common.ExecutionHash{},\n\t\tTransactionsRoot: common.Root{},\n\t\tWithdrawalsRoot:  common.Root{},\n\t\tBlobGasUsed:      math.U64(0),\n\t\tExcessBlobGas:    math.U64(0),\n\t}\n}\n\nfunc TestExecutionPayloadHeader_Getters(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\theader := generateExecutionPayloadHeader(v)\n\t\trequire.NotNil(t, header)\n\n\t\trequire.Equal(t, common.ExecutionHash{}, header.GetParentHash())\n\t\trequire.Equal(\n\t\t\tt,\n\t\t\tcommon.ExecutionAddress{},\n\t\t\theader.GetFeeRecipient(),\n\t\t)\n\t\trequire.Equal(t, bytes.B32{}, header.GetStateRoot())\n\t\trequire.Equal(t, bytes.B32{}, header.GetReceiptsRoot())\n\t\trequire.Equal(t, bytes.B256{}, header.GetLogsBloom())\n\t\trequire.Equal(t, bytes.B32{}, header.GetPrevRandao())\n\t\trequire.Equal(t, math.U64(0), header.GetNumber())\n\t\trequire.Equal(t, math.U64(0), header.GetGasLimit())\n\t\trequire.Equal(t, math.U64(0), header.GetGasUsed())\n\t\trequire.Equal(t, math.U64(0), header.GetTimestamp())\n\t\trequire.Equal(t, []byte(nil), header.GetExtraData())\n\t\trequire.Equal(t, math.NewU256(0), header.GetBaseFeePerGas())\n\t\trequire.Equal(t, common.ExecutionHash{}, header.GetBlockHash())\n\t\trequire.Equal(t, common.Root{}, header.GetTransactionsRoot())\n\t\trequire.Equal(t, common.Root{}, header.GetWithdrawalsRoot())\n\t\trequire.Equal(t, math.U64(0), header.GetBlobGasUsed())\n\t\trequire.Equal(t, math.U64(0), header.GetExcessBlobGas())\n\t})\n}\n\nfunc TestExecutionPayloadHeader_IsNil(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\theader := generateExecutionPayloadHeader(v)\n\t\trequire.NotNil(t, header)\n\t})\n}\n\nfunc TestExecutionPayloadHeader_Version(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\theader := generateExecutionPayloadHeader(v)\n\t\trequire.Equal(t, v, header.GetForkVersion())\n\t})\n}\n\nfunc TestExecutionPayloadHeader_MarshalUnmarshalJSON(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\toriginalHeader := generateExecutionPayloadHeader(v)\n\n\t\tdata, err := originalHeader.MarshalJSON()\n\t\trequire.NoError(t, err)\n\t\trequire.NotNil(t, data)\n\n\t\tvar header types.ExecutionPayloadHeader\n\t\terr = header.UnmarshalJSON(data)\n\t\trequire.NoError(t, err)\n\t\theader.Versionable = types.NewVersionable(originalHeader.GetForkVersion())\n\t\trequire.Equal(t, originalHeader, &header)\n\t})\n}\n\nfunc TestExecutionPayloadHeader_Serialization(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\toriginal := generateExecutionPayloadHeader(v)\n\n\t\tdata, err := original.MarshalSSZ()\n\t\trequire.NoError(t, err)\n\t\trequire.NotNil(t, data)\n\n\t\tunmarshalled := types.NewEmptyExecutionPayloadHeaderWithVersion(original.GetForkVersion())\n\t\terr = sszutil.Unmarshal(data, unmarshalled)\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, original, unmarshalled)\n\t})\n}\n\nfunc TestExecutionPayloadHeader_MarshalSSZTo(t *testing.T) {\n\tt.Parallel()\n\ttestcases := []struct {\n\t\tname     string\n\t\tmalleate func(common.Version) *types.ExecutionPayloadHeader\n\t\texpErr   error\n\t}{\n\t\t{\n\t\t\tname:     \"valid\",\n\t\t\tmalleate: generateExecutionPayloadHeader,\n\t\t\texpErr:   nil,\n\t\t},\n\t\t{\n\t\t\tname: \"invalid extra data passes marshalling\",\n\t\t\tmalleate: func(version common.Version) *types.ExecutionPayloadHeader {\n\t\t\t\theader := generateExecutionPayloadHeader(version)\n\t\t\t\theader.ExtraData = make([]byte, 100)\n\t\t\t\treturn header\n\t\t\t},\n\t\t\texpErr: nil,\n\t\t},\n\t}\n\n\tfor _, tc := range testcases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\t\t\theader := tc.malleate(v)\n\t\t\t\tbuf := make([]byte, 64)\n\t\t\t\t_, err := header.MarshalSSZTo(buf)\n\t\t\t\tif tc.expErr != nil {\n\t\t\t\t\trequire.Error(t, err)\n\t\t\t\t} else {\n\t\t\t\t\trequire.NoError(t, err)\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t}\n}\n\nfunc TestExecutionPayloadHeader_NewFromSSZ_EmptyBuf(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tbuf := make([]byte, 0)\n\t\theader := types.NewEmptyExecutionPayloadHeaderWithVersion(v)\n\t\terr := sszutil.Unmarshal(buf, header)\n\t\trequire.ErrorIs(t, err, io.ErrUnexpectedEOF)\n\t})\n}\n\nfunc TestExecutionPayloadHeader_NewFromSSZ_Invalid(t *testing.T) {\n\tt.Parallel()\n\ttestcases := []struct {\n\t\tname     string\n\t\tmalleate func() []byte\n\t\texpErr   error\n\t}{\n\t\t{\n\t\t\tname: \"offset exceeds length\",\n\t\t\tmalleate: func() []byte {\n\t\t\t\theader := generateExecutionPayloadHeader(version.Deneb())\n\t\t\t\tbuf, err := header.MarshalSSZ()\n\t\t\t\trequire.NoError(t, err)\n\n\t\t\t\tbuf[436] = 10\n\t\t\t\tbuf[437] = 10\n\t\t\t\tbuf[438] = 10\n\t\t\t\tbuf[439] = 10\n\t\t\t\treturn buf\n\t\t\t},\n\t\t\texpErr: ssz.ErrOffsetBeyondCapacity,\n\t\t},\n\t\t{\n\t\t\tname: \"invalid extra data: extra data too large\",\n\t\t\tmalleate: func() []byte {\n\t\t\t\theader := generateExecutionPayloadHeader(version.Deneb())\n\t\t\t\tbuf, err := header.MarshalSSZ()\n\n\t\t\t\t// add dummy extra data to exceed the 32 limit\n\t\t\t\tdummyExtra := make([]byte, 100)\n\t\t\t\tbuf = append(buf, dummyExtra...)\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\treturn buf\n\t\t\t},\n\t\t\texpErr: ssz.ErrMaxLengthExceeded,\n\t\t},\n\t}\n\tfor _, tc := range testcases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tbuf := tc.malleate()\n\t\t\tdest := types.NewEmptyExecutionPayloadHeaderWithVersion(version.Deneb())\n\t\t\terr := sszutil.Unmarshal(buf, dest)\n\t\t\trequire.ErrorIs(t, err, tc.expErr)\n\t\t})\n\t}\n}\n\nfunc TestExecutionPayloadHeader_NewFromSSZ_Invalid_TooSmall(t *testing.T) {\n\tt.Parallel()\n\theader := generateExecutionPayloadHeader(version.Deneb())\n\tbuf, err := header.MarshalSSZ()\n\trequire.NoError(t, err)\n\n\tbuf[436] = 1\n\tbuf[437] = 0\n\tbuf[438] = 0\n\tbuf[439] = 0\n\n\tdest := types.NewEmptyExecutionPayloadHeaderWithVersion(version.Deneb())\n\terr = sszutil.Unmarshal(buf, dest)\n\trequire.Error(t, err)\n\n\t// Can be either ErrFirstOffsetMismatch or ErrBadOffsetProgression due to reused Decoder in\n\t// SSZ lib. If the SSZ lib happens to grab a reused Decoder from the decoderPool, the decoder's\n\t// `offsets` field is already initialized to an empty slice instead of nil. This passes the nil\n\t// check in the ErrFirstOffsetMismatch error condition resulting in no error. Immediately after,\n\t// it will still fail the ErrBadOffsetProgression error condition. This flakiness depends upon\n\t// retrieving a used Decoder from the decoderPool as well as the intentional misuse of the\n\t// marshaled data. In the case that an actor intentionally tries to induce this behavior, the\n\t// unmarshaling of the data correctly results in error, just a different error.\n\t// In this unit test, we simply expect the error to be one of the two possible errors.\n\tisExpectedError := errors.IsAny(err, ssz.ErrFirstOffsetMismatch, ssz.ErrBadOffsetProgression)\n\trequire.True(\n\t\tt, isExpectedError, \"expected %w or %w, got %w\",\n\t\tssz.ErrFirstOffsetMismatch, ssz.ErrBadOffsetProgression, err,\n\t)\n}\n\nfunc TestExecutionPayloadHeader_SizeSSZ(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\theader := generateExecutionPayloadHeader(v)\n\t\tsize := ssz.Size(header)\n\t\trequire.Equal(t, types.ExecutionPayloadHeaderStaticSize, size)\n\t})\n}\n\nfunc TestExecutionPayloadHeader_HashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\theader := generateExecutionPayloadHeader(v)\n\t\trequire.NotPanics(t, func() {\n\t\t\theader.HashTreeRoot()\n\t\t})\n\t})\n}\n\nfunc TestExecutionPayloadHeader_GetTree(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\theader := generateExecutionPayloadHeader(v)\n\t\t_, err := header.GetTree()\n\t\trequire.NoError(t, err)\n\t})\n}\n\nfunc TestExecutablePayloadHeader_UnmarshalJSON_Error(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\toriginal := generateExecutionPayloadHeader(v)\n\t\tvalidJSON, err := original.MarshalJSON()\n\t\trequire.NoError(t, err)\n\n\t\ttestCases := []struct {\n\t\t\tname          string\n\t\t\tremoveField   string\n\t\t\texpectedError string\n\t\t}{\n\t\t\t{\n\t\t\t\tname:          \"missing required field 'parentHash'\",\n\t\t\t\tremoveField:   \"parentHash\",\n\t\t\t\texpectedError: \"missing required field 'parentHash' for ExecutionPayloadHeader\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:          \"missing required field 'feeRecipient'\",\n\t\t\t\tremoveField:   \"feeRecipient\",\n\t\t\t\texpectedError: \"missing required field 'feeRecipient' for ExecutionPayloadHeader\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:          \"missing required field 'stateRoot'\",\n\t\t\t\tremoveField:   \"stateRoot\",\n\t\t\t\texpectedError: \"missing required field 'stateRoot' for ExecutionPayloadHeader\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:          \"missing required field 'receiptsRoot'\",\n\t\t\t\tremoveField:   \"receiptsRoot\",\n\t\t\t\texpectedError: \"missing required field 'receiptsRoot' for ExecutionPayloadHeader\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:          \"missing required field 'logsBloom'\",\n\t\t\t\tremoveField:   \"logsBloom\",\n\t\t\t\texpectedError: \"missing required field 'logsBloom' for ExecutionPayloadHeader\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:          \"missing required field 'prevRandao'\",\n\t\t\t\tremoveField:   \"prevRandao\",\n\t\t\t\texpectedError: \"missing required field 'prevRandao' for ExecutionPayloadHeader\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:          \"missing required field 'blockNumber'\",\n\t\t\t\tremoveField:   \"blockNumber\",\n\t\t\t\texpectedError: \"missing required field 'blockNumber' for ExecutionPayloadHeader\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:          \"missing required field 'gasLimit'\",\n\t\t\t\tremoveField:   \"gasLimit\",\n\t\t\t\texpectedError: \"missing required field 'gasLimit' for ExecutionPayloadHeader\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:          \"missing required field 'gasUsed'\",\n\t\t\t\tremoveField:   \"gasUsed\",\n\t\t\t\texpectedError: \"missing required field 'gasUsed' for ExecutionPayloadHeader\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:          \"missing required field 'timestamp'\",\n\t\t\t\tremoveField:   \"timestamp\",\n\t\t\t\texpectedError: \"missing required field 'timestamp' for ExecutionPayloadHeader\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:          \"missing required field 'extraData'\",\n\t\t\t\tremoveField:   \"extraData\",\n\t\t\t\texpectedError: \"missing required field 'extraData' for ExecutionPayloadHeader\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:          \"missing required field 'baseFeePerGas'\",\n\t\t\t\tremoveField:   \"baseFeePerGas\",\n\t\t\t\texpectedError: \"missing required field 'baseFeePerGas' for ExecutionPayloadHeader\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:          \"missing required field 'blockHash'\",\n\t\t\t\tremoveField:   \"blockHash\",\n\t\t\t\texpectedError: \"missing required field 'blockHash' for ExecutionPayloadHeader\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:          \"missing required field 'transactionsRoot'\",\n\t\t\t\tremoveField:   \"transactionsRoot\",\n\t\t\t\texpectedError: \"missing required field 'transactionsRoot' for ExecutionPayloadHeader\",\n\t\t\t},\n\t\t}\n\n\t\tfor _, tc := range testCases {\n\t\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\t\tvar payload types.ExecutionPayloadHeader\n\t\t\t\tvar jsonMap map[string]interface{}\n\n\t\t\t\terrUnmarshal := json.Unmarshal(validJSON, &jsonMap)\n\t\t\t\trequire.NoError(t, errUnmarshal)\n\n\t\t\t\tdelete(jsonMap, tc.removeField)\n\n\t\t\t\tmalformedJSON, errMarshal := json.Marshal(jsonMap)\n\t\t\t\trequire.NoError(t, errMarshal)\n\n\t\t\t\terr = payload.UnmarshalJSON(malformedJSON)\n\t\t\t\trequire.Error(t, err)\n\t\t\t\trequire.Contains(t, err.Error(), tc.expectedError)\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestExecutablePayloadHeader_UnmarshalJSON_Empty(t *testing.T) {\n\tt.Parallel()\n\tvar payload types.ExecutionPayloadHeader\n\terr := payload.UnmarshalJSON([]byte{})\n\trequire.Error(t, err)\n}\n\nfunc TestExecutablePayloadHeader_HashTreeRootWith(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\ttestcases := []struct {\n\t\t\tname     string\n\t\t\tmalleate func() *types.ExecutionPayloadHeader\n\t\t\texpErr   error\n\t\t}{\n\t\t\t{\n\t\t\t\tname: \"invalid ExtraData length\",\n\t\t\t\tmalleate: func() *types.ExecutionPayloadHeader {\n\t\t\t\t\tvar header = generateExecutionPayloadHeader(v)\n\t\t\t\t\theader.ExtraData = make([]byte, 50)\n\t\t\t\t\treturn header\n\t\t\t\t},\n\t\t\t\texpErr: fastssz.ErrIncorrectListSize,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tc := range testcases {\n\t\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\t\t\t\thh := fastssz.DefaultHasherPool.Get()\n\t\t\t\theader := tc.malleate()\n\t\t\t\terr := header.HashTreeRootWith(hh)\n\t\t\t\trequire.Equal(t, tc.expErr, err)\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestExecutionPayloadHeader_NewFromSSZ(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\ttestCases := []struct {\n\t\t\tname           string\n\t\t\tdata           []byte\n\t\t\texpErr         error\n\t\t\texpectedHeader *types.ExecutionPayloadHeader\n\t\t}{\n\t\t\t{\n\t\t\t\tname: \"Valid SSZ data\",\n\t\t\t\tdata: func() []byte {\n\t\t\t\t\tdata, _ := generateExecutionPayloadHeader(v).MarshalSSZ()\n\t\t\t\t\treturn data\n\t\t\t\t}(),\n\t\t\t\texpErr:         nil,\n\t\t\t\texpectedHeader: generateExecutionPayloadHeader(v),\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Invalid SSZ data\",\n\t\t\t\tdata:           []byte{0x01, 0x02},\n\t\t\t\texpErr:         io.ErrUnexpectedEOF,\n\t\t\t\texpectedHeader: nil,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname:           \"Empty SSZ data\",\n\t\t\t\tdata:           []byte{},\n\t\t\t\texpErr:         io.ErrUnexpectedEOF,\n\t\t\t\texpectedHeader: nil,\n\t\t\t},\n\t\t}\n\n\t\tfor _, tc := range testCases {\n\t\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\t\t\t\theader := types.NewEmptyExecutionPayloadHeaderWithVersion(v)\n\t\t\t\tif tc.name == \"Different fork version\" {\n\t\t\t\t\trequire.Panics(t, func() {\n\t\t\t\t\t\t_ = sszutil.Unmarshal(tc.data, header)\n\t\t\t\t\t}, \"Expected panic for different fork version\")\n\t\t\t\t} else {\n\t\t\t\t\terr := sszutil.Unmarshal(tc.data, header)\n\t\t\t\t\tif tc.expErr != nil {\n\t\t\t\t\t\trequire.ErrorIs(t, err, tc.expErr)\n\t\t\t\t\t} else {\n\t\t\t\t\t\trequire.NoError(t, err)\n\t\t\t\t\t\trequire.Equal(t, tc.expectedHeader, header)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestExecutionPayloadHeader_NewFromJSON(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\ttype testCase struct {\n\t\t\tname          string\n\t\t\tdata          []byte\n\t\t\theader        *types.ExecutionPayloadHeader\n\t\t\texpectedError error\n\t\t}\n\t\ttestCases := []testCase{\n\t\t\tfunc() testCase {\n\t\t\t\theader := generateExecutionPayloadHeader(v)\n\t\t\t\treturn testCase{\n\t\t\t\t\tname:   \"Valid JSON\",\n\t\t\t\t\theader: header,\n\t\t\t\t\tdata: func() []byte {\n\t\t\t\t\t\tdata, err := json.Marshal(header)\n\t\t\t\t\t\trequire.NoError(t, err)\n\t\t\t\t\t\treturn data\n\t\t\t\t\t}(),\n\t\t\t\t}\n\t\t\t}(),\n\t\t\t{\n\t\t\t\tname:          \"Invalid JSON\",\n\t\t\t\tdata:          []byte{},\n\t\t\t\texpectedError: errors.New(\"unexpected end of JSON input\"),\n\t\t\t},\n\t\t}\n\n\t\tfor _, tc := range testCases {\n\t\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\t\tt.Parallel()\n\t\t\t\theader := types.NewEmptyExecutionPayloadHeaderWithVersion(v)\n\t\t\t\terr := json.Unmarshal(tc.data, header)\n\n\t\t\t\tif tc.expectedError != nil {\n\t\t\t\t\trequire.Error(t, err)\n\t\t\t\t\trequire.Contains(t, err.Error(), tc.expectedError.Error())\n\t\t\t\t} else {\n\t\t\t\t\trequire.NoError(t, err)\n\t\t\t\t}\n\t\t\t\tif tc.header != nil {\n\t\t\t\t\trequire.Equal(t, tc.header, header)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "consensus-types/types/payload_requests.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"math/big\"\n\t\"unsafe\"\n\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\tbkitgethtypes \"github.com/berachain/beacon-kit/gethlib/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\tgethcommon \"github.com/ethereum/go-ethereum/common\"\n\tgethtypes \"github.com/ethereum/go-ethereum/core/types\"\n\tgethtrie \"github.com/ethereum/go-ethereum/trie\"\n)\n\n// NewPayloadRequest as per the Ethereum 2.0 specification:\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/deneb/beacon-chain.md#modified-newpayloadrequest\ntype NewPayloadRequest interface {\n\tconstraints.Versionable\n\tHasValidVersionedAndBlockHashes() error\n\tGetExecutionPayload() *ExecutionPayload\n\tGetVersionedHashes() []common.ExecutionHash\n\tGetParentBeaconBlockRoot() common.Root\n\tGetEncodedExecutionRequests() ([]EncodedExecutionRequest, error)\n\tGetParentProposerPubkey() *crypto.BLSPubkey\n}\n\ntype newPayloadRequest struct {\n\tconstraints.Versionable\n\t// executionPayload is the payload to the execution client.\n\texecutionPayload *ExecutionPayload\n\t// versionedHashes is the versioned hashes of the execution payload.\n\tversionedHashes []common.ExecutionHash\n\t// parentBeaconBlockRoot is the root of the parent beacon block.\n\tparentBeaconBlockRoot common.Root\n\t// ExecutionRequests is introduced in Pectra. It is only non-nil after Pectra.\n\texecutionRequests []EncodedExecutionRequest\n\t// ParentProposerPubkey is introduced in Pectra1. It is only non-nil after Pectra1.\n\tparentProposerPubkey *crypto.BLSPubkey\n}\n\n// BuildNewPayloadRequestFromFork will build a NewPayloadRequest.\nfunc BuildNewPayloadRequestFromFork(blk *BeaconBlock, parentProposerPubkey *crypto.BLSPubkey) (NewPayloadRequest, error) {\n\tforkVersion := blk.GetForkVersion()\n\tif version.IsBefore(forkVersion, version.Deneb()) {\n\t\treturn nil, ErrForkVersionNotSupported\n\t}\n\n\tvar (\n\t\tbody                  = blk.GetBody()\n\t\tpayload               = body.GetExecutionPayload()\n\t\tparentBeaconBlockRoot = blk.GetParentBlockRoot()\n\t\texecutionRequestsList []EncodedExecutionRequest\n\t)\n\n\tif version.EqualsOrIsAfter(forkVersion, version.Electra()) {\n\t\t// If we're post-electra, we set execution requests.\n\t\texecutionRequests, err := body.GetExecutionRequests()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\texecutionRequestsList, err = GetExecutionRequestsList(executionRequests)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif version.IsBefore(forkVersion, version.Electra1()) {\n\t\tif parentProposerPubkey != nil {\n\t\t\treturn nil, engineprimitives.ErrNonEmptyPrevProposerPubKey\n\t\t}\n\t} else {\n\t\tif parentProposerPubkey == nil {\n\t\t\treturn nil, engineprimitives.ErrEmptyPrevProposerPubKey\n\t\t}\n\t}\n\n\treturn &newPayloadRequest{\n\t\tVersionable:           NewVersionable(payload.GetForkVersion()),\n\t\texecutionPayload:      payload,\n\t\tversionedHashes:       body.GetBlobKzgCommitments().ToVersionedHashes(),\n\t\tparentBeaconBlockRoot: parentBeaconBlockRoot,\n\t\texecutionRequests:     executionRequestsList,\n\t\tparentProposerPubkey:  parentProposerPubkey,\n\t}, nil\n}\n\nfunc (n *newPayloadRequest) GetExecutionPayload() *ExecutionPayload {\n\treturn n.executionPayload\n}\n\nfunc (n *newPayloadRequest) GetVersionedHashes() []common.ExecutionHash {\n\treturn n.versionedHashes\n}\n\nfunc (n *newPayloadRequest) GetParentBeaconBlockRoot() common.Root {\n\treturn n.parentBeaconBlockRoot\n}\n\n// GetParentProposerPubkey may return a nil parent pub key. See BuildNewPayloadRequestFromFork\n// to understand how parentProposerPubkey gets populated\nfunc (n *newPayloadRequest) GetParentProposerPubkey() *crypto.BLSPubkey {\n\treturn n.parentProposerPubkey\n}\n\nfunc (n *newPayloadRequest) GetEncodedExecutionRequests() ([]EncodedExecutionRequest, error) {\n\tif version.IsBefore(n.GetForkVersion(), version.Electra()) {\n\t\treturn nil, errors.Wrap(\n\t\t\tErrForkVersionNotSupported,\n\t\t\t\"execution requests not supported in newPayloadRequest before electra\",\n\t\t)\n\t}\n\tif n.executionRequests == nil {\n\t\treturn nil, errors.Wrap(ErrNilValue, \"executionRequests cannot be nil\")\n\t}\n\treturn n.executionRequests, nil\n}\n\n// HasValidVersionedAndBlockHashes checks if the version and block hashes are\n// valid.\n// As per the Ethereum 2.0 specification:\n// https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.2/specs/deneb/beacon-chain.md#is_valid_block_hash\n// https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.2/specs/deneb/beacon-chain.md#is_valid_versioned_hashes\nfunc (n *newPayloadRequest) HasValidVersionedAndBlockHashes() error {\n\tvar executionRequests []EncodedExecutionRequest\n\tif version.EqualsOrIsAfter(n.GetForkVersion(), version.Electra()) {\n\t\tvar err error\n\t\texecutionRequests, err = n.GetEncodedExecutionRequests()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tblock, blobHashes, err := MakeEthBlock(\n\t\tn.GetExecutionPayload(),\n\t\tn.GetParentBeaconBlockRoot(),\n\t\texecutionRequests,\n\t\tn.GetParentProposerPubkey(),\n\t)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Validate the blob hashes from the transactions in the execution payload.\n\t// Check if the number of blob hashes matches the number of versioned hashes.\n\tif len(blobHashes) != len(n.GetVersionedHashes()) {\n\t\treturn errors.Wrapf(\n\t\t\tengineprimitives.ErrMismatchedNumVersionedHashes,\n\t\t\t\"expected %d, got %d\",\n\t\t\tlen(blobHashes),\n\t\t\tlen(n.GetVersionedHashes()),\n\t\t)\n\t}\n\n\t// Validate each blob hash against the corresponding versioned hash.\n\tfor i, blobHash := range blobHashes {\n\t\tif common.ExecutionHash(blobHash) != n.GetVersionedHashes()[i] {\n\t\t\treturn errors.Wrapf(\n\t\t\t\tengineprimitives.ErrInvalidVersionedHash,\n\t\t\t\t\"index %d: expected %v, got %v\",\n\t\t\t\ti,\n\t\t\t\tblobHash,\n\t\t\t\tn.GetVersionedHashes()[i],\n\t\t\t)\n\t\t}\n\t}\n\n\t// Verify that the payload is telling the truth about its block hash.\n\tif common.ExecutionHash(block.Hash()) != n.GetExecutionPayload().GetBlockHash() {\n\t\treturn errors.Wrapf(engineprimitives.ErrPayloadBlockHashMismatch,\n\t\t\t\"expected %x, got %x\",\n\t\t\tblock.Hash(), n.GetExecutionPayload().GetBlockHash(),\n\t\t)\n\t}\n\treturn nil\n}\n\n// MakeEthBlock builds an Ethereum block out of given payload and parent block root and\n// execution requests and/or parent proposer pubkey if needed.\n// It also returns blobHashes out of payload to ease up checks.\nfunc MakeEthBlock(\n\tpayload *ExecutionPayload,\n\tparentBeaconBlockRoot common.Root,\n\texecutionRequests []EncodedExecutionRequest,\n\tparentProposerPubKey *crypto.BLSPubkey,\n) (\n\t*bkitgethtypes.Block,\n\t[]gethcommon.Hash,\n\terror,\n) {\n\tvar (\n\t\ttxs        = make([]*bkitgethtypes.Transaction, 0, len(payload.GetTransactions()))\n\t\tblobHashes = make([]gethcommon.Hash, 0)\n\t)\n\n\tfor i, encTx := range payload.GetTransactions() {\n\t\tvar tx bkitgethtypes.Transaction\n\t\tif err := tx.UnmarshalBinary(encTx); err != nil {\n\t\t\treturn nil, nil, errors.Wrapf(err, \"invalid transaction %d\", i)\n\t\t}\n\t\ttxs = append(txs, &tx)\n\t\tblobHashes = append(blobHashes, tx.BlobHashes()...)\n\t}\n\n\twds := payload.GetWithdrawals()\n\twithdrawalsHash := gethtypes.DeriveSha(wds, gethtrie.NewStackTrie(nil))\n\n\tblkHeader := &bkitgethtypes.Header{\n\t\tParentHash:           gethcommon.Hash(payload.GetParentHash()),\n\t\tUncleHash:            gethtypes.EmptyUncleHash,\n\t\tCoinbase:             gethcommon.Address(payload.GetFeeRecipient()),\n\t\tRoot:                 gethcommon.Hash(payload.GetStateRoot()),\n\t\tTxHash:               gethtypes.DeriveSha(bkitgethtypes.Transactions(txs), gethtrie.NewStackTrie(nil)),\n\t\tReceiptHash:          gethcommon.Hash(payload.GetReceiptsRoot()),\n\t\tBloom:                gethtypes.Bloom(payload.GetLogsBloom()),\n\t\tDifficulty:           big.NewInt(0),\n\t\tNumber:               new(big.Int).SetUint64(payload.GetNumber().Unwrap()),\n\t\tGasLimit:             payload.GetGasLimit().Unwrap(),\n\t\tGasUsed:              payload.GetGasUsed().Unwrap(),\n\t\tTime:                 payload.GetTimestamp().Unwrap(),\n\t\tBaseFee:              payload.GetBaseFeePerGas().ToBig(),\n\t\tExtra:                payload.GetExtraData(),\n\t\tMixDigest:            gethcommon.Hash(payload.GetPrevRandao()),\n\t\tWithdrawalsHash:      &withdrawalsHash,\n\t\tExcessBlobGas:        payload.GetExcessBlobGas().UnwrapPtr(),\n\t\tBlobGasUsed:          payload.GetBlobGasUsed().UnwrapPtr(),\n\t\tParentBeaconRoot:     (*gethcommon.Hash)(&parentBeaconBlockRoot),\n\t\tParentProposerPubkey: (*bkitgethtypes.ExecutionPubkey)(parentProposerPubKey),\n\t}\n\n\tif version.EqualsOrIsAfter(payload.GetForkVersion(), version.Electra()) {\n\t\tif executionRequests == nil {\n\t\t\treturn nil, nil, errors.Wrap(ErrNilValue, \"executionRequests is nil after electra in makeEthBlock\")\n\t\t}\n\t\tresult := make([][]byte, len(executionRequests))\n\t\tfor i, req := range executionRequests {\n\t\t\tresult[i] = req // conversion from ExecutionRequest to []byte\n\t\t}\n\t\treqHash := gethtypes.CalcRequestsHash(result)\n\t\tblkHeader.RequestsHash = &reqHash\n\t}\n\n\tblock := bkitgethtypes.NewBlockWithHeader(blkHeader).WithBody(\n\t\tbkitgethtypes.Body{\n\t\t\tTransactions: txs,\n\t\t\tUncles:       nil,\n\t\t\tWithdrawals:  *(*gethtypes.Withdrawals)(unsafe.Pointer(&wds)), //#nosec:G103 // its okay.\n\t\t},\n\t)\n\treturn block, blobHashes, nil\n}\n\ntype ForkchoiceUpdateRequest struct {\n\t// State is the forkchoice state.\n\tState *engineprimitives.ForkchoiceStateV1\n\t// PayloadAttributes is the payload attributer.\n\tPayloadAttributes *engineprimitives.PayloadAttributes\n\t// ForkVersion is the fork version that we\n\t// are going to be submitting for.\n\tForkVersion common.Version\n}\n\n// BuildForkchoiceUpdateRequest builds a forkchoice update request.\nfunc BuildForkchoiceUpdateRequest(\n\tstate *engineprimitives.ForkchoiceStateV1,\n\tpayloadAttributes *engineprimitives.PayloadAttributes,\n\tforkVersion common.Version,\n) *ForkchoiceUpdateRequest {\n\treturn &ForkchoiceUpdateRequest{\n\t\tState:             state,\n\t\tPayloadAttributes: payloadAttributes,\n\t\tForkVersion:       forkVersion,\n\t}\n}\n\n// BuildForkchoiceUpdateRequestNoAttrs builds a forkchoice update request\n// without\n// any attributes.\nfunc BuildForkchoiceUpdateRequestNoAttrs(\n\tstate *engineprimitives.ForkchoiceStateV1,\n\tforkVersion common.Version,\n) *ForkchoiceUpdateRequest {\n\treturn &ForkchoiceUpdateRequest{\n\t\tState:       state,\n\t\tForkVersion: forkVersion,\n\t}\n}\n\n// GetPayloadRequest represents a request to get a payload.\ntype GetPayloadRequest struct {\n\t// PayloadID is the payload ID.\n\tPayloadID engineprimitives.PayloadID\n\t// ForkVersion is the fork version that we are\n\t// currently on.\n\tForkVersion common.Version\n}\n\n// BuildGetPayloadRequest builds a get payload request.\nfunc BuildGetPayloadRequest(\n\tpayloadID engineprimitives.PayloadID,\n\tforkVersion common.Version,\n) *GetPayloadRequest {\n\treturn &GetPayloadRequest{\n\t\tPayloadID:   payloadID,\n\t\tForkVersion: forkVersion,\n\t}\n}\n"
  },
  {
    "path": "consensus-types/types/payload_requests_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/berachain/beacon-kit/testing/utils\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestBuildNewPayloadRequestFromFork(t *testing.T) {\n\tt.Parallel()\n\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tblock := utils.GenerateValidBeaconBlock(t, v)\n\n\t\tvar parentProposerPubKey *crypto.BLSPubkey\n\t\tif version.EqualsOrIsAfter(v, version.Electra1()) {\n\t\t\tparentProposerPubKey = &crypto.BLSPubkey{0x01}\n\t\t}\n\t\trequest, err := types.BuildNewPayloadRequestFromFork(block, parentProposerPubKey)\n\t\trequire.NoError(t, err)\n\t\trequire.NotNil(t, request)\n\t\trequire.Equal(t, block.GetBody().GetExecutionPayload(), request.GetExecutionPayload())\n\t\trequire.Equal(t, block.GetBody().GetBlobKzgCommitments().ToVersionedHashes(), request.GetVersionedHashes())\n\t\trequire.Equal(t, block.GetParentBlockRoot(), request.GetParentBeaconBlockRoot())\n\n\t\tif version.EqualsOrIsAfter(v, version.Electra()) {\n\t\t\trequests, getErr := block.GetBody().GetExecutionRequests()\n\t\t\trequire.NoError(t, getErr)\n\t\t\tlist, getErr := types.GetExecutionRequestsList(requests)\n\t\t\trequire.NoError(t, getErr)\n\t\t\texecutionRequests, getErr := request.GetEncodedExecutionRequests()\n\t\t\trequire.NoError(t, getErr)\n\t\t\trequire.Equal(t, list, executionRequests)\n\t\t}\n\t})\n}\n\nfunc TestBuildForkchoiceUpdateRequest(t *testing.T) {\n\tt.Parallel()\n\tvar (\n\t\tstate       = &engineprimitives.ForkchoiceStateV1{}\n\t\tforkVersion = version.Deneb1()\n\t)\n\tpayloadAttributes, err := engineprimitives.NewPayloadAttributes(\n\t\tforkVersion,\n\t\tmath.U64(time.Now().Truncate(time.Second).Unix()),\n\t\tcommon.Bytes32{0x01},\n\t\tcommon.ExecutionAddress{},\n\t\tengineprimitives.Withdrawals{},\n\t\tcommon.Root{},\n\t\tnil,\n\t)\n\trequire.NoError(t, err)\n\n\trequest := types.BuildForkchoiceUpdateRequest(\n\t\tstate,\n\t\tpayloadAttributes,\n\t\tforkVersion,\n\t)\n\n\trequire.NotNil(t, request)\n\trequire.Equal(t, state, request.State)\n\trequire.Equal(t, payloadAttributes, request.PayloadAttributes)\n\trequire.Equal(t, forkVersion, request.ForkVersion)\n}\n\nfunc TestBuildGetPayloadRequest(t *testing.T) {\n\tt.Parallel()\n\tpayloadID := engineprimitives.PayloadID{}\n\tforkVersion := version.Altair()\n\n\trequest := types.BuildGetPayloadRequest(payloadID, forkVersion)\n\n\trequire.NotNil(t, request)\n\trequire.Equal(t, payloadID, request.PayloadID)\n\trequire.Equal(t, forkVersion, request.ForkVersion)\n}\n\nfunc TestHasValidVersionedAndBlockHashesPayloadError(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tblock := utils.GenerateValidBeaconBlock(t, v)\n\t\t// Remove txs and kzg commitments from body cos not valid\n\t\tblock.GetBody().SetExecutionPayload(&types.ExecutionPayload{\n\t\t\tVersionable: types.NewVersionable(v),\n\t\t})\n\t\tblock.GetBody().SetBlobKzgCommitments(eip4844.KZGCommitments[common.ExecutionHash]{})\n\n\t\tvar parentProposerPubKey *crypto.BLSPubkey\n\t\tif version.EqualsOrIsAfter(v, version.Electra1()) {\n\t\t\tparentProposerPubKey = &crypto.BLSPubkey{0x01}\n\t\t}\n\t\trequest, err := types.BuildNewPayloadRequestFromFork(block, parentProposerPubKey)\n\t\trequire.NoError(t, err)\n\t\trequire.NotNil(t, request)\n\t\trequire.Equal(t, block.GetBody().GetExecutionPayload(), request.GetExecutionPayload())\n\t\trequire.Equal(t, block.GetBody().GetBlobKzgCommitments().ToVersionedHashes(), request.GetVersionedHashes())\n\t\trequire.Equal(t, block.GetParentBlockRoot(), request.GetParentBeaconBlockRoot())\n\n\t\tif version.EqualsOrIsAfter(v, version.Electra()) {\n\t\t\trequests, getErr := block.GetBody().GetExecutionRequests()\n\t\t\trequire.NoError(t, getErr)\n\t\t\tlist, getErr := types.GetExecutionRequestsList(requests)\n\t\t\trequire.NoError(t, getErr)\n\t\t\texecutionRequests, getErr := request.GetEncodedExecutionRequests()\n\t\t\trequire.NoError(t, getErr)\n\t\t\trequire.Equal(t, list, executionRequests)\n\t\t}\n\t\terr = request.HasValidVersionedAndBlockHashes()\n\t\trequire.ErrorIs(t, err, engineprimitives.ErrPayloadBlockHashMismatch)\n\t})\n}\n\nfunc TestHasValidVersionedAndBlockHashesMismatchedHashes(t *testing.T) {\n\tt.Parallel()\n\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tblock := utils.GenerateValidBeaconBlock(t, v)\n\t\t// Remove txs and kzg commitments from body cos not valid\n\t\tblock.GetBody().SetExecutionPayload(&types.ExecutionPayload{\n\t\t\tVersionable: types.NewVersionable(v),\n\t\t})\n\t\tblock.GetBody().SetBlobKzgCommitments(eip4844.KZGCommitments[common.ExecutionHash]{{}})\n\n\t\tvar parentProposerPubKey *crypto.BLSPubkey\n\t\tif version.EqualsOrIsAfter(v, version.Electra1()) {\n\t\t\tparentProposerPubKey = &crypto.BLSPubkey{0x01}\n\t\t}\n\t\trequest, err := types.BuildNewPayloadRequestFromFork(block, parentProposerPubKey)\n\t\trequire.NoError(t, err)\n\n\t\terr = request.HasValidVersionedAndBlockHashes()\n\t\trequire.ErrorIs(t, err, engineprimitives.ErrMismatchedNumVersionedHashes)\n\t})\n}\n"
  },
  {
    "path": "consensus-types/types/payload_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\tkaralabessz \"github.com/karalabe/ssz\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc generateExecutionPayload() *types.ExecutionPayload {\n\tvar (\n\t\ttransactions = [][]byte{{0x07}}\n\t\twithdrawals  = []*engineprimitives.Withdrawal{\n\t\t\t{\n\t\t\t\tIndex:     0,\n\t\t\t\tValidator: 0,\n\t\t\t\tAddress:   common.ExecutionAddress{},\n\t\t\t\tAmount:    0,\n\t\t\t},\n\t\t}\n\t)\n\n\tep := &types.ExecutionPayload{\n\t\tVersionable:   types.NewVersionable(version.Deneb1()),\n\t\tParentHash:    common.ExecutionHash{},\n\t\tFeeRecipient:  common.ExecutionAddress{},\n\t\tStateRoot:     bytes.B32{},\n\t\tReceiptsRoot:  bytes.B32{},\n\t\tLogsBloom:     bytes.B256{},\n\t\tRandom:        bytes.B32{},\n\t\tNumber:        math.U64(0),\n\t\tGasLimit:      math.U64(0),\n\t\tGasUsed:       math.U64(0),\n\t\tTimestamp:     math.U64(0),\n\t\tExtraData:     []byte{0x01},\n\t\tBaseFeePerGas: &math.U256{},\n\t\tBlockHash:     common.ExecutionHash{},\n\t\tTransactions:  transactions,\n\t\tWithdrawals:   withdrawals,\n\t\tBlobGasUsed:   math.U64(0),\n\t\tExcessBlobGas: math.U64(0),\n\t}\n\treturn ep\n}\n\nfunc TestExecutionPayload_Serialization(t *testing.T) {\n\tt.Parallel()\n\toriginal := generateExecutionPayload()\n\n\tdata, err := original.MarshalSSZ()\n\trequire.NoError(t, err)\n\trequire.NotNil(t, data)\n\n\tunmarshalled := types.NewEmptyExecutionPayloadWithVersion(original.GetForkVersion())\n\terr = ssz.Unmarshal(data, unmarshalled)\n\trequire.NoError(t, err)\n\trequire.Equal(t, original, unmarshalled)\n\n\tvar buf []byte\n\tbuf, err = original.MarshalSSZTo(buf)\n\trequire.NoError(t, err)\n\n\t// The two byte slices should be equal\n\trequire.Equal(t, data, buf)\n}\n\nfunc TestExecutionPayload_SizeSSZ(t *testing.T) {\n\tt.Parallel()\n\tpayload := generateExecutionPayload()\n\tsize := karalabessz.Size(payload)\n\trequire.Equal(t, uint32(578), size)\n\n\tunmarshalledBody := types.NewEmptyExecutionPayloadWithVersion(version.Deneb1())\n\terr := ssz.Unmarshal(\n\t\t[]byte{0x01, 0x02, 0x03}, // Invalid data\n\t\tunmarshalledBody,\n\t)\n\trequire.ErrorIs(t, err, io.ErrUnexpectedEOF)\n}\n\nfunc TestExecutionPayload_HashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\tpayload := generateExecutionPayload()\n\trequire.NotPanics(t, func() {\n\t\t_ = payload.HashTreeRoot()\n\t})\n}\n\nfunc TestExecutionPayload_GetTree(t *testing.T) {\n\tt.Parallel()\n\tpayload := generateExecutionPayload()\n\ttree, err := payload.GetTree()\n\trequire.NoError(t, err)\n\trequire.NotNil(t, tree)\n}\n\nfunc TestExecutionPayload_Getters(t *testing.T) {\n\tt.Parallel()\n\tpayload := generateExecutionPayload()\n\trequire.Equal(t, common.ExecutionHash{}, payload.GetParentHash())\n\trequire.Equal(\n\t\tt,\n\t\tcommon.ExecutionAddress{},\n\t\tpayload.GetFeeRecipient(),\n\t)\n\n\ttransactions := make(engineprimitives.Transactions, 1)\n\ttransactions[0] = []byte{0x07}\n\twithdrawals := make(engineprimitives.Withdrawals, 1)\n\twithdrawals[0] = &engineprimitives.Withdrawal{\n\t\tIndex:     0,\n\t\tValidator: 0,\n\t\tAddress:   common.ExecutionAddress{},\n\t\tAmount:    0,\n\t}\n\trequire.Equal(t, common.ExecutionHash{}, payload.GetParentHash())\n\trequire.Equal(t, common.ExecutionAddress{}, payload.GetFeeRecipient())\n\trequire.Equal(t, bytes.B32{}, payload.GetStateRoot())\n\trequire.Equal(t, bytes.B32{}, payload.GetReceiptsRoot())\n\trequire.Equal(t, bytes.B256{}, payload.GetLogsBloom())\n\trequire.Equal(t, bytes.B32{}, payload.GetPrevRandao())\n\trequire.Equal(t, math.U64(0), payload.GetNumber())\n\trequire.Equal(t, math.U64(0), payload.GetGasLimit())\n\trequire.Equal(t, math.U64(0), payload.GetGasUsed())\n\trequire.Equal(t, math.U64(0), payload.GetTimestamp())\n\trequire.Equal(t, []byte{0x01}, payload.GetExtraData())\n\trequire.Equal(t, &math.U256{}, payload.GetBaseFeePerGas())\n\trequire.Equal(t, common.ExecutionHash{}, payload.GetBlockHash())\n\trequire.Equal(t, transactions, payload.GetTransactions())\n\trequire.Equal(t, withdrawals, payload.GetWithdrawals())\n\trequire.Equal(t, math.U64(0), payload.GetBlobGasUsed())\n\trequire.Equal(t, math.U64(0), payload.GetExcessBlobGas())\n}\n\nfunc TestExecutionPayload_MarshalJSON(t *testing.T) {\n\tt.Parallel()\n\tpayload := generateExecutionPayload()\n\n\tdata, err := payload.MarshalJSON()\n\trequire.NoError(t, err)\n\trequire.NotNil(t, data)\n\n\tvar unmarshalled types.ExecutionPayload\n\terr = unmarshalled.UnmarshalJSON(data)\n\trequire.NoError(t, err)\n\n\tunmarshalled.Versionable = payload.Versionable\n\trequire.Equal(t, payload, &unmarshalled)\n}\n\nfunc TestExecutionPayload_MarshalJSON_ValueAndPointer(t *testing.T) {\n\tt.Parallel()\n\tval := types.ExecutionPayload{}\n\n\t// Marshal on raw val uses default json marshal\n\tvalSerialized, err := json.Marshal(val)\n\trequire.NoError(t, err)\n\n\t// Marshal on ptr val uses implemented MarshalJSON\n\tptrSerialized, err := json.Marshal(&val)\n\trequire.NoError(t, err)\n\n\trequire.Equal(t, valSerialized, ptrSerialized)\n}\n\nfunc TestExecutionPayload_IsNil(t *testing.T) {\n\tt.Parallel()\n\tvar payload *types.ExecutionPayload\n\trequire.Nil(t, payload)\n\n\tpayload = generateExecutionPayload()\n\trequire.NotNil(t, payload)\n}\n\nfunc TestExecutionPayload_IsBlinded(t *testing.T) {\n\tt.Parallel()\n\tpayload := generateExecutionPayload()\n\trequire.False(t, payload.IsBlinded())\n}\n\nfunc TestExecutionPayload_Version(t *testing.T) {\n\tt.Parallel()\n\tpayload := generateExecutionPayload()\n\trequire.Equal(t, version.Deneb1(), payload.GetForkVersion())\n}\n\nfunc TestExecutionPayload_ToHeader(t *testing.T) {\n\tt.Parallel()\n\tpayload := &types.ExecutionPayload{\n\t\tVersionable:   types.NewVersionable(version.Deneb1()),\n\t\tParentHash:    common.ExecutionHash{},\n\t\tFeeRecipient:  common.ExecutionAddress{},\n\t\tStateRoot:     bytes.B32{},\n\t\tReceiptsRoot:  bytes.B32{},\n\t\tLogsBloom:     bytes.B256{},\n\t\tRandom:        bytes.B32{},\n\t\tNumber:        math.U64(0),\n\t\tGasLimit:      math.U64(0),\n\t\tGasUsed:       math.U64(0),\n\t\tTimestamp:     math.U64(0),\n\t\tExtraData:     []byte{},\n\t\tBaseFeePerGas: &math.U256{},\n\t\tBlockHash:     common.ExecutionHash{},\n\t\tTransactions:  [][]byte{{0x01}},\n\t\tWithdrawals:   engineprimitives.Withdrawals{},\n\t\tBlobGasUsed:   math.U64(0),\n\t\tExcessBlobGas: math.U64(0),\n\t}\n\theader, err := payload.ToHeader()\n\trequire.NoError(t, err)\n\trequire.NotNil(t, header)\n\n\trequire.Equal(t, payload.GetParentHash(), header.GetParentHash())\n\trequire.Equal(t, payload.GetFeeRecipient(), header.GetFeeRecipient())\n\trequire.Equal(t, payload.GetStateRoot(), header.GetStateRoot())\n\trequire.Equal(t, payload.GetReceiptsRoot(), header.GetReceiptsRoot())\n\trequire.Equal(t, payload.GetLogsBloom(), header.GetLogsBloom())\n\trequire.Equal(t, payload.GetPrevRandao(), header.GetPrevRandao())\n\trequire.Equal(t, payload.GetNumber(), header.GetNumber())\n\trequire.Equal(t, payload.GetGasLimit(), header.GetGasLimit())\n\trequire.Equal(t, payload.GetGasUsed(), header.GetGasUsed())\n\trequire.Equal(t, payload.GetTimestamp(), header.GetTimestamp())\n\trequire.Equal(t, payload.GetExtraData(), header.GetExtraData())\n\trequire.Equal(t, payload.GetBaseFeePerGas(), header.GetBaseFeePerGas())\n\trequire.Equal(t, payload.GetBlockHash(), header.GetBlockHash())\n\trequire.Equal(t, payload.GetBlobGasUsed(), header.GetBlobGasUsed())\n\trequire.Equal(t, payload.GetExcessBlobGas(), header.GetExcessBlobGas())\n\trequire.Equal(t, payload.GetForkVersion(), header.GetForkVersion())\n\n\trequire.Equal(t, payload.HashTreeRoot(), header.HashTreeRoot())\n}\n\nfunc TestExecutionPayload_UnmarshalJSON_Error(t *testing.T) {\n\tt.Parallel()\n\toriginal := generateExecutionPayload()\n\tvalidJSON, err := original.MarshalJSON()\n\trequire.NoError(t, err)\n\n\ttestCases := []struct {\n\t\tname          string\n\t\tremoveField   string\n\t\texpectedError string\n\t}{\n\t\t{\n\t\t\tname:          \"missing required field 'parentHash'\",\n\t\t\tremoveField:   \"parentHash\",\n\t\t\texpectedError: \"missing required field 'parentHash' for ExecutionPayload\",\n\t\t},\n\t\t{\n\t\t\tname:          \"missing required field 'feeRecipient'\",\n\t\t\tremoveField:   \"feeRecipient\",\n\t\t\texpectedError: \"missing required field 'feeRecipient' for ExecutionPayload\",\n\t\t},\n\t\t{\n\t\t\tname:          \"missing required field 'stateRoot'\",\n\t\t\tremoveField:   \"stateRoot\",\n\t\t\texpectedError: \"missing required field 'stateRoot' for ExecutionPayload\",\n\t\t},\n\t\t{\n\t\t\tname:          \"missing required field 'receiptsRoot'\",\n\t\t\tremoveField:   \"receiptsRoot\",\n\t\t\texpectedError: \"missing required field 'receiptsRoot' for ExecutionPayload\",\n\t\t},\n\t\t{\n\t\t\tname:          \"missing required field 'logsBloom'\",\n\t\t\tremoveField:   \"logsBloom\",\n\t\t\texpectedError: \"missing required field 'logsBloom' for ExecutionPayload\",\n\t\t},\n\t\t{\n\t\t\tname:          \"missing required field 'prevRandao'\",\n\t\t\tremoveField:   \"prevRandao\",\n\t\t\texpectedError: \"missing required field 'prevRandao' for ExecutionPayload\",\n\t\t},\n\t\t{\n\t\t\tname:          \"missing required field 'blockNumber'\",\n\t\t\tremoveField:   \"blockNumber\",\n\t\t\texpectedError: \"missing required field 'blockNumber' for ExecutionPayload\",\n\t\t},\n\t\t{\n\t\t\tname:          \"missing required field 'gasLimit'\",\n\t\t\tremoveField:   \"gasLimit\",\n\t\t\texpectedError: \"missing required field 'gasLimit' for ExecutionPayload\",\n\t\t},\n\t\t{\n\t\t\tname:          \"missing required field 'gasUsed'\",\n\t\t\tremoveField:   \"gasUsed\",\n\t\t\texpectedError: \"missing required field 'gasUsed' for ExecutionPayload\",\n\t\t},\n\t\t{\n\t\t\tname:          \"missing required field 'timestamp'\",\n\t\t\tremoveField:   \"timestamp\",\n\t\t\texpectedError: \"missing required field 'timestamp' for ExecutionPayload\",\n\t\t},\n\t\t{\n\t\t\tname:          \"missing required field 'extraData'\",\n\t\t\tremoveField:   \"extraData\",\n\t\t\texpectedError: \"missing required field 'extraData' for ExecutionPayload\",\n\t\t},\n\t\t{\n\t\t\tname:          \"missing required field 'baseFeePerGas'\",\n\t\t\tremoveField:   \"baseFeePerGas\",\n\t\t\texpectedError: \"missing required field 'baseFeePerGas' for ExecutionPayload\",\n\t\t},\n\t\t{\n\t\t\tname:          \"missing required field 'blockHash'\",\n\t\t\tremoveField:   \"blockHash\",\n\t\t\texpectedError: \"missing required field 'blockHash' for ExecutionPayload\",\n\t\t},\n\t\t{\n\t\t\tname:          \"missing required field 'transactions'\",\n\t\t\tremoveField:   \"transactions\",\n\t\t\texpectedError: \"missing required field 'transactions' for ExecutionPayload\",\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tvar payload types.ExecutionPayload\n\t\t\tvar jsonMap map[string]interface{}\n\n\t\t\terrUnmarshal := json.Unmarshal(validJSON, &jsonMap)\n\t\t\trequire.NoError(t, errUnmarshal)\n\n\t\t\tdelete(jsonMap, tc.removeField)\n\n\t\t\tmalformedJSON, errMarshal := json.Marshal(jsonMap)\n\t\t\trequire.NoError(t, errMarshal)\n\n\t\t\terr = payload.UnmarshalJSON(malformedJSON)\n\t\t\trequire.Error(t, err)\n\t\t\trequire.Contains(t, err.Error(), tc.expectedError)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "consensus-types/types/pending_partial_withdrawal.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tfastssz \"github.com/ferranbt/fastssz\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// sszPendingPartialWithdrawalSize defines the total SSZ serialized size for\n// PendingPartialWithdrawal. The fields are assumed to be encoded as follows:\n// - ValidatorIndex: 8 bytes (uint64)\n// - Amount:         8 bytes (math.Gwei)\n// - WithdrawableEpoch: 8 bytes (uint64)\n// Total = 8 + 8 + 8 = 24 bytes.\nconst sszPendingPartialWithdrawalSize = 24\n\n// Compile-time check to ensure PendingPartialWithdrawal and PendingPartialWithdrawals implements the necessary interfaces.\nvar (\n\t_ ssz.StaticObject            = (*PendingPartialWithdrawal)(nil)\n\t_ constraints.SSZMarshallable = (*PendingPartialWithdrawal)(nil)\n\n\t_ ssz.DynamicObject           = (*PendingPartialWithdrawals)(nil)\n\t_ constraints.SSZMarshallable = (*PendingPartialWithdrawals)(nil)\n)\n\n// PendingPartialWithdrawal reflects the following spec:\n//\n//\tclass PendingPartialWithdrawal(Container):\n//\t    validator_index: ValidatorIndex\n//\t    amount: Gwei\n//\t    withdrawable_epoch: Epoch\ntype PendingPartialWithdrawal struct {\n\tValidatorIndex    math.ValidatorIndex\n\tAmount            math.Gwei\n\tWithdrawableEpoch math.Epoch\n}\n\n/* -------------------------------------------------------------------------- */\n/*                      PendingPartialWithdrawal SSZ                          */\n/* -------------------------------------------------------------------------- */\n\n// ValidateAfterDecodingSSZ validates the PendingPartialWithdrawal object\n// after decoding from SSZ. Customize further validation as needed.\nfunc (p *PendingPartialWithdrawal) ValidateAfterDecodingSSZ() error {\n\treturn nil\n}\n\n// DefineSSZ registers the SSZ encoding for each field in PendingPartialWithdrawal.\nfunc (p *PendingPartialWithdrawal) DefineSSZ(codec *ssz.Codec) {\n\tssz.DefineUint64(codec, &p.ValidatorIndex)\n\tssz.DefineUint64(codec, &p.Amount)\n\tssz.DefineUint64(codec, &p.WithdrawableEpoch)\n}\n\n// SizeSSZ returns the fixed size of the SSZ serialization for PendingPartialWithdrawal.\nfunc (p *PendingPartialWithdrawal) SizeSSZ(_ *ssz.Sizer) uint32 {\n\treturn sszPendingPartialWithdrawalSize\n}\n\n// MarshalSSZ returns the SSZ encoding of the PendingPartialWithdrawal.\nfunc (p *PendingPartialWithdrawal) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(p))\n\treturn buf, ssz.EncodeToBytes(buf, p)\n}\n\n// HashTreeRoot computes and returns the hash tree root for the PendingPartialWithdrawal.\nfunc (p *PendingPartialWithdrawal) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(p)\n}\n\n// HashTreeRootWith SSZ hashes the Deposit object with a hasher. Needed for BeaconState SSZ.\nfunc (p *PendingPartialWithdrawal) HashTreeRootWith(hh fastssz.HashWalker) error {\n\tindx := hh.Index()\n\n\t// Field (0) 'ValidatorIndex'\n\thh.PutUint64(uint64(p.ValidatorIndex))\n\n\t// Field (1) 'Amount'\n\thh.PutUint64(uint64(p.Amount))\n\n\t// Field (2) 'WithdrawableEpoch'\n\thh.PutUint64(uint64(p.WithdrawableEpoch))\n\n\thh.Merkleize(indx)\n\treturn nil\n}\n\n// PendingPartialWithdrawals is a SSZ list of PendingPartialWithdrawal containers.\ntype PendingPartialWithdrawals []*PendingPartialWithdrawal\n\n// NewEmptyPendingPartialWithdrawals returns a new empty PendingPartialWithdrawals list.\nfunc NewEmptyPendingPartialWithdrawals() *PendingPartialWithdrawals {\n\treturn &PendingPartialWithdrawals{}\n}\n\n// DefineSSZ defines the SSZ encoding for the PendingPartialWithdrawals list.\nfunc (p *PendingPartialWithdrawals) DefineSSZ(codec *ssz.Codec) {\n\tssz.DefineSliceOfStaticObjectsOffset(codec, (*[]*PendingPartialWithdrawal)(p), constants.PendingPartialWithdrawalsLimit)\n\tssz.DefineSliceOfStaticObjectsContent(codec, (*[]*PendingPartialWithdrawal)(p), constants.PendingPartialWithdrawalsLimit)\n}\n\n// SizeSSZ returns the size of the PendingPartialWithdrawals list.\nfunc (p *PendingPartialWithdrawals) SizeSSZ(siz *ssz.Sizer, fixed bool) uint32 {\n\tif fixed {\n\t\treturn constants.SSZOffsetSize\n\t}\n\treturn constants.SSZOffsetSize + ssz.SizeSliceOfStaticObjects(siz, *p)\n}\n\n// MarshalSSZ returns the SSZ encoding of the PendingPartialWithdrawals list.\nfunc (p *PendingPartialWithdrawals) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(p))\n\treturn buf, ssz.EncodeToBytes(buf, p)\n}\n\n// ValidateAfterDecodingSSZ validates the PendingPartialWithdrawals list after decoding from SSZ.\nfunc (p *PendingPartialWithdrawals) ValidateAfterDecodingSSZ() error {\n\tif p == nil {\n\t\treturn errors.New(\"nil PendingPartialWithdrawals\")\n\t}\n\tif len(*p) > constants.PendingPartialWithdrawalsLimit {\n\t\treturn errors.New(\"pending partial withdrawals too large\")\n\t}\n\treturn nil\n}\n\n// PendingBalanceToWithdraw implements get_pending_balance_to_withdraw from the ETH2.0 spec.\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/electra/beacon-chain.md#new-get_pending_balance_to_withdraw\nfunc (p PendingPartialWithdrawals) PendingBalanceToWithdraw(validatorIndex math.ValidatorIndex) math.Gwei {\n\tvar total math.Gwei\n\tfor _, withdrawal := range p {\n\t\tif withdrawal.ValidatorIndex == validatorIndex {\n\t\t\ttotal += withdrawal.Amount\n\t\t}\n\t}\n\treturn total\n}\n"
  },
  {
    "path": "consensus-types/types/pending_partial_withdrawal_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\tprysmtypes \"github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestPendingPartialWithdrawal_ValidValuesSSZ(t *testing.T) {\n\tt.Parallel()\n\ttestCases := []struct {\n\t\tname    string\n\t\tpending *types.PendingPartialWithdrawal\n\t}{\n\t\t{\n\t\t\tname: \"basic\",\n\t\t\tpending: &types.PendingPartialWithdrawal{\n\t\t\t\tValidatorIndex:    1,\n\t\t\t\tAmount:            1000,\n\t\t\t\tWithdrawableEpoch: 10,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"zero amount\",\n\t\t\tpending: &types.PendingPartialWithdrawal{\n\t\t\t\tValidatorIndex:    2,\n\t\t\t\tAmount:            0,\n\t\t\t\tWithdrawableEpoch: 20,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"max values\",\n\t\t\tpending: &types.PendingPartialWithdrawal{\n\t\t\t\tValidatorIndex:    1<<64 - 1,\n\t\t\t\tAmount:            1<<64 - 1,\n\t\t\t\tWithdrawableEpoch: 1<<64 - 1,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"random-ish values\",\n\t\t\tpending: &types.PendingPartialWithdrawal{\n\t\t\t\tValidatorIndex:    7,\n\t\t\t\tAmount:            54321,\n\t\t\t\tWithdrawableEpoch: 999,\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\t// Marshal the original pending partial withdrawal.\n\t\t\tpendingBytes, err := tc.pending.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\n\t\t\t// Unmarshal into the prysm type.\n\t\t\tvar prysmType prysmtypes.PendingPartialWithdrawal\n\t\t\terr = prysmType.UnmarshalSSZ(pendingBytes)\n\t\t\trequire.NoError(t, err)\n\n\t\t\t// Compare the HashTreeRoots.\n\t\t\toriginalHTR := tc.pending.HashTreeRoot()\n\t\t\tprysmHTR, err := prysmType.HashTreeRoot()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, originalHTR[:], prysmHTR[:])\n\n\t\t\t// Marshal the prysm request\n\t\t\tprysmBytes, err := prysmType.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\n\t\t\t// Unmarshal back into original type\n\t\t\tvar recomputedPending types.PendingPartialWithdrawal\n\t\t\terr = ssz.Unmarshal(prysmBytes, &recomputedPending)\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, *tc.pending, recomputedPending)\n\t\t})\n\t}\n}\n\n//nolint:paralleltest // Invalid SSZ values cannot be run in parallel due to shared zeroalloc.\nfunc TestPendingPartialWithdrawal_InvalidValuesUnmarshalSSZ(t *testing.T) {\n\t// Build a valid pending partial withdrawal to get a baseline payload.\n\tvalidPending := &types.PendingPartialWithdrawal{\n\t\tValidatorIndex:    1,\n\t\tAmount:            1000,\n\t\tWithdrawableEpoch: 10,\n\t}\n\tvalidBytes, err := validPending.MarshalSSZ()\n\trequire.NoError(t, err)\n\n\t// Define several invalid payloads.\n\tinvalidPayloads := [][]byte{\n\t\tnil,                       // nil slice\n\t\t{},                        // empty slice\n\t\t[]byte(\"this is not ssz\"), // arbitrary non-SSZ data\n\t\t{0x00, 0x01},              // too short to be valid\n\t\t// A truncated valid payload: remove last 5 bytes.\n\t\tfunc() []byte {\n\t\t\tif len(validBytes) > 5 {\n\t\t\t\treturn validBytes[:len(validBytes)-5]\n\t\t\t}\n\t\t\treturn validBytes\n\t\t}(),\n\t\t// A valid payload with extra trailing bytes.\n\t\tfunc() []byte {\n\t\t\textra := []byte{0xAA, 0xBB, 0xCC, 0xDD}\n\t\t\treturn append(validBytes, extra...)\n\t\t}(),\n\t}\n\n\tfor i, payload := range invalidPayloads {\n\t\ti, payload := i, payload // capture loop variables\n\t\tt.Run(fmt.Sprintf(\"invalidPendingPartialWithdrawal_%d\", i), func(t *testing.T) {\n\t\t\t// Ensure that Unmarshal does not panic and returns an error.\n\t\t\trequire.NotPanics(t, func() {\n\t\t\t\tvar p types.PendingPartialWithdrawal\n\t\t\t\terr = ssz.Unmarshal(payload, &p)\n\t\t\t\trequire.Error(t, err, \"expected error for payload %v\", payload)\n\t\t\t})\n\t\t})\n\t}\n}\n\n// -----------------------------------------------------------------------------\n// Tests for the slice type: PendingPartialWithdrawals\n// -----------------------------------------------------------------------------\n\nfunc TestPendingPartialWithdrawals_ValidValuesSSZ(t *testing.T) {\n\tt.Parallel()\n\n\ttestCases := []struct {\n\t\tname     string\n\t\twithdraw *types.PendingPartialWithdrawals\n\t}{\n\t\t{\n\t\t\tname:     \"empty slice\",\n\t\t\twithdraw: types.NewEmptyPendingPartialWithdrawals(),\n\t\t},\n\t\t{\n\t\t\tname: \"one element\",\n\t\t\twithdraw: &types.PendingPartialWithdrawals{\n\t\t\t\t&types.PendingPartialWithdrawal{\n\t\t\t\t\tValidatorIndex:    1,\n\t\t\t\t\tAmount:            1000,\n\t\t\t\t\tWithdrawableEpoch: 10,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"multiple elements\",\n\t\t\twithdraw: &types.PendingPartialWithdrawals{\n\t\t\t\t&types.PendingPartialWithdrawal{ValidatorIndex: 1, Amount: 1000, WithdrawableEpoch: 10},\n\t\t\t\t&types.PendingPartialWithdrawal{ValidatorIndex: 2, Amount: 2000, WithdrawableEpoch: 20},\n\t\t\t\t&types.PendingPartialWithdrawal{ValidatorIndex: 3, Amount: 3000, WithdrawableEpoch: 30},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\t// Marshal the slice to SSZ.\n\t\t\twithdrawBytes, err := tc.withdraw.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\n\t\t\t// Unmarshal into a new PendingPartialWithdrawals variable.\n\t\t\tvar recomputed types.PendingPartialWithdrawals\n\t\t\terr = ssz.Unmarshal(withdrawBytes, &recomputed)\n\t\t\trequire.NoError(t, err)\n\n\t\t\t// Compare the original slice to the recomputed one.\n\t\t\trequire.Equal(t, tc.withdraw, &recomputed)\n\t\t})\n\t}\n}\n\n//nolint:paralleltest // Invalid SSZ payloads rely on shared zeroalloc\nfunc TestPendingPartialWithdrawals_InvalidValuesUnmarshalSSZ(t *testing.T) {\n\t// Build a valid pending partial withdrawals slice to obtain a baseline payload.\n\tvalidWithdrawals := types.PendingPartialWithdrawals{\n\t\t&types.PendingPartialWithdrawal{\n\t\t\tValidatorIndex:    1,\n\t\t\tAmount:            1000,\n\t\t\tWithdrawableEpoch: 10,\n\t\t},\n\t\t&types.PendingPartialWithdrawal{\n\t\t\tValidatorIndex:    2,\n\t\t\tAmount:            2000,\n\t\t\tWithdrawableEpoch: 20,\n\t\t},\n\t}\n\tvalidBytes, err := validWithdrawals.MarshalSSZ()\n\trequire.NoError(t, err)\n\n\tinvalidPayloads := [][]byte{\n\t\tnil,                       // nil slice\n\t\t{},                        // empty slice\n\t\t[]byte(\"this is not ssz\"), // arbitrary non-SSZ data\n\t\t{0x00, 0x01},              // too short to be valid\n\t\t// A truncated valid payload.\n\t\tfunc() []byte {\n\t\t\tif len(validBytes) > 5 {\n\t\t\t\treturn validBytes[:len(validBytes)-5]\n\t\t\t}\n\t\t\treturn validBytes\n\t\t}(),\n\t\t// A valid payload with extra trailing bytes.\n\t\tfunc() []byte {\n\t\t\textra := []byte{0xAA, 0xBB, 0xCC, 0xDD}\n\t\t\treturn append(validBytes, extra...)\n\t\t}(),\n\t}\n\n\tfor i, payload := range invalidPayloads {\n\t\ti, payload := i, payload // capture range variables\n\t\tt.Run(fmt.Sprintf(\"invalidPendingSlice_%d\", i), func(t *testing.T) {\n\t\t\t// Ensure that unmarshalling does not panic and returns an error.\n\t\t\trequire.NotPanics(t, func() {\n\t\t\t\tvar withdrawals types.PendingPartialWithdrawals\n\t\t\t\terr = ssz.Unmarshal(payload, &withdrawals)\n\t\t\t\trequire.Error(t, err, \"expected error for payload %v\", payload)\n\t\t\t})\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "consensus-types/types/proposer_slashings.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//nolint:dupl // separate file for ease of future implementation\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// Compile-time assertions to ensure ProposerSlashing implements necessary interfaces.\nvar (\n\t_ ssz.StaticObject                    = (*ProposerSlashing)(nil)\n\t_ constraints.SSZMarshallableRootable = (*ProposerSlashing)(nil)\n\t_ common.UnusedEnforcer               = (*ProposerSlashings)(nil)\n)\n\ntype (\n\tProposerSlashing  = common.UnusedType\n\tProposerSlashings []*ProposerSlashing\n)\n\n// SizeSSZ returns the SSZ encoded size in bytes for the ProposerSlashings.\nfunc (ps ProposerSlashings) SizeSSZ(siz *ssz.Sizer, _ bool) uint32 {\n\treturn ssz.SizeSliceOfStaticObjects(siz, ps)\n}\n\n// DefineSSZ defines the SSZ encoding for the ProposerSlashings object.\nfunc (ps ProposerSlashings) DefineSSZ(c *ssz.Codec) {\n\tc.DefineDecoder(func(*ssz.Decoder) {\n\t\tssz.DefineSliceOfStaticObjectsContent(c, (*[]*ProposerSlashing)(&ps), constants.MaxProposerSlashings)\n\t})\n\tc.DefineEncoder(func(*ssz.Encoder) {\n\t\tssz.DefineSliceOfStaticObjectsContent(c, (*[]*ProposerSlashing)(&ps), constants.MaxProposerSlashings)\n\t})\n\tc.DefineHasher(func(*ssz.Hasher) {\n\t\tssz.DefineSliceOfStaticObjectsOffset(c, (*[]*ProposerSlashing)(&ps), constants.MaxProposerSlashings)\n\t})\n}\n\n// HashTreeRoot returns the hash tree root of the ProposerSlashings.\nfunc (ps ProposerSlashings) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(ps)\n}\n\n// EnforceUnused return true if the length of the ProposerSlashings is 0.\n// As long as this type remains unimplemented and unvalidated by consensus,\n// we must enforce that it contains no data.\nfunc (ps ProposerSlashings) EnforceUnused() error {\n\tif len(ps) != 0 {\n\t\treturn errors.New(\"ProposerSlashings must be unused\")\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "consensus-types/types/signed_beacon_block.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// Compile-time assertions to ensure SignedBeaconBlock implements necessary interfaces.\nvar (\n\t_ ssz.DynamicObject                            = (*SignedBeaconBlock)(nil)\n\t_ constraints.SSZVersionedMarshallableRootable = (*SignedBeaconBlock)(nil)\n)\n\n// SignedBeaconBlock is a struct that contains a BeaconBlock and a BLSSignature.\n//\n// NOTE: This struct is only ever (un)marshalled with SSZ and NOT with JSON.\ntype SignedBeaconBlock struct {\n\t*BeaconBlock\n\tSignature crypto.BLSSignature\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                 Constructors                               */\n/* -------------------------------------------------------------------------- */\n\n// NewSignedBeaconBlock signs the provided BeaconBlock and populates the receiver.\n//\n// NOTE: will panic if any provided argument is nil. Only errors if signing fails.\nfunc NewSignedBeaconBlock(\n\tblk *BeaconBlock, forkData *ForkData, cs ProposerDomain, signer crypto.BLSSigner,\n) (*SignedBeaconBlock, error) {\n\tdomain := forkData.ComputeDomain(cs.DomainTypeProposer())\n\tsigningRoot := ComputeSigningRoot(blk, domain)\n\tsignature, err := signer.Sign(signingRoot[:])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &SignedBeaconBlock{\n\t\tBeaconBlock: blk,\n\t\tSignature:   signature,\n\t}, nil\n}\n\nfunc NewEmptySignedBeaconBlockWithVersion(forkVersion common.Version) (*SignedBeaconBlock, error) {\n\tswitch forkVersion {\n\tcase version.Deneb(), version.Deneb1(), version.Electra(), version.Electra1(), version.Fulu():\n\t\treturn &SignedBeaconBlock{\n\t\t\tBeaconBlock: NewEmptyBeaconBlockWithVersion(forkVersion),\n\t\t}, nil\n\tdefault:\n\t\t// We return a non-nil block here to appease nilaway.\n\t\treturn nil, errors.Wrapf(ErrForkVersionNotSupported, \"fork %d\", forkVersion)\n\t}\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// SizeSSZ returns the size of the SignedBeaconBlockHeader object\n// in SSZ encoding.\n// Total size: MessageOffset (4) + Signature (96) + MessageContentDynamic.\nfunc (b *SignedBeaconBlock) SizeSSZ(siz *ssz.Sizer, fixed bool) uint32 {\n\tsize := constants.SSZOffsetSize + bytes.B96Size\n\tif fixed {\n\t\treturn size\n\t}\n\tsize += ssz.SizeDynamicObject(siz, b.BeaconBlock)\n\treturn size\n}\n\n// DefineSSZ defines the SSZ encoding for the SignedBeaconBlockHeader object.\nfunc (b *SignedBeaconBlock) DefineSSZ(codec *ssz.Codec) {\n\tssz.DefineDynamicObjectOffset(codec, &b.BeaconBlock)\n\tssz.DefineStaticBytes(codec, &b.Signature)\n\n\t// Define the dynamic data (fields)\n\tssz.DefineDynamicObjectContent(codec, &b.BeaconBlock)\n}\n\n// MarshalSSZ marshals the SignedBeaconBlockHeader object to SSZ format.\nfunc (b *SignedBeaconBlock) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(b))\n\treturn buf, ssz.EncodeToBytes(buf, b)\n}\n\nfunc (b *SignedBeaconBlock) ValidateAfterDecodingSSZ() error {\n\treturn b.BeaconBlock.ValidateAfterDecodingSSZ()\n}\n\n// HashTreeRoot computes the SSZ hash tree root of the\n// SignedBeaconBlockHeader object.\nfunc (b *SignedBeaconBlock) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(b)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                 Getters                                    */\n/* -------------------------------------------------------------------------- */\n\nfunc (b *SignedBeaconBlock) GetBeaconBlock() *BeaconBlock {\n\treturn b.BeaconBlock\n}\n\nfunc (b *SignedBeaconBlock) GetSignature() crypto.BLSSignature {\n\treturn b.Signature\n}\n"
  },
  {
    "path": "consensus-types/types/signed_beacon_block_header.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// Compile-time assertions to ensure SignedBeaconBlockHeader implements necessary interfaces.\nvar (\n\t_ ssz.StaticObject                    = (*SignedBeaconBlockHeader)(nil)\n\t_ constraints.SSZMarshallableRootable = (*SignedBeaconBlockHeader)(nil)\n)\n\n// SignedBeaconBlockHeader is a struct that contains a BeaconBlockHeader and a BLSSignature.\n//\n// NOTE: This struct is only ever (un)marshalled with SSZ and NOT with JSON.\ntype SignedBeaconBlockHeader struct {\n\tHeader    *BeaconBlockHeader\n\tSignature crypto.BLSSignature\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                 Constructor                                */\n/* -------------------------------------------------------------------------- */\n\n// NewSignedBeaconBlockHeader creates a new BeaconBlockHeader.\nfunc NewSignedBeaconBlockHeader(\n\theader *BeaconBlockHeader,\n\tsignature crypto.BLSSignature,\n) *SignedBeaconBlockHeader {\n\treturn &SignedBeaconBlockHeader{\n\t\theader, signature,\n\t}\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// SizeSSZ returns the size of the SignedBeaconBlockHeader object\n// in SSZ encoding. Total size: Header (112) + Signature (96).\nfunc (b *SignedBeaconBlockHeader) SizeSSZ(sizer *ssz.Sizer) uint32 {\n\t//nolint:mnd // no magic\n\tsize := (*BeaconBlockHeader)(nil).SizeSSZ(sizer) + 96\n\treturn size\n}\n\n// DefineSSZ defines the SSZ encoding for the SignedBeaconBlockHeader object.\nfunc (b *SignedBeaconBlockHeader) DefineSSZ(codec *ssz.Codec) {\n\tssz.DefineStaticObject(codec, &b.Header)\n\tssz.DefineStaticBytes(codec, &b.Signature)\n}\n\n// MarshalSSZ marshals the SignedBeaconBlockHeader object to SSZ format.\nfunc (b *SignedBeaconBlockHeader) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(b))\n\treturn buf, ssz.EncodeToBytes(buf, b)\n}\n\nfunc (*SignedBeaconBlockHeader) ValidateAfterDecodingSSZ() error { return nil }\n\n// HashTreeRoot computes the SSZ hash tree root of the\n// SignedBeaconBlockHeader object.\nfunc (b *SignedBeaconBlockHeader) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(b)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                            Getters and Setters                             */\n/* -------------------------------------------------------------------------- */\n\n// Getheader retrieves the header of the SignedBeaconBlockHeader.\nfunc (b *SignedBeaconBlockHeader) GetHeader() *BeaconBlockHeader {\n\treturn b.Header\n}\n\n// GetSignature retrieves the Signature of the SignedBeaconBlockHeader.\nfunc (b *SignedBeaconBlockHeader) GetSignature() crypto.BLSSignature {\n\treturn b.Signature\n}\n"
  },
  {
    "path": "consensus-types/types/signed_beacon_block_header_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tkaralabessz \"github.com/karalabe/ssz\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestSignedBeaconBlockHeader_Serialization(t *testing.T) {\n\tt.Parallel()\n\theader := types.NewBeaconBlockHeader(\n\t\tmath.Slot(100),\n\t\tmath.ValidatorIndex(200),\n\t\tcommon.Root{0xde, 0xad, 0xbe, 0xef},\n\t\tcommon.Root{0xca, 0xca, 0xca, 0xfe},\n\t\tcommon.Root{0xde, 0xad, 0xca, 0xfe},\n\t)\n\tsig := crypto.BLSSignature{0xde, 0xad, 0xc4, 0xc4}\n\torig := &types.SignedBeaconBlockHeader{\n\t\tHeader:    header,\n\t\tSignature: sig,\n\t}\n\n\tdata, err := orig.MarshalSSZ()\n\trequire.NoError(t, err)\n\trequire.NotNil(t, data)\n\n\tunmarshalled := new(types.SignedBeaconBlockHeader)\n\terr = ssz.Unmarshal(data, unmarshalled)\n\trequire.NoError(t, err)\n\trequire.Equal(t, orig, unmarshalled)\n\n\tbuf := make([]byte, karalabessz.Size(orig))\n\terr = karalabessz.EncodeToBytes(buf, orig)\n\trequire.NoError(t, err)\n\n\t// The two byte slices should be equal\n\trequire.Equal(t, data, buf)\n}\n\nfunc TestSignedBeaconBlockHeader_EmptySerialization(t *testing.T) {\n\tt.Parallel()\n\torig := &types.SignedBeaconBlockHeader{}\n\tdata, err := orig.MarshalSSZ()\n\trequire.NoError(t, err)\n\trequire.NotNil(t, data)\n\n\tunmarshalled := new(types.SignedBeaconBlockHeader)\n\terr = ssz.Unmarshal(data, unmarshalled)\n\trequire.NoError(t, err)\n\trequire.NotNil(t, unmarshalled)\n\trequire.NotNil(t, unmarshalled.GetHeader())\n\trequire.NotNil(t, unmarshalled.GetSignature())\n\trequire.Equal(t, &types.BeaconBlockHeader{}, unmarshalled.GetHeader())\n\n\tbuf := make([]byte, karalabessz.Size(orig))\n\terr = karalabessz.EncodeToBytes(buf, orig)\n\trequire.NoError(t, err)\n\n\t// The two byte slices should be equal\n\trequire.Equal(t, data, buf)\n}\n\nfunc TestSignedBeaconBlockHeader_SizeSSZ(t *testing.T) {\n\tt.Parallel()\n\tsigHeader := types.NewSignedBeaconBlockHeader(\n\t\ttypes.NewBeaconBlockHeader(\n\t\t\tmath.Slot(100),\n\t\t\tmath.ValidatorIndex(200),\n\t\t\tcommon.Root{0xaa},\n\t\t\tcommon.Root{0xbb},\n\t\t\tcommon.Root{0xcc},\n\t\t),\n\t\tcrypto.BLSSignature{0xff},\n\t)\n\n\tsize := karalabessz.Size(sigHeader)\n\trequire.Equal(t, uint32(208), size)\n}\n\nfunc TestSignedBeaconBlockHeader_HashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\tsigHeader := types.NewSignedBeaconBlockHeader(\n\t\ttypes.NewBeaconBlockHeader(\n\t\t\tmath.Slot(100),\n\t\t\tmath.ValidatorIndex(200),\n\t\t\tcommon.Root{0xaa},\n\t\t\tcommon.Root{0xbb},\n\t\t\tcommon.Root{0xcc},\n\t\t),\n\t\tcrypto.BLSSignature{0xff},\n\t)\n\t_ = sigHeader.HashTreeRoot()\n}\n"
  },
  {
    "path": "consensus-types/types/signed_beacon_block_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/node-core/components/signer\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\tsszutil \"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/berachain/beacon-kit/testing/utils\"\n\tcmtcrypto \"github.com/cometbft/cometbft/crypto\"\n\t\"github.com/cometbft/cometbft/crypto/bls12381\"\n\t\"github.com/cometbft/cometbft/privval\"\n\t\"github.com/karalabe/ssz\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// runForAllSupportedVersions iterates over all supported versions,\n// creating a subtest for each that runs the provided testFunc.\n// TODO: Find a better home for this function.\nfunc runForAllSupportedVersions(t *testing.T, testFunc func(t *testing.T, v common.Version)) {\n\tt.Helper()\n\tfor _, v := range version.GetSupportedVersions() {\n\t\tv := v // capture the variable for parallel tests\n\t\tt.Run(v.String(), func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\ttestFunc(t, v)\n\t\t})\n\t}\n}\n\nfunc generateFakeSignedBeaconBlock(t *testing.T, version common.Version) *types.SignedBeaconBlock {\n\tt.Helper()\n\n\treturn &types.SignedBeaconBlock{\n\t\tBeaconBlock: utils.GenerateValidBeaconBlock(t, version),\n\t}\n}\n\nfunc generatePrivKey() (cmtcrypto.PrivKey, error) {\n\tprivKey, err := bls12381.GenPrivKey()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn privKey, nil\n}\n\nfunc generateSigningRoot(blk *types.BeaconBlock) (common.Root, error) {\n\tcs, err := spec.DevnetChainSpec()\n\tif err != nil {\n\t\treturn common.Root{}, err\n\t}\n\tdomain := (&types.ForkData{}).ComputeDomain(cs.DomainTypeProposer())\n\tsigningRoot := types.ComputeSigningRoot(blk, domain)\n\treturn signingRoot, nil\n}\n\nfunc generateRealSignedBeaconBlock(t *testing.T, blsSigner crypto.BLSSigner, version common.Version) (*types.SignedBeaconBlock, error) {\n\tt.Helper()\n\n\tblk := utils.GenerateValidBeaconBlock(t, version)\n\n\tsigningRoot, err := generateSigningRoot(blk)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tsignature, err := blsSigner.Sign(signingRoot[:])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &types.SignedBeaconBlock{\n\t\tBeaconBlock: blk,\n\t\tSignature:   signature,\n\t}, nil\n}\n\n// TestNewSignedBeaconBlockFromSSZ tests the roundtrip SSZ encoding for Deneb.\nfunc TestNewSignedBeaconBlockFromSSZ(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\toriginalBlock := generateFakeSignedBeaconBlock(t, v)\n\t\tblockBytes, err := originalBlock.MarshalSSZ()\n\t\trequire.NoError(t, err)\n\t\trequire.NotNil(t, blockBytes)\n\n\t\tnewBlock, err := types.NewEmptySignedBeaconBlockWithVersion(originalBlock.GetForkVersion())\n\t\trequire.NoError(t, err)\n\t\terr = sszutil.Unmarshal(blockBytes, newBlock)\n\t\trequire.NoError(t, err)\n\t\trequire.NotNil(t, newBlock)\n\t\trequire.Equal(t, originalBlock, newBlock)\n\t})\n}\n\nfunc TestNewSignedBeaconBlockFromSSZForkVersionNotSupported(t *testing.T) {\n\tt.Parallel()\n\n\t_, err := types.NewEmptySignedBeaconBlockWithVersion(version.Altair())\n\trequire.ErrorIs(t, err, types.ErrForkVersionNotSupported)\n}\n\nfunc TestSignedBeaconBlock_HashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tsBlk := generateFakeSignedBeaconBlock(t, v)\n\t\tsBlk.HashTreeRoot()\n\t})\n}\n\n// TestSignedBeaconBlock_SignBeaconBlock ensures the validity of the block\n// signatures.\nfunc TestSignedBeaconBlock_SignBeaconBlock(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\t// Generate a new bls key signer\n\t\tfilePV, err := privval.GenFilePV(\n\t\t\t\"signed_beacon_block_test_filepv_key\",\n\t\t\t\"signed_beacon_block_test_filepv_state\",\n\t\t\tgeneratePrivKey,\n\t\t)\n\t\trequire.NoError(t, err)\n\t\tblsSigner := signer.BLSSigner{PrivValidator: filePV}\n\n\t\t// Generate real signed beacon block\n\t\tsignedBlk, err := generateRealSignedBeaconBlock(t, blsSigner, v)\n\t\trequire.NoError(t, err)\n\t\trequire.NotNil(t, signedBlk)\n\n\t\t// Use SignBeaconBlock to sign the same BeaconBlock\n\t\tcs, err := spec.DevnetChainSpec()\n\t\trequire.NoError(t, err)\n\t\tnewSignedBlk, err := types.NewSignedBeaconBlock(\n\t\t\tsignedBlk.GetBeaconBlock(),\n\t\t\t&types.ForkData{},\n\t\t\tcs,\n\t\t\tblsSigner,\n\t\t)\n\t\trequire.NoError(t, err)\n\n\t\t// Check that the signature from SignBeaconBlock matches\n\t\tsig1 := signedBlk.GetSignature()\n\t\tsig2 := newSignedBlk.GetSignature()\n\t\trequire.Equal(t, sig1, sig2)\n\n\t\t// Verify the signature is good\n\t\tsigningRoot, err := generateSigningRoot(newSignedBlk.GetBeaconBlock())\n\t\trequire.NoError(t, err)\n\t\terr = blsSigner.VerifySignature(blsSigner.PublicKey(), signingRoot[:], newSignedBlk.GetSignature())\n\t\trequire.NoError(t, err)\n\t})\n}\n\nfunc TestSignedBeaconBlock_SizeSSZ(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tsBlk := generateFakeSignedBeaconBlock(t, v)\n\t\tsize := ssz.Size(sBlk)\n\t\trequire.Positive(t, size)\n\t})\n}\n\nfunc TestSignedBeaconBlock_EmptySerialization(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, fv common.Version) {\n\t\torig := &types.SignedBeaconBlock{\n\t\t\tBeaconBlock: types.NewEmptyBeaconBlockWithVersion(fv),\n\t\t}\n\t\tdata, err := orig.MarshalSSZ()\n\t\trequire.NoError(t, err)\n\t\trequire.NotNil(t, data)\n\n\t\tunmarshalled, err := types.NewEmptySignedBeaconBlockWithVersion(fv)\n\t\trequire.NoError(t, err)\n\t\terr = sszutil.Unmarshal(data, unmarshalled)\n\t\trequire.NoError(t, err)\n\t\trequire.NotNil(t, unmarshalled.GetBeaconBlock())\n\t\trequire.NotNil(t, unmarshalled.GetSignature())\n\n\t\tbuf := make([]byte, ssz.Size(orig))\n\t\terr = ssz.EncodeToBytes(buf, orig)\n\t\trequire.NoError(t, err)\n\n\t\t// The two byte slices should be equal\n\t\trequire.Equal(t, data, buf)\n\t})\n}\n"
  },
  {
    "path": "consensus-types/types/signing_data.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"encoding/binary\"\n\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/karalabe/ssz\"\n)\n\nvar (\n\t_ ssz.StaticObject                    = (*SigningData)(nil)\n\t_ constraints.SSZMarshallableRootable = (*SigningData)(nil)\n)\n\n// SigningData as defined in the Ethereum 2.0 specification.\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#signingdata\ntype SigningData struct {\n\t// ObjectRoot is the hash tree root of the object being signed.\n\tObjectRoot common.Root\n\t// Domain is the domain the object is being signed in.\n\tDomain common.Domain\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// SizeSSZ returns the size of the SigningData object in SSZ encoding.\nfunc (*SigningData) SizeSSZ(_ *ssz.Sizer) uint32 {\n\t//nolint:mnd // 32*2 = 64.\n\treturn 64\n}\n\n// DefineSSZ defines the SSZ encoding for the SigningData object.\nfunc (s *SigningData) DefineSSZ(codec *ssz.Codec) {\n\tssz.DefineStaticBytes(codec, &s.ObjectRoot)\n\tssz.DefineStaticBytes(codec, &s.Domain)\n}\n\n// HashTreeRoot computes the SSZ hash tree root of the SigningData object.\nfunc (s *SigningData) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(s)\n}\n\n// MarshalSSZTo marshals the SigningData object to SSZ format into the provided\n// buffer.\nfunc (s *SigningData) MarshalSSZTo(buf []byte) ([]byte, error) {\n\treturn buf, ssz.EncodeToBytes(buf, s)\n}\n\n// MarshalSSZ marshals the SigningData object to SSZ format.\nfunc (s *SigningData) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(s))\n\treturn s.MarshalSSZTo(buf)\n}\n\nfunc (*SigningData) ValidateAfterDecodingSSZ() error { return nil }\n\n// ComputeSigningRoot as defined in the Ethereum 2.0 specification.\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#compute_signing_root\nfunc ComputeSigningRoot(\n\tsszObject interface{ HashTreeRoot() common.Root },\n\tdomain common.Domain,\n) common.Root {\n\treturn (&SigningData{\n\t\tObjectRoot: sszObject.HashTreeRoot(),\n\t\tDomain:     domain,\n\t}).HashTreeRoot()\n}\n\n// ComputeSigningRootUInt64 computes the signing root of a uint64 value.\nfunc ComputeSigningRootUInt64(\n\tvalue uint64,\n\tdomain common.Domain,\n\n) common.Root {\n\tbz := make([]byte, constants.RootLength)\n\tbinary.LittleEndian.PutUint64(bz, value)\n\treturn (&SigningData{\n\t\tObjectRoot: common.Root(bz),\n\t\tDomain:     domain,\n\t}).HashTreeRoot()\n}\n"
  },
  {
    "path": "consensus-types/types/signing_data_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"io\"\n\t\"testing\"\n\n\ttypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc generateSigningData() *types.SigningData {\n\treturn &types.SigningData{\n\t\tObjectRoot: common.Root{\n\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32},\n\t\tDomain: bytes.B32{\n\t\t\t33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,\n\t\t\t51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64},\n\t}\n}\nfunc TestSigningData_MarshalSSZ_UnmarshalSSZ(t *testing.T) {\n\tt.Parallel()\n\ttestCases := []struct {\n\t\tname     string\n\t\tdata     *types.SigningData\n\t\texpected *types.SigningData\n\t\terr      error\n\t}{\n\t\t{\n\t\t\tname:     \"Valid SigningData\",\n\t\t\tdata:     generateSigningData(),\n\t\t\texpected: generateSigningData(),\n\t\t\terr:      nil,\n\t\t},\n\t\t{\n\t\t\tname: \"Empty SigningData\",\n\t\t\tdata: &types.SigningData{\n\t\t\t\tObjectRoot: common.Root{},\n\t\t\t\tDomain:     bytes.B32{},\n\t\t\t},\n\t\t\texpected: &types.SigningData{\n\t\t\t\tObjectRoot: common.Root{},\n\t\t\t\tDomain:     bytes.B32{},\n\t\t\t},\n\t\t\terr: nil,\n\t\t},\n\t\t{\n\t\t\tname:     \"Invalid Buffer Size\",\n\t\t\tdata:     generateSigningData(),\n\t\t\texpected: nil,\n\t\t\terr:      io.ErrUnexpectedEOF,\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tdata, err := tc.data.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.NotNil(t, data)\n\n\t\t\tunmarshalled := new(types.SigningData)\n\t\t\tif tc.name == \"Invalid Buffer Size\" {\n\t\t\t\terr = ssz.Unmarshal(data[:32], unmarshalled)\n\t\t\t\trequire.ErrorIs(t, err, tc.err)\n\t\t\t} else {\n\t\t\t\terr = ssz.Unmarshal(data, unmarshalled)\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tc.expected, unmarshalled)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "consensus-types/types/slashing_info.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tfastssz \"github.com/ferranbt/fastssz\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// SlashingInfoSize is the size of the SlashingInfo object in SSZ encoding.\nconst SlashingInfoSize = 16 // 8 bytes for Slot + 8 bytes for Index\n\n// Compile-time assertions to ensure SlashingInfo implements the correct\n// interfaces.\nvar (\n\t_ ssz.StaticObject                    = (*SlashingInfo)(nil)\n\t_ constraints.SSZMarshallableRootable = (*SlashingInfo)(nil)\n)\n\n// Compile-time assertion to ensure SlashingInfoSize matches the SizeSSZ method.\nvar _ = [1]struct{}{}[16-SlashingInfoSize]\n\n// SlashingInfo represents a slashing info.\ntype SlashingInfo struct {\n\t// Slot is the slot number of the slashing info.\n\tSlot math.Slot\n\t// ValidatorIndex is the validator index of the slashing info.\n\tIndex math.U64\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// SizeSSZ returns the size of the SlashingInfo object in SSZ encoding.\nfunc (*SlashingInfo) SizeSSZ(*ssz.Sizer) uint32 {\n\treturn SlashingInfoSize\n}\n\n// DefineSSZ defines the SSZ encoding for the SlashingInfo object.\nfunc (s *SlashingInfo) DefineSSZ(codec *ssz.Codec) {\n\tssz.DefineUint64(codec, &s.Slot)\n\tssz.DefineUint64(codec, &s.Index)\n}\n\n// HashTreeRoot computes the SSZ hash tree root of the SlashingInfo object.\nfunc (s *SlashingInfo) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(s)\n}\n\n// MarshalSSZ marshals the SlashingInfo object to SSZ format.\nfunc (s *SlashingInfo) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(s))\n\treturn buf, ssz.EncodeToBytes(buf, s)\n}\n\nfunc (*SlashingInfo) ValidateAfterDecodingSSZ() error { return nil }\n\n/* -------------------------------------------------------------------------- */\n/*                                   FastSSZ                                  */\n/* -------------------------------------------------------------------------- */\n\n// MarshalSSZTo ssz marshals the SlashingInfo object into a pre-allocated byte\n// slice.\nfunc (s *SlashingInfo) MarshalSSZTo(dst []byte) ([]byte, error) {\n\tbz, err := s.MarshalSSZ()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdst = append(dst, bz...)\n\treturn dst, nil\n}\n\n// HashTreeRootWith ssz hashes the SlashingInfo object with a hasher.\nfunc (s *SlashingInfo) HashTreeRootWith(hh fastssz.HashWalker) error {\n\tindx := hh.Index()\n\n\t// Field (0) 'Slot'\n\thh.PutUint64(uint64(s.Slot))\n\n\t// Field (1) 'Index'\n\thh.PutUint64(uint64(s.Index))\n\n\thh.Merkleize(indx)\n\treturn nil\n}\n\n// GetTree ssz hashes the SlashingInfo object.\nfunc (s *SlashingInfo) GetTree() (*fastssz.Node, error) {\n\treturn fastssz.ProofTree(s)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                             Getters and Setters                            */\n/* -------------------------------------------------------------------------- */\n\n// GetSlot returns the slot of the slashing info.\nfunc (s *SlashingInfo) GetSlot() math.Slot {\n\treturn s.Slot\n}\n\n// GetIndex returns the index of the slashing info.\nfunc (s *SlashingInfo) GetIndex() math.U64 {\n\treturn s.Index\n}\n\n// SetSlot sets the slot of the slashing info.\nfunc (s *SlashingInfo) SetSlot(slot math.Slot) {\n\ts.Slot = slot\n}\n\n// SetIndex sets the index of the slashing info.\nfunc (s *SlashingInfo) SetIndex(index math.U64) {\n\ts.Index = index\n}\n"
  },
  {
    "path": "consensus-types/types/slashing_info_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc generateSlashingInfo() *types.SlashingInfo {\n\treturn &types.SlashingInfo{\n\t\tSlot:  12345,\n\t\tIndex: 67890,\n\t}\n}\n\nfunc TestSlashingInfo_MarshalSSZ_UnmarshalSSZ(t *testing.T) {\n\tt.Parallel()\n\ttestCases := []struct {\n\t\tname     string\n\t\tdata     *types.SlashingInfo\n\t\texpected *types.SlashingInfo\n\t\terr      error\n\t}{\n\t\t{\n\t\t\tname:     \"Valid SlashingInfo\",\n\t\t\tdata:     generateSlashingInfo(),\n\t\t\texpected: generateSlashingInfo(),\n\t\t\terr:      nil,\n\t\t},\n\t\t{\n\t\t\tname: \"Empty SlashingInfo\",\n\t\t\tdata: &types.SlashingInfo{\n\t\t\t\tSlot:  0,\n\t\t\t\tIndex: 0,\n\t\t\t},\n\t\t\texpected: &types.SlashingInfo{\n\t\t\t\tSlot:  0,\n\t\t\t\tIndex: 0,\n\t\t\t},\n\t\t\terr: nil,\n\t\t},\n\t\t{\n\t\t\tname:     \"Invalid Buffer Size\",\n\t\t\tdata:     generateSlashingInfo(),\n\t\t\texpected: nil,\n\t\t\terr:      io.ErrUnexpectedEOF,\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tdata, err := tc.data.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.NotNil(t, data)\n\n\t\t\tunmarshalled := new(types.SlashingInfo)\n\t\t\tif tc.name == \"Invalid Buffer Size\" {\n\t\t\t\terr = ssz.Unmarshal(data[:8], unmarshalled)\n\t\t\t\trequire.ErrorIs(t, err, tc.err)\n\t\t\t} else {\n\t\t\t\terr = ssz.Unmarshal(data, unmarshalled)\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tc.expected, unmarshalled)\n\n\t\t\t\tvar buf []byte\n\t\t\t\tbuf, err = tc.data.MarshalSSZTo(buf)\n\t\t\t\trequire.NoError(t, err)\n\n\t\t\t\t// The two byte slices should be equal\n\t\t\t\trequire.Equal(t, data, buf)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestSlashingInfo_GetTree(t *testing.T) {\n\tt.Parallel()\n\tdata := generateSlashingInfo()\n\n\ttree, err := data.GetTree()\n\trequire.NoError(t, err)\n\trequire.NotNil(t, tree)\n\n\texpectedRoot := data.HashTreeRoot()\n\tactualRoot := tree.Hash()\n\trequire.Equal(t, string(expectedRoot[:]), string(actualRoot))\n}\n\nfunc TestSlashingInfo_SetSlot(t *testing.T) {\n\tt.Parallel()\n\tdata := generateSlashingInfo()\n\n\tnewSlot := math.Slot(67890)\n\tdata.SetSlot(newSlot)\n\n\trequire.Equal(t, newSlot, data.GetSlot())\n}\n\nfunc TestSlashingInfo_SetIndex(t *testing.T) {\n\tt.Parallel()\n\tdata := generateSlashingInfo()\n\n\tnewIndex := math.U64(12345)\n\tdata.SetIndex(newIndex)\n\n\trequire.Equal(t, newIndex, data.GetIndex())\n}\n"
  },
  {
    "path": "consensus-types/types/state.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\tfastssz \"github.com/ferranbt/fastssz\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// BeaconState represents the entire state of the beacon chain.\ntype BeaconState struct {\n\tconstraints.Versionable `json:\"-\"`\n\n\t// Versioning\n\tGenesisValidatorsRoot common.Root `json:\"genesis_validators_root,omitempty\"`\n\tSlot                  math.Slot   `json:\"slot,omitempty\"`\n\tFork                  *Fork       `json:\"fork,omitempty\"`\n\n\t// History\n\tLatestBlockHeader *BeaconBlockHeader `json:\"latest_block_header,omitempty\"`\n\tBlockRoots        []common.Root      `json:\"block_roots,omitempty\"`\n\tStateRoots        []common.Root      `json:\"state_roots,omitempty\"`\n\n\t// Eth1\n\tEth1Data                     *Eth1Data               `json:\"eth1_data,omitempty\"`\n\tEth1DepositIndex             uint64                  `json:\"eth1_deposit_index,omitempty\"`\n\tLatestExecutionPayloadHeader *ExecutionPayloadHeader `json:\"latest_execution_payload_header,omitempty\"`\n\n\t// Registry\n\tValidators []*Validator `json:\"validators,omitempty\"`\n\tBalances   []uint64     `json:\"balances,omitempty\"`\n\n\t// Randomness\n\tRandaoMixes []common.Bytes32 `json:\"randao_mixes,omitempty\"`\n\n\t// Withdrawals\n\tNextWithdrawalIndex          uint64              `json:\"next_withdrawal_index,omitempty\"`\n\tNextWithdrawalValidatorIndex math.ValidatorIndex `json:\"next_withdrawal_validator_index,omitempty\"`\n\n\t// Slashing\n\tSlashings     []math.Gwei `json:\"slashings,omitempty\"`\n\tTotalSlashing math.Gwei   `json:\"total_slashing,omitempty\"`\n\n\t// PendingPartialWithdrawals is introduced in electra\n\tPendingPartialWithdrawals []*PendingPartialWithdrawal `json:\"pending_partial_withdrawals,omitempty\"`\n}\n\n// NewEmptyBeaconStateWithVersion returns a new empty BeaconState with the given fork version.\nfunc NewEmptyBeaconStateWithVersion(version common.Version) *BeaconState {\n\treturn &BeaconState{\n\t\tVersionable: NewVersionable(version),\n\t}\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// SizeSSZ returns the ssz encoded size in bytes for the BeaconState object.\nfunc (st *BeaconState) SizeSSZ(siz *ssz.Sizer, fixed bool) uint32 {\n\t/*\n\t\tGenesisValidatorsRoot = 32\n\t\tSlot = 8\n\t\tFork = 4 + 4 + 8 = 16\n\t\tLatestBlockHeader = 8 + 8 + 32 + 32 + 32 = 112\n\t\tBlockRoots = 4 (Dynamic field)\n\t\tStateRoots = 4 (Dynamic field)\n\t\tEth1Data = 32 + 8 + 32 = 72\n\t\tEth1DepositIndex = 8\n\t\tLatestExecutionPayloadHeader = 4 (Dynamic field)\n\t\tValidators = 4 (Dynamic field)\n\t\tBalances = 4 (Dynamic field)\n\t\tRandaoMixes = 4 (Dynamic field)\n\t\tNextWithdrawalIndex = 8\n\t\tNextWithdrawalValidatorIndex = 8\n\t\tSlashings = 4 (Dynamic field)\n\t\tTotalSlashings = 8\n\n\t\t// Electra Fork\n\t\tPendingPartialWithdrawals = 4 (Dynamic field)\n\t*/\n\tvar size uint32 = 300\n\n\tif version.EqualsOrIsAfter(st.GetForkVersion(), version.Electra()) {\n\t\t// Add 4 for PendingPartialWithdrawals after Electra\n\t\tsize += 4\n\t}\n\n\tif fixed {\n\t\treturn size\n\t}\n\n\t// Dynamic size fields\n\tsize += ssz.SizeSliceOfStaticBytes(siz, st.BlockRoots)\n\tsize += ssz.SizeSliceOfStaticBytes(siz, st.StateRoots)\n\tsize += ssz.SizeDynamicObject(siz, st.LatestExecutionPayloadHeader)\n\tsize += ssz.SizeSliceOfStaticObjects(siz, st.Validators)\n\tsize += ssz.SizeSliceOfUint64s(siz, st.Balances)\n\tsize += ssz.SizeSliceOfStaticBytes(siz, st.RandaoMixes)\n\tsize += ssz.SizeSliceOfUint64s(siz, st.Slashings)\n\tif version.EqualsOrIsAfter(st.GetForkVersion(), version.Electra()) {\n\t\tsize += ssz.SizeSliceOfStaticObjects(siz, st.PendingPartialWithdrawals)\n\t}\n\n\treturn size\n}\n\n// DefineSSZ defines the SSZ encoding for the BeaconState object.\n//\n//nolint:mnd // TODO: get from accessible chainspec field params\nfunc (st *BeaconState) DefineSSZ(codec *ssz.Codec) {\n\t// Versioning\n\tssz.DefineStaticBytes(codec, &st.GenesisValidatorsRoot)\n\tssz.DefineUint64(codec, &st.Slot)\n\tssz.DefineStaticObject(codec, &st.Fork)\n\n\t// History\n\tssz.DefineStaticObject(codec, &st.LatestBlockHeader)\n\tssz.DefineSliceOfStaticBytesOffset(codec, &st.BlockRoots, 8192)\n\tssz.DefineSliceOfStaticBytesOffset(codec, &st.StateRoots, 8192)\n\n\t// Eth1\n\tssz.DefineStaticObject(codec, &st.Eth1Data)\n\tssz.DefineUint64(codec, &st.Eth1DepositIndex)\n\tssz.DefineDynamicObjectOffset(codec, &st.LatestExecutionPayloadHeader)\n\n\t// Registry\n\tssz.DefineSliceOfStaticObjectsOffset(codec, &st.Validators, 1099511627776)\n\tssz.DefineSliceOfUint64sOffset(codec, &st.Balances, 1099511627776)\n\n\t// Randomness\n\tssz.DefineSliceOfStaticBytesOffset(codec, &st.RandaoMixes, 65536)\n\n\t// Withdrawals\n\tssz.DefineUint64(codec, &st.NextWithdrawalIndex)\n\tssz.DefineUint64(codec, &st.NextWithdrawalValidatorIndex)\n\n\t// Slashing\n\tssz.DefineSliceOfUint64sOffset(codec, &st.Slashings, 1099511627776)\n\tssz.DefineUint64(codec, (*uint64)(&st.TotalSlashing))\n\n\t// Electra Withdrawals\n\tif version.EqualsOrIsAfter(st.GetForkVersion(), version.Electra()) {\n\t\tssz.DefineSliceOfStaticObjectsOffset(codec, &st.PendingPartialWithdrawals, constants.PendingPartialWithdrawalsLimit)\n\t}\n\n\t// Dynamic content\n\tssz.DefineSliceOfStaticBytesContent(codec, &st.BlockRoots, 8192)\n\tssz.DefineSliceOfStaticBytesContent(codec, &st.StateRoots, 8192)\n\tssz.DefineDynamicObjectContent(codec, &st.LatestExecutionPayloadHeader)\n\tssz.DefineSliceOfStaticObjectsContent(codec, &st.Validators, 1099511627776)\n\tssz.DefineSliceOfUint64sContent(codec, &st.Balances, 1099511627776)\n\tssz.DefineSliceOfStaticBytesContent(codec, &st.RandaoMixes, 65536)\n\tssz.DefineSliceOfUint64sContent(codec, &st.Slashings, 1099511627776)\n\t// Electra Withdrawals\n\tif version.EqualsOrIsAfter(st.GetForkVersion(), version.Electra()) {\n\t\tssz.DefineSliceOfStaticObjectsContent(codec, &st.PendingPartialWithdrawals, constants.PendingPartialWithdrawalsLimit)\n\t}\n}\n\n// MarshalSSZ marshals the BeaconState into SSZ format.\nfunc (st *BeaconState) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(st))\n\treturn buf, ssz.EncodeToBytes(buf, st)\n}\n\n// UnmarshalSSZ unmarshals the BeaconState from SSZ format.\nfunc (st *BeaconState) UnmarshalSSZ(buf []byte) error {\n\treturn ssz.DecodeFromBytes(buf, st)\n}\n\n// HashTreeRoot computes the Merkleization of the BeaconState.\nfunc (st *BeaconState) HashTreeRoot() common.Root {\n\treturn ssz.HashConcurrent(st)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   FastSSZ                                  */\n/* -------------------------------------------------------------------------- */\n\n// HashTreeRootWith ssz hashes the BeaconState object with a hasher.\n//\n//nolint:mnd,funlen,gocognit // todo fix.\nfunc (st *BeaconState) HashTreeRootWith(\n\thh fastssz.HashWalker,\n) error {\n\tindx := hh.Index()\n\n\t// Field (0) 'GenesisValidatorsRoot'\n\thh.PutBytes(st.GenesisValidatorsRoot[:])\n\n\t// Field (1) 'Slot'\n\thh.PutUint64(uint64(st.Slot))\n\n\t// Field (2) 'Fork'\n\tif st.Fork == nil {\n\t\tst.Fork = &Fork{}\n\t}\n\tif err := st.Fork.HashTreeRootWith(hh); err != nil {\n\t\treturn err\n\t}\n\n\t// Field (3) 'LatestBlockHeader'\n\tif st.LatestBlockHeader == nil {\n\t\tst.LatestBlockHeader = &BeaconBlockHeader{}\n\t}\n\tif err := st.LatestBlockHeader.HashTreeRootWith(hh); err != nil {\n\t\treturn err\n\t}\n\n\t// Field (4) 'BlockRoots'\n\tif size := len(st.BlockRoots); size > 8192 {\n\t\treturn fastssz.ErrListTooBigFn(\"BeaconState.BlockRoots\", size, 8192)\n\t}\n\tsubIndx := hh.Index()\n\tfor _, i := range st.BlockRoots {\n\t\thh.Append(i[:])\n\t}\n\tnumItems := uint64(len(st.BlockRoots))\n\thh.MerkleizeWithMixin(subIndx, numItems, 8192)\n\n\t// Field (5) 'StateRoots'\n\tif size := len(st.StateRoots); size > 8192 {\n\t\treturn fastssz.ErrListTooBigFn(\"BeaconState.StateRoots\", size, 8192)\n\t}\n\tsubIndx = hh.Index()\n\tfor _, i := range st.StateRoots {\n\t\thh.Append(i[:])\n\t}\n\tnumItems = uint64(len(st.StateRoots))\n\thh.MerkleizeWithMixin(subIndx, numItems, 8192)\n\n\t// Field (6) 'Eth1Data'\n\tif st.Eth1Data == nil {\n\t\tst.Eth1Data = &Eth1Data{}\n\t}\n\tif err := st.Eth1Data.HashTreeRootWith(hh); err != nil {\n\t\treturn err\n\t}\n\n\t// Field (7) 'Eth1DepositIndex'\n\thh.PutUint64(st.Eth1DepositIndex)\n\n\t// Field (8) 'LatestExecutionPayloadHeader'\n\tif st.LatestExecutionPayloadHeader == nil {\n\t\tst.LatestExecutionPayloadHeader = NewEmptyExecutionPayloadHeaderWithVersion(st.GetForkVersion())\n\t}\n\tif err := st.LatestExecutionPayloadHeader.HashTreeRootWith(hh); err != nil {\n\t\treturn err\n\t}\n\n\t// Field (9) 'Validators'\n\tsubIndx = hh.Index()\n\tnum := uint64(len(st.Validators))\n\tif num > 1099511627776 {\n\t\treturn fastssz.ErrIncorrectListSize\n\t}\n\tfor _, elem := range st.Validators {\n\t\tif err := elem.HashTreeRootWith(hh); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\thh.MerkleizeWithMixin(subIndx, num, 1099511627776)\n\n\t// Field (10) 'Balances'\n\tif size := len(st.Balances); size > 1099511627776 {\n\t\treturn fastssz.ErrListTooBigFn(\n\t\t\t\"BeaconState.Balances\",\n\t\t\tsize,\n\t\t\t1099511627776,\n\t\t)\n\t}\n\tsubIndx = hh.Index()\n\tfor _, i := range st.Balances {\n\t\thh.AppendUint64(i)\n\t}\n\thh.FillUpTo32()\n\tnumItems = uint64(len(st.Balances))\n\thh.MerkleizeWithMixin(\n\t\tsubIndx,\n\t\tnumItems,\n\t\tfastssz.CalculateLimit(1099511627776, numItems, 8),\n\t)\n\n\t// Field (11) 'RandaoMixes'\n\tif size := len(st.RandaoMixes); size > 65536 {\n\t\treturn fastssz.ErrListTooBigFn(\"BeaconState.RandaoMixes\", size, 65536)\n\t}\n\tsubIndx = hh.Index()\n\tfor _, i := range st.RandaoMixes {\n\t\thh.Append(i[:])\n\t}\n\tnumItems = uint64(len(st.RandaoMixes))\n\thh.MerkleizeWithMixin(subIndx, numItems, 65536)\n\n\t// Field (12) 'NextWithdrawalIndex'\n\thh.PutUint64(st.NextWithdrawalIndex)\n\n\t// Field (13) 'NextWithdrawalValidatorIndex'\n\thh.PutUint64(uint64(st.NextWithdrawalValidatorIndex))\n\n\t// Field (14) 'Slashings'\n\tif size := len(st.Slashings); size > 1099511627776 {\n\t\treturn fastssz.ErrListTooBigFn(\n\t\t\t\"BeaconState.Slashings\",\n\t\t\tsize,\n\t\t\t1099511627776,\n\t\t)\n\t}\n\tsubIndx = hh.Index()\n\tfor _, i := range st.Slashings {\n\t\thh.AppendUint64(uint64(i))\n\t}\n\thh.FillUpTo32()\n\tnumItems = uint64(len(st.Slashings))\n\thh.MerkleizeWithMixin(\n\t\tsubIndx,\n\t\tnumItems,\n\t\tfastssz.CalculateLimit(1099511627776, numItems, 8),\n\t)\n\n\t// Field (15) 'TotalSlashing'\n\thh.PutUint64(uint64(st.TotalSlashing))\n\n\t// Field (16) 'PendingPartialWithdrawals' post-electra\n\tif version.EqualsOrIsAfter(st.GetForkVersion(), version.Electra()) {\n\t\tsubIndx = hh.Index()\n\t\tnumPPW := uint64(len(st.PendingPartialWithdrawals))\n\t\tif numPPW > constants.PendingPartialWithdrawalsLimit {\n\t\t\treturn fastssz.ErrIncorrectListSize\n\t\t}\n\t\tfor _, elem := range st.PendingPartialWithdrawals {\n\t\t\tif err := elem.HashTreeRootWith(hh); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\thh.MerkleizeWithMixin(subIndx, numPPW, constants.PendingPartialWithdrawalsLimit)\n\t}\n\thh.Merkleize(indx)\n\treturn nil\n}\n\n// GetTree ssz hashes the BeaconState object.\nfunc (st *BeaconState) GetTree() (*fastssz.Node, error) {\n\treturn fastssz.ProofTree(st)\n}\n"
  },
  {
    "path": "consensus-types/types/state_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\tssz \"github.com/ferranbt/fastssz\"\n\tkaralabessz \"github.com/karalabe/ssz\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// generateValidBeaconState generates a valid beacon state for the types.\nfunc generateValidBeaconState(forkVersion common.Version) *types.BeaconState {\n\tbeaconState := &types.BeaconState{\n\t\tVersionable:           types.NewVersionable(forkVersion),\n\t\tGenesisValidatorsRoot: common.Root{0x01, 0x02, 0x03},\n\t\tSlot:                  1234,\n\t\tBlockRoots: []common.Root{\n\t\t\t{0x04, 0x05, 0x06},\n\t\t\t{0x07, 0x08, 0x09},\n\t\t},\n\t\tStateRoots: []common.Root{\n\t\t\t{0x0a, 0x0b, 0x0c},\n\t\t\t{0x0d, 0x0e, 0x0f},\n\t\t},\n\t\tFork: &types.Fork{\n\t\t\tPreviousVersion: [4]byte{0x01, 0x00, 0x00, 0x00},\n\t\t\tCurrentVersion:  [4]byte{0x02, 0x00, 0x00, 0x00},\n\t\t\tEpoch:           5678,\n\t\t},\n\t\tValidators: []*types.Validator{\n\t\t\t{\n\t\t\t\tPubkey:                     [48]byte{0x01},\n\t\t\t\tWithdrawalCredentials:      [32]byte{0x02},\n\t\t\t\tEffectiveBalance:           32000000000,\n\t\t\t\tSlashed:                    false,\n\t\t\t\tActivationEligibilityEpoch: 1,\n\t\t\t\tActivationEpoch:            2,\n\t\t\t\tExitEpoch:                  18446744073709551615,\n\t\t\t\tWithdrawableEpoch:          18446744073709551615,\n\t\t\t},\n\t\t\t{\n\t\t\t\tPubkey:                     [48]byte{0x03},\n\t\t\t\tWithdrawalCredentials:      [32]byte{0x04},\n\t\t\t\tEffectiveBalance:           31000000000,\n\t\t\t\tSlashed:                    true,\n\t\t\t\tActivationEligibilityEpoch: 3,\n\t\t\t\tActivationEpoch:            4,\n\t\t\t\tExitEpoch:                  5,\n\t\t\t\tWithdrawableEpoch:          6,\n\t\t\t},\n\t\t},\n\t\tBalances:                     []uint64{32000000000, 31000000000},\n\t\tRandaoMixes:                  generateRandomBytes32(65536),\n\t\tSlashings:                    []math.Gwei{1000000000, 2000000000},\n\t\tNextWithdrawalIndex:          7,\n\t\tNextWithdrawalValidatorIndex: 8,\n\t\tTotalSlashing:                3000000000,\n\t\tLatestExecutionPayloadHeader: &types.ExecutionPayloadHeader{\n\t\t\tParentHash:       [32]byte{0x16, 0x17, 0x18},\n\t\t\tFeeRecipient:     [20]byte{0x19, 0x1a, 0x1b},\n\t\t\tStateRoot:        [32]byte{0x1c, 0x1d, 0x1e},\n\t\t\tReceiptsRoot:     [32]byte{0x1f, 0x20, 0x21},\n\t\t\tLogsBloom:        [256]byte{0x22},\n\t\t\tRandom:           [32]byte{0x23, 0x24, 0x25},\n\t\t\tNumber:           9876,\n\t\t\tGasLimit:         30000000,\n\t\t\tGasUsed:          25000000,\n\t\t\tTimestamp:        1625097600,\n\t\t\tExtraData:        []byte{0x26, 0x27, 0x28},\n\t\t\tBaseFeePerGas:    math.NewU256(3906250),\n\t\t\tBlockHash:        [32]byte{0x2c, 0x2d, 0x2e},\n\t\t\tTransactionsRoot: [32]byte{0x2f, 0x30, 0x31},\n\t\t\tWithdrawalsRoot:  [32]byte{0x32, 0x33, 0x34},\n\t\t},\n\t\tLatestBlockHeader: &types.BeaconBlockHeader{\n\t\t\tSlot:            5678,\n\t\t\tProposerIndex:   123,\n\t\t\tParentBlockRoot: [32]byte{0x35, 0x36, 0x37},\n\t\t\tStateRoot:       [32]byte{0x38, 0x39, 0x3a},\n\t\t\tBodyRoot:        [32]byte{0x3b, 0x3c, 0x3d},\n\t\t},\n\t\tEth1Data: &types.Eth1Data{\n\t\t\tDepositRoot:  [32]byte{0x3e, 0x3f, 0x40},\n\t\t\tDepositCount: 1000,\n\t\t\tBlockHash:    [32]byte{0x41, 0x42, 0x43},\n\t\t},\n\t\tEth1DepositIndex: 100,\n\t}\n\n\tif version.EqualsOrIsAfter(beaconState.GetForkVersion(), version.Electra()) {\n\t\tbeaconState.PendingPartialWithdrawals = []*types.PendingPartialWithdrawal{\n\t\t\t{\n\t\t\t\tValidatorIndex:    123,\n\t\t\t\tAmount:            32000000000,\n\t\t\t\tWithdrawableEpoch: 100,\n\t\t\t},\n\t\t\t{\n\t\t\t\tValidatorIndex:    124,\n\t\t\t\tAmount:            100,\n\t\t\t\tWithdrawableEpoch: 1,\n\t\t\t},\n\t\t}\n\t}\n\treturn beaconState\n}\n\nfunc generateRandomBytes32(count int) []common.Bytes32 {\n\tresult := make([]common.Bytes32, count)\n\tfor i := range result {\n\t\tvar randomBytes [32]byte\n\t\tfor j := range randomBytes {\n\t\t\trandomBytes[j] = byte((i + j) % 256)\n\t\t}\n\t\tresult[i] = randomBytes\n\t}\n\treturn result\n}\n\nfunc TestBeaconStateMarshalUnmarshalSSZ(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tgenState := generateValidBeaconState(v)\n\n\t\tdata, fastSSZMarshalErr := genState.MarshalSSZ()\n\t\trequire.NoError(t, fastSSZMarshalErr)\n\t\trequire.NotNil(t, data)\n\n\t\tnewState := types.NewEmptyBeaconStateWithVersion(v)\n\t\terr := newState.UnmarshalSSZ(data)\n\t\trequire.NoError(t, err)\n\n\t\trequire.EqualValues(t, genState, newState)\n\n\t\t// Check if the state size is greater than 0\n\t\trequire.Positive(t, karalabessz.Size(genState))\n\t})\n}\n\nfunc TestHashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tstate := generateValidBeaconState(v)\n\t\trequire.NotPanics(t, func() {\n\t\t\tstate.HashTreeRoot()\n\t\t})\n\t})\n}\n\nfunc TestGetTree(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tstate := generateValidBeaconState(v)\n\t\ttree, err := state.GetTree()\n\t\trequire.NoError(t, err)\n\t\trequire.NotNil(t, tree)\n\t})\n}\n\nfunc TestBeaconState_UnmarshalSSZ_Error(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tstate := types.NewEmptyBeaconStateWithVersion(v)\n\t\terr := state.UnmarshalSSZ([]byte{0x01, 0x02, 0x03}) // Invalid data\n\t\trequire.ErrorIs(t, err, io.ErrUnexpectedEOF)\n\t})\n}\n\nfunc TestBeaconState_HashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\trunForAllSupportedVersions(t, func(t *testing.T, v common.Version) {\n\t\tstate := generateValidBeaconState(v)\n\n\t\t// Get the HashTreeRoot\n\t\troot := state.HashTreeRoot()\n\n\t\t// Get the HashConcurrent\n\t\tconcurrentRoot := common.Root(karalabessz.HashSequential(state))\n\n\t\t// Get the HashTreeRootWith\n\t\thasher := ssz.NewHasher()\n\t\terr := state.HashTreeRootWith(hasher)\n\t\trequire.NoError(t, err)\n\t\troot2 := hasher.Hash()\n\n\t\t// Compare the results\n\t\trequire.Equal(\n\t\t\tt,\n\t\t\troot,\n\t\t\tconcurrentRoot,\n\t\t\t\"HashTreeRoot and HashSequential should produce the same result\",\n\t\t)\n\n\t\trequire.Equal(t,\n\t\t\troot[:],\n\t\t\troot2,\n\t\t\t\"HashTreeRoot and HashTreeRootWith should produce the same result\",\n\t\t)\n\t})\n}\n"
  },
  {
    "path": "consensus-types/types/sync_aggregate.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz/schema\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// Compile-time assertions to ensure SyncAggregate implements necessary interfaces.\nvar (\n\t_ ssz.StaticObject                    = (*SyncAggregate)(nil)\n\t_ constraints.SSZMarshallableRootable = (*SyncAggregate)(nil)\n\t_ common.UnusedEnforcer               = (*SyncAggregate)(nil)\n)\n\nconst (\n\tsyncCommitteeSize       = 512\n\tsyncCommitteeBitsLength = syncCommitteeSize / 8\n)\n\ntype SyncAggregate struct {\n\tSyncCommitteeBits      [syncCommitteeBitsLength]byte\n\tSyncCommitteeSignature crypto.BLSSignature\n}\n\n// SizeSSZ returns the SSZ encoded size in bytes for the SyncAggregate.\nfunc (s *SyncAggregate) SizeSSZ(_ *ssz.Sizer) uint32 {\n\treturn syncCommitteeBitsLength + schema.B96Size\n}\n\n// DefineSSZ defines the SSZ encoding for the SyncAggregate object.\nfunc (s *SyncAggregate) DefineSSZ(c *ssz.Codec) {\n\tssz.DefineStaticBytes(c, &s.SyncCommitteeBits)\n\tssz.DefineStaticBytes(c, &s.SyncCommitteeSignature)\n}\n\n// MarshalSSZ marshals the SyncAggregate object to SSZ format.\nfunc (s *SyncAggregate) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(s))\n\treturn buf, ssz.EncodeToBytes(buf, s)\n}\n\nfunc (*SyncAggregate) ValidateAfterDecodingSSZ() error { return nil }\n\n// HashTreeRoot returns the hash tree root of the Deposits.\nfunc (s *SyncAggregate) HashTreeRoot() common.Root {\n\thtr := ssz.HashSequential(s)\n\treturn htr\n}\n\n// EnforceUnused return true if the SyncAggregate contains all zero values.\n// As long as this type remains unused and unvalidated by consensus,\n// we must enforce that it contains no data.\nfunc (s *SyncAggregate) EnforceUnused() error {\n\tif (s != nil && *s != SyncAggregate{}) {\n\t\treturn errors.New(\"SyncAggregate must be unused\")\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "consensus-types/types/validator.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tfastssz \"github.com/ferranbt/fastssz\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// ValidatorSize is the size of the Validator struct in bytes.\nconst ValidatorSize = 121\n\n// Compile-time checks for the Validator struct.\nvar (\n\t_ ssz.StaticObject                    = (*Validator)(nil)\n\t_ constraints.SSZMarshallableRootable = (*Validator)(nil)\n)\n\n// Validator as defined in the Ethereum 2.0 Spec\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#validator\ntype Validator struct {\n\t// Pubkey is the validator's 48-byte BLS public key.\n\tPubkey crypto.BLSPubkey `json:\"pubkey\"`\n\t// WithdrawalCredentials are an address that controls the validator.\n\tWithdrawalCredentials WithdrawalCredentials `json:\"withdrawalCredentials\"`\n\t// EffectiveBalance is the validator's current effective balance in gwei.\n\tEffectiveBalance math.Gwei `json:\"effectiveBalance\"`\n\t// Slashed indicates whether the validator has been slashed.\n\tSlashed bool `json:\"slashed\"`\n\t// ActivationEligibilityEpoch is the epoch in which the validator became\n\t// eligible for activation.\n\tActivationEligibilityEpoch math.Epoch `json:\"activationEligibilityEpoch\"`\n\t// ActivationEpoch is the epoch in which the validator activated.\n\tActivationEpoch math.Epoch `json:\"activationEpoch\"`\n\t// ExitEpoch is the epoch in which the validator exited.\n\tExitEpoch math.Epoch `json:\"exitEpoch\"`\n\t// WithdrawableEpoch is the epoch in which the validator can withdraw.\n\tWithdrawableEpoch math.Epoch `json:\"withdrawableEpoch\"`\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                 Constructor                                */\n/* -------------------------------------------------------------------------- */\n\n// NewValidatorFromDeposit creates a new Validator from the\n// given public key, withdrawal credentials, and amount.\n//\n// As defined in the Ethereum 2.0 specification:\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#deposits\nfunc NewValidatorFromDeposit(\n\tpubkey crypto.BLSPubkey,\n\twithdrawalCredentials WithdrawalCredentials,\n\tamount math.Gwei,\n\teffectiveBalanceIncrement math.Gwei,\n\tmaxEffectiveBalance math.Gwei,\n) *Validator {\n\treturn &Validator{\n\t\tPubkey:                pubkey,\n\t\tWithdrawalCredentials: withdrawalCredentials,\n\t\tEffectiveBalance: ComputeEffectiveBalance(\n\t\t\tamount,\n\t\t\teffectiveBalanceIncrement,\n\t\t\tmaxEffectiveBalance,\n\t\t),\n\t\tSlashed:                    false,\n\t\tActivationEligibilityEpoch: constants.FarFutureEpoch,\n\t\tActivationEpoch:            constants.FarFutureEpoch,\n\t\tExitEpoch:                  constants.FarFutureEpoch,\n\t\tWithdrawableEpoch:          constants.FarFutureEpoch,\n\t}\n}\n\nfunc NewEmptyValidator() *Validator {\n\treturn &Validator{}\n}\n\nfunc ComputeEffectiveBalance(\n\tamount, effectiveBalanceIncrement, maxEffectiveBalance math.Gwei,\n) math.Gwei {\n\treturn min(amount-amount%effectiveBalanceIncrement, maxEffectiveBalance)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// SizeSSZ returns the size of the Validator object in SSZ encoding.\nfunc (*Validator) SizeSSZ(*ssz.Sizer) uint32 {\n\treturn ValidatorSize\n}\n\n// DefineSSZ defines the SSZ encoding for the Validator object.\nfunc (v *Validator) DefineSSZ(codec *ssz.Codec) {\n\tssz.DefineStaticBytes(codec, &v.Pubkey)\n\tssz.DefineStaticBytes(codec, &v.WithdrawalCredentials)\n\tssz.DefineUint64(codec, &v.EffectiveBalance)\n\tssz.DefineBool(codec, &v.Slashed)\n\tssz.DefineUint64(codec, &v.ActivationEligibilityEpoch)\n\tssz.DefineUint64(codec, &v.ActivationEpoch)\n\tssz.DefineUint64(codec, &v.ExitEpoch)\n\tssz.DefineUint64(codec, &v.WithdrawableEpoch)\n}\n\n// HashTreeRoot computes the SSZ hash tree root of the Validator object.\nfunc (v *Validator) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(v)\n}\n\n// MarshalSSZ marshals the Validator object to SSZ format.\nfunc (v *Validator) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(v))\n\treturn buf, ssz.EncodeToBytes(buf, v)\n}\n\nfunc (*Validator) ValidateAfterDecodingSSZ() error { return nil }\n\n/* -------------------------------------------------------------------------- */\n/*                                   FastSSZ                                  */\n/* -------------------------------------------------------------------------- */\n\n// MarshalSSZTo marshals the Validator object to SSZ format into the provided\n// buffer.\nfunc (v *Validator) MarshalSSZTo(dst []byte) ([]byte, error) {\n\tbz, err := v.MarshalSSZ()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdst = append(dst, bz...)\n\treturn dst, nil\n}\n\n// HashTreeRootWith ssz hashes the Validator object with a hasher.\nfunc (v *Validator) HashTreeRootWith(hh fastssz.HashWalker) error {\n\tindx := hh.Index()\n\n\t// Field (0) 'Pubkey'\n\thh.PutBytes(v.Pubkey[:])\n\n\t// Field (1) 'WithdrawalCredentials'\n\thh.PutBytes(v.WithdrawalCredentials[:])\n\n\t// Field (2) 'EffectiveBalance'\n\thh.PutUint64(uint64(v.EffectiveBalance))\n\n\t// Field (3) 'Slashed'\n\thh.PutBool(v.Slashed)\n\n\t// Field (4) 'ActivationEligibilityEpoch'\n\thh.PutUint64(uint64(v.ActivationEligibilityEpoch))\n\n\t// Field (5) 'ActivationEpoch'\n\thh.PutUint64(uint64(v.ActivationEpoch))\n\n\t// Field (6) 'ExitEpoch'\n\thh.PutUint64(uint64(v.ExitEpoch))\n\n\t// Field (7) 'WithdrawableEpoch'\n\thh.PutUint64(uint64(v.WithdrawableEpoch))\n\n\thh.Merkleize(indx)\n\treturn nil\n}\n\n// GetTree ssz hashes the Validator object.\nfunc (v *Validator) GetTree() (*fastssz.Node, error) {\n\treturn fastssz.ProofTree(v)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                             Getters and Setters                            */\n/* -------------------------------------------------------------------------- */\n\n// GetPubkey returns the public key of the validator.\nfunc (v *Validator) GetPubkey() crypto.BLSPubkey {\n\treturn v.Pubkey\n}\n\n// GetEffectiveBalance returns the effective balance of the validator.\nfunc (v *Validator) GetEffectiveBalance() math.Gwei {\n\treturn v.EffectiveBalance\n}\n\n// IsActive as defined in the Ethereum 2.0 Spec\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#is_active_validator\nfunc (v Validator) IsActive(epoch math.Epoch) bool {\n\treturn v.ActivationEpoch <= epoch && epoch < v.ExitEpoch\n}\n\n// IsEligibleForActivation as defined in the Ethereum 2.0 Spec\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#is_eligible_for_activation_queue\nfunc (v Validator) IsEligibleForActivation(finalizedEpoch math.Epoch) bool {\n\treturn v.ActivationEligibilityEpoch <= finalizedEpoch &&\n\t\tv.ActivationEpoch == constants.FarFutureEpoch\n}\n\n// IsEligibleForActivationQueue is defined slightly differently from Ethereum 2.0 Spec\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#is_eligible_for_activation_queue\nfunc (v Validator) IsEligibleForActivationQueue(threshold math.Gwei) bool {\n\treturn v.ActivationEligibilityEpoch == constants.FarFutureEpoch && v.EffectiveBalance >= threshold\n}\n\n// IsSlashable as defined in the Ethereum 2.0 Spec\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#is_slashable_validator\nfunc (v Validator) IsSlashable(epoch math.Epoch) bool {\n\treturn !v.Slashed && v.ActivationEpoch <= epoch &&\n\t\tepoch < v.WithdrawableEpoch\n}\n\n// IsSlashed returns whether the validator has been slashed.\nfunc (v Validator) IsSlashed() bool {\n\treturn v.Slashed\n}\n\n// IsFullyWithdrawable as defined in the Ethereum 2.0 specification:\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#is_fully_withdrawable_validator\nfunc (v Validator) IsFullyWithdrawable(\n\tbalance math.Gwei,\n\tepoch math.Epoch,\n) bool {\n\treturn v.HasEth1WithdrawalCredentials() && v.WithdrawableEpoch <= epoch &&\n\t\tbalance > 0\n}\n\n// IsPartiallyWithdrawable as defined in the Ethereum 2.0 specification:\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#is_partially_withdrawable_validator\nfunc (v Validator) IsPartiallyWithdrawable(\n\tbalance, maxEffectiveBalance math.Gwei,\n) bool {\n\thasExcessBalance := balance > maxEffectiveBalance\n\treturn v.HasEth1WithdrawalCredentials() &&\n\t\tv.HasMaxEffectiveBalance(maxEffectiveBalance) && hasExcessBalance\n}\n\n// HasEth1WithdrawalCredentials as defined in the Ethereum 2.0 specification:\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/validator.md#eth1_address_withdrawal_prefix\nfunc (v Validator) HasEth1WithdrawalCredentials() bool {\n\treturn v.WithdrawalCredentials.IsValidEth1WithdrawalCredentials()\n}\n\n// HasExecutionWithdrawalCredential deviated from `has_execution_withdrawal_credential` by not checking for\n// compounding withdrawal credentials, i.e 0x02.\nfunc (v Validator) HasExecutionWithdrawalCredential() bool {\n\treturn v.HasEth1WithdrawalCredentials()\n}\n\n// HasMaxEffectiveBalance determines if the validator has the maximum effective\n// balance.\nfunc (v Validator) HasMaxEffectiveBalance(\n\tmaxEffectiveBalance math.Gwei,\n) bool {\n\treturn v.EffectiveBalance == maxEffectiveBalance\n}\n\n// SetEffectiveBalance sets the effective balance of the validator.\nfunc (v *Validator) SetEffectiveBalance(balance math.Gwei) {\n\tv.EffectiveBalance = balance\n}\n\nfunc (v *Validator) SetActivationEligibilityEpoch(e math.Epoch) {\n\tv.ActivationEligibilityEpoch = e\n}\n\nfunc (v *Validator) GetActivationEligibilityEpoch() math.Epoch {\n\treturn v.ActivationEligibilityEpoch\n}\n\nfunc (v *Validator) SetActivationEpoch(e math.Epoch) {\n\tv.ActivationEpoch = e\n}\n\nfunc (v *Validator) GetActivationEpoch() math.Epoch {\n\treturn v.ActivationEpoch\n}\n\nfunc (v *Validator) SetExitEpoch(e math.Epoch) {\n\tv.ExitEpoch = e\n}\n\nfunc (v Validator) GetExitEpoch() math.Epoch {\n\treturn v.ExitEpoch\n}\n\nfunc (v *Validator) SetWithdrawableEpoch(e math.Epoch) {\n\tv.WithdrawableEpoch = e\n}\n\nfunc (v Validator) GetWithdrawableEpoch() math.Epoch {\n\treturn v.WithdrawableEpoch\n}\n\n// GetWithdrawalCredentials returns the withdrawal credentials of the validator.\nfunc (v Validator) GetWithdrawalCredentials() WithdrawalCredentials {\n\treturn v.WithdrawalCredentials\n}\n\n// HasCompoundingWithdrawalCredential is equivalent to has_compounding_withdrawal_credential.\n// On Berachain, all validators are considered to be 'compounding' validators, regardless of whether\n// they have the '0x2' prefix. We introduce this for spec parity.\nfunc (v Validator) HasCompoundingWithdrawalCredential() bool {\n\treturn true\n}\n\n// Status returns the current validator status based on its set epoch values.\n// This function taken from Prysm:\n// https://github.com/prysmaticlabs/prysm/blob/0229a2055e6349655a471b2427f349e40c275cee/beacon-chain/rpc/eth/helpers/validator_status.go#L31\nfunc (v *Validator) Status(currentEpoch math.Epoch) (string, error) {\n\tactivationEpoch := v.GetActivationEpoch()\n\tactivationEligibilityEpoch := v.GetActivationEligibilityEpoch()\n\tfarFutureEpoch := constants.FarFutureEpoch\n\texitEpoch := v.GetExitEpoch()\n\twithdrawableEpoch := v.GetWithdrawableEpoch()\n\n\t// Status: pending\n\tif activationEpoch > currentEpoch {\n\t\tif activationEligibilityEpoch == farFutureEpoch {\n\t\t\treturn constants.ValidatorStatusPendingInitialized, nil\n\t\t} else if activationEligibilityEpoch < farFutureEpoch {\n\t\t\treturn constants.ValidatorStatusPendingQueued, nil\n\t\t}\n\t}\n\n\t// Status: active\n\tif activationEpoch <= currentEpoch && currentEpoch < exitEpoch {\n\t\tif exitEpoch == farFutureEpoch {\n\t\t\treturn constants.ValidatorStatusActiveOngoing, nil\n\t\t} else if exitEpoch < farFutureEpoch {\n\t\t\tif v.IsSlashed() {\n\t\t\t\treturn constants.ValidatorStatusActiveSlashed, nil\n\t\t\t}\n\t\t\treturn constants.ValidatorStatusActiveExiting, nil\n\t\t}\n\t}\n\n\t// Status: exited\n\tif exitEpoch <= currentEpoch && currentEpoch < withdrawableEpoch {\n\t\tif v.IsSlashed() {\n\t\t\treturn constants.ValidatorStatusExitedSlashed, nil\n\t\t}\n\t\treturn constants.ValidatorStatusExitedUnslashed, nil\n\t}\n\n\t// Status: withdrawal\n\tif withdrawableEpoch <= currentEpoch {\n\t\tif v.GetEffectiveBalance() != math.Gwei(0) {\n\t\t\treturn constants.ValidatorStatusWithdrawalPossible, nil\n\t\t}\n\t\treturn constants.ValidatorStatusWithdrawalDone, nil\n\t}\n\n\treturn \"\", ErrInvalidValidatorStatus\n}\n"
  },
  {
    "path": "consensus-types/types/validator_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tfastssz \"github.com/ferranbt/fastssz\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestNewValidatorFromDeposit(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname                      string\n\t\tpubkey                    crypto.BLSPubkey\n\t\twithdrawalCredentials     types.WithdrawalCredentials\n\t\tamount                    math.Gwei\n\t\teffectiveBalanceIncrement math.Gwei\n\t\tmaxEffectiveBalance       math.Gwei\n\t\twant                      *types.Validator\n\t}{\n\t\t{\n\t\t\tname:   \"normal case\",\n\t\t\tpubkey: [48]byte{0x01},\n\t\t\twithdrawalCredentials: types.\n\t\t\t\tNewCredentialsFromExecutionAddress(\n\t\t\t\t\tcommon.ExecutionAddress{0x01},\n\t\t\t\t),\n\t\t\tamount:                    32e9,\n\t\t\teffectiveBalanceIncrement: 1e9,\n\t\t\tmaxEffectiveBalance:       32e9,\n\t\t\twant: &types.Validator{\n\t\t\t\tPubkey: [48]byte{0x01},\n\t\t\t\tWithdrawalCredentials: types.\n\t\t\t\t\tNewCredentialsFromExecutionAddress(\n\t\t\t\t\t\tcommon.ExecutionAddress{0x01},\n\t\t\t\t\t),\n\t\t\t\tEffectiveBalance:           32e9,\n\t\t\t\tSlashed:                    false,\n\t\t\t\tActivationEligibilityEpoch: constants.FarFutureEpoch,\n\t\t\t\tActivationEpoch:            constants.FarFutureEpoch,\n\t\t\t\tExitEpoch:                  constants.FarFutureEpoch,\n\t\t\t\tWithdrawableEpoch:          constants.FarFutureEpoch,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"effective balance capped at max\",\n\t\t\tpubkey: [48]byte{0x02},\n\t\t\twithdrawalCredentials: types.\n\t\t\t\tNewCredentialsFromExecutionAddress(\n\t\t\t\t\tcommon.ExecutionAddress{0x02},\n\t\t\t\t),\n\t\t\tamount:                    40e9,\n\t\t\teffectiveBalanceIncrement: 1e9,\n\t\t\tmaxEffectiveBalance:       32e9,\n\t\t\twant: &types.Validator{\n\t\t\t\tPubkey: [48]byte{0x02},\n\t\t\t\tWithdrawalCredentials: types.\n\t\t\t\t\tNewCredentialsFromExecutionAddress(\n\t\t\t\t\t\tcommon.ExecutionAddress{0x02},\n\t\t\t\t\t),\n\t\t\t\tEffectiveBalance:           32e9,\n\t\t\t\tSlashed:                    false,\n\t\t\t\tActivationEligibilityEpoch: constants.FarFutureEpoch,\n\t\t\t\tActivationEpoch:            constants.FarFutureEpoch,\n\t\t\t\tExitEpoch:                  constants.FarFutureEpoch,\n\t\t\t\tWithdrawableEpoch:          constants.FarFutureEpoch,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"effective balance rounded down\",\n\t\t\tpubkey: [48]byte{0x03},\n\t\t\twithdrawalCredentials: types.\n\t\t\t\tNewCredentialsFromExecutionAddress(\n\t\t\t\t\tcommon.ExecutionAddress{0x03},\n\t\t\t\t),\n\t\t\tamount:                    32.5e9,\n\t\t\teffectiveBalanceIncrement: 1e9,\n\t\t\tmaxEffectiveBalance:       32e9,\n\t\t\twant: &types.Validator{\n\t\t\t\tPubkey: [48]byte{0x03},\n\t\t\t\tWithdrawalCredentials: types.\n\t\t\t\t\tNewCredentialsFromExecutionAddress(\n\t\t\t\t\t\tcommon.ExecutionAddress{0x03},\n\t\t\t\t\t),\n\t\t\t\tEffectiveBalance:           32e9,\n\t\t\t\tSlashed:                    false,\n\t\t\t\tActivationEligibilityEpoch: constants.FarFutureEpoch,\n\t\t\t\tActivationEpoch:            constants.FarFutureEpoch,\n\t\t\t\tExitEpoch:                  constants.FarFutureEpoch,\n\t\t\t\tWithdrawableEpoch:          constants.FarFutureEpoch,\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot := types.NewValidatorFromDeposit(\n\t\t\t\ttt.pubkey,\n\t\t\t\ttt.withdrawalCredentials,\n\t\t\t\ttt.amount,\n\t\t\t\ttt.effectiveBalanceIncrement,\n\t\t\t\ttt.maxEffectiveBalance,\n\t\t\t)\n\t\t\trequire.Equal(t, tt.want, got)\n\t\t})\n\t}\n}\n\nfunc TestValidator_IsActive(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname      string\n\t\tepoch     math.Epoch\n\t\tvalidator *types.Validator\n\t\twant      bool\n\t}{\n\t\t{\n\t\t\tname:  \"active\",\n\t\t\tepoch: 10,\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tActivationEpoch: 5,\n\t\t\t\tExitEpoch:       15,\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname:  \"not active, before activation\",\n\t\t\tepoch: 4,\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tActivationEpoch: 5,\n\t\t\t\tExitEpoch:       15,\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tname:  \"not active, after exit\",\n\t\t\tepoch: 16,\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tActivationEpoch: 5,\n\t\t\t\tExitEpoch:       15,\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\trequire.Equal(t, tt.want, tt.validator.IsActive(tt.epoch))\n\t\t})\n\t}\n}\n\nfunc TestValidator_IsEligibleForActivation(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname           string\n\t\tfinalizedEpoch math.Epoch\n\t\tvalidator      *types.Validator\n\t\twant           bool\n\t}{\n\t\t{\n\t\t\tname:           \"eligible\",\n\t\t\tfinalizedEpoch: 10,\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tActivationEligibilityEpoch: 5,\n\t\t\t\tActivationEpoch:            constants.FarFutureEpoch,\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname:           \"not eligible, activation eligibility in future\",\n\t\t\tfinalizedEpoch: 4,\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tActivationEligibilityEpoch: 5,\n\t\t\t\tActivationEpoch:            constants.FarFutureEpoch,\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tname:           \"not eligible, already activated\",\n\t\t\tfinalizedEpoch: 10,\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tActivationEligibilityEpoch: 5,\n\t\t\t\tActivationEpoch:            8,\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\trequire.Equal(\n\t\t\t\tt,\n\t\t\t\ttt.want,\n\t\t\t\ttt.validator.IsEligibleForActivation(tt.finalizedEpoch),\n\t\t\t)\n\t\t})\n\t}\n}\n\nfunc TestValidator_IsEligibleForActivationQueue(t *testing.T) {\n\tt.Parallel()\n\tmaxEffectiveBalance := math.Gwei(32e9)\n\ttests := []struct {\n\t\tname      string\n\t\tvalidator *types.Validator\n\t\twant      bool\n\t}{\n\t\t{\n\t\t\tname: \"eligible\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tActivationEligibilityEpoch: constants.FarFutureEpoch,\n\t\t\t\tEffectiveBalance:           maxEffectiveBalance,\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname: \"not eligible, activation eligibility set\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tActivationEligibilityEpoch: 5,\n\t\t\t\tEffectiveBalance:           maxEffectiveBalance,\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tname: \"not eligible, effective balance too low\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tActivationEligibilityEpoch: constants.FarFutureEpoch,\n\t\t\t\tEffectiveBalance:           maxEffectiveBalance - 1,\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\trequire.Equal(\n\t\t\t\tt,\n\t\t\t\ttt.want,\n\t\t\t\ttt.validator.IsEligibleForActivationQueue(maxEffectiveBalance),\n\t\t\t)\n\t\t})\n\t}\n}\n\nfunc TestValidator_IsSlashable(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname      string\n\t\tepoch     math.Epoch\n\t\tvalidator *types.Validator\n\t\twant      bool\n\t}{\n\t\t{\n\t\t\tname:  \"slashable\",\n\t\t\tepoch: 10,\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tSlashed:           false,\n\t\t\t\tActivationEpoch:   5,\n\t\t\t\tWithdrawableEpoch: 15,\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname:  \"not slashable, already slashed\",\n\t\t\tepoch: 10,\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tSlashed:           true,\n\t\t\t\tActivationEpoch:   5,\n\t\t\t\tWithdrawableEpoch: 15,\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tname:  \"not slashable, before activation\",\n\t\t\tepoch: 4,\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tSlashed:           false,\n\t\t\t\tActivationEpoch:   5,\n\t\t\t\tWithdrawableEpoch: 15,\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tname:  \"not slashable, after withdrawable\",\n\t\t\tepoch: 16,\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tSlashed:           false,\n\t\t\t\tActivationEpoch:   5,\n\t\t\t\tWithdrawableEpoch: 15,\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\trequire.Equal(t, tt.want, tt.validator.IsSlashable(tt.epoch))\n\t\t})\n\t}\n}\n\nfunc TestValidator_IsFullyWithdrawable(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname      string\n\t\tbalance   math.Gwei\n\t\tepoch     math.Epoch\n\t\tvalidator *types.Validator\n\t\twant      bool\n\t}{\n\t\t{\n\t\t\tname:    \"fully withdrawable\",\n\t\t\tbalance: 32e9,\n\t\t\tepoch:   10,\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tWithdrawalCredentials: types.\n\t\t\t\t\tNewCredentialsFromExecutionAddress(\n\t\t\t\t\t\tcommon.ExecutionAddress{0x01},\n\t\t\t\t\t),\n\t\t\t\tWithdrawableEpoch: 5,\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"not fully withdrawable, non-eth1 credentials\",\n\t\t\tbalance: 32e9,\n\t\t\tepoch:   10,\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tWithdrawalCredentials: types.\n\t\t\t\t\tWithdrawalCredentials{0x00},\n\t\t\t\tWithdrawableEpoch: 5,\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"not fully withdrawable, before withdrawable epoch\",\n\t\t\tbalance: 32e9,\n\t\t\tepoch:   4,\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tWithdrawalCredentials: types.\n\t\t\t\t\tNewCredentialsFromExecutionAddress(\n\t\t\t\t\t\tcommon.ExecutionAddress{0x01},\n\t\t\t\t\t),\n\t\t\t\tWithdrawableEpoch: 5,\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"not fully withdrawable, zero balance\",\n\t\t\tbalance: 0,\n\t\t\tepoch:   10,\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tWithdrawalCredentials: types.\n\t\t\t\t\tNewCredentialsFromExecutionAddress(\n\t\t\t\t\t\tcommon.ExecutionAddress{0x01},\n\t\t\t\t\t),\n\t\t\t\tWithdrawableEpoch: 5,\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\trequire.Equal(\n\t\t\t\tt,\n\t\t\t\ttt.want,\n\t\t\t\ttt.validator.IsFullyWithdrawable(tt.balance, tt.epoch),\n\t\t\t)\n\t\t})\n\t}\n}\n\nfunc TestValidator_IsPartiallyWithdrawable(t *testing.T) {\n\tt.Parallel()\n\tmaxEffectiveBalance := math.Gwei(32e9)\n\ttests := []struct {\n\t\tname      string\n\t\tbalance   math.Gwei\n\t\tvalidator *types.Validator\n\t\twant      bool\n\t}{\n\t\t{\n\t\t\tname:    \"partially withdrawable\",\n\t\t\tbalance: 33e9,\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tWithdrawalCredentials: types.\n\t\t\t\t\tNewCredentialsFromExecutionAddress(\n\t\t\t\t\t\tcommon.ExecutionAddress{0x01},\n\t\t\t\t\t),\n\t\t\t\tEffectiveBalance: maxEffectiveBalance,\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"not partially withdrawable, non-eth1 credentials\",\n\t\t\tbalance: 33e9,\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tWithdrawalCredentials: types.WithdrawalCredentials{\n\t\t\t\t\t0x00,\n\t\t\t\t},\n\t\t\t\tEffectiveBalance: maxEffectiveBalance,\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"not partially withdrawable, not at max effective balance\",\n\t\t\tbalance: 33e9,\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tWithdrawalCredentials: types.\n\t\t\t\t\tNewCredentialsFromExecutionAddress(\n\t\t\t\t\t\tcommon.ExecutionAddress{0x01},\n\t\t\t\t\t),\n\t\t\t\tEffectiveBalance: maxEffectiveBalance - 1,\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"not partially withdrawable, no excess balance\",\n\t\t\tbalance: 32e9,\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tWithdrawalCredentials: types.\n\t\t\t\t\tNewCredentialsFromExecutionAddress(\n\t\t\t\t\t\tcommon.ExecutionAddress{0x01},\n\t\t\t\t\t),\n\t\t\t\tEffectiveBalance: maxEffectiveBalance,\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\trequire.Equal(\n\t\t\t\tt,\n\t\t\t\ttt.want,\n\t\t\t\ttt.validator.IsPartiallyWithdrawable(\n\t\t\t\t\ttt.balance,\n\t\t\t\t\tmaxEffectiveBalance,\n\t\t\t\t),\n\t\t\t)\n\t\t})\n\t}\n}\n\nfunc TestValidator_HasEth1WithdrawalCredentials(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname      string\n\t\tvalidator *types.Validator\n\t\twant      bool\n\t}{\n\t\t{\n\t\t\tname: \"has eth1 credentials\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tWithdrawalCredentials: types.\n\t\t\t\t\tNewCredentialsFromExecutionAddress(\n\t\t\t\t\t\tcommon.ExecutionAddress{0x01},\n\t\t\t\t\t),\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname: \"does not have eth1 credentials\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tWithdrawalCredentials: types.WithdrawalCredentials{\n\t\t\t\t\t0x00,\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\trequire.Equal(\n\t\t\t\tt,\n\t\t\t\ttt.want,\n\t\t\t\ttt.validator.HasEth1WithdrawalCredentials(),\n\t\t\t)\n\t\t})\n\t}\n}\n\nfunc TestValidator_HasMaxEffectiveBalance(t *testing.T) {\n\tt.Parallel()\n\tmaxEffectiveBalance := math.Gwei(32e9)\n\ttests := []struct {\n\t\tname      string\n\t\tvalidator *types.Validator\n\t\twant      bool\n\t}{\n\t\t{\n\t\t\tname: \"has max effective balance\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tEffectiveBalance: maxEffectiveBalance,\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname: \"does not have max effective balance\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tEffectiveBalance: maxEffectiveBalance - 1,\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\trequire.Equal(\n\t\t\t\tt,\n\t\t\t\ttt.want,\n\t\t\t\ttt.validator.HasMaxEffectiveBalance(maxEffectiveBalance),\n\t\t\t)\n\t\t})\n\t}\n}\n\nfunc TestValidator_MarshalUnmarshalSSZ(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname       string\n\t\tvalidator  *types.Validator\n\t\tinvalidSSZ bool\n\t}{\n\t\t{\n\t\t\tname: \"normal case\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tPubkey: [48]byte{0x01},\n\t\t\t\tWithdrawalCredentials: types.\n\t\t\t\t\tNewCredentialsFromExecutionAddress(\n\t\t\t\t\t\tcommon.ExecutionAddress{0x01},\n\t\t\t\t\t),\n\t\t\t\tEffectiveBalance:           32e9,\n\t\t\t\tSlashed:                    false,\n\t\t\t\tActivationEligibilityEpoch: constants.FarFutureEpoch,\n\t\t\t\tActivationEpoch:            constants.FarFutureEpoch,\n\t\t\t\tExitEpoch:                  constants.FarFutureEpoch,\n\t\t\t\tWithdrawableEpoch:          constants.FarFutureEpoch,\n\t\t\t},\n\t\t\tinvalidSSZ: false,\n\t\t},\n\t\t{\n\t\t\tname: \"slashed validator\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tPubkey: [48]byte{0x02},\n\t\t\t\tWithdrawalCredentials: types.\n\t\t\t\t\tNewCredentialsFromExecutionAddress(\n\t\t\t\t\t\tcommon.ExecutionAddress{0x02},\n\t\t\t\t\t),\n\t\t\t\tEffectiveBalance:           32e9,\n\t\t\t\tSlashed:                    true,\n\t\t\t\tActivationEligibilityEpoch: 5,\n\t\t\t\tActivationEpoch:            6,\n\t\t\t\tExitEpoch:                  10,\n\t\t\t\tWithdrawableEpoch:          15,\n\t\t\t},\n\t\t\tinvalidSSZ: false,\n\t\t},\n\t\t{\n\t\t\tname: \"validator with zero balance\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tPubkey: [48]byte{0x03},\n\t\t\t\tWithdrawalCredentials: types.\n\t\t\t\t\tNewCredentialsFromExecutionAddress(\n\t\t\t\t\t\tcommon.ExecutionAddress{0x03},\n\t\t\t\t\t),\n\t\t\t\tEffectiveBalance:           0,\n\t\t\t\tSlashed:                    false,\n\t\t\t\tActivationEligibilityEpoch: constants.FarFutureEpoch,\n\t\t\t\tActivationEpoch:            constants.FarFutureEpoch,\n\t\t\t\tExitEpoch:                  constants.FarFutureEpoch,\n\t\t\t\tWithdrawableEpoch:          constants.FarFutureEpoch,\n\t\t\t},\n\t\t\tinvalidSSZ: false,\n\t\t},\n\t\t{\n\t\t\tname: \"validator with non-default epochs\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tPubkey: [48]byte{0x04},\n\t\t\t\tWithdrawalCredentials: types.\n\t\t\t\t\tNewCredentialsFromExecutionAddress(\n\t\t\t\t\t\tcommon.ExecutionAddress{0x04},\n\t\t\t\t\t),\n\t\t\t\tEffectiveBalance:           16e9,\n\t\t\t\tSlashed:                    false,\n\t\t\t\tActivationEligibilityEpoch: 10,\n\t\t\t\tActivationEpoch:            12,\n\t\t\t\tExitEpoch:                  20,\n\t\t\t\tWithdrawableEpoch:          25,\n\t\t\t},\n\t\t\tinvalidSSZ: false,\n\t\t},\n\t\t{\n\t\t\tname:       \"invalid SSZ size\",\n\t\t\tvalidator:  &types.Validator{},\n\t\t\tinvalidSSZ: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tif tt.invalidSSZ {\n\t\t\t\t// Create a byte slice with an invalid size (not 121)\n\t\t\t\tinvalidSizeData := make([]byte, 120)\n\t\t\t\tunmarshalled := new(types.Validator)\n\t\t\t\terr := ssz.Unmarshal(invalidSizeData, unmarshalled)\n\t\t\t\trequire.ErrorIs(t, err, io.ErrUnexpectedEOF, \"Test case: %s\", tt.name)\n\t\t\t} else {\n\t\t\t\t// Marshal the validator\n\t\t\t\tmarshaled, err := tt.validator.MarshalSSZ()\n\t\t\t\trequire.NoError(t, err)\n\n\t\t\t\t// Unmarshal into a new validator\n\t\t\t\tunmarshalled := new(types.Validator)\n\t\t\t\terr = ssz.Unmarshal(marshaled, unmarshalled)\n\t\t\t\trequire.NoError(t, err)\n\n\t\t\t\t// Check if the original and unmarshaled validators are equal\n\t\t\t\trequire.Equal(\n\t\t\t\t\tt,\n\t\t\t\t\ttt.validator,\n\t\t\t\t\tunmarshalled,\n\t\t\t\t\t\"Test case: %s\",\n\t\t\t\t\ttt.name,\n\t\t\t\t)\n\n\t\t\t\tvar buf []byte\n\t\t\t\tbuf, err = tt.validator.MarshalSSZTo(buf)\n\t\t\t\trequire.NoError(t, err)\n\n\t\t\t\t// The two byte slices should be equal\n\t\t\t\trequire.Equal(t, marshaled, buf)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestValidator_HashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname      string\n\t\tvalidator *types.Validator\n\t}{\n\t\t{\n\t\t\tname: \"normal case\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tPubkey: [48]byte{0x01},\n\t\t\t\tWithdrawalCredentials: types.\n\t\t\t\t\tNewCredentialsFromExecutionAddress(\n\t\t\t\t\t\tcommon.ExecutionAddress{0x01},\n\t\t\t\t\t),\n\t\t\t\tEffectiveBalance:           32e9,\n\t\t\t\tSlashed:                    false,\n\t\t\t\tActivationEligibilityEpoch: constants.FarFutureEpoch,\n\t\t\t\tActivationEpoch:            constants.FarFutureEpoch,\n\t\t\t\tExitEpoch:                  constants.FarFutureEpoch,\n\t\t\t\tWithdrawableEpoch:          constants.FarFutureEpoch,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"slashed validator\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tPubkey: [48]byte{0x02},\n\t\t\t\tWithdrawalCredentials: types.\n\t\t\t\t\tNewCredentialsFromExecutionAddress(\n\t\t\t\t\t\tcommon.ExecutionAddress{0x02},\n\t\t\t\t\t),\n\t\t\t\tEffectiveBalance:           32e9,\n\t\t\t\tSlashed:                    true,\n\t\t\t\tActivationEligibilityEpoch: 5,\n\t\t\t\tActivationEpoch:            6,\n\t\t\t\tExitEpoch:                  10,\n\t\t\t\tWithdrawableEpoch:          15,\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\t// Test HashTreeRoot\n\t\t\troot := tt.validator.HashTreeRoot()\n\t\t\trequire.NotEqual(t, [32]byte{}, root)\n\n\t\t\t// Test HashTreeRootWith\n\t\t\thh := fastssz.NewHasher()\n\t\t\terr := tt.validator.HashTreeRootWith(hh)\n\t\t\trequire.NoError(t, err)\n\n\t\t\t// Test GetTree\n\t\t\ttree, err := tt.validator.GetTree()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.NotNil(t, tree)\n\t\t})\n\t}\n}\n\nfunc TestValidator_SetEffectiveBalance(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname      string\n\t\tbalance   math.Gwei\n\t\tvalidator *types.Validator\n\t\twant      math.Gwei\n\t}{\n\t\t{\n\t\t\tname:    \"set effective balance\",\n\t\t\tbalance: 32e9,\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tEffectiveBalance: 0,\n\t\t\t},\n\t\t\twant: 32e9,\n\t\t},\n\t\t{\n\t\t\tname:    \"update effective balance\",\n\t\t\tbalance: 16e9,\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tEffectiveBalance: 32e9,\n\t\t\t},\n\t\t\twant: 16e9,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\ttt.validator.SetEffectiveBalance(tt.balance)\n\t\t\trequire.Equal(t, tt.want, tt.validator.EffectiveBalance,\n\t\t\t\t\"Test case: %s\", tt.name)\n\t\t})\n\t}\n}\n\nfunc TestValidator_GetWithdrawableEpoch(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname      string\n\t\tvalidator *types.Validator\n\t\twant      math.Epoch\n\t}{\n\t\t{\n\t\t\tname: \"get withdrawable epoch\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tWithdrawableEpoch: 10,\n\t\t\t},\n\t\t\twant: 10,\n\t\t},\n\t\t{\n\t\t\tname: \"get far future withdrawable epoch\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tWithdrawableEpoch: constants.FarFutureEpoch,\n\t\t\t},\n\t\t\twant: constants.FarFutureEpoch,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot := tt.validator.GetWithdrawableEpoch()\n\t\t\trequire.Equal(t, tt.want, got, \"Test case: %s\", tt.name)\n\t\t})\n\t}\n}\n\nfunc TestValidator_GetWithdrawalCredentials(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname      string\n\t\tvalidator *types.Validator\n\t\twant      types.WithdrawalCredentials\n\t}{\n\t\t{\n\t\t\tname: \"get withdrawal credentials\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tWithdrawalCredentials: types.\n\t\t\t\t\tNewCredentialsFromExecutionAddress(\n\t\t\t\t\t\tcommon.ExecutionAddress{0x01},\n\t\t\t\t\t),\n\t\t\t},\n\t\t\twant: types.NewCredentialsFromExecutionAddress(\n\t\t\t\tcommon.ExecutionAddress{0x01},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tname: \"get empty withdrawal credentials\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tWithdrawalCredentials: types.WithdrawalCredentials{0x00},\n\t\t\t},\n\t\t\twant: types.WithdrawalCredentials{0x00},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot := tt.validator.GetWithdrawalCredentials()\n\t\t\trequire.Equal(t, tt.want, got, \"Test case: %s\", tt.name)\n\t\t})\n\t}\n}\n\nfunc TestValidator_IsSlashed(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname      string\n\t\tvalidator *types.Validator\n\t\twant      bool\n\t}{\n\t\t{\n\t\t\tname: \"validator is slashed\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tSlashed: true,\n\t\t\t},\n\t\t\twant: true,\n\t\t},\n\t\t{\n\t\t\tname: \"validator is not slashed\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tSlashed: false,\n\t\t\t},\n\t\t\twant: false,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot := tt.validator.IsSlashed()\n\t\t\trequire.Equal(t, tt.want, got, \"Test case: %s\", tt.name)\n\t\t})\n\t}\n}\n\nfunc TestValidator_GetPubkey(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname      string\n\t\tvalidator *types.Validator\n\t\twant      crypto.BLSPubkey\n\t}{\n\t\t{\n\t\t\tname: \"get pubkey\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tPubkey: [48]byte{0x01},\n\t\t\t},\n\t\t\twant: [48]byte{0x01},\n\t\t},\n\t\t{\n\t\t\tname: \"get pubkey with multiple bytes\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tPubkey: [48]byte{0x01, 0x02, 0x03},\n\t\t\t},\n\t\t\twant: [48]byte{0x01, 0x02, 0x03},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot := tt.validator.GetPubkey()\n\t\t\trequire.Equal(t, tt.want, got, \"Test case: %s\", tt.name)\n\t\t})\n\t}\n}\n\nfunc TestValidator_GetEffectiveBalance(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname      string\n\t\tvalidator *types.Validator\n\t\twant      math.Gwei\n\t}{\n\t\t{\n\t\t\tname: \"get effective balance\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tEffectiveBalance: 32e9,\n\t\t\t},\n\t\t\twant: 32e9,\n\t\t},\n\t\t{\n\t\t\tname: \"get zero effective balance\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tEffectiveBalance: 0,\n\t\t\t},\n\t\t\twant: 0,\n\t\t},\n\t\t{\n\t\t\tname: \"get maximum effective balance\",\n\t\t\tvalidator: &types.Validator{\n\t\t\t\tEffectiveBalance: math.Gwei(1<<64 - 1),\n\t\t\t},\n\t\t\twant: math.Gwei(1<<64 - 1),\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot := tt.validator.GetEffectiveBalance()\n\t\t\trequire.Equal(t, tt.want, got, \"Test case: %s\", tt.name)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "consensus-types/types/validators.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//nolint:dupl // False positive detected.\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// Validators is a type alias for a SSZ list of Validator containers.\ntype Validators []*Validator\n\n// SizeSSZ returns the SSZ encoded size in bytes for the Validators.\nfunc (vs Validators) SizeSSZ(siz *ssz.Sizer, _ bool) uint32 {\n\treturn ssz.SizeSliceOfStaticObjects(siz, ([]*Validator)(vs))\n}\n\n// DefineSSZ defines the SSZ encoding for the Validators object.\n// TODO: get from accessible chainspec field params.\nfunc (vs Validators) DefineSSZ(c *ssz.Codec) {\n\tc.DefineDecoder(func(*ssz.Decoder) {\n\t\tssz.DefineSliceOfStaticObjectsContent(\n\t\t\tc, (*[]*Validator)(&vs), constants.ValidatorsRegistryLimit)\n\t})\n\tc.DefineEncoder(func(*ssz.Encoder) {\n\t\tssz.DefineSliceOfStaticObjectsContent(\n\t\t\tc, (*[]*Validator)(&vs), constants.ValidatorsRegistryLimit)\n\t})\n\n\tc.DefineHasher(func(*ssz.Hasher) {\n\t\tssz.DefineSliceOfStaticObjectsOffset(\n\t\t\tc, (*[]*Validator)(&vs), constants.ValidatorsRegistryLimit)\n\t})\n}\n\n// HashTreeRoot returns the SSZ hash tree root for the Validators object.\nfunc (vs Validators) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(vs)\n}\n"
  },
  {
    "path": "consensus-types/types/versionable.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n)\n\n// versionable is a helper struct that implements the Versionable interface.\ntype versionable struct {\n\tforkVersion common.Version\n}\n\n// NewVersionable creates a new versionable object.\nfunc NewVersionable(forkVersion common.Version) constraints.Versionable {\n\treturn &versionable{forkVersion: forkVersion}\n}\n\n// GetForkVersion returns the fork version of the versionable object.\nfunc (v *versionable) GetForkVersion() common.Version {\n\treturn v.forkVersion\n}\n"
  },
  {
    "path": "consensus-types/types/voluntary_exits.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//nolint:dupl // separate file for ease of future implementation\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// Compile-time assertions to ensure VoluntaryExit implements necessary interfaces.\nvar (\n\t_ ssz.StaticObject                    = (*VoluntaryExit)(nil)\n\t_ constraints.SSZMarshallableRootable = (*VoluntaryExit)(nil)\n\t_ common.UnusedEnforcer               = (*VoluntaryExits)(nil)\n)\n\ntype (\n\tVoluntaryExit  = common.UnusedType\n\tVoluntaryExits []*VoluntaryExit\n)\n\n// SizeSSZ returns the SSZ encoded size in bytes for the VoluntaryExits.\nfunc (vs VoluntaryExits) SizeSSZ(siz *ssz.Sizer, _ bool) uint32 {\n\treturn ssz.SizeSliceOfStaticObjects(siz, vs)\n}\n\n// DefineSSZ defines the SSZ encoding for the VoluntaryExits object.\nfunc (vs VoluntaryExits) DefineSSZ(c *ssz.Codec) {\n\tc.DefineDecoder(func(*ssz.Decoder) {\n\t\tssz.DefineSliceOfStaticObjectsContent(c, (*[]*VoluntaryExit)(&vs), constants.MaxVoluntaryExits)\n\t})\n\tc.DefineEncoder(func(*ssz.Encoder) {\n\t\tssz.DefineSliceOfStaticObjectsContent(c, (*[]*VoluntaryExit)(&vs), constants.MaxVoluntaryExits)\n\t})\n\tc.DefineHasher(func(*ssz.Hasher) {\n\t\tssz.DefineSliceOfStaticObjectsOffset(c, (*[]*VoluntaryExit)(&vs), constants.MaxVoluntaryExits)\n\t})\n}\n\n// HashTreeRoot returns the hash tree root of the VoluntaryExits.\nfunc (vs VoluntaryExits) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(vs)\n}\n\n// EnforceUnused return true if the length of the VoluntaryExits is 0.\n// As long as this type remains unimplemented and unvalidated by consensus,\n// we must enforce that it contains no data.\nfunc (vs VoluntaryExits) EnforceUnused() error {\n\tif len(vs) != 0 {\n\t\treturn errors.New(\"VoluntaryExits must be unused\")\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "consensus-types/types/withdrawal_credentials.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\npackage types\n\nimport (\n\t\"bytes\"\n\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n)\n\nconst (\n\t// EthSecp256k1CredentialPrefix is the prefix for an Ethereum secp256k1.\n\tEthSecp256k1CredentialPrefix = byte(1)\n\n\t// numZeroBytesInEth1WithdrawalCredentials is the number of zero bytes in a valid eth1\n\t// withdrawal credentials.\n\tnumZeroBytesInEth1WithdrawalCredentials = 11\n)\n\n// WithdrawalCredentials is a staking credential that is used to identify a validator.\ntype WithdrawalCredentials common.Bytes32\n\n// NewCredentialsFromExecutionAddress creates a new valid Eth1 WithdrawalCredentials\n// from an execution address.\nfunc NewCredentialsFromExecutionAddress(address common.ExecutionAddress) WithdrawalCredentials {\n\tcredentials := WithdrawalCredentials{}\n\tcredentials[0] = EthSecp256k1CredentialPrefix\n\tcopy(credentials[12:], address[:])\n\treturn credentials\n}\n\n// IsValidEth1WithdrawalCredentials checks if the withdrawal credentials are valid\n// eth1 withdrawal credentials as defined in the Ethereum 2.0 specification:\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/validator.md#eth1_address_withdrawal_prefix\nfunc (wc WithdrawalCredentials) IsValidEth1WithdrawalCredentials() bool {\n\tzeroBytes := make([]byte, numZeroBytesInEth1WithdrawalCredentials)\n\treturn wc[0] == EthSecp256k1CredentialPrefix && bytes.Equal(wc[1:12], zeroBytes)\n}\n\n// ToExecutionAddress converts the WithdrawalCredentials to an ExecutionAddress.\n// Returns error if the withdrawal credentials are not valid.\nfunc (wc WithdrawalCredentials) ToExecutionAddress() (common.ExecutionAddress, error) {\n\tif !wc.IsValidEth1WithdrawalCredentials() {\n\t\treturn common.ExecutionAddress{}, ErrInvalidWithdrawalCredentials\n\t}\n\treturn common.ExecutionAddress(wc[12:]), nil\n}\n\n// UnmarshalJSON implements the json.Unmarshaler interface for Bytes32.\n// TODO: Figure out how to not have to do this.\nfunc (wc *WithdrawalCredentials) UnmarshalJSON(input []byte) error {\n\treturn (*common.Bytes32)(wc).UnmarshalJSON(input)\n}\n\n// String returns the hex string representation of Bytes32.\n// TODO: Figure out how to not have to do this.\nfunc (wc WithdrawalCredentials) String() string {\n\treturn common.Bytes32(wc).String()\n}\n\n// MarshalText implements the encoding.TextMarshaler interface for Bytes32.\n// TODO: Figure out how to not have to do this.\nfunc (wc WithdrawalCredentials) MarshalText() ([]byte, error) {\n\treturn common.Bytes32(wc).MarshalText()\n}\n\n// UnmarshalText implements the encoding.TextUnmarshaler interface for Bytes32.\n// TODO: Figure out how to not have to do this.\nfunc (wc *WithdrawalCredentials) UnmarshalText(text []byte) error {\n\treturn (*common.Bytes32)(wc).UnmarshalText(text)\n}\n"
  },
  {
    "path": "consensus-types/types/withdrawal_credentials_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"testing\"\n\n\ttypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestNewCredentialsFromExecutionAddress(t *testing.T) {\n\tt.Parallel()\n\taddress := common.ExecutionAddress{0xde, 0xad, 0xbe, 0xef}\n\texpectedCredentials := types.WithdrawalCredentials{}\n\texpectedCredentials[0] = 0x01 // EthSecp256k1CredentialPrefix\n\tcopy(expectedCredentials[12:], address[:])\n\tfor i := 1; i < 12; i++ {\n\t\texpectedCredentials[i] = 0x00\n\t}\n\trequire.Len(\n\t\tt,\n\t\texpectedCredentials,\n\t\t32,\n\t\t\"Expected credentials to be 32 bytes long\",\n\t)\n\trequire.Equal(\n\t\tt,\n\t\tbyte(0x01),\n\t\texpectedCredentials[0],\n\t\t\"Expected prefix to be 0x01\",\n\t)\n\trequire.Equal(\n\t\tt,\n\t\taddress,\n\t\tcommon.ExecutionAddress(expectedCredentials[12:]),\n\t\t\"Expected address to be set correctly\",\n\t)\n\tcredentials := types.\n\t\tNewCredentialsFromExecutionAddress(address)\n\trequire.Equal(\n\t\tt,\n\t\texpectedCredentials,\n\t\tcredentials,\n\t\t\"Generated credentials do not match expected\",\n\t)\n}\n\nfunc TestIsValidEth1WithdrawalCredentials(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\twc       types.WithdrawalCredentials\n\t\texpected bool\n\t}{\n\t\t{\n\t\t\tname: \"valid eth1 withdrawal credentials\",\n\t\t\twc: func() types.WithdrawalCredentials {\n\t\t\t\twc := types.WithdrawalCredentials{}\n\t\t\t\twc[0] = types.EthSecp256k1CredentialPrefix\n\t\t\t\t// bytes 1-11 should be zero\n\t\t\t\tfor i := 1; i < 12; i++ {\n\t\t\t\t\twc[i] = 0x00\n\t\t\t\t}\n\t\t\t\t// rest can be any value\n\t\t\t\taddr := common.ExecutionAddress{0xde, 0xad, 0xbe, 0xef}\n\t\t\t\tcopy(wc[12:], addr[:])\n\t\t\t\treturn wc\n\t\t\t}(),\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname: \"invalid prefix\",\n\t\t\twc: func() types.WithdrawalCredentials {\n\t\t\t\twc := types.WithdrawalCredentials{}\n\t\t\t\twc[0] = 0x02 // wrong prefix\n\t\t\t\treturn wc\n\t\t\t}(),\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname: \"non-zero padding bytes\",\n\t\t\twc: func() types.WithdrawalCredentials {\n\t\t\t\twc := types.WithdrawalCredentials{}\n\t\t\t\twc[0] = types.EthSecp256k1CredentialPrefix\n\t\t\t\twc[5] = 0x01 // non-zero byte in padding area\n\t\t\t\treturn wc\n\t\t\t}(),\n\t\t\texpected: false,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := tt.wc.IsValidEth1WithdrawalCredentials()\n\t\t\trequire.Equal(t, tt.expected, result,\n\t\t\t\t\"Test case %s\", tt.name)\n\t\t})\n\t}\n}\n\nfunc TestToExecutionAddress(t *testing.T) {\n\tt.Parallel()\n\texpectedAddress := common.ExecutionAddress{0xde, 0xad, 0xbe, 0xef}\n\tcredentials := types.WithdrawalCredentials{}\n\tfor i := range credentials {\n\t\t// First byte should be 0x01\n\t\tswitch {\n\t\tcase i == 0:\n\t\t\tcredentials[i] = 0x01 // EthSecp256k1CredentialPrefix\n\t\tcase i > 0 && i < 12:\n\t\t\tcredentials[i] = 0x00 // then we have 11 bytes of padding\n\t\tdefault:\n\t\t\tcredentials[i] = expectedAddress[i-12] // then the address\n\t\t}\n\t}\n\n\taddress, err := credentials.ToExecutionAddress()\n\trequire.NoError(t, err,\n\t\t\"Conversion to execution address should not error\")\n\trequire.Equal(\n\t\tt,\n\t\texpectedAddress,\n\t\taddress,\n\t\t\"Converted address does not match expected\",\n\t)\n}\n\nfunc TestToExecutionAddress_InvalidPrefix(t *testing.T) {\n\tt.Parallel()\n\tcredentials := types.WithdrawalCredentials{}\n\tfor i := range credentials {\n\t\tcredentials[i] = 0x00 // Invalid prefix\n\t}\n\n\t_, err := credentials.ToExecutionAddress()\n\n\trequire.Error(t, err, \"Expected an error due to invalid prefix\")\n}\n\nfunc TestWithdrawalCredentials_UnmarshalJSON(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected types.WithdrawalCredentials\n\t\twantErr  bool\n\t}{\n\t\t{\n\t\t\tname: \"valid JSON\",\n\t\t\tinput: `\"0x0100000000000000000000000000000` +\n\t\t\t\t`000000000000000000000000000000000\"`,\n\t\t\texpected: types.WithdrawalCredentials{0x01},\n\t\t\twantErr:  false,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid JSON\",\n\t\t\tinput:   `\"invalid\"`,\n\t\t\twantErr: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar wc types.WithdrawalCredentials\n\n\t\t\terr := wc.UnmarshalJSON([]byte(tt.input))\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err, \"Test case %s\", tt.name)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err, \"Test case %s\", tt.name)\n\t\t\t\trequire.Equal(t, tt.expected, wc, \"Test case %s\", tt.name)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestWithdrawalCredentials_String(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\twc       types.WithdrawalCredentials\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tname: \"valid string\",\n\t\t\twc:   types.WithdrawalCredentials{0x01},\n\t\t\texpected: \"0x010000000000000000000000000000\" +\n\t\t\t\t\"0000000000000000000000000000000000\",\n\t\t},\n\t\t{\n\t\t\tname: \"valid string with full address\",\n\t\t\twc: types.WithdrawalCredentials{0x01, 0xde, 0xad, 0xbe, 0xef, 0x00,\n\t\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t\t\t\t0x00, 0x00, 0x00, 0x00},\n\t\t\texpected: \"0x01deadbeef00000000000000000000000\" +\n\t\t\t\t\"0000000000000000000000000000000\",\n\t\t},\n\t\t{\n\t\t\tname: \"empty credentials\",\n\t\t\twc:   types.WithdrawalCredentials{},\n\t\t\texpected: \"0x0000000000000000000000000000000000\" +\n\t\t\t\t\"000000000000000000000000000000\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\trequire.Equal(t, tt.expected, tt.wc.String(),\n\t\t\t\t\"Test case %s\", tt.name)\n\t\t})\n\t}\n}\n\nfunc TestWithdrawalCredentials_MarshalText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\twc       types.WithdrawalCredentials\n\t\texpected []byte\n\t\twantErr  bool\n\t}{\n\t\t{\n\t\t\tname: \"valid marshal\",\n\t\t\twc:   types.WithdrawalCredentials{0x01},\n\t\t\texpected: []byte(\"0x010000000000000000000000000000000000\" +\n\t\t\t\t\"0000000000000000000000000000\"),\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname: \"valid marshal with different prefix\",\n\t\t\twc:   types.WithdrawalCredentials{0x02},\n\t\t\texpected: []byte(\"0x020000000000000000000000000000000000\" +\n\t\t\t\t\"0000000000000000000000000000\"),\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname: \"valid marshal with full address\",\n\t\t\twc: types.WithdrawalCredentials{0x01, 0xde, 0xad, 0xbe, 0xef, 0x00,\n\t\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t\t\t\t0x00, 0x00, 0x00, 0x00},\n\t\t\texpected: []byte(\"0x01deadbeef00000000000000000000000000000\" +\n\t\t\t\t\"0000000000000000000000000\"),\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname: \"empty credentials\",\n\t\t\twc:   types.WithdrawalCredentials{},\n\t\t\texpected: []byte(\"0x0000000000000000000000000000000000000000\" +\n\t\t\t\t\"000000000000000000000000\"),\n\t\t\twantErr: false,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult, err := tt.wc.MarshalText()\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err, \"Test case %s\", tt.name)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err, \"Test case %s\", tt.name)\n\t\t\t\trequire.Equal(t, tt.expected, result,\n\t\t\t\t\t\"Test case %s\", tt.name)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestWithdrawalCredentials_UnmarshalText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tinput    []byte\n\t\texpected types.WithdrawalCredentials\n\t\twantErr  bool\n\t}{\n\t\t{\n\t\t\tname: \"valid unmarshal\",\n\t\t\tinput: []byte(\"0x010000000000000000000000000000000\" +\n\t\t\t\t\"0000000000000000000000000000000\"),\n\t\t\texpected: types.WithdrawalCredentials{0x01},\n\t\t\twantErr:  false,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid unmarshal\",\n\t\t\tinput:   []byte(\"invalid\"),\n\t\t\twantErr: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar wc types.WithdrawalCredentials\n\t\t\terr := wc.UnmarshalText(tt.input)\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err, \"Test case %s\", tt.name)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err, \"Test case %s\", tt.name)\n\t\t\t\trequire.Equal(t, tt.expected, wc,\n\t\t\t\t\t\"Test case %s\", tt.name)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "consensus-types/types/withdrawal_request.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\tsszutil \"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/karalabe/ssz\"\n)\n\nconst sszWithdrawRequestSize = 76 // ExecutionAddress = 20, ValidatorPubKey = 48, Amount = 8\n\n// Compile-time check to ensure WithdrawalRequest implements the necessary interfaces.\nvar (\n\t_ ssz.StaticObject            = (*WithdrawalRequest)(nil)\n\t_ constraints.SSZMarshallable = (*WithdrawalRequest)(nil)\n)\n\n// WithdrawalRequest is introduced in EIP7002 which we use for withdrawals.\ntype WithdrawalRequest struct {\n\tSourceAddress   common.ExecutionAddress\n\tValidatorPubKey crypto.BLSPubkey\n\tAmount          math.Gwei\n}\n\n/* -------------------------------------------------------------------------- */\n/*                        Withdrawal Request SSZ                              */\n/* -------------------------------------------------------------------------- */\n\nfunc (w *WithdrawalRequest) ValidateAfterDecodingSSZ() error {\n\treturn nil\n}\n\nfunc (w *WithdrawalRequest) DefineSSZ(codec *ssz.Codec) {\n\tssz.DefineStaticBytes(codec, &w.SourceAddress)\n\tssz.DefineStaticBytes(codec, &w.ValidatorPubKey)\n\tssz.DefineUint64(codec, &w.Amount)\n}\n\nfunc (w *WithdrawalRequest) SizeSSZ(_ *ssz.Sizer) uint32 {\n\treturn sszWithdrawRequestSize\n}\n\nfunc (w *WithdrawalRequest) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(w))\n\treturn buf, ssz.EncodeToBytes(buf, w)\n}\n\n// HashTreeRoot returns the hash tree root of the Deposits.\nfunc (w *WithdrawalRequest) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(w)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                       Withdrawal Requests SSZ                              */\n/* -------------------------------------------------------------------------- */\n\n// Compile-time check to ensure WithdrawalRequests implements the necessary interfaces.\nvar _ constraints.SSZMarshaler = (*WithdrawalRequests)(nil)\n\n// WithdrawalRequests is used for SSZ unmarshalling a list of WithdrawalRequest\ntype WithdrawalRequests []*WithdrawalRequest\n\n// MarshalSSZ marshals the WithdrawalRequests object to SSZ format by encoding each deposit individually.\nfunc (wr WithdrawalRequests) MarshalSSZ() ([]byte, error) {\n\treturn sszutil.MarshalItemsEIP7685(wr)\n}\n\n// ValidateAfterDecodingSSZ validates the WithdrawalRequests object after decoding.\nfunc (wr WithdrawalRequests) ValidateAfterDecodingSSZ() error {\n\tif len(wr) > constants.MaxWithdrawalRequestsPerPayload {\n\t\treturn fmt.Errorf(\n\t\t\t\"invalid number of withdrawal requests, got %d max %d\",\n\t\t\tlen(wr), constants.MaxWithdrawalRequestsPerPayload,\n\t\t)\n\t}\n\treturn nil\n}\n\n// DecodeWithdrawalRequests decodes SSZ data by decoding each withdrawal individually.\nfunc DecodeWithdrawalRequests(data []byte) (WithdrawalRequests, error) {\n\tmaxSize := constants.MaxWithdrawalRequestsPerPayload * sszWithdrawRequestSize\n\tif len(data) > maxSize {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"invalid withdrawal requests SSZ size, requests should not be more \"+\n\t\t\t\t\"than the max per payload, got %d max %d\", len(data), maxSize,\n\t\t)\n\t}\n\tif len(data) < sszWithdrawRequestSize {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"invalid withdrawal requests SSZ size, got %d expected at least %d\",\n\t\t\tlen(data), sszWithdrawRequestSize,\n\t\t)\n\t}\n\n\t// Use the EIP-7685 unmarshalItems helper.\n\treturn sszutil.UnmarshalItemsEIP7685(\n\t\tdata,\n\t\tsszWithdrawRequestSize,\n\t\tfunc() *WithdrawalRequest { return new(WithdrawalRequest) },\n\t)\n}\n"
  },
  {
    "path": "consensus-types/types/withdrawals_request_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\tenginev1 \"github.com/prysmaticlabs/prysm/v5/proto/engine/v1\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestWithdrawalRequest_ValidValuesSSZ(t *testing.T) {\n\tt.Parallel()\n\ttestCases := []struct {\n\t\tname              string\n\t\twithdrawalRequest *types.WithdrawalRequest\n\t}{\n\t\t{\n\t\t\tname: \"basic\",\n\t\t\twithdrawalRequest: &types.WithdrawalRequest{\n\t\t\t\t// 20-byte execution address\n\t\t\t\tSourceAddress: common.ExecutionAddress{\n\t\t\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t\t},\n\t\t\t\t// 48-byte public key\n\t\t\t\tValidatorPubKey: crypto.BLSPubkey{\n\t\t\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t\t\t21, 22, 23, 24, 25, 26, 27, 28, 29, 30,\n\t\t\t\t\t31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n\t\t\t\t\t41, 42, 43, 44, 45, 46, 47, 48,\n\t\t\t\t},\n\t\t\t\tAmount: 1000,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"zero amount\",\n\t\t\twithdrawalRequest: &types.WithdrawalRequest{\n\t\t\t\tSourceAddress: common.ExecutionAddress{\n\t\t\t\t\t10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\n\t\t\t\t\t20, 21, 22, 23, 24, 25, 26, 27, 28, 29,\n\t\t\t\t},\n\t\t\t\tValidatorPubKey: crypto.BLSPubkey{\n\t\t\t\t\t10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\n\t\t\t\t\t20, 21, 22, 23, 24, 25, 26, 27, 28, 29,\n\t\t\t\t\t30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\n\t\t\t\t\t40, 41, 42, 43, 44, 45, 46, 47, 48, 49,\n\t\t\t\t\t50, 51, 52, 53, 54, 55, 56, 57,\n\t\t\t\t},\n\t\t\t\tAmount: 0,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"max values\",\n\t\t\twithdrawalRequest: &types.WithdrawalRequest{\n\t\t\t\tSourceAddress: common.ExecutionAddress{\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t},\n\t\t\t\tValidatorPubKey: crypto.BLSPubkey{\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t},\n\t\t\t\tAmount: 1<<64 - 1,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"random-ish values\",\n\t\t\twithdrawalRequest: &types.WithdrawalRequest{\n\t\t\t\tSourceAddress: common.ExecutionAddress{\n\t\t\t\t\t7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\n\t\t\t\t\t17, 18, 19, 20, 21, 22, 23, 24, 25, 26,\n\t\t\t\t},\n\t\t\t\tValidatorPubKey: crypto.BLSPubkey{\n\t\t\t\t\t7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\n\t\t\t\t\t17, 18, 19, 20, 21, 22, 23, 24, 25, 26,\n\t\t\t\t\t27, 28, 29, 30, 31, 32, 33, 34, 35, 36,\n\t\t\t\t\t37, 38, 39, 40, 41, 42, 43, 44, 45, 46,\n\t\t\t\t\t47, 48, 49, 50, 51, 52, 53, 54,\n\t\t\t\t},\n\t\t\t\tAmount: 54321,\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\t// Marshal the original withdrawal request.\n\t\t\twithdrawalRequestBytes, err := tc.withdrawalRequest.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\n\t\t\t// Unmarshal into a Prysm withdrawal request.\n\t\t\tvar prysmWithdrawal enginev1.WithdrawalRequest\n\t\t\terr = prysmWithdrawal.UnmarshalSSZ(withdrawalRequestBytes)\n\t\t\trequire.NoError(t, err)\n\n\t\t\tprysmHTR, err := prysmWithdrawal.HashTreeRoot()\n\t\t\trequire.NoError(t, err)\n\t\t\twithdrawalHTR := tc.withdrawalRequest.HashTreeRoot()\n\n\t\t\t// Compare the HashTreeRoots. Effectively a test for comparing all field values.\n\t\t\trequire.Equal(t, withdrawalHTR[:], prysmHTR[:])\n\n\t\t\t// Marshal the Prysm withdrawal request.\n\t\t\tprysmWithdrawalBytes, err := prysmWithdrawal.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\n\t\t\t// Unmarshal back into a new WithdrawalRequest.\n\t\t\tvar recomputedWithdrawalRequest types.WithdrawalRequest\n\t\t\terr = ssz.Unmarshal(prysmWithdrawalBytes, &recomputedWithdrawalRequest)\n\t\t\trequire.NoError(t, err)\n\n\t\t\t// Compare that the original and recomputed values match.\n\t\t\trequire.Equal(t, *tc.withdrawalRequest, recomputedWithdrawalRequest)\n\t\t})\n\t}\n}\n\n//nolint:paralleltest // Invalid SSZ values cannot be run in parallel due to zeroalloc, which is global shared memory.\nfunc TestWithdrawalRequest_InvalidValuesUnmarshalSSZ(t *testing.T) {\n\t// Build a valid withdrawal request to obtain a baseline valid payload.\n\tvalidWithdrawal := &types.WithdrawalRequest{\n\t\tSourceAddress: common.ExecutionAddress{\n\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t},\n\t\tValidatorPubKey: crypto.BLSPubkey{\n\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n\t\t\t21, 22, 23, 24, 25, 26, 27, 28, 29, 30,\n\t\t\t31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n\t\t\t41, 42, 43, 44, 45, 46, 47, 48,\n\t\t},\n\t\tAmount: 1000,\n\t}\n\tvalidBytes, err := validWithdrawal.MarshalSSZ()\n\trequire.NoError(t, err)\n\n\t// Build a slice of invalid payloads.\n\tinvalidPayloads := [][]byte{\n\t\tnil,                       // nil slice\n\t\t{},                        // empty slice\n\t\t[]byte(\"this is not ssz\"), // arbitrary non-SSZ data\n\t\t{0x00, 0x01},              // too short to be valid\n\t\t// A truncated valid payload: remove last 5 bytes.\n\t\tfunc() []byte {\n\t\t\tif len(validBytes) > 5 {\n\t\t\t\treturn validBytes[:len(validBytes)-5]\n\t\t\t}\n\t\t\treturn validBytes\n\t\t}(),\n\t\t// A valid payload with extra trailing bytes.\n\t\tfunc() []byte {\n\t\t\textra := []byte{0xAA, 0xBB, 0xCC, 0xDD}\n\t\t\treturn append(validBytes, extra...)\n\t\t}(),\n\t}\n\n\tfor i, payload := range invalidPayloads {\n\t\ti, payload := i, payload // capture loop variables\n\t\tt.Run(fmt.Sprintf(\"invalidWithdrawal_%d\", i), func(t *testing.T) {\n\t\t\t// Ensure that calling UnmarshalSSZ does not panic and returns an error.\n\t\t\trequire.NotPanics(t, func() {\n\t\t\t\tvar w types.WithdrawalRequest\n\t\t\t\terr = ssz.Unmarshal(payload, &w)\n\t\t\t\trequire.Error(t, err, \"expected error for payload %v\", payload)\n\t\t\t})\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "contracts/.gas-snapshot",
    "content": "BeaconVerifierTest:test_verifyBeaconBlockProposer() (gas: 155057)\nBeaconVerifierTest:test_verifyCoinbase() (gas: 49435)\nBeaconVerifierTest:test_verifyExecutionNumber() (gas: 49540)\nDepositContractTest:testFuzz_DepositCount(uint256) (runs: 256, μ: 3248621, ~: 3269529)\nDepositContractTest:testFuzz_DepositNativeNotDivisibleByGwei(uint256) (runs: 256, μ: 56864, ~: 56870)\nDepositContractTest:testFuzz_DepositNativeWrongMinAmount(uint256) (runs: 256, μ: 88553, ~: 88567)\nDepositContractTest:testFuzz_DepositWrongAmount(uint256) (runs: 256, μ: 50030, ~: 50110)\nDepositContractTest:testFuzz_DepositWrongCredentials(bytes) (runs: 256, μ: 38885, ~: 38895)\nDepositContractTest:testFuzz_DepositsWrongPubKey(bytes) (runs: 256, μ: 42781, ~: 42781)\nDepositContractTest:test_Deposit() (gas: 107673)\nDepositContractTest:test_DepositNative() (gas: 107602)\nDepositContractTest:test_DepositNativeNotDivisibleByGwei() (gas: 92838)\nDepositContractTest:test_DepositNativeWrongMinAmount() (gas: 88040)\nDepositContractTest:test_DepositWrongAmount() (gas: 49193)\nDepositContractTest:test_DepositWrongCredentials() (gas: 44349)\nDepositContractTest:test_DepositWrongPubKey() (gas: 42198)\nDepositContractTest:test__codesize() (gas: 14224)\nSSZTest:test_ValidatorPubkeyRoot() (gas: 3495)\nSSZTest:test_addressHashTreeRoot() (gas: 3731)\nSSZTest:test_uint64HashTreeRoot() (gas: 4955)"
  },
  {
    "path": "contracts/Makefile",
    "content": "#!/usr/bin/make -f\n\n#################\n#     forge     #\n#################\n\nforge-build: |\n\t@forge build --extra-output-files bin --extra-output-files abi  --root $(CONTRACTS_DIR)\n\nforge-clean: |\n\t@forge clean --root $(CONTRACTS_DIR)\n\ntest-forge-unit:\n\t@echo \"Running forge unit tests...\"\n\t@cd $(CONTRACTS_DIR) && FOUNDRY_PROFILE=coverage forge test \n\ntest-forge-cover:\n\t@echo \"Running forge test with coverage...\"\n\t@cd $(CONTRACTS_DIR) && FOUNDRY_PROFILE=coverage forge build && forge coverage --nmt testFuzz --report lcov --report-file ../test-forge-cover.txt\n\ntest-forge-fuzz:\n\t@echo \"Running forge fuzz tests...\"\n\t@cd $(CONTRACTS_DIR) && FOUNDRY_PROFILE=fuzz forge test\n\nforge-snapshot:\n\t@echo \"Running forge snapshot...\"\n\t@cd $(CONTRACTS_DIR) && forge snapshot --isolate --fuzz-runs 1\n\nforge-snapshot-diff:\n\t@echo \"Running forge snapshot diff...\"\n\t@cd $(CONTRACTS_DIR) && forge snapshot --diff --isolate --fuzz-runs 1\n\nforge-lint-fix:\n\t@echo \"--> Running forge fmt\"\n\t@cd $(CONTRACTS_DIR) && forge fmt --root $(CONTRACTS_DIR) .\n\nforge-lint:\n\t@echo \"--> Running forge lint\"\n\t@cd $(CONTRACTS_DIR) && forge fmt --check\n"
  },
  {
    "path": "contracts/README.md",
    "content": "# BeaconKit Contracts\n\n## Mock PoL Contracts\n\nMock Proof-of-Liquidity contracts for testing execution client integration.\n\n### Usage\n\nGenerate bytecode for genesis deployment:\n\n```bash\n# Build contracts\nforge build\n\n# Extract SimplePoLDistributor bytecode\ncat out/MockPoL.sol/SimplePoLDistributor.json | jq -r .deployedBytecode.object\n\n# Extract ValidatorRegistry bytecode\ncat out/MockValidatorRegistry.sol/ValidatorRegistry.json | jq -r .deployedBytecode.object\n```\n\nThe same pattern can be used to extract bytecode for other contracts in the\n`brip0004/` directory.\n\n### Contracts\n\n- `MockPoL.sol` - Basic PoL distributor with multi-contract state changes\n- `MockPoLReverting.sol` - PoL distributor that reverts after 10 distributions\n- `MockPoLGasEnforcer.sol` - Gas-constrained PoL distributor for gas limit testing\n- `MockValidatorRegistry.sol` - Registry contract for testing cross-contract calls\n"
  },
  {
    "path": "contracts/foundry.toml",
    "content": "# Full reference https://github.com/foundry-rs/foundry/tree/master/crates/config\n[profile.default]\nauto_detect_solc = false\nsolc = \"0.8.26\"\nevm_version = \"cancun\"\nfuzz = { runs = 256, seed = \"42\" }\ngas_reports = [\"*\"]\ncache = true\noptimizer = true\noptimizer_runs = 4294967295\nvia_ir = false\nout = \"out\"\nscript = \"script\"\nsrc = \"src\"\ntest = \"test\"\nverbosity = 3\nfs_permissions = [{ access = \"read\", path = \"./\"}]\n\n[profile.fuzz]\nfuzz = { runs = 1024 }\nverbosity = 1\n\n[profile.coverage]\nfuzz = { runs = 16 }\n\n[fmt]\nbracket_spacing = true\nint_types = \"long\"\nline_length = 80\nmultiline_func_header = \"all\"\nnumber_underscore = \"thousands\"\nquote_style = \"double\"\ntab_width = 4\nwrap_comments = false\n\n[rpc_endpoints]\nlocalhost = \"http://localhost:8545\"\nsepolia = \"https://sepolia.gateway.tenderly.co\"\n"
  },
  {
    "path": "contracts/remappings.txt",
    "content": "@forge-std/=lib/forge-std/src/\n@solady/src/=lib/solady/src/\n@solady/test/=lib/solady/test/\n@interfaces/=interfaces/\n@src/=src/\n"
  },
  {
    "path": "contracts/slither.config.json",
    "content": "{\n  \"detectors_to_exclude\": \"assembly,calls-loop,low-level-calls,naming-convention,similar-names,solc-version,timestamp,unused-return\",\n  \"exclude_informational\": true,\n  \"exclude_low\": false,\n  \"exclude_medium\": false,\n  \"exclude_high\": false,\n  \"filter_paths\": \"lib|node_modules|script|test\"\n}\n"
  },
  {
    "path": "contracts/src/brip0004/MockPoL.sol",
    "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport \"./MockValidatorRegistry.sol\";\n\n/// @title SimplePoLDistributor\n/// @notice Mock PoL distributor for testing execution client integration\n/// @dev Interacts with ValidatorRegistry to test multi-contract state changes\ncontract SimplePoLDistributor {\n    /// @notice System address that can call distributeFor (execution layer client)\n    address private constant SYSTEM_ADDRESS =\n        0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE;\n\n    /// @notice The validator registry contract address (hardcoded for genesis deployment)\n    ValidatorRegistry private constant VALIDATOR_REGISTRY =\n        ValidatorRegistry(0x4200000000000000000000000000000000000043);\n\n    /// @notice Event emitted when distributeFor is called\n    event PoLDistributed(bytes pubkey);\n\n    /// @notice Counter for total distributions\n    uint256 public totalDistributions;\n\n    /// @notice Error thrown when caller is not the system address\n    error NotSystemAddress();\n\n    /// @dev Restricts access to system address (execution layer client only)\n    modifier onlySystemCall() {\n        if (msg.sender != SYSTEM_ADDRESS) {\n            revert NotSystemAddress();\n        }\n        _;\n    }\n\n    /// @notice Main function called by execution client\n    /// @param pubkey The validator public key\n    /// @dev Calls ValidatorRegistry to test multi-contract state changes\n    // slither-disable-next-line reentrancy-events\n    function distributeFor(bytes calldata pubkey) external onlySystemCall {\n        totalDistributions++;\n        VALIDATOR_REGISTRY.recordValidatorActivity(pubkey);\n\n        emit PoLDistributed(pubkey);\n    }\n}\n"
  },
  {
    "path": "contracts/src/brip0004/MockPoLGasEnforcer.sol",
    "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\n/// @title GasEnforcedPoLDistributor\n/// @notice PoL distributor requiring exactly 29,999,646 gas for testing gas limits\n/// @dev Reverts if called with incorrect gas amount\ncontract GasEnforcedPoLDistributor {\n    function distributeFor(bytes calldata /*pubkey*/ ) public view {\n        uint256 start_gas = gasleft();\n        require(start_gas == 29_999_646, \"Insufficient gas\");\n    }\n}\n"
  },
  {
    "path": "contracts/src/brip0004/MockPoLReverting.sol",
    "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport \"./MockValidatorRegistry.sol\";\n\n/// @title RevertingPoLDistributor\n/// @notice Mock PoL distributor that reverts after 10 distributions for testing\n/// @dev Interacts with ValidatorRegistry to test multi-contract state changes\ncontract RevertingPoLDistributor {\n    /// @notice System address that can call distributeFor (execution layer client)\n    address private constant SYSTEM_ADDRESS =\n        0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE;\n\n    /// @notice The validator registry contract address (hardcoded for genesis deployment)\n    ValidatorRegistry private constant VALIDATOR_REGISTRY =\n        ValidatorRegistry(0x4200000000000000000000000000000000000043);\n\n    /// @notice Event emitted when distributeFor is called\n    event PoLDistributed(bytes pubkey);\n\n    /// @notice Counter for total distributions\n    uint256 public totalDistributions;\n\n    /// @notice Error thrown when caller is not the system address\n    error NotSystemAddress();\n\n    /// @dev Restricts access to system address (execution layer client only)\n    modifier onlySystemCall() {\n        if (msg.sender != SYSTEM_ADDRESS) {\n            revert NotSystemAddress();\n        }\n        _;\n    }\n\n    /// @notice Main function called by execution client\n    /// @param pubkey The validator public key\n    /// @dev Calls ValidatorRegistry to test multi-contract state changes\n    // slither-disable-next-line reentrancy-events\n    function distributeFor(bytes calldata pubkey) external onlySystemCall {\n        require(totalDistributions < 10, \"Max distributions reached\");\n        totalDistributions++;\n        VALIDATOR_REGISTRY.recordValidatorActivity(pubkey);\n\n        emit PoLDistributed(pubkey);\n    }\n}\n"
  },
  {
    "path": "contracts/src/brip0004/MockValidatorRegistry.sol",
    "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\n/// @title ValidatorRegistry\n/// @notice Simple registry contract for testing multi-contract state changes\n/// @dev Called by PoL distributors to increment activity counter\ncontract ValidatorRegistry {\n    /// @notice Activity counter incremented on each call\n    uint256 public callCount;\n\n    /// @notice Event emitted when activity is recorded\n    event RegistryCalled(uint256 newCount);\n\n    /// @notice Records validator activity by incrementing counter\n    function recordValidatorActivity(bytes calldata /* pubkey */ ) external {\n        callCount++;\n        emit RegistryCalled(callCount);\n    }\n}\n"
  },
  {
    "path": "contracts/src/eip4399/RandaoTester.sol",
    "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.25;\n\n/// @title RandaoTester\n/// @dev This contract is used during the integration testing of\n///      EIP-4399 in BeaconKit.\n///      DO NOT USE THIS FOR GENERATING RANDOMNESS IN PRODUCTION\n//       FOR ANYTHING IMPORTANT.\n/// @author https://eips.ethereum.org/EIPS/eip-4399\n/// @author itsdevbear@berachain.com\ncontract RandaoTester {\n    /// @notice Stores the last retrieved RANDAO mix.\n    uint256 public lastValue;\n\n    /// @notice Retrieves and stores the previous RANDAO mix.\n    /// @dev Accesses the `prevrandao` property from the block global variable.\n    /// @return The last retrieved RANDAO mix.\n    function storePrevRandao() external returns (uint256) {\n        lastValue = block.prevrandao;\n        return block.prevrandao;\n    }\n}\n"
  },
  {
    "path": "contracts/src/eip4788/README.md",
    "content": "# ERC-4788 Bytecode\n\nAs taken from: [https://etherscan.io/address/0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02#code](https://etherscan.io/address/0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02#code)\n"
  },
  {
    "path": "contracts/src/eip4788/SSZ.sol",
    "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.21;\n\n/// @notice Library for SSZ (Simple Serialize) proof verification.\n/// @author [madlabman](https://github.com/madlabman/eip-4788-proof)\nlibrary SSZ {\n    /// @dev SHA256 precompile address.\n    uint8 internal constant SHA256 = 0x02;\n\n    error BranchHasMissingItem();\n    error BranchHasExtraItem();\n\n    /// @notice Modified version of `verify` from `MerkleProofLib` to support\n    /// generalized indices and sha256 precompile.\n    /// @dev Returns whether `leaf` exists in the Merkle tree with `root`,\n    /// given `proof`.\n    function verifyProof(\n        bytes32[] calldata proof,\n        bytes32 root,\n        bytes32 leaf,\n        uint256 index\n    )\n        internal\n        view\n        returns (bool isValid)\n    {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if proof.length {\n                // Left shift by 5 is equivalent to multiplying by 0x20.\n                let end := add(proof.offset, shl(5, proof.length))\n                // Initialize `offset` to the offset of `proof` in the calldata.\n                let offset := proof.offset\n                // Iterate over proof elements to compute root hash.\n                for { } 1 { } {\n                    // Slot of `leaf` in scratch space.\n                    // If the condition is true: 0x20, otherwise: 0x00.\n                    let scratch := shl(5, and(index, 1))\n                    index := shr(1, index)\n                    if iszero(index) {\n                        // revert BranchHasExtraItem()\n                        mstore(0x00, 0x5849603f)\n                        revert(0x1c, 0x04)\n                    }\n                    // Store elements to hash contiguously in scratch space.\n                    // Scratch space is 64 bytes (0x00 - 0x3f) and both elements\n                    // are 32 bytes.\n                    mstore(scratch, leaf)\n                    mstore(xor(scratch, 0x20), calldataload(offset))\n                    // Call sha256 precompile\n                    let result :=\n                        staticcall(gas(), SHA256, 0x00, 0x40, 0x00, 0x20)\n\n                    if eq(result, 0) { revert(0, 0) }\n\n                    // Reuse `leaf` to store the hash to reduce stack operations.\n                    leaf := mload(0x00)\n                    offset := add(offset, 0x20)\n                    if iszero(lt(offset, end)) { break }\n                }\n            }\n            // index != 1\n            if gt(sub(index, 1), 0) {\n                // revert BranchHasMissingItem()\n                mstore(0x00, 0x1b6661c3)\n                revert(0x1c, 0x04)\n            }\n            isValid := eq(leaf, root)\n        }\n    }\n}\n\n/// @notice Contract for testing SSZ (Simple Serialize) proof verification with the `SSZ` library.\n/// @author Inspired by [madlabman](https://github.com/madlabman/eip-4788-proof).\ncontract SSZTest {\n    /// @notice The address of the EIP-4788 Beacon Roots contract.\n    address public constant BEACON_ROOTS =\n        0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02;\n\n    // Signature: 0x3033b0ff\n    error RootNotFound();\n\n    /// @notice Verifies a proof of inclusion for a given leaf in a Merkle tree.\n    /// @param proof The proof of inclusion.\n    /// @param root The root of the Merkle tree.\n    /// @param leaf The leaf to verify.\n    /// @param index The index of the leaf in the Merkle tree.\n    /// @return isValid Whether the proof is valid.\n    function verifyProof(\n        bytes32[] calldata proof,\n        bytes32 root,\n        bytes32 leaf,\n        uint256 index\n    )\n        external\n        view\n        returns (bool isValid)\n    {\n        isValid = SSZ.verifyProof(proof, root, leaf, index);\n    }\n\n    /// @notice Verifies a proof of inclusion for a given leaf in a Merkle tree. Reverts if the proof is invalid.\n    /// @param proof The proof of inclusion.\n    /// @param root The root of the Merkle tree.\n    /// @param leaf The leaf to verify.\n    /// @param index The index of the leaf in the Merkle tree.\n    function mustVerifyProof(\n        bytes32[] calldata proof,\n        bytes32 root,\n        bytes32 leaf,\n        uint256 index\n    )\n        external\n        view\n    {\n        if (!SSZ.verifyProof(proof, root, leaf, index)) {\n            revert(\"Proof is invalid\");\n        }\n    }\n\n    /// @notice Get the parent block root at a given timestamp.\n    /// @dev Reverts with `RootNotFound()` if the root is not found.\n    function getParentBlockRootAt(uint64 ts)\n        external\n        view\n        returns (bytes32 root)\n    {\n        assembly (\"memory-safe\") {\n            mstore(0, ts)\n            let success := staticcall(gas(), BEACON_ROOTS, 0, 0x20, 0, 0x20)\n            if iszero(success) {\n                mstore(0, 0x3033b0ff) // RootNotFound()\n                revert(0x1c, 0x04)\n            }\n            root := mload(0)\n        }\n    }\n}\n"
  },
  {
    "path": "contracts/src/eip4788/deployment.json",
    "content": "{\n    \"type\": \"0x0\",\n    \"nonce\": \"0x0\",\n    \"to\": null,\n    \"gas\": \"0x3d090\",\n    \"gasPrice\": \"0xe8d4a51000\",\n    \"maxPriorityFeePerGas\": null,\n    \"maxFeePerGas\": null,\n    \"value\": \"0x0\",\n    \"input\": \"0x60618060095f395ff33373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500\",\n    \"v\": \"0x1b\",\n    \"r\": \"0x539\",\n    \"s\": \"0x1b9b6eb1f0\",\n    \"hash\": \"0xdf52c2d3bbe38820fff7b5eaab3db1b91f8e1412b56497d88388fb5d4ea1fde0\"\n  }"
  },
  {
    "path": "contracts/src/staking/DepositContract.sol",
    "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport { ERC165 } from \"./IERC165.sol\";\nimport { IDepositContract } from \"./IDepositContract.sol\";\n\n/**\n * @title DepositContract\n * @author Berachain Team\n * @notice A contract that handles validators deposits.\n * @dev Its events are used by the beacon chain to manage the staking process.\n * @dev This contract does not implement the deposit merkle tree.\n */\ncontract DepositContract is IDepositContract, ERC165 {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                        CONSTANTS                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev The minimum amount of `BERA` to deposit.\n    /// @dev This is 1 ether in Gwei since our deposit contract denominates in Gwei. 1e9 * 1e9 = 1e18.\n    uint64 internal constant MIN_DEPOSIT_AMOUNT_IN_GWEI = 1e9;\n\n    /// @dev The length of the public key, PUBLIC_KEY_LENGTH bytes.\n    uint8 internal constant PUBLIC_KEY_LENGTH = 48;\n\n    /// @dev The length of the signature, SIGNATURE_LENGTH bytes.\n    uint8 internal constant SIGNATURE_LENGTH = 96;\n\n    /// @dev The length of the credentials, 1 byte prefix + 11 bytes padding + 20 bytes address = 32 bytes.\n    uint8 internal constant CREDENTIALS_LENGTH = 32;\n\n    /// @dev 1 day in seconds.\n    /// @dev This is the delay before a new operator can accept a change.\n    uint96 private constant ONE_DAY = 86_400;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                           STORAGE                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev QueuedOperator is a struct that represents an operator address change request.\n    struct QueuedOperator {\n        uint96 queuedTimestamp;\n        address newOperator;\n    }\n\n    /// @dev depositCount represents the number of deposits that\n    /// have been made to the contract.\n    /// @dev The index of the next deposit will use this value.\n    uint64 public depositCount;\n\n    /// @dev The hash tree root of the genesis deposits.\n    /// @dev Should be set in deployment (predeploy state or constructor).\n    // slither-disable-next-line constable-states\n    bytes32 public genesisDepositsRoot;\n\n    /// @dev The mapping of public keys to operator addresses.\n    mapping(bytes => address) private _operatorByPubKey;\n\n    /// @dev The mapping of public keys to operator change requests.\n    mapping(bytes => QueuedOperator) public queuedOperator;\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                            VIEWS                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @inheritdoc ERC165\n    function supportsInterface(bytes4 interfaceId)\n        external\n        pure\n        override\n        returns (bool)\n    {\n        return interfaceId == type(ERC165).interfaceId\n            || interfaceId == type(IDepositContract).interfaceId;\n    }\n\n    /// @inheritdoc IDepositContract\n    function getOperator(bytes calldata pubkey)\n        external\n        view\n        returns (address)\n    {\n        return _operatorByPubKey[pubkey];\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                            DEPOSIT                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @inheritdoc IDepositContract\n    function deposit(\n        bytes calldata pubkey,\n        bytes calldata credentials,\n        bytes calldata signature,\n        address operator\n    )\n        public\n        payable\n        virtual\n    {\n        if (pubkey.length != PUBLIC_KEY_LENGTH) {\n            revert InvalidPubKeyLength();\n        }\n\n        if (credentials.length != CREDENTIALS_LENGTH) {\n            revert InvalidCredentialsLength();\n        }\n\n        if (signature.length != SIGNATURE_LENGTH) {\n            revert InvalidSignatureLength();\n        }\n\n        // Set operator on the first deposit.\n        // zero `_operatorByPubKey[pubkey]` means the pubkey is not registered.\n        if (_operatorByPubKey[pubkey] == address(0)) {\n            if (operator == address(0)) {\n                revert ZeroOperatorOnFirstDeposit();\n            }\n            _operatorByPubKey[pubkey] = operator;\n            emit OperatorUpdated(pubkey, operator, address(0));\n        }\n        // If not the first deposit, operator address must be 0.\n        // This prevents from the front-running of the first deposit to set the operator.\n        else if (operator != address(0)) {\n            revert OperatorAlreadySet();\n        }\n\n        uint64 amountInGwei = _deposit();\n\n        if (amountInGwei < MIN_DEPOSIT_AMOUNT_IN_GWEI) {\n            revert InsufficientDeposit();\n        }\n\n        // slither-disable-next-line reentrancy-benign,reentrancy-events\n        emit Deposit(\n            pubkey, credentials, amountInGwei, signature, depositCount++\n        );\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                        OPERATOR CHANGE                    */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @inheritdoc IDepositContract\n    function requestOperatorChange(\n        bytes calldata pubkey,\n        address newOperator\n    )\n        external\n    {\n        // Cache the current operator.\n        address currentOperator = _operatorByPubKey[pubkey];\n        // Only the current operator can request a change.\n        // This will also revert if the pubkey is not registered.\n        if (msg.sender != currentOperator) {\n            revert NotOperator();\n        }\n        // Revert if the new operator is zero address.\n        if (newOperator == address(0)) {\n            revert ZeroAddress();\n        }\n        QueuedOperator storage qO = queuedOperator[pubkey];\n        qO.newOperator = newOperator;\n        qO.queuedTimestamp = uint96(block.timestamp);\n        emit OperatorChangeQueued(\n            pubkey, newOperator, currentOperator, block.timestamp\n        );\n    }\n\n    /// @inheritdoc IDepositContract\n    function cancelOperatorChange(bytes calldata pubkey) external {\n        // Only the current operator can cancel the change.\n        if (msg.sender != _operatorByPubKey[pubkey]) {\n            revert NotOperator();\n        }\n        delete queuedOperator[pubkey];\n        emit OperatorChangeCancelled(pubkey);\n    }\n\n    /// @inheritdoc IDepositContract\n    function acceptOperatorChange(bytes calldata pubkey) external {\n        QueuedOperator storage qO = queuedOperator[pubkey];\n        (address newOperator, uint96 queuedTimestamp) =\n            (qO.newOperator, qO.queuedTimestamp);\n\n        // Only the new operator can accept the change.\n        // This will revert if nothing is queued as newOperator will be zero address.\n        if (msg.sender != newOperator) {\n            revert NotNewOperator();\n        }\n        // Check if the queue delay has passed.\n        if (queuedTimestamp + ONE_DAY > uint96(block.timestamp)) {\n            revert NotEnoughTime();\n        }\n        // Cache the old operator.\n        address oldOperator = _operatorByPubKey[pubkey];\n        _operatorByPubKey[pubkey] = newOperator;\n        delete queuedOperator[pubkey];\n        emit OperatorUpdated(pubkey, newOperator, oldOperator);\n    }\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                            INTERNAL                         */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /// @dev Validates the deposit amount and sends the native asset to the zero address.\n    function _deposit() internal virtual returns (uint64) {\n        if (msg.value % 1 gwei != 0) {\n            revert DepositNotMultipleOfGwei();\n        }\n\n        uint256 amountInGwei = msg.value / 1 gwei;\n        if (amountInGwei > type(uint64).max) {\n            revert DepositValueTooHigh();\n        }\n\n        _safeTransferETH(address(0), msg.value);\n\n        return uint64(amountInGwei);\n    }\n\n    /**\n     * @notice Safely transfers ETH to the given address.\n     * @dev From the Solady library.\n     * @param to The address to transfer the ETH to.\n     * @param amount The amount of ETH to transfer.\n     */\n    function _safeTransferETH(address to, uint256 amount) internal {\n        /// @solidity memory-safe-assembly\n        assembly {\n            if iszero(\n                call(gas(), to, amount, codesize(), 0x00, codesize(), 0x00)\n            ) {\n                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.\n                revert(0x1c, 0x04)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "contracts/src/staking/IDepositContract.sol",
    "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\n/// @title IDepositContract\n/// @author Berachain Team.\ninterface IDepositContract {\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                           ERRORS                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    // Signature: 0xe8966d7a\n    error NotEnoughTime();\n    // Signature: 0xd92e233d\n    error ZeroAddress();\n    // Signature: 0x7c214f04\n    error NotOperator();\n\n    /// @dev Error thrown when the deposit amount is too small, to prevent dust deposits.\n    // Signature: 0x0e1eddda\n    error InsufficientDeposit();\n\n    /// @dev Error thrown when the deposit amount is not a multiple of Gwei.\n    // Signature: 0x40567b38\n    error DepositNotMultipleOfGwei();\n\n    /// @dev Error thrown when the deposit amount is too high, since it is a uint64.\n    // Signature: 0x2aa66734\n    error DepositValueTooHigh();\n\n    /// @dev Error thrown when the public key length is not 48 bytes.\n    // Signature: 0x9f106472\n    error InvalidPubKeyLength();\n\n    /// @dev Error thrown when the withdrawal credentials length is not 32 bytes.\n    // Signature: 0xb39bca16\n    error InvalidCredentialsLength();\n\n    /// @dev Error thrown when the signature length is not 96 bytes.\n    // Signature: 0x4be6321b\n    error InvalidSignatureLength();\n\n    /// @dev Error thrown when the input operator is zero address on the first deposit.\n    // Signature: 0x51969a7a\n    error ZeroOperatorOnFirstDeposit();\n\n    /// @dev Error thrown when the operator is already set and caller passed non-zero operator.\n    // Signature: 0xc4142b41\n    error OperatorAlreadySet();\n\n    /// @dev Error thrown when the caller is not the current operator.\n    // Signature: 0x819a0d0b\n    error NotNewOperator();\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                           EVENTS                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /**\n     * @dev Emitted when a deposit is made, which could mean a new validator or a top up of an existing one.\n     * @param pubkey the public key of the validator who is being deposited for if not a new validator.\n     * @param credentials the public key of the operator if new validator or the depositor if top up.\n     * @param amount the amount of stake being deposited, in Gwei.\n     * @param signature the signature of the deposit message, only checked when creating a new validator.\n     * @param index the index of the deposit.\n     */\n    event Deposit(\n        bytes pubkey,\n        bytes credentials,\n        uint64 amount,\n        bytes signature,\n        uint64 index\n    );\n\n    /**\n     * @notice Emitted when the operator change of a validator is queued.\n     * @param pubkey The pubkey of the validator.\n     * @param queuedOperator The new queued operator address.\n     * @param currentOperator The current operator address.\n     * @param queuedTimestamp The timestamp when the change was queued.\n     */\n    event OperatorChangeQueued(\n        bytes indexed pubkey,\n        address queuedOperator,\n        address currentOperator,\n        uint256 queuedTimestamp\n    );\n\n    /**\n     * @notice Emitted when the operator change of a validator is cancelled.\n     * @param pubkey The pubkey of the validator.\n     */\n    event OperatorChangeCancelled(bytes indexed pubkey);\n\n    /**\n     * @notice Emitted when the operator of a validator is updated.\n     * @param pubkey The pubkey of the validator.\n     * @param newOperator The new operator address.\n     * @param previousOperator The previous operator address.\n     */\n    event OperatorUpdated(\n        bytes indexed pubkey, address newOperator, address previousOperator\n    );\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                            VIEWS                           */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /**\n     * @notice Get the operator address for a given pubkey.\n     * @dev Returns zero address if the pubkey is not registered.\n     * @param pubkey The pubkey of the validator.\n     * @return The operator address for the given pubkey.\n     */\n    function getOperator(bytes calldata pubkey)\n        external\n        view\n        returns (address);\n\n    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n    /*                            WRITES                          */\n    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n    /**\n     * @notice Submit a deposit message to the Beaconchain.\n     * @notice This will be used to create a new validator or to top up an existing one, increasing stake.\n     * @param pubkey is the consensus public key of the validator. If subsequent deposit, its ignored.\n     * @param credentials is the staking credentials of the validator. If this is the first deposit it is\n     * validator operator public key, if subsequent deposit it is the depositor's public key.\n     * @param signature is the signature used only on the first deposit.\n     * @param operator is the address of the operator.\n     * @dev emits the Deposit event upon successful deposit.\n     * @dev Reverts if the operator is already set and caller passed non-zero operator.\n     */\n    function deposit(\n        bytes calldata pubkey,\n        bytes calldata credentials,\n        bytes calldata signature,\n        address operator\n    )\n        external\n        payable;\n\n    /**\n     * @notice Request to change the operator of a validator.\n     * @dev Only the current operator can request a change.\n     * @param pubkey The pubkey of the validator.\n     * @param newOperator The new operator address.\n     */\n    function requestOperatorChange(\n        bytes calldata pubkey,\n        address newOperator\n    )\n        external;\n\n    /**\n     * @notice Cancel the operator change of a validator.\n     * @dev Only the current operator can cancel the change.\n     * @param pubkey The pubkey of the validator.\n     */\n    function cancelOperatorChange(bytes calldata pubkey) external;\n\n    /**\n     * @notice Accept the operator change of a validator.\n     * @dev Only the new operator can accept the change.\n     * @dev Reverts if the queue delay has not passed.\n     * @param pubkey The pubkey of the validator.\n     */\n    function acceptOperatorChange(bytes calldata pubkey) external;\n}\n"
  },
  {
    "path": "contracts/src/staking/IERC165.sol",
    "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\n// Based on official specification in https://eips.ethereum.org/EIPS/eip-165\ninterface ERC165 {\n    /// @notice Query if a contract implements an interface\n    /// @param interfaceId The interface identifier, as specified in ERC-165\n    /// @dev Interface identification is specified in ERC-165. This function\n    ///  uses less than 30,000 gas.\n    /// @return `true` if the contract implements `interfaceId` and\n    ///  `interfaceId` is not 0xffffffff, `false` otherwise\n    function supportsInterface(bytes4 interfaceId)\n        external\n        pure\n        returns (bool);\n}\n"
  },
  {
    "path": "contracts/test/staking/DepositContract.t.sol",
    "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.25;\n\nimport \"forge-std/Test.sol\";\n\nimport { SoladyTest } from \"@solady/test/utils/SoladyTest.sol\";\nimport { IDepositContract } from \"@src/staking/IDepositContract.sol\";\nimport { DepositContract } from \"@src/staking/DepositContract.sol\";\n\ncontract DepositContractTest is SoladyTest, StdCheats {\n    /// @dev The depositor address.\n    address internal depositor = 0x20f33CE90A13a4b5E7697E3544c3083B8F8A51D4;\n\n    /// @dev The owner address.\n    address owner = 0x6969696969696969696969696969696969696969;\n\n    /// @dev The validator public key.\n    bytes internal VALIDATOR_PUBKEY = _create48Byte();\n\n    /// @dev The withdrawal credentials that we will use.\n    bytes internal WITHDRAWAL_CREDENTIALS = _credential(address(this));\n\n    /// @dev The staking credentials that are right.\n    bytes internal STAKING_CREDENTIALS = _credential(depositor);\n\n    bytes32 internal constant STAKING_ASSET_SLOT = bytes32(0);\n\n    /// @dev the deposit contract.\n    DepositContract internal depositContract;\n\n    function setUp() public virtual {\n        depositContract = new DepositContract();\n    }\n\n    function testFuzz_DepositsWrongPubKey(bytes calldata pubKey) public {\n        vm.assume(pubKey.length != 96);\n        vm.expectRevert(IDepositContract.InvalidPubKeyLength.selector);\n        vm.deal(depositor, 32 ether);\n        vm.prank(depositor);\n        depositContract.deposit{ value: 32 ether }(\n            bytes(\"wrong_public_key\"),\n            STAKING_CREDENTIALS,\n            _create96Byte(),\n            depositor\n        );\n    }\n\n    function test_DepositWrongPubKey() public {\n        vm.expectRevert(IDepositContract.InvalidPubKeyLength.selector);\n        vm.deal(depositor, 32 ether);\n        vm.prank(depositor);\n        depositContract.deposit{ value: 32 ether }(\n            bytes(\"wrong_public_key\"),\n            STAKING_CREDENTIALS,\n            _create96Byte(),\n            depositor\n        );\n    }\n\n    function testFuzz_DepositWrongCredentials(bytes calldata credentials)\n        public\n    {\n        vm.assume(credentials.length != 32);\n\n        vm.deal(depositor, 32 ether);\n        vm.expectRevert(IDepositContract.InvalidCredentialsLength.selector);\n        vm.prank(depositor);\n        depositContract.deposit{ value: 32 ether }(\n            _create48Byte(), credentials, _create96Byte(), depositor\n        );\n    }\n\n    function test_DepositWrongCredentials() public {\n        vm.expectRevert(IDepositContract.InvalidCredentialsLength.selector);\n        vm.deal(depositor, 32 ether);\n        vm.prank(depositor);\n        depositContract.deposit{ value: 32 ether }(\n            VALIDATOR_PUBKEY,\n            bytes(\"wrong_credentials\"),\n            _create96Byte(),\n            depositor\n        );\n    }\n\n    function test_DepositWrongAmount() public {\n        vm.expectRevert(IDepositContract.InsufficientDeposit.selector);\n        vm.prank(depositor);\n        // send with 0 ether\n        depositContract.deposit(\n            VALIDATOR_PUBKEY, STAKING_CREDENTIALS, _create96Byte(), depositor\n        );\n    }\n\n    function testFuzz_DepositNativeWrongMinAmount(uint256 amountInEther)\n        public\n    {\n        amountInEther = _bound(amountInEther, 1, 31);\n        uint256 amountInGwei = amountInEther * 1 gwei;\n        vm.deal(depositor, amountInGwei);\n        vm.prank(depositor);\n        vm.expectRevert(IDepositContract.InsufficientDeposit.selector);\n        depositContract.deposit{ value: amountInGwei }(\n            VALIDATOR_PUBKEY, STAKING_CREDENTIALS, _create96Byte(), depositor\n        );\n    }\n\n    function test_DepositNativeWrongMinAmount() public {\n        uint256 amount = 31 gwei;\n        vm.deal(depositor, amount);\n        vm.prank(depositor);\n        vm.expectRevert(IDepositContract.InsufficientDeposit.selector);\n        depositContract.deposit{ value: amount }(\n            VALIDATOR_PUBKEY, STAKING_CREDENTIALS, _create96Byte(), depositor\n        );\n    }\n\n    function testFuzz_DepositNativeNotDivisibleByGwei(uint256 amount) public {\n        amount = _bound(amount, 31e9 + 1, uint256(type(uint64).max));\n        vm.assume(amount % 1e9 != 0);\n        vm.deal(depositor, amount);\n\n        vm.prank(depositor);\n        vm.expectRevert(IDepositContract.DepositNotMultipleOfGwei.selector);\n        depositContract.deposit{ value: amount }(\n            VALIDATOR_PUBKEY, STAKING_CREDENTIALS, _create96Byte(), depositor\n        );\n    }\n\n    function test_DepositNativeNotDivisibleByGwei() public {\n        uint256 amount = 32e9 + 1;\n        vm.deal(depositor, amount);\n        vm.expectRevert(IDepositContract.DepositNotMultipleOfGwei.selector);\n        vm.prank(depositor);\n        depositContract.deposit{ value: amount }(\n            VALIDATOR_PUBKEY, STAKING_CREDENTIALS, _create96Byte(), depositor\n        );\n\n        amount = 32e9 - 1;\n        vm.deal(depositor, amount);\n        vm.expectRevert(IDepositContract.DepositNotMultipleOfGwei.selector);\n        vm.prank(depositor);\n        depositContract.deposit{ value: amount }(\n            VALIDATOR_PUBKEY, STAKING_CREDENTIALS, _create96Byte(), depositor\n        );\n    }\n\n    function test_DepositNative() public {\n        vm.deal(depositor, 32 ether);\n        vm.prank(depositor);\n        vm.expectEmit(true, true, true, true);\n        emit IDepositContract.Deposit(\n            VALIDATOR_PUBKEY, STAKING_CREDENTIALS, 32 gwei, _create96Byte(), 0\n        );\n        depositContract.deposit{ value: 32 ether }(\n            VALIDATOR_PUBKEY, STAKING_CREDENTIALS, _create96Byte(), depositor\n        );\n    }\n\n    function testFuzz_DepositCount(uint256 count) public {\n        count = _bound(count, 1, 100);\n        uint64 depositCount;\n        for (uint256 i; i < count; ++i) {\n            depositor = makeAddr(vm.toString(i));\n            vm.deal(depositor, 32 ether);\n\n            vm.startPrank(depositor);\n            vm.expectEmit(true, true, true, true);\n            emit IDepositContract.Deposit(\n                _newPubkey(i),\n                STAKING_CREDENTIALS,\n                32 gwei,\n                _create96Byte(),\n                depositCount++\n            );\n            depositContract.deposit{ value: 32 ether }(\n                _newPubkey(i), STAKING_CREDENTIALS, _create96Byte(), depositor\n            );\n            vm.stopPrank();\n        }\n        assertEq(depositContract.depositCount(), depositCount);\n    }\n\n    function _credential(address addr) internal pure returns (bytes memory) {\n        return abi.encodePacked(bytes1(0x01), bytes11(0x0), addr);\n    }\n\n    function _create96Byte() internal pure returns (bytes memory) {\n        return abi.encodePacked(bytes32(\"32\"), bytes32(\"32\"), bytes32(\"32\"));\n    }\n\n    function _create48Byte() internal pure returns (bytes memory) {\n        return abi.encodePacked(bytes32(\"32\"), bytes16(\"16\"));\n    }\n\n    function _newPubkey(uint256 i) internal pure returns (bytes memory) {\n        return abi.encodePacked(bytes32(i), bytes16(\"16\"));\n    }\n}\n"
  },
  {
    "path": "da/blob/factory.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage blob\n\nimport (\n\t\"time\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/da/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/merkle\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\n// SidecarFactory is a factory for sidecars.\ntype SidecarFactory struct {\n\t// metrics is used to collect and report factory metrics.\n\tmetrics *factoryMetrics\n}\n\n// NewSidecarFactory creates a new sidecar factory.\nfunc NewSidecarFactory(\n\ttelemetrySink TelemetrySink,\n) *SidecarFactory {\n\treturn &SidecarFactory{\n\t\tmetrics: newFactoryMetrics(telemetrySink),\n\t}\n}\n\n// BuildSidecars builds a sidecar.\nfunc (f *SidecarFactory) BuildSidecars(\n\tsignedBlk *ctypes.SignedBeaconBlock,\n\tbundle engineprimitives.BlobsBundle,\n) (types.BlobSidecars, error) {\n\tvar (\n\t\tblobs       = bundle.GetBlobs()\n\t\tcommitments = bundle.GetCommitments()\n\t\tproofs      = bundle.GetProofs()\n\t\tnumBlobs    = uint64(len(blobs))\n\t\tsidecars    = make([]*types.BlobSidecar, numBlobs)\n\t\tblk         = signedBlk.GetBeaconBlock()\n\t\tbody        = blk.GetBody()\n\t\theader      = blk.GetHeader()\n\t\tg           = errgroup.Group{}\n\t)\n\n\tstartTime := time.Now()\n\tdefer f.metrics.measureBuildSidecarsDuration(\n\t\tstartTime, math.U64(numBlobs),\n\t)\n\n\t// We can reuse the signature from the SignedBeaconBlock. Verifying the\n\t// signature will require the corresponding BeaconBlock to reconstruct the\n\t// signing root.\n\tsigHeader := ctypes.NewSignedBeaconBlockHeader(header, signedBlk.GetSignature())\n\n\tfor i := range numBlobs {\n\t\tg.Go(func() error {\n\t\t\tinclusionProof, err := f.BuildKZGInclusionProof(body, math.U64(i))\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tsidecars[i] = types.BuildBlobSidecar(\n\t\t\t\tmath.U64(i),\n\t\t\t\tsigHeader,\n\t\t\t\tblobs[i],\n\t\t\t\tcommitments[i],\n\t\t\t\tproofs[i],\n\t\t\t\tinclusionProof,\n\t\t\t)\n\t\t\treturn nil\n\t\t})\n\t}\n\n\treturn sidecars, g.Wait()\n}\n\n// BuildKZGInclusionProof builds a KZG inclusion proof.\nfunc (f *SidecarFactory) BuildKZGInclusionProof(\n\tbody *ctypes.BeaconBlockBody,\n\tindex math.U64,\n) ([]common.Root, error) {\n\tstartTime := time.Now()\n\tdefer f.metrics.measureBuildKZGInclusionProofDuration(startTime)\n\n\t// Build the merkle proof to the commitment within the\n\t// list of commitments.\n\tcommitmentsProof, err := f.BuildCommitmentProof(body, index)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Build the merkle proof for the body root.\n\tbodyProof, err := f.BuildBlockBodyProof(body)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// By property of the merkle tree, we can concatenate the\n\t// two proofs to get the final proof.\n\treturn append(commitmentsProof, bodyProof...), nil\n}\n\n// BuildBlockBodyProof builds a block body proof.\nfunc (f *SidecarFactory) BuildBlockBodyProof(\n\tbody *ctypes.BeaconBlockBody,\n) ([]common.Root, error) {\n\tstartTime := time.Now()\n\tdefer f.metrics.measureBuildBlockBodyProofDuration(startTime)\n\ttlrs, err := body.GetTopLevelRoots()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttree, err := merkle.NewTreeWithMaxLeaves[common.Root](\n\t\ttlrs,\n\t\tbody.Length()-1,\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn tree.MerkleProof(ctypes.KZGPosition)\n}\n\n// BuildCommitmentProof builds a commitment proof.\nfunc (f *SidecarFactory) BuildCommitmentProof(\n\tbody *ctypes.BeaconBlockBody,\n\tindex math.U64,\n) ([]common.Root, error) {\n\tstartTime := time.Now()\n\tdefer f.metrics.measureBuildCommitmentProofDuration(startTime)\n\tbodyTree, err := merkle.NewTreeWithMaxLeaves[common.Root](\n\t\tbody.GetBlobKzgCommitments().Leafify(),\n\t\tconstants.MaxBlobCommitmentsPerBlock,\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn bodyTree.MerkleProofWithMixin(index.Unwrap())\n}\n"
  },
  {
    "path": "da/blob/factory_metrics.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage blob\n\nimport (\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// factoryMetrics is a struct that contains metrics for the factory.\ntype factoryMetrics struct {\n\t// TelemetrySink is the sink for the metrics.\n\tsink TelemetrySink\n}\n\n// newFactoryMetrics creates a new factoryMetrics.\nfunc newFactoryMetrics(\n\tsink TelemetrySink,\n) *factoryMetrics {\n\treturn &factoryMetrics{\n\t\tsink: sink,\n\t}\n}\n\n// measureBuildSidecarsDuration measures the duration of the build sidecars.\nfunc (fm *factoryMetrics) measureBuildSidecarsDuration(\n\tstartTime time.Time, numSidecars math.U64,\n) {\n\tfm.sink.MeasureSince(\n\t\t\"beacon_kit.da.blob.factory.build_sidecar_duration\",\n\t\tstartTime,\n\t\t\"num_sidecars\",\n\t\tnumSidecars.Base10(),\n\t)\n}\n\n// measureBuildKZGInclusionProofDuration measures the duration of the build KZG\n// inclusion proof.\nfunc (fm *factoryMetrics) measureBuildKZGInclusionProofDuration(\n\tstartTime time.Time,\n) {\n\tfm.sink.MeasureSince(\n\t\t\"beacon_kit.da.blob.factory.build_kzg_inclusion_proof_duration\",\n\t\tstartTime,\n\t)\n}\n\n// measureBuildBlockBodyProofDuration measures the duration of the build block\n// body proof.\nfunc (fm *factoryMetrics) measureBuildBlockBodyProofDuration(\n\tstartTime time.Time,\n) {\n\tfm.sink.MeasureSince(\n\t\t\"beacon_kit.da.blob.factory.build_block_body_proof_duration\",\n\t\tstartTime,\n\t)\n}\n\n// measureBuildCommitmentProofDuration measures the duration of the build\n// commitment proof.\nfunc (fm *factoryMetrics) measureBuildCommitmentProofDuration(\n\tstartTime time.Time,\n) {\n\tfm.sink.MeasureSince(\n\t\t\"beacon_kit.da.blob.factory.build_commitment_proof_duration\",\n\t\tstartTime,\n\t)\n}\n"
  },
  {
    "path": "da/blob/factory_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage blob_test\n\n// TODO: Create a mock such that core/types doesn't need\n// to be imported here.\n\n// MockSpec is a mock implementation of the ChainSpec interface used for\n// testing.\ntype MockSpec struct{}\n\n// MaxBlobCommitmentsPerBlock returns the maximum number of blob commitments per\n// block.\n// This mock implementation always returns 16.\nfunc (m *MockSpec) MaxBlobCommitmentsPerBlock() uint64 {\n\treturn 16\n}\n\n// TODO: Re-enable once we can easily decouple from core/types.\n// func TestBuildKZGInclusionProof(t *testing.T) {\n// \tchainspec := &MockSpec{}\n// \tfactory := da.NewSidecarFactory[da.BeaconBlockBody](\n// \t\tchainspec,\n// \t\t5,\n// \t)\n// \tbody := mockBody()\n// \t// Test for a valid index\n//\n// \tindex := uint64(0)\n// \tproof, err := factory.BuildKZGInclusionProof(body, index)\n// \trequire.NoError(\n// \t\tt,\n// \t\terr,\n// \t\t\"Building KZG inclusion proof should not produce an error\",\n// \t)\n// \trequire.NotNil(t, proof, \"Proof should not be nil\")\n\n// \tbodyRoot, err := body.HashTreeRoot()\n// \trequire.NoError(t, err, \"Hashing the body should not produce an error\")\n\n// \t// Verify the valid KZG inclusion proof\n// \tvalidProof := merkle.VerifyProof(\n// \t\tbodyRoot,\n// \t\tbody.GetBlobKzgCommitments()[index].ToHashChunks()[0],\n// \t\ttypes.KZGOffset(chainspec.MaxBlobCommitmentsPerBlock())+index,\n// \t\tproof,\n// \t)\n// \trequire.True(t, validProof, \"The KZG inclusion proof should be valid\")\n\n// \t// Test for an invalid index\n// \tinvalidIndex := uint64(100) // Assuming this is out of range\n// \t_, err = factory.BuildKZGInclusionProof(body, invalidIndex)\n// \trequire.Error(\n// \t\tt,\n// \t\terr,\n// \t\t\"Building KZG inclusion proof with invalid index should produce an error\",\n// \t)\n\n// \trequire.True(t, validProof, \"The KZG inclusion proof should be valid\")\n\n// \t// Attempt to verify the invalid KZG inclusion proof and expect failure\n// \tinvalidProof, err := factory.BuildKZGInclusionProof(body, invalidIndex)\n// \trequire.Error(\n// \t\tt,\n// \t\terr,\n// \t\t\"Building KZG inclusion proof should produce an error\",\n// \t)\n// \tvalidInvalidProof := merkle.VerifyProof(\n// \t\tbodyRoot,\n// \t\tbody.GetBlobKzgCommitments()[index].ToHashChunks()[0],\n// \t\ttypes.KZGOffset(chainspec.MaxBlobCommitmentsPerBlock())+index,\n// \t\tinvalidProof,\n// \t)\n// \trequire.False(\n// \t\tt,\n// \t\tvalidInvalidProof,\n// \t\t\"The KZG inclusion proof for an invalid index should be invalid\",\n// \t)\n// }\n\n// func mockBody() da.BeaconBlockBody {\n// \t// Create a real ExecutionPayloadDeneb and BeaconBlockBody\n// \texecutionPayload := &engineprimitives.ExecutionPayload{\n// \t\tParentHash:    common.HexToHash(\"0x01\"),\n// \t\tFeeRecipient:  common.HexToAddress(\"0x02\"),\n// \t\tStateRoot:     common.HexToHash(\"0x03\"),\n// \t\tReceiptsRoot:  common.HexToHash(\"0x04\"),\n// \t\tLogsBloom:     bytes.Repeat([]byte(\"b\"), 256),\n// \t\tRandom:        common.HexToHash(\"0x05\"),\n// \t\tBaseFeePerGas: math.Wei(bytes.Repeat([]byte(\"f\"), 32)),\n// \t\tBlockHash:     common.HexToHash(\"0x06\"),\n// \t\tTransactions:  [][]byte{[]byte(\"tx1\"), []byte(\"tx2\")},\n// \t\tExtraData:     []byte(\"extra\"),\n// \t}\n\n// \treturn &types.BeaconBlockBodyDeneb{\n// \t\tRandaoReveal: [96]byte{0x01},\n// \t\tEth1Data: &primitives.Eth1Data{\n// \t\t\tDepositRoot:  common.Root{},\n// \t\t\tDepositCount: 0,\n// \t\t\tBlockHash:    common.ZeroHash,\n// \t\t},\n// \t\tExecutionPayload: executionPayload,\n// \t\tBlobKzgCommitments: kzg.Commitments{\n// \t\t\t[48]byte(bytes.Repeat([]byte{0x01}, 48)),\n// \t\t\t[48]byte(bytes.Repeat([]byte{0x10}, 48)),\n// \t\t\t[48]byte(bytes.Repeat([]byte{0x11}, 48)),\n// \t\t},\n// \t}\n// }\n"
  },
  {
    "path": "da/blob/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage blob\n\nimport (\n\t\"time\"\n)\n\n// TelemetrySink is an interface for sending metrics to a telemetry backend.\ntype TelemetrySink interface {\n\t// MeasureSince measures the time since the provided start time,\n\t// identified by the provided keys.\n\tMeasureSince(key string, start time.Time, args ...string)\n}\n"
  },
  {
    "path": "da/blob/processor.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage blob\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/da/kzg\"\n\tdastore \"github.com/berachain/beacon-kit/da/store\"\n\tdatypes \"github.com/berachain/beacon-kit/da/types\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// Processor is the blob processor that handles the processing and verification\n// of blob sidecars.\ntype Processor struct {\n\t// logger is used to log information and errors.\n\tlogger log.Logger\n\t// verifier is responsible for verifying the blobs.\n\tverifier *verifier\n\t// metrics is used to collect and report processor metrics.\n\tmetrics *processorMetrics\n}\n\n// NewProcessor creates a new blob processor.\nfunc NewProcessor(\n\tlogger log.Logger,\n\tproofVerifier kzg.BlobProofVerifier,\n\ttelemetrySink TelemetrySink,\n) *Processor {\n\tverifier := newVerifier(proofVerifier, telemetrySink)\n\n\treturn &Processor{\n\t\tlogger:   logger,\n\t\tverifier: verifier,\n\t\tmetrics:  newProcessorMetrics(telemetrySink),\n\t}\n}\n\n// VerifySidecars verifies the blobs and ensures they match the local state.\nfunc (sp *Processor) VerifySidecars(\n\tctx context.Context,\n\tsidecars datypes.BlobSidecars,\n\tblkHeader *ctypes.BeaconBlockHeader,\n\tkzgCommitments eip4844.KZGCommitments[common.ExecutionHash],\n) error {\n\tdefer sp.metrics.measureVerifySidecarsDuration(\n\t\ttime.Now(), math.U64(len(sidecars)),\n\t)\n\n\t// Abort if there are no blobs to store.\n\tif len(sidecars) == 0 {\n\t\treturn nil\n\t}\n\n\t// Verify the blobs and ensure they match the local state.\n\treturn sp.verifier.verifySidecars(\n\t\tctx,\n\t\tsidecars,\n\t\tblkHeader,\n\t\tkzgCommitments,\n\t)\n}\n\n// ProcessSidecars processes the blobs and ensures they match the local state.\nfunc (sp *Processor) ProcessSidecars(\n\tavs *dastore.Store,\n\tsidecars datypes.BlobSidecars,\n) error {\n\tdefer sp.metrics.measureProcessSidecarsDuration(\n\t\ttime.Now(), math.U64(len(sidecars)),\n\t)\n\n\t// Abort if there are no blobs to store.\n\tif len(sidecars) == 0 {\n\t\treturn nil\n\t}\n\n\t// If we have reached this point, we can safely assume that the blobs are\n\t// valid and can be persisted, as well as that index 0 is filled.\n\treturn avs.Persist(sidecars)\n}\n"
  },
  {
    "path": "da/blob/processor_metrics.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage blob\n\nimport (\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// processorMetrics is a struct that contains metrics for the processor.\ntype processorMetrics struct {\n\t// TelemetrySink is the sink for the metrics.\n\tsink TelemetrySink\n}\n\n// newProcessorMetrics creates a new processorMetrics.\nfunc newProcessorMetrics(\n\tsink TelemetrySink,\n) *processorMetrics {\n\treturn &processorMetrics{\n\t\tsink: sink,\n\t}\n}\n\n// measureVerifySidecarsDuration measures the duration of the blob verification.\nfunc (pm *processorMetrics) measureVerifySidecarsDuration(\n\tstartTime time.Time,\n\tnumSidecars math.U64,\n) {\n\tpm.sink.MeasureSince(\n\t\t\"beacon_kit.da.blob.processor.verify_blobs_duration\",\n\t\tstartTime,\n\t\t\"num_sidecars\",\n\t\tnumSidecars.Base10(),\n\t)\n}\n\n// measureProcessSidecarsDuration measures the duration of the blob processing.\nfunc (pm *processorMetrics) measureProcessSidecarsDuration(\n\tstartTime time.Time,\n\tnumSidecars math.U64,\n) {\n\tpm.sink.MeasureSince(\n\t\t\"beacon_kit.da.blob.processor.process_blob_duration\",\n\t\tstartTime,\n\t\t\"num_sidecars\",\n\t\tnumSidecars.Base10(),\n\t)\n}\n"
  },
  {
    "path": "da/blob/verifier.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage blob\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/da/kzg\"\n\tdatypes \"github.com/berachain/beacon-kit/da/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\n// verifier is responsible for verifying blobs, including their\n// inclusion and KZG proofs.\ntype verifier struct {\n\t// proofVerifier is used to verify the KZG proofs of the blobs.\n\tproofVerifier kzg.BlobProofVerifier\n\t// metrics collects and reports metrics related to the verification process.\n\tmetrics *verifierMetrics\n}\n\n// newVerifier creates a new Verifier with the given proof verifier.\nfunc newVerifier(\n\tproofVerifier kzg.BlobProofVerifier,\n\ttelemetrySink TelemetrySink,\n) *verifier {\n\treturn &verifier{\n\t\tproofVerifier: proofVerifier,\n\t\tmetrics:       newVerifierMetrics(telemetrySink),\n\t}\n}\n\n// verifySidecars verifies the blobs for both inclusion as well\n// as the KZG proofs.\nfunc (bv *verifier) verifySidecars(\n\tctx context.Context,\n\tsidecars datypes.BlobSidecars,\n\tblkHeader *ctypes.BeaconBlockHeader,\n\tkzgCommitments eip4844.KZGCommitments[common.ExecutionHash],\n) error {\n\tnumSidecars := uint64(len(sidecars))\n\tdefer bv.metrics.measureVerifySidecarsDuration(\n\t\ttime.Now(), math.U64(numSidecars),\n\t\tbv.proofVerifier.GetImplementation(),\n\t)\n\n\tg, _ := errgroup.WithContext(ctx)\n\n\t// Create lookup table for each blob sidecar commitment and indicies.\n\tblobSidecarCommitments := make(map[eip4844.KZGCommitment]struct{})\n\tblobSidecarIndicies := make(map[uint64]struct{})\n\n\t// Validate sidecar fields against data from the BeaconBlock.\n\tfor i, s := range sidecars {\n\t\t// Fill lookup table with commitments from the blob sidecars.\n\t\tblobSidecarCommitments[s.GetKzgCommitment()] = struct{}{}\n\n\t\t// We should only have unique indexes.\n\t\tif _, exists := blobSidecarIndicies[s.GetIndex()]; exists {\n\t\t\treturn fmt.Errorf(\"duplicate sidecar Index: %d\", i)\n\t\t}\n\t\tblobSidecarIndicies[s.GetIndex()] = struct{}{}\n\n\t\t// This check happens outside the goroutines so that we do not\n\t\t// process the inclusion proofs before validating the index.\n\t\tif s.GetIndex() >= numSidecars {\n\t\t\treturn fmt.Errorf(\"invalid sidecar Index: %d\", i)\n\t\t}\n\n\t\t// Check BlobSidecar.Header equality with BeaconBlockHeader\n\t\tif !s.GetBeaconBlockHeader().Equals(blkHeader) {\n\t\t\treturn fmt.Errorf(\"unequal block header: idx: %d\", i)\n\t\t}\n\t}\n\n\t// Ensure each commitment from the BeaconBlock has a corresponding sidecar commitment.\n\tfor _, kzgCommitment := range kzgCommitments {\n\t\tif _, exists := blobSidecarCommitments[kzgCommitment]; !exists {\n\t\t\treturn fmt.Errorf(\"missing kzg commitment: %s\", kzgCommitment)\n\t\t}\n\t}\n\n\t// Verify the inclusion proofs on the blobs concurrently.\n\tg.Go(func() error {\n\t\treturn bv.verifyInclusionProofs(sidecars)\n\t})\n\n\t// Verify the KZG proofs on the blobs concurrently.\n\tg.Go(func() error {\n\t\treturn bv.verifyKZGProofs(sidecars)\n\t})\n\n\t// Wait for all goroutines to finish and return the result.\n\treturn g.Wait()\n}\n\nfunc (bv *verifier) verifyInclusionProofs(\n\tscs datypes.BlobSidecars,\n) error {\n\tstartTime := time.Now()\n\tdefer bv.metrics.measureVerifyInclusionProofsDuration(\n\t\tstartTime, math.U64(len(scs)),\n\t)\n\n\treturn scs.VerifyInclusionProofs()\n}\n\n// verifyKZGProofs verifies the sidecars.\nfunc (bv *verifier) verifyKZGProofs(\n\tscs datypes.BlobSidecars,\n) error {\n\tstart := time.Now()\n\tdefer bv.metrics.measureVerifyKZGProofsDuration(\n\t\tstart, math.U64(len(scs)),\n\t\tbv.proofVerifier.GetImplementation(),\n\t)\n\n\tswitch len(scs) {\n\tcase 0:\n\t\treturn nil\n\tcase 1:\n\t\tblob := scs[0].GetBlob()\n\t\t// This method is fastest for a single blob.\n\t\treturn bv.proofVerifier.VerifyBlobProof(\n\t\t\t&blob,\n\t\t\tscs[0].GetKzgProof(),\n\t\t\tscs[0].GetKzgCommitment(),\n\t\t)\n\tdefault:\n\t\t// For multiple blobs batch verification is more performant\n\t\t// than verifying each blob individually (even when done in parallel).\n\t\treturn bv.proofVerifier.VerifyBlobProofBatch(kzg.ArgsFromSidecars(scs))\n\t}\n}\n"
  },
  {
    "path": "da/blob/verifier_metrics.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage blob\n\nimport (\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// verifierMetrics is a struct that contains metrics for the verifier.\ntype verifierMetrics struct {\n\t// TelemetrySink is the sink for the metrics.\n\tsink TelemetrySink\n}\n\n// newVerifierMetrics creates a new verifierMetrics.\nfunc newVerifierMetrics(\n\tsink TelemetrySink,\n) *verifierMetrics {\n\treturn &verifierMetrics{\n\t\tsink: sink,\n\t}\n}\n\n// measureVerifySidecarsDuration measures the duration of the blob verification.\nfunc (vm *verifierMetrics) measureVerifySidecarsDuration(\n\tstartTime time.Time,\n\tnumSidecars math.U64,\n\tkzgImplementation string,\n) {\n\tvm.sink.MeasureSince(\n\t\t\"beacon_kit.da.blob.verifier.verify_blobs_duration\",\n\t\tstartTime,\n\t\t\"num_sidecars\",\n\t\tnumSidecars.Base10(),\n\t\t\"kzg_implementation\",\n\t\tkzgImplementation,\n\t)\n}\n\n// measureVerifyInclusionProofsDuration measures the duration of the inclusion\n// proofs verification.\nfunc (vm *verifierMetrics) measureVerifyInclusionProofsDuration(\n\tstartTime time.Time,\n\tnumSidecars math.U64,\n) {\n\tvm.sink.MeasureSince(\n\t\t\"beacon_kit.da.blob.verifier.verify_inclusion_proofs_duration\",\n\t\tstartTime,\n\t\t\"num_sidecars\",\n\t\tnumSidecars.Base10(),\n\t)\n}\n\n// measureVerifyKZGProofsDuration measures the duration of the KZG proofs\n// verification.\nfunc (vm *verifierMetrics) measureVerifyKZGProofsDuration(\n\tstartTime time.Time,\n\tnumSidecars math.U64,\n\tkzgImplementation string,\n) {\n\tvm.sink.MeasureSince(\n\t\t\"beacon_kit.da.blob.verifier.verify_kzg_proofs_duration\",\n\t\tstartTime,\n\t\t\"num_sidecars\",\n\t\tnumSidecars.Base10(),\n\t\t\"kzg_implementation\",\n\t\tkzgImplementation,\n\t)\n}\n"
  },
  {
    "path": "da/kzg/config.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage kzg\n\nconst (\n\t// defaultTrustedSetupPath is the default path to the trusted setup.\n\tdefaultTrustedSetupPath = \"./testing/files/kzg-trusted-setup.json\"\n\t// defaultImplementation is the default KZG implementation to use.\n\t// Options are `crate-crypto/go-kzg-4844`.\n\tdefaultImplementation = \"crate-crypto/go-kzg-4844\"\n)\n\ntype Config struct {\n\t// TrustedSetupPath is the path to the trusted setup.\n\tTrustedSetupPath string `mapstructure:\"trusted-setup-path\"`\n\t// Implementation is the KZG implementation to use.\n\tImplementation string `mapstructure:\"implementation\"`\n}\n\n// DefaultConfig returns the default configuration.\nfunc DefaultConfig() Config {\n\treturn Config{\n\t\tTrustedSetupPath: defaultTrustedSetupPath,\n\t\tImplementation:   defaultImplementation,\n\t}\n}\n"
  },
  {
    "path": "da/kzg/config_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage kzg_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/da/kzg\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestDefaultConfig(t *testing.T) {\n\tt.Parallel()\n\tcfg := kzg.DefaultConfig()\n\trequire.Equal(\n\t\tt,\n\t\t\"./testing/files/kzg-trusted-setup.json\",\n\t\tcfg.TrustedSetupPath,\n\t)\n\trequire.Equal(\n\t\tt,\n\t\t\"crate-crypto/go-kzg-4844\",\n\t\tcfg.Implementation,\n\t)\n}\n"
  },
  {
    "path": "da/kzg/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage kzg\n\nimport \"github.com/berachain/beacon-kit/errors\"\n\nvar (\n\t// ErrUnsupportedKzgImplementation is returned when an unsupported KZG\n\t// implementation is requested.\n\tErrUnsupportedKzgImplementation = errors.New(\n\t\t\"unsupported KZG implementation\",\n\t)\n)\n"
  },
  {
    "path": "da/kzg/gokzg/gokzg.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage gokzg\n\nimport (\n\t\"unsafe\"\n\n\t\"github.com/berachain/beacon-kit/da/kzg/types\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\tgokzg4844 \"github.com/crate-crypto/go-kzg-4844\"\n)\n\nconst Implementation = \"crate-crypto/go-kzg-4844\"\n\n// Verifier is a KZG verifier that uses the Go implementation of KZG.\ntype Verifier struct {\n\t*gokzg4844.Context\n}\n\n// NewVerifier creates a new GoKZGVerifier.\nfunc NewVerifier(ts *gokzg4844.JSONTrustedSetup) (*Verifier, error) {\n\tctx, err := gokzg4844.NewContext4096(ts)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Verifier{ctx}, nil\n}\n\n// GetImplementation returns the implementation of the verifier.\nfunc (v Verifier) GetImplementation() string {\n\treturn Implementation\n}\n\n// VerifyBlobProof verifies the KZG proof that the polynomial represented by the\n// blob evaluated at the given point is the claimed value.\nfunc (v Verifier) VerifyBlobProof(\n\tblob *eip4844.Blob,\n\tproof eip4844.KZGProof,\n\tcommitment eip4844.KZGCommitment,\n) error {\n\treturn v.Context.\n\t\tVerifyBlobKZGProof(\n\t\t\t(*gokzg4844.Blob)(blob),\n\t\t\t(gokzg4844.KZGCommitment)(commitment),\n\t\t\t(gokzg4844.KZGProof)(proof))\n}\n\n// VerifyBlobProofBatch verifies the KZG proof that the polynomial represented\n// by the blob evaluated at the given point is the claimed value.\n// It is more efficient than VerifyBlobProof when verifying multiple proofs.\nfunc (v Verifier) VerifyBlobProofBatch(\n\targs *types.BlobProofArgs,\n) error {\n\tblobs := make([]gokzg4844.Blob, len(args.Blobs))\n\tfor i := range args.Blobs {\n\t\tblobs[i] = *(*gokzg4844.Blob)(args.Blobs[i])\n\t}\n\n\t//#nosec:G103 // \"use of unsafe calls should be audited\" lmeow.\n\treturn v.Context.\n\t\tVerifyBlobKZGProofBatch(\n\t\t\tblobs,\n\t\t\t*(*[]gokzg4844.KZGCommitment)(\n\t\t\t\tunsafe.Pointer(&args.Commitments)),\n\t\t\t*(*[]gokzg4844.KZGProof)(unsafe.Pointer(&args.Proofs)),\n\t\t)\n}\n"
  },
  {
    "path": "da/kzg/gokzg/gokzg_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage gokzg_test\n\nimport (\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/da/kzg/gokzg\"\n\t\"github.com/berachain/beacon-kit/da/kzg/types\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n\tgokzg4844 \"github.com/crate-crypto/go-kzg-4844\"\n\t\"github.com/spf13/afero\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nvar baseDir = \"../../../testing/files/\"\n\nfunc TestVerifyBlobProof(t *testing.T) {\n\tt.Parallel()\n\tverifier, err := setupVerifier()\n\trequire.NoError(t, err)\n\tvalidBlob, validProof, validCommitment := setupTestData(\n\t\tt, \"test_data.json\")\n\ttestCases := []struct {\n\t\tname        string\n\t\tblob        *eip4844.Blob\n\t\tproof       eip4844.KZGProof\n\t\tcommitment  eip4844.KZGCommitment\n\t\texpectError bool\n\t}{\n\t\t{\n\t\t\tname:        \"Valid Proof\",\n\t\t\tblob:        validBlob,\n\t\t\tproof:       validProof,\n\t\t\tcommitment:  validCommitment,\n\t\t\texpectError: false,\n\t\t},\n\t\t{\n\t\t\tname:        \"Short buffer for commitment\",\n\t\t\tblob:        &eip4844.Blob{},\n\t\t\tproof:       eip4844.KZGProof{},\n\t\t\tcommitment:  eip4844.KZGCommitment{},\n\t\t\texpectError: true,\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\terrVerify := verifier.VerifyBlobProof(\n\t\t\t\ttc.blob,\n\t\t\t\ttc.proof,\n\t\t\t\ttc.commitment,\n\t\t\t)\n\t\t\tif tc.expectError {\n\t\t\t\trequire.Error(t, errVerify)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, errVerify)\n\t\t\t}\n\t\t})\n\t}\n}\n\n// TestVerifyBlobProofBatch tests the VerifyBlobProofBatch function\n// for valid proofs.\nfunc TestVerifyBlobProofBatch(t *testing.T) {\n\tt.Parallel()\n\t// Load the test data\n\tverifier, err := setupVerifier()\n\trequire.NoError(t, err)\n\tfs := afero.NewOsFs()\n\tfullPath := filepath.Join(baseDir, \"test_data_batch.json\")\n\tfile, err := afero.ReadFile(fs, fullPath)\n\trequire.NoError(t, err)\n\n\t// Unmarshal the JSON data\n\tvar data struct {\n\t\tBlobs       []string `json:\"blobs\"`\n\t\tProofs      []string `json:\"proofs\"`\n\t\tCommitments []string `json:\"commitments\"`\n\t}\n\terr = json.Unmarshal(file, &data)\n\trequire.NoError(t, err)\n\n\t// Convert the data to the types expected by VerifyBlobProofBatch\n\targs := &types.BlobProofArgs{\n\t\tBlobs:       make([]*eip4844.Blob, len(data.Blobs)),\n\t\tProofs:      make([]eip4844.KZGProof, len(data.Proofs)),\n\t\tCommitments: make([]eip4844.KZGCommitment, len(data.Commitments)),\n\t}\n\tfor i := range data.Blobs {\n\t\tvar blob eip4844.Blob\n\t\terr = blob.UnmarshalJSON([]byte(`\"` + data.Blobs[i] + `\"`))\n\t\trequire.NoError(t, err)\n\t\targs.Blobs[i] = &blob\n\n\t\tvar proof eip4844.KZGProof\n\t\terr = proof.UnmarshalJSON([]byte(`\"` + data.Proofs[i] + `\"`))\n\t\trequire.NoError(t, err)\n\t\targs.Proofs[i] = proof\n\n\t\tvar commitment eip4844.KZGCommitment\n\t\terr = commitment.UnmarshalJSON([]byte(`\"` + data.Commitments[i] + `\"`))\n\t\trequire.NoError(t, err)\n\t\targs.Commitments[i] = commitment\n\t}\n\n\terr = verifier.VerifyBlobProofBatch(args)\n\trequire.NoError(t, err)\n}\n\nfunc TestGetImplementation(t *testing.T) {\n\tt.Parallel()\n\tverifier, err := setupVerifier()\n\trequire.NoError(t, err)\n\n\timpl := verifier.GetImplementation()\n\trequire.Equal(t, gokzg.Implementation, impl)\n}\n\n// setupVerifier reads the trusted setup file and creates a new GoKZGVerifier.\nfunc setupVerifier() (*gokzg.Verifier, error) {\n\tfs := afero.NewOsFs()\n\tfileName := \"kzg-trusted-setup.json\"\n\tfullPath := filepath.Join(baseDir, fileName)\n\tfile, err := afero.ReadFile(fs, fullPath)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar ts gokzg4844.JSONTrustedSetup\n\tif errUnmarshal := json.Unmarshal(file, &ts); errUnmarshal != nil {\n\t\treturn nil, errUnmarshal\n\t}\n\n\tverifier, errVerifier := gokzg.NewVerifier(&ts)\n\tif errVerifier != nil {\n\t\treturn nil, errVerifier\n\t}\n\treturn verifier, nil\n}\n\nfunc setupTestData(t *testing.T, fileName string) (\n\t*eip4844.Blob, eip4844.KZGProof, eip4844.KZGCommitment,\n) {\n\tt.Helper()\n\n\tfilePath := filepath.Join(baseDir, fileName)\n\tdata, err := afero.ReadFile(afero.NewOsFs(), filePath)\n\trequire.NoError(t, err)\n\ttype Test struct {\n\t\tInput struct {\n\t\t\tBlob       string `json:\"blob\"`\n\t\t\tCommitment string `json:\"commitment\"`\n\t\t\tProof      string `json:\"proof\"`\n\t\t} `json:\"input\"`\n\t}\n\tvar test Test\n\n\terr = json.Unmarshal(data, &test)\n\trequire.NoError(t, err)\n\n\tvar blob eip4844.Blob\n\terrBlob := blob.UnmarshalJSON([]byte(`\"` + test.Input.Blob + `\"`))\n\trequire.NoError(t, errBlob)\n\n\tvar commitment eip4844.KZGCommitment\n\n\terrCommitment := commitment.UnmarshalJSON([]byte(\n\t\t`\"` + test.Input.Commitment + `\"`))\n\trequire.NoError(t, errCommitment)\n\n\tvar proof eip4844.KZGProof\n\n\terrProof := proof.UnmarshalJSON([]byte(`\"` + test.Input.Proof + `\"`))\n\trequire.NoError(t, errProof)\n\n\treturn &blob, proof, commitment\n}\n"
  },
  {
    "path": "da/kzg/noop/noop.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage noop\n\nimport (\n\t\"github.com/berachain/beacon-kit/da/kzg/types\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n)\n\n// Verifier is a no-op KZG proof verifier.\ntype Verifier struct{}\n\n// NewVerifier creates a new GoKZGVerifier.\nfunc NewVerifier() *Verifier {\n\treturn &Verifier{}\n}\n\n// GetImplementation returns the implementation of the verifier.\nfunc (v Verifier) GetImplementation() string {\n\treturn \"noop\"\n}\n\n// VerifyBlobProof is a no-op.\nfunc (v Verifier) VerifyBlobProof(\n\t*eip4844.Blob,\n\teip4844.KZGProof,\n\teip4844.KZGCommitment,\n) error {\n\treturn nil\n}\n\n// VerifyBlobProofBatch is a no-op.\nfunc (v Verifier) VerifyBlobProofBatch(\n\t*types.BlobProofArgs,\n) error {\n\treturn nil\n}\n"
  },
  {
    "path": "da/kzg/noop/noop_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage noop_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/da/kzg/noop\"\n\t\"github.com/berachain/beacon-kit/da/kzg/types\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n)\n\nfunc TestVerifyBlobProof(t *testing.T) {\n\tt.Parallel()\n\tverifier := noop.NewVerifier()\n\terr := verifier.VerifyBlobProof(\n\t\t&eip4844.Blob{},\n\t\teip4844.KZGProof{},\n\t\teip4844.KZGCommitment{},\n\t)\n\tif err != nil {\n\t\tt.Fatalf(\"expected no error, got %v\", err)\n\t}\n}\n\nfunc TestVerifyBlobProofBatch(t *testing.T) {\n\tt.Parallel()\n\tverifier := noop.NewVerifier()\n\targs := &types.BlobProofArgs{\n\t\tBlobs:       []*eip4844.Blob{{}},\n\t\tProofs:      []eip4844.KZGProof{{}},\n\t\tCommitments: []eip4844.KZGCommitment{{}},\n\t}\n\terr := verifier.VerifyBlobProofBatch(args)\n\tif err != nil {\n\t\tt.Fatalf(\"expected no error, got %v\", err)\n\t}\n}\n"
  },
  {
    "path": "da/kzg/proof.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage kzg\n\nimport (\n\t\"github.com/berachain/beacon-kit/da/kzg/gokzg\"\n\tkzgtypes \"github.com/berachain/beacon-kit/da/kzg/types\"\n\tdatypes \"github.com/berachain/beacon-kit/da/types\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\tgokzg4844 \"github.com/crate-crypto/go-kzg-4844\"\n)\n\n// BlobProofVerifier is a verifier for blobs.\ntype BlobProofVerifier interface {\n\t// GetImplementation returns the implementation of the verifier.\n\tGetImplementation() string\n\t// VerifyBlobProof verifies that the blob data corresponds to the provided\n\t// commitment.\n\tVerifyBlobProof(\n\t\tblob *eip4844.Blob,\n\t\tproof eip4844.KZGProof,\n\t\tcommitment eip4844.KZGCommitment,\n\t) error\n\t// VerifyBlobProofBatch verifies the KZG proof that the polynomial\n\t// represented\n\t// by the blob evaluated at the given point is the claimed value.\n\t// For most implementations it is more efficient than VerifyBlobProof when\n\t// verifying multiple proofs.\n\tVerifyBlobProofBatch(*kzgtypes.BlobProofArgs) error\n}\n\n// NewBlobProofVerifier creates a new BlobVerifier with the given\n// implementation.\nfunc NewBlobProofVerifier(\n\timpl string,\n\tts *gokzg4844.JSONTrustedSetup,\n) (BlobProofVerifier, error) {\n\tswitch impl {\n\tcase gokzg.Implementation:\n\t\treturn gokzg.NewVerifier(ts)\n\tdefault:\n\t\treturn nil, errors.Wrapf(\n\t\t\tErrUnsupportedKzgImplementation,\n\t\t\t\"supplied: %s, supported: %s\",\n\t\t\timpl, gokzg.Implementation,\n\t\t)\n\t}\n}\n\n// ArgsFromSidecars converts a BlobSidecars to a slice of BlobProofArgs.\nfunc ArgsFromSidecars(\n\tscs datypes.BlobSidecars,\n) *kzgtypes.BlobProofArgs {\n\tproofArgs := &kzgtypes.BlobProofArgs{\n\t\tBlobs:       make([]*eip4844.Blob, len(scs)),\n\t\tProofs:      make([]eip4844.KZGProof, len(scs)),\n\t\tCommitments: make([]eip4844.KZGCommitment, len(scs)),\n\t}\n\tfor i, sidecar := range scs {\n\t\tblob := sidecar.GetBlob()\n\t\tproofArgs.Blobs[i] = &blob\n\t\tproofArgs.Proofs[i] = sidecar.GetKzgProof()\n\t\tproofArgs.Commitments[i] = sidecar.GetKzgCommitment()\n\t}\n\treturn proofArgs\n}\n"
  },
  {
    "path": "da/kzg/proof_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage kzg_test\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/da/kzg\"\n\t\"github.com/berachain/beacon-kit/da/kzg/gokzg\"\n\t\"github.com/berachain/beacon-kit/da/types\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n\tgokzg4844 \"github.com/crate-crypto/go-kzg-4844\"\n\t\"github.com/spf13/afero\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nvar baseDir = \"../../testing/files/\"\n\nfunc TestNewBlobProofVerifier_KzgImpl(t *testing.T) {\n\tt.Parallel()\n\tts, err := loadTrustedSetupFromFile()\n\trequire.NoError(t, err)\n\n\tverifier, err := kzg.NewBlobProofVerifier(gokzg.Implementation, ts)\n\trequire.NoError(t, err)\n\trequire.NotNil(t, verifier)\n\trequire.Equal(t, gokzg.Implementation, verifier.GetImplementation())\n}\n\nfunc TestNewBlobProofVerifier_InvalidImpl(t *testing.T) {\n\tt.Parallel()\n\tts, err := loadTrustedSetupFromFile()\n\trequire.NoError(t, err)\n\n\tinvalidImpl := \"invalid-implementation\"\n\t_, err = kzg.NewBlobProofVerifier(invalidImpl, ts)\n\trequire.ErrorIs(t, err, kzg.ErrUnsupportedKzgImplementation)\n}\n\n// loadTrustedSetupFromFile is the helper function.\nfunc loadTrustedSetupFromFile() (*gokzg4844.JSONTrustedSetup, error) {\n\tfileName := \"kzg-trusted-setup.json\"\n\tfullPath := filepath.Join(baseDir, fileName)\n\tdata, err := os.ReadFile(fullPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar ts gokzg4844.JSONTrustedSetup\n\terr = json.Unmarshal(data, &ts)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &ts, nil\n}\n\nfunc TestArgsFromSidecars(t *testing.T) {\n\tt.Parallel()\n\tfs := afero.NewOsFs()\n\tfullPath := filepath.Join(baseDir, \"test_data.json\")\n\tfile, err := afero.ReadFile(fs, fullPath)\n\trequire.NoError(t, err)\n\n\ttype Data struct {\n\t\tInput struct {\n\t\t\tBlob       string `json:\"blob\"`\n\t\t\tCommitment string `json:\"commitment\"`\n\t\t\tProof      string `json:\"proof\"`\n\t\t} `json:\"input\"`\n\t}\n\tvar data Data\n\n\terr = json.Unmarshal(file, &data)\n\trequire.NoError(t, err)\n\n\tscs := types.BlobSidecars{\n\t\t{\n\t\t\tBlob:          eip4844.Blob{data.Input.Blob[0]},\n\t\t\tKzgProof:      eip4844.KZGProof{data.Input.Proof[0]},\n\t\t\tKzgCommitment: eip4844.KZGCommitment{data.Input.Commitment[0]},\n\t\t},\n\t}\n\n\targs := kzg.ArgsFromSidecars(scs)\n\n\trequire.Len(t, args.Blobs, 1)\n\trequire.Len(t, args.Proofs, 1)\n\trequire.Len(t, args.Commitments, 1)\n}\n"
  },
  {
    "path": "da/kzg/types/args.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n)\n\n// BlobProofArgs represents the arguments for a blob proof.\ntype BlobProofArgs struct {\n\t// Blob is the blob.\n\tBlobs []*eip4844.Blob\n\t// Proof is the KZG proof.\n\tProofs []eip4844.KZGProof\n\t// Commitment is the KZG commitment.\n\tCommitments []eip4844.KZGCommitment\n}\n"
  },
  {
    "path": "da/store/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage store\n\nimport \"github.com/berachain/beacon-kit/errors\"\n\nvar (\n\t// ErrAttemptedToStoreNilSidecar is returned when an attempt is made to\n\t// store a\n\t// nil sidecar.\n\tErrAttemptedToStoreNilSidecar = errors.New(\"attempted to store nil sidecar\")\n\n\t// ErrAttemptedToVerifyNilSidecars is returned when an attempt is made to\n\t// verify\n\t// nil sidecars.\n\tErrAttemptedToVerifyNilSidecars = errors.New(\n\t\t\"attempted to verify nil sidecars\",\n\t)\n)\n"
  },
  {
    "path": "da/store/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage store\n\n// IndexDB is a database that allows prefixing by index.\ntype IndexDB interface {\n\tHas(index uint64, key []byte) (bool, error)\n\tGet(index uint64, key []byte) ([]byte, error)\n\tSet(index uint64, key []byte, value []byte) error\n\n\t// Prune returns error if start > end.\n\tPrune(start uint64, end uint64) error\n\n\t// GetByIndex takes the database index and returns all associated entries,\n\t// expecting database keys to follow the prefix() format. If index does not\n\t// exist in the DB for any reason (pruned, invalid index), an empty list is\n\t// returned with no error.\n\tGetByIndex(index uint64) ([][]byte, error)\n\n\t// DeleteByIndex removes all entries at the specified index\n\tDeleteByIndex(index uint64) error\n}\n"
  },
  {
    "path": "da/store/store.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage store\n\nimport (\n\t\"context\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/da/types\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// Store is the default implementation of the AvailabilityStore.\ntype Store struct {\n\t// IndexDB is a basic database interface.\n\tIndexDB\n\t// logger is used for logging.\n\tlogger log.Logger\n}\n\n// New creates a new instance of the AvailabilityStore.\nfunc New(\n\tdb IndexDB,\n\tlogger log.Logger,\n) *Store {\n\treturn &Store{\n\t\tIndexDB: db,\n\t\tlogger:  logger,\n\t}\n}\n\n// IsDataAvailable ensures that all blobs referenced in the block are\n// stored before it returns without an error.\nfunc (s *Store) IsDataAvailable(\n\t_ context.Context,\n\tslot math.Slot,\n\tbody *ctypes.BeaconBlockBody,\n) bool {\n\tfor _, commitment := range body.GetBlobKzgCommitments() {\n\t\t// Check if the block data is available in the IndexDB\n\t\tblockData, err := s.IndexDB.Has(slot.Unwrap(), commitment[:])\n\t\tif err != nil || !blockData {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// GetBlobSidecars fetches the sidecars for a specific slot.\nfunc (s *Store) GetBlobSidecars(slot math.Slot) (types.BlobSidecars, error) {\n\tsidecarBzs, err := s.IndexDB.GetByIndex(slot.Unwrap())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tsidecars := make(types.BlobSidecars, 0, len(sidecarBzs))\n\tfor _, sidecarBz := range sidecarBzs {\n\t\tsidecar := new(types.BlobSidecar)\n\t\tif err = ssz.Unmarshal(sidecarBz, sidecar); err != nil {\n\t\t\treturn sidecars, err\n\t\t}\n\t\tsidecars = append(sidecars, sidecar)\n\t}\n\n\treturn sidecars, nil\n}\n\n// Persist ensures the sidecar data remains accessible, utilizing parallel\n// processing for efficiency.\nfunc (s *Store) Persist(sidecars types.BlobSidecars) error {\n\tvar slot math.Slot\n\t// Store each sidecar sequentially. The store's underlying RangeDB is not\n\t// built to handle concurrent writes.\n\tfor _, sidecar := range sidecars {\n\t\tif sidecar == nil {\n\t\t\treturn ErrAttemptedToStoreNilSidecar\n\t\t}\n\t\tbz, err := sidecar.MarshalSSZ()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tslot = sidecar.GetBeaconBlockHeader().GetSlot()\n\t\terr = s.IndexDB.Set(slot.Unwrap(), sidecar.KzgCommitment[:], bz)\n\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// Slots should all be the same at this point. Just use the slot from the\n\t// last sidecar.\n\ts.logger.Info(\"Successfully stored all blob sidecars 🚗\",\n\t\t\"slot\", slot.Base10(), \"num_sidecars\", len(sidecars),\n\t)\n\treturn nil\n}\n\n// DeleteBlobSidecars removes all blob sidecars for the specified slot.\nfunc (s *Store) DeleteBlobSidecars(slot math.Slot) error {\n\treturn s.IndexDB.DeleteByIndex(slot.Unwrap())\n}\n"
  },
  {
    "path": "da/store/store_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage store_test\n\nimport (\n\t\"testing\"\n\n\t\"cosmossdk.io/log\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/da/store\"\n\tdatypes \"github.com/berachain/beacon-kit/da/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/storage/filedb\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc setSlot(scs datypes.BlobSidecars, slot math.Slot) {\n\tfor _, sc := range scs {\n\t\thdr := sc.GetBeaconBlockHeader()\n\t\thdr.SetSlot(slot)\n\t}\n}\n\nfunc TestStore_PersistRace(t *testing.T) {\n\tt.Parallel()\n\t// This test case needs to be run with the '-race' flag\n\ttmpFilePath := t.TempDir()\n\n\tlogger := log.NewNopLogger()\n\n\t// Create the DB\n\ts := store.New(\n\t\tfiledb.NewRangeDB(\n\t\t\tfiledb.NewDB(filedb.WithRootDirectory(tmpFilePath),\n\t\t\t\tfiledb.WithFileExtension(\"ssz\"),\n\t\t\t\tfiledb.WithDirectoryPermissions(0700),\n\t\t\t\tfiledb.WithLogger(logger),\n\t\t\t),\n\t\t),\n\t\tlogger.With(\"service\", \"da-store\"),\n\t)\n\n\t// This many blobs is not currently possible, but it doesn't hurt eh\n\tsc := make([]*datypes.BlobSidecar, 20)\n\tfor i := range sc {\n\t\tsc[i] = &datypes.BlobSidecar{\n\t\t\tIndex: uint64(i),\n\t\t\tSignedBeaconBlockHeader: &types.SignedBeaconBlockHeader{\n\t\t\t\tHeader: &types.BeaconBlockHeader{},\n\t\t\t},\n\t\t\tInclusionProof: make([]common.Root, types.KZGInclusionProofDepth),\n\t\t}\n\t}\n\tvar sidecars datypes.BlobSidecars = sc\n\n\t// Multiple writes to DB\n\tsetSlot(sidecars, 0)\n\terr := s.Persist(sidecars)\n\trequire.NoError(t, err)\n\tsetSlot(sidecars, 1)\n\terr = s.Persist(sidecars)\n\trequire.NoError(t, err)\n\n\t// Pruning here primes the race condition for db.firstNonNilIndex\n\terr = s.Prune(0, 1)\n\trequire.NoError(t, err)\n\tsetSlot(sidecars, 0)\n\terr = s.Persist(sidecars)\n\trequire.NoError(t, err)\n}\n"
  },
  {
    "path": "da/types/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport \"github.com/berachain/beacon-kit/errors\"\n\nvar (\n\t// ErrSidecarContainsDifferingBlockRoots is returned when a sidecar contains\n\t// blobs with differing block roots.\n\tErrSidecarContainsDifferingBlockRoots = errors.New(\n\t\t\"sidecar contains blobs with differing block roots\")\n\n\t// ErrAttemptedToVerifyNilSidecar is returned when\n\t// an attempt is made to store a nil sidecar.\n\tErrAttemptedToVerifyNilSidecar = errors.New(\n\t\t\"attempted to verify nil sidecar\",\n\t)\n\n\t// ErrInvalidInclusionProof is returned when an invalid KZG commitment\n\t// inclusion.\n\tErrInvalidInclusionProof = errors.New(\n\t\t\"invalid KZG commitment inclusion proof\")\n)\n"
  },
  {
    "path": "da/types/sidecar.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"fmt\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/merkle\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// Compile-time assertions to ensure BlobSidecar implements necessary interfaces.\nvar (\n\t_ ssz.StaticObject                    = (*BlobSidecar)(nil)\n\t_ constraints.SSZMarshallableRootable = (*BlobSidecar)(nil)\n)\n\n// BlobSidecar as per the Ethereum 2.0 specification:\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/deneb/p2p-interface.md#blobsidecar\n//\n// NOTE: This struct is only ever (un)marshalled with SSZ and NOT with JSON.\ntype BlobSidecar struct {\n\t// Index represents the index of the blob in the block.\n\tIndex uint64\n\t// Blob represents the blob data.\n\tBlob eip4844.Blob\n\t// KzgCommitment is the KZG commitment of the blob.\n\tKzgCommitment eip4844.KZGCommitment\n\t// Kzg proof allows folr the verification of the KZG commitment.\n\tKzgProof eip4844.KZGProof\n\t// BeaconBlockHeader represents the beacon block header for which this blob\n\t// is being included.\n\tSignedBeaconBlockHeader *ctypes.SignedBeaconBlockHeader\n\t// InclusionProof is the inclusion proof of the blob in the beacon block\n\t// body.\n\tInclusionProof []common.Root\n}\n\n// BuildBlobSidecar creates a blob sidecar from the given blobs and\n// beacon block.\nfunc BuildBlobSidecar(\n\tindex math.U64,\n\theader *ctypes.SignedBeaconBlockHeader,\n\tblob *eip4844.Blob,\n\tcommitment eip4844.KZGCommitment,\n\tproof eip4844.KZGProof,\n\tinclusionProof []common.Root,\n) *BlobSidecar {\n\treturn &BlobSidecar{\n\t\tIndex:                   index.Unwrap(),\n\t\tBlob:                    *blob,\n\t\tKzgCommitment:           commitment,\n\t\tKzgProof:                proof,\n\t\tSignedBeaconBlockHeader: header,\n\t\tInclusionProof:          inclusionProof,\n\t}\n}\n\n// HasValidInclusionProof verifies the inclusion proof of the\n// blob in the beacon body.\nfunc (b *BlobSidecar) HasValidInclusionProof() bool {\n\theader := b.GetBeaconBlockHeader()\n\treturn header != nil && merkle.IsValidMerkleBranch(\n\t\tb.KzgCommitment.HashTreeRoot(),\n\t\tb.InclusionProof,\n\t\tctypes.KZGInclusionProofDepth,\n\t\tctypes.KZGOffset+b.Index,\n\t\theader.BodyRoot,\n\t)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   Getters                                  */\n/* -------------------------------------------------------------------------- */\n\nfunc (b *BlobSidecar) GetIndex() uint64 {\n\treturn b.Index\n}\n\nfunc (b *BlobSidecar) GetBlob() eip4844.Blob {\n\treturn b.Blob\n}\n\nfunc (b *BlobSidecar) GetKzgProof() eip4844.KZGProof {\n\treturn b.KzgProof\n}\n\nfunc (b *BlobSidecar) GetKzgCommitment() eip4844.KZGCommitment {\n\treturn b.KzgCommitment\n}\n\nfunc (b *BlobSidecar) GetBeaconBlockHeader() *ctypes.BeaconBlockHeader {\n\treturn b.SignedBeaconBlockHeader.Header\n}\n\nfunc (b *BlobSidecar) GetInclusionProof() []common.Root {\n\treturn b.InclusionProof\n}\n\nfunc (b *BlobSidecar) GetSignature() crypto.BLSSignature {\n\treturn b.SignedBeaconBlockHeader.Signature\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// DefineSSZ defines the SSZ encoding for the BlobSidecar object.\nfunc (b *BlobSidecar) DefineSSZ(codec *ssz.Codec) {\n\tssz.DefineUint64(codec, &b.Index)\n\tssz.DefineStaticBytes(codec, &b.Blob)\n\tssz.DefineStaticBytes(codec, &b.KzgCommitment)\n\tssz.DefineStaticBytes(codec, &b.KzgProof)\n\tssz.DefineStaticObject(codec, &b.SignedBeaconBlockHeader)\n\tssz.DefineCheckedArrayOfStaticBytes(codec, &b.InclusionProof, ctypes.KZGInclusionProofDepth)\n}\n\n// SizeSSZ returns the size of the BlobSidecar object in SSZ encoding.\n// TODO: get from accessible chainspec field params.\nfunc (b *BlobSidecar) SizeSSZ(sizer *ssz.Sizer) uint32 {\n\tssize := (*ctypes.SignedBeaconBlockHeader)(nil).SizeSSZ(sizer)\n\treturn 8 + // Index\n\t\t131072 + // Blob\n\t\t48 + // KzgCommitment\n\t\t48 + // KzgProof\n\t\tssize + // SignedBeaconBlockHeader\n\t\tctypes.KZGInclusionProofDepth*32 // InclusionProof\n}\n\n// MarshalSSZ marshals the BlobSidecar object to SSZ format.\nfunc (b *BlobSidecar) MarshalSSZ() ([]byte, error) {\n\tif len(b.InclusionProof) != ctypes.KZGInclusionProofDepth {\n\t\treturn []byte{}, errors.New(\"invalid inclusion proof length\")\n\t}\n\tbuf := make([]byte, ssz.Size(b))\n\treturn buf, ssz.EncodeToBytes(buf, b)\n}\n\nfunc (b *BlobSidecar) ValidateAfterDecodingSSZ() error {\n\t// Verify inclusion proof length\n\tif len(b.InclusionProof) != ctypes.KZGInclusionProofDepth {\n\t\treturn fmt.Errorf(\"invalid inclusion proof length, got %d, expect %d\",\n\t\t\tb.InclusionProof,\n\t\t\tctypes.KZGInclusionProofDepth,\n\t\t)\n\t}\n\n\t// Ensure SignedBeaconBlockHeader is not nil\n\tif b.SignedBeaconBlockHeader == nil {\n\t\tb.SignedBeaconBlockHeader = &ctypes.SignedBeaconBlockHeader{}\n\t}\n\treturn nil\n}\n\n// MarshalSSZTo marshals the BlobSidecar object to the provided buffer in SSZ\n// format.\nfunc (b *BlobSidecar) MarshalSSZTo(buf []byte) ([]byte, error) {\n\treturn buf, ssz.EncodeToBytes(buf, b)\n}\n\n// HashTreeRoot computes the SSZ hash tree root of the BlobSidecar object.\nfunc (b *BlobSidecar) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(b)\n}\n"
  },
  {
    "path": "da/types/sidecar_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"strconv\"\n\t\"testing\"\n\t\"time\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/da/blob\"\n\t\"github.com/berachain/beacon-kit/da/types\"\n\tbyteslib \"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/math/log\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/berachain/beacon-kit/testing/utils\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestSidecarMarshalling(t *testing.T) {\n\tt.Parallel()\n\t// Create a sample BlobSidecar\n\tblob := eip4844.Blob{}\n\tfor i := range blob {\n\t\tblob[i] = byte(i % 256)\n\t}\n\tinclusionProof := make([]common.Root, 0, ctypes.KZGInclusionProofDepth)\n\tfor i := 1; i <= ctypes.KZGInclusionProofDepth; i++ {\n\t\tit := byteslib.ExtendToSize([]byte(strconv.Itoa(i)), byteslib.B32Size)\n\t\tproof, errBytes := byteslib.ToBytes32(it)\n\t\trequire.NoError(t, errBytes)\n\t\tinclusionProof = append(inclusionProof, common.Root(proof))\n\t}\n\tsidecar := types.BuildBlobSidecar(\n\t\t1,\n\t\t&ctypes.SignedBeaconBlockHeader{\n\t\t\tHeader:    &ctypes.BeaconBlockHeader{},\n\t\t\tSignature: crypto.BLSSignature{},\n\t\t},\n\t\t&blob,\n\t\teip4844.KZGCommitment{},\n\t\teip4844.KZGProof{},\n\t\tinclusionProof,\n\t)\n\n\t// Marshal the sidecar\n\tmarshalled, err := sidecar.MarshalSSZ()\n\trequire.NoError(t, err, \"Marshalling should not produce an error\")\n\trequire.NotNil(t, marshalled, \"Marshalling should produce a result\")\n\n\t// Unmarshal the sidecar\n\tunmarshalled := new(types.BlobSidecar)\n\terr = ssz.Unmarshal(marshalled, unmarshalled)\n\trequire.NoError(t, err, \"Unmarshalling should not produce an error\")\n\n\t// Compare the original and unmarshalled sidecars\n\tassert.Equal(\n\t\tt,\n\t\tsidecar,\n\t\tunmarshalled,\n\t\t\"The original and unmarshalled sidecars should be equal\",\n\t)\n}\n\ntype InclusionSink struct{}\n\nfunc (is InclusionSink) MeasureSince(_ string, _ time.Time, _ ...string) {}\n\nfunc TestHasValidInclusionProof(t *testing.T) {\n\tt.Parallel()\n\n\tsink := InclusionSink{}\n\ttests := []struct {\n\t\tname           string\n\t\tsidecars       func(t *testing.T) types.BlobSidecars\n\t\texpectedResult bool\n\t}{\n\t\t{\n\t\t\tname: \"Invalid inclusion proof\",\n\t\t\tsidecars: func(t *testing.T) types.BlobSidecars {\n\t\t\t\tt.Helper()\n\t\t\t\tinclusionProof := make([]common.Root, 0)\n\t\t\t\tfor i := 1; i <= ctypes.KZGInclusionProofDepth; i++ {\n\t\t\t\t\tit := byteslib.ExtendToSize(\n\t\t\t\t\t\t[]byte(strconv.Itoa(i)),\n\t\t\t\t\t\tbyteslib.B32Size,\n\t\t\t\t\t)\n\t\t\t\t\tproof, err2 := byteslib.ToBytes32(it)\n\t\t\t\t\trequire.NoError(t, err2)\n\t\t\t\t\tinclusionProof = append(inclusionProof, common.Root(proof))\n\t\t\t\t}\n\t\t\t\treturn types.BlobSidecars{types.BuildBlobSidecar(\n\t\t\t\t\tmath.U64(0),\n\t\t\t\t\t&ctypes.SignedBeaconBlockHeader{\n\t\t\t\t\t\tHeader: &ctypes.BeaconBlockHeader{\n\t\t\t\t\t\t\tBodyRoot: [32]byte{3},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tSignature: crypto.BLSSignature{},\n\t\t\t\t\t},\n\t\t\t\t\t&eip4844.Blob{},\n\t\t\t\t\teip4844.KZGCommitment{},\n\t\t\t\t\teip4844.KZGProof{},\n\t\t\t\t\tinclusionProof,\n\t\t\t\t)}\n\t\t\t},\n\t\t\texpectedResult: false,\n\t\t},\n\t\t{\n\t\t\tname: \"Empty inclusion proof\",\n\t\t\tsidecars: func(*testing.T) types.BlobSidecars {\n\t\t\t\treturn types.BlobSidecars{types.BuildBlobSidecar(\n\t\t\t\t\tmath.U64(0),\n\t\t\t\t\t&ctypes.SignedBeaconBlockHeader{},\n\t\t\t\t\t&eip4844.Blob{},\n\t\t\t\t\teip4844.KZGCommitment{},\n\t\t\t\t\teip4844.KZGProof{},\n\t\t\t\t\t[]common.Root{},\n\t\t\t\t)}\n\t\t\t},\n\t\t\texpectedResult: false,\n\t\t},\n\t\t{\n\t\t\tname: \"Valid inclusion proof\",\n\t\t\tsidecars: func(t *testing.T) types.BlobSidecars {\n\t\t\t\tt.Helper()\n\t\t\t\tblock := utils.GenerateValidBeaconBlock(t, version.Electra())\n\n\t\t\t\tsidecarFactory := blob.NewSidecarFactory(sink)\n\t\t\t\tnumBlobs := len(block.GetBody().GetBlobKzgCommitments())\n\t\t\t\tsidecars := make(types.BlobSidecars, numBlobs)\n\t\t\t\tfor i := range numBlobs {\n\t\t\t\t\tinclusionProof, incErr := sidecarFactory.BuildKZGInclusionProof(\n\t\t\t\t\t\tblock.GetBody(), math.U64(i),\n\t\t\t\t\t)\n\t\t\t\t\trequire.NoError(t, incErr)\n\t\t\t\t\tsigHeader := ctypes.NewSignedBeaconBlockHeader(block.GetHeader(), crypto.BLSSignature{})\n\t\t\t\t\tsidecars[i] = types.BuildBlobSidecar(\n\t\t\t\t\t\tmath.U64(i),\n\t\t\t\t\t\tsigHeader,\n\t\t\t\t\t\t&eip4844.Blob{},\n\t\t\t\t\t\tblock.GetBody().BlobKzgCommitments[i],\n\t\t\t\t\t\teip4844.KZGProof{},\n\t\t\t\t\t\tinclusionProof,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\treturn sidecars\n\t\t\t},\n\t\t\texpectedResult: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tsidecars := tt.sidecars(t)\n\t\t\tfor _, sidecar := range sidecars {\n\t\t\t\tresult := sidecar.HasValidInclusionProof()\n\t\t\t\trequire.Equal(t, tt.expectedResult, result,\n\t\t\t\t\t\"Result should match expected value\")\n\t\t\t}\n\t\t})\n\t}\n}\n\n// Test taken from Prysm:\n// https://github.com/prysmaticlabs/prysm/blob/6ce6b869e54c2f98fab5cc836a24e493df19ec49/consensus-types/blocks/kzg_test.go#L107-L120\n// This test explains the calculation of the KZG commitment root's Merkle index\n// in the Body's Merkle tree based on the index of the KZG commitment list in the Body.\nfunc Test_KZGRootIndex(t *testing.T) {\n\tt.Parallel()\n\t// Level of the KZG commitment root's parent.\n\tkzgParentRootLevel := log.ILog2Ceil(ctypes.KZGPosition)\n\trequire.NotEqual(t, 0, kzgParentRootLevel)\n\t// Merkle index of the KZG commitment root's parent.\n\t// The parent's left child is the KZG commitment root,\n\t// and its right child is the KZG commitment size.\n\tkzgParentRootIndex := ctypes.KZGPosition + (1 << kzgParentRootLevel)\n\trequire.Equal(t, uint64(ctypes.KZGGeneralizedIndex), kzgParentRootIndex)\n\t// The KZG commitment root is the left child of its parent.\n\t// Its Merkle index is the double of its parent's Merkle index.\n\trequire.Equal(t, 2*kzgParentRootIndex, uint64(ctypes.KZGRootIndex))\n}\n\nfunc TestHashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname           string\n\t\tsidecar        func(t *testing.T) *types.BlobSidecar\n\t\texpectedResult common.Root\n\t\texpectError    bool\n\t}{\n\t\t{\n\t\t\tname: \"Valid BlobSidecar\",\n\t\t\tsidecar: func(t *testing.T) *types.BlobSidecar {\n\t\t\t\tt.Helper()\n\t\t\t\tinclusionProof := make([]common.Root, 0)\n\t\t\t\tfor i := int(1); i <= 8; i++ {\n\t\t\t\t\tit := byteslib.ExtendToSize(\n\t\t\t\t\t\t[]byte(strconv.Itoa(i)),\n\t\t\t\t\t\tbyteslib.B32Size,\n\t\t\t\t\t)\n\t\t\t\t\tproof, err := byteslib.ToBytes32(it)\n\t\t\t\t\trequire.NoError(t, err)\n\t\t\t\t\tinclusionProof = append(inclusionProof, common.Root(proof))\n\t\t\t\t}\n\t\t\t\treturn types.BuildBlobSidecar(\n\t\t\t\t\tmath.U64(1),\n\t\t\t\t\t&ctypes.SignedBeaconBlockHeader{\n\t\t\t\t\t\tHeader: &ctypes.BeaconBlockHeader{\n\t\t\t\t\t\t\tBodyRoot: [32]byte{7, 8, 9},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tSignature: crypto.BLSSignature{0xde, 0xad},\n\t\t\t\t\t},\n\t\t\t\t\t&eip4844.Blob{0, 1, 2, 3, 4, 5, 6, 7},\n\t\t\t\t\teip4844.KZGCommitment{1, 2, 3},\n\t\t\t\t\teip4844.KZGProof{4, 5, 6},\n\t\t\t\t\tinclusionProof,\n\t\t\t\t)\n\t\t\t},\n\t\t\texpectedResult: [32]uint8{\n\t\t\t\t0xd8, 0xb2, 0x91, 0x39, 0x93, 0x75, 0x38, 0x1f,\n\t\t\t\t0xd4, 0xdf, 0xef, 0xa7, 0x16, 0x91, 0xd9, 0x9,\n\t\t\t\t0x3, 0x62, 0xee, 0x3a, 0x79, 0x96, 0x57, 0xc4,\n\t\t\t\t0xc4, 0x6d, 0x86, 0x79, 0x78, 0x1b, 0xb4, 0xe3,\n\t\t\t},\n\t\t\texpectError: false,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\trequire.NotPanics(t, func() {\n\t\t\t\tsidecar := tt.sidecar(t)\n\t\t\t\tresult := sidecar.HashTreeRoot()\n\t\t\t\trequire.Equal(\n\t\t\t\t\tt,\n\t\t\t\t\ttt.expectedResult,\n\t\t\t\t\tresult,\n\t\t\t\t\t\"HashTreeRoot result should match expected value\",\n\t\t\t\t)\n\t\t\t}, \"HashTreeRoot should not panic\")\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "da/types/sidecars.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/karalabe/ssz\"\n\t\"github.com/sourcegraph/conc/iter\"\n)\n\n// Compile-time check to ensure BlobSidecars implements the necessary interfaces.\nvar (\n\t_ ssz.DynamicObject           = (*BlobSidecars)(nil)\n\t_ constraints.SSZMarshallable = (*BlobSidecars)(nil)\n)\n\n// Sidecars is a slice of blob side cars to be included in the block.\ntype BlobSidecars []*BlobSidecar\n\n// ValidateBlockRoots checks to make sure that\n// all blobs in the sidecar are from the same block.\nfunc (bs *BlobSidecars) ValidateBlockRoots() error {\n\tif bs == nil {\n\t\treturn ErrAttemptedToVerifyNilSidecar\n\t}\n\tsidecars := *bs\n\t// We only need to check if there is more than\n\t// a single blob in the sidecar.\n\tif len(sidecars) > 1 {\n\t\tfirstHtr := sidecars[0].SignedBeaconBlockHeader.HashTreeRoot()\n\t\tfor i := 1; i < len(sidecars); i++ {\n\t\t\tif firstHtr != sidecars[i].SignedBeaconBlockHeader.HashTreeRoot() {\n\t\t\t\treturn ErrSidecarContainsDifferingBlockRoots\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// VerifyInclusionProofs verifies the inclusion proofs for all sidecars.\nfunc (bs *BlobSidecars) VerifyInclusionProofs() error {\n\treturn errors.Join(iter.Map(\n\t\t*bs,\n\t\tfunc(sidecar **BlobSidecar) error {\n\t\t\tsc := *sidecar\n\t\t\tif sc == nil {\n\t\t\t\treturn ErrAttemptedToVerifyNilSidecar\n\t\t\t}\n\n\t\t\t// Verify the KZG inclusion proof.\n\t\t\tif !sc.HasValidInclusionProof() {\n\t\t\t\treturn ErrInvalidInclusionProof\n\t\t\t}\n\t\t\treturn nil\n\t\t},\n\t)...)\n}\n\n// DefineSSZ defines the SSZ encoding for the BlobSidecars object.\nfunc (bs *BlobSidecars) DefineSSZ(codec *ssz.Codec) {\n\tssz.DefineSliceOfStaticObjectsOffset(\n\t\tcodec, (*[]*BlobSidecar)(bs), constants.MaxBlobSidecarsPerBlock,\n\t)\n\tssz.DefineSliceOfStaticObjectsContent(\n\t\tcodec, (*[]*BlobSidecar)(bs), constants.MaxBlobSidecarsPerBlock,\n\t)\n}\n\n// SizeSSZ returns the size of the BlobSidecars object in SSZ encoding.\nfunc (bs *BlobSidecars) SizeSSZ(siz *ssz.Sizer, fixed bool) uint32 {\n\tif fixed {\n\t\treturn constants.SSZOffsetSize\n\t}\n\treturn constants.SSZOffsetSize + ssz.SizeSliceOfStaticObjects(siz, *bs)\n}\n\n// MarshalSSZ marshals the BlobSidecars object to SSZ format.\nfunc (bs *BlobSidecars) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(bs))\n\treturn buf, ssz.EncodeToBytes(buf, bs)\n}\n\nfunc (bs *BlobSidecars) ValidateAfterDecodingSSZ() error {\n\tif len(*bs) > constants.MaxBlobSidecarsPerBlock {\n\t\treturn fmt.Errorf(\n\t\t\t\"invalid number of blob sidecars, got %d max %d\",\n\t\t\tlen(*bs), constants.MaxBlobSidecarsPerBlock,\n\t\t)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "da/types/sidecars_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"strconv\"\n\t\"testing\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/da/types\"\n\tbyteslib \"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestEmptySidecarMarshalling(t *testing.T) {\n\tt.Parallel()\n\tinclusionProof := make([]common.Root, 0)\n\t// Create an empty BlobSidecar\n\tfor i := 1; i <= ctypes.KZGInclusionProofDepth; i++ {\n\t\tit := byteslib.ExtendToSize([]byte(strconv.Itoa(i)), byteslib.B32Size)\n\t\tproof, errBytes := byteslib.ToBytes32(it)\n\t\trequire.NoError(t, errBytes)\n\t\tinclusionProof = append(inclusionProof, common.Root(proof))\n\t}\n\n\tsidecar := types.BuildBlobSidecar(\n\t\tmath.U64(0),\n\t\t&ctypes.SignedBeaconBlockHeader{\n\t\t\tHeader:    &ctypes.BeaconBlockHeader{},\n\t\t\tSignature: crypto.BLSSignature{},\n\t\t},\n\t\t&eip4844.Blob{},\n\t\teip4844.KZGCommitment{},\n\t\t[48]byte{},\n\t\tinclusionProof,\n\t)\n\n\t// Marshal the empty sidecar\n\tmarshalled, err := sidecar.MarshalSSZ()\n\trequire.NoError(\n\t\tt,\n\t\terr,\n\t\t\"Marshalling empty sidecar should not produce an error\",\n\t)\n\trequire.NotNil(\n\t\tt,\n\t\tmarshalled,\n\t\t\"Marshalling empty sidecar should produce a result\",\n\t)\n\n\t// Unmarshal the empty sidecar\n\tunmarshalled := new(types.BlobSidecar)\n\terr = ssz.Unmarshal(marshalled, unmarshalled)\n\trequire.NoError(\n\t\tt,\n\t\terr,\n\t\t\"Unmarshalling empty sidecar should not produce an error\",\n\t)\n\n\t// Compare the original and unmarshalled empty sidecars\n\trequire.Equal(\n\t\tt,\n\t\tsidecar,\n\t\tunmarshalled,\n\t\t\"The original and unmarshalled empty sidecars should be equal\",\n\t)\n}\n\nfunc TestValidateBlockRoots(t *testing.T) {\n\tt.Parallel()\n\tinclusionProof := make([]common.Root, 0)\n\t// Create a sample BlobSidecar with valid roots\n\tfor i := 1; i <= ctypes.KZGInclusionProofDepth; i++ {\n\t\tit := byteslib.ExtendToSize([]byte(strconv.Itoa(i)), byteslib.B32Size)\n\t\tproof, errBytes := byteslib.ToBytes32(it)\n\t\trequire.NoError(t, errBytes)\n\t\tinclusionProof = append(inclusionProof, common.Root(proof))\n\t}\n\n\tvalidSidecar := types.BuildBlobSidecar(\n\t\tmath.U64(0),\n\t\t&ctypes.SignedBeaconBlockHeader{\n\t\t\tHeader: &ctypes.BeaconBlockHeader{\n\t\t\t\tStateRoot: [32]byte{1},\n\t\t\t\tBodyRoot:  [32]byte{2},\n\t\t\t},\n\t\t\tSignature: crypto.BLSSignature{},\n\t\t},\n\t\t&eip4844.Blob{},\n\t\t[48]byte{},\n\t\t[48]byte{},\n\t\tinclusionProof,\n\t)\n\n\t// Validate the sidecar with valid roots\n\tsidecars := types.BlobSidecars{\n\t\tvalidSidecar,\n\t}\n\terr := sidecars.ValidateBlockRoots()\n\trequire.NoError(\n\t\tt,\n\t\terr,\n\t\t\"Validating sidecar with valid roots should not produce an error\",\n\t)\n\n\t// Create a sample BlobSidecar with invalid roots\n\tdifferentBlockRootSidecar := types.BuildBlobSidecar(\n\t\tmath.U64(0),\n\t\t&ctypes.SignedBeaconBlockHeader{\n\t\t\tHeader: &ctypes.BeaconBlockHeader{\n\t\t\t\tStateRoot: [32]byte{1},\n\t\t\t\tBodyRoot:  [32]byte{3},\n\t\t\t},\n\t\t\tSignature: crypto.BLSSignature{},\n\t\t},\n\t\t&eip4844.Blob{},\n\t\teip4844.KZGCommitment{},\n\t\teip4844.KZGProof{},\n\t\tinclusionProof,\n\t)\n\t// Validate the sidecar with invalid roots\n\tsidecarsInvalid := types.BlobSidecars{\n\t\tvalidSidecar,\n\t\tdifferentBlockRootSidecar,\n\t}\n\terr = sidecarsInvalid.ValidateBlockRoots()\n\trequire.Error(\n\t\tt,\n\t\terr,\n\t\t\"Validating sidecar with invalid roots should produce an error\",\n\t)\n}\n\nfunc TestZeroSidecarsInBlobSidecarsIsNotNil(t *testing.T) {\n\tt.Parallel()\n\t// This test exists to ensure that proposing a BlobSidecars with 0\n\t// Sidecars is not considered IsNil().\n\tsidecars := &types.BlobSidecars{}\n\trequire.NotNil(t, sidecars)\n}\n"
  },
  {
    "path": "docs/.gitkeep",
    "content": "Coming soon..."
  },
  {
    "path": "engine-primitives/engine-primitives/attributes.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage engineprimitives\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n)\n\n// PayloadAttributes is the attributes of a block payload.\ntype PayloadAttributes struct {\n\t// Timestamp is the timestamp at which the block will be built at.\n\tTimestamp math.U64 `json:\"timestamp\"`\n\t// PrevRandao is the previous Randao value from the beacon chain as\n\t// per EIP-4399.\n\tPrevRandao common.Bytes32 `json:\"prevRandao\"`\n\t// SuggestedFeeRecipient is the suggested fee recipient for the block. If\n\t// the execution client has a different fee recipient, it will typically\n\t// ignore this value.\n\tSuggestedFeeRecipient common.ExecutionAddress `json:\"suggestedFeeRecipient\"`\n\t// Withdrawals is the list of withdrawals to be included in the block as per\n\t// EIP-4895\n\tWithdrawals Withdrawals `json:\"withdrawals\"`\n\t// ParentBeaconBlockRoot is the root of the parent beacon block. (The block\n\t// prior)\n\t// to the block currently being processed. This field was added for\n\t// EIP-4788.\n\tParentBeaconBlockRoot common.Root `json:\"parentBeaconBlockRoot\"`\n\t// ParentProposerPubkey carries the public key of previous block proposed\n\t// This field was added for BRIP-0004. Should be nil for fork versions\n\t// before Electra1.\n\tParentProposerPubkey *crypto.BLSPubkey `json:\"parentProposerPubKey\"`\n}\n\n// NewPayloadAttributes creates a new PayloadAttributes and validates it for\n// the given fork version.\nfunc NewPayloadAttributes(\n\tforkVersion common.Version,\n\ttimestamp math.U64,\n\tprevRandao common.Bytes32,\n\tsuggestedFeeRecipient common.ExecutionAddress,\n\twithdrawals Withdrawals,\n\tparentBeaconBlockRoot common.Root,\n\tparentProposerPubkey *crypto.BLSPubkey,\n) (*PayloadAttributes, error) {\n\tpa := &PayloadAttributes{\n\t\tTimestamp:             timestamp,\n\t\tPrevRandao:            prevRandao,\n\t\tSuggestedFeeRecipient: suggestedFeeRecipient,\n\t\tWithdrawals:           withdrawals,\n\t\tParentBeaconBlockRoot: parentBeaconBlockRoot,\n\t\tParentProposerPubkey:  parentProposerPubkey,\n\t}\n\n\tif err := pa.validate(forkVersion); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn pa, nil\n}\n\n// GetSuggestedFeeRecipient returns the suggested fee recipient.\nfunc (p *PayloadAttributes) GetSuggestedFeeRecipient() common.ExecutionAddress {\n\treturn p.SuggestedFeeRecipient\n}\n\n// Validate validates the PayloadAttributes for the given fork version.\nfunc (p *PayloadAttributes) validate(forkVersion common.Version) error {\n\tif p.Timestamp == 0 {\n\t\treturn ErrInvalidTimestamp\n\t}\n\n\tif p.PrevRandao == [32]byte{} {\n\t\treturn ErrEmptyPrevRandao\n\t}\n\n\t// For any fork version Capella onwards, withdrawals are required.\n\tif p.Withdrawals == nil && version.EqualsOrIsAfter(forkVersion, version.Capella()) {\n\t\treturn ErrNilWithdrawals\n\t}\n\n\t// For any fork version Electra1 onwards, the parent proposer pubkey is required.\n\tif version.IsBefore(forkVersion, version.Electra1()) {\n\t\tif p.ParentProposerPubkey != nil {\n\t\t\treturn ErrNonEmptyPrevProposerPubKey\n\t\t}\n\t} else {\n\t\tif p.ParentProposerPubkey == nil {\n\t\t\treturn ErrEmptyPrevProposerPubKey\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "engine-primitives/engine-primitives/attributes_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage engineprimitives_test\n\nimport (\n\t\"testing\"\n\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/stretchr/testify/require\"\n)\n\ntype payloadAttributesInput struct {\n\tforkVersion           common.Version\n\ttimestamp             math.U64\n\tprevRandao            common.Bytes32\n\tsuggestedFeeRecipient common.ExecutionAddress\n\twithdrawals           engineprimitives.Withdrawals\n\tparentBeaconBlockRoot common.Root\n\tparentProposerPubKey  *crypto.BLSPubkey\n}\n\nfunc TestPayloadAttributes(t *testing.T) {\n\tt.Parallel()\n\t// default valid data\n\tvalidInput := payloadAttributesInput{\n\t\tforkVersion:           version.Altair(),\n\t\ttimestamp:             math.U64(123456789),\n\t\tprevRandao:            common.Bytes32{1, 2, 3},\n\t\tsuggestedFeeRecipient: common.ExecutionAddress{},\n\t\twithdrawals:           engineprimitives.Withdrawals{},\n\t\tparentBeaconBlockRoot: common.Root{},\n\t\tparentProposerPubKey:  nil,\n\t}\n\ttests := []struct {\n\t\tname    string\n\t\tinput   func() payloadAttributesInput\n\t\twantErr error\n\t}{\n\t\t{\n\t\t\tname: \"Valid payload attributes\",\n\t\t\tinput: func() payloadAttributesInput {\n\t\t\t\treturn validInput\n\t\t\t},\n\t\t\twantErr: nil,\n\t\t},\n\t\t{\n\t\t\tname: \"Invalid timestamp\",\n\t\t\tinput: func() payloadAttributesInput {\n\t\t\t\tres := validInput\n\t\t\t\tres.timestamp = 0\n\t\t\t\treturn res\n\t\t\t},\n\t\t\twantErr: engineprimitives.ErrInvalidTimestamp,\n\t\t},\n\t\t{\n\t\t\tname: \"Invalid PreRandao\",\n\t\t\tinput: func() payloadAttributesInput {\n\t\t\t\tres := validInput\n\t\t\t\tres.prevRandao = common.Bytes32{}\n\t\t\t\treturn res\n\t\t\t},\n\t\t\twantErr: engineprimitives.ErrEmptyPrevRandao,\n\t\t},\n\t\t{\n\t\t\tname: \"Invalid nil withdrawals on Capella\",\n\t\t\tinput: func() payloadAttributesInput {\n\t\t\t\tres := validInput\n\t\t\t\tres.forkVersion = version.Capella()\n\t\t\t\tres.withdrawals = nil\n\t\t\t\treturn res\n\t\t\t},\n\t\t\twantErr: engineprimitives.ErrNilWithdrawals,\n\t\t},\n\t\t{\n\t\t\tname: \"Invalid - parent proposer pubkey before Electra1\",\n\t\t\tinput: func() payloadAttributesInput {\n\t\t\t\tres := validInput\n\t\t\t\tres.forkVersion = version.Electra()\n\t\t\t\tres.parentProposerPubKey = &crypto.BLSPubkey{0x01}\n\t\t\t\treturn res\n\t\t\t},\n\t\t\twantErr: engineprimitives.ErrNonEmptyPrevProposerPubKey,\n\t\t},\n\t\t{\n\t\t\tname: \"Invalid - no parent proposer pubkey after Electra1\",\n\t\t\tinput: func() payloadAttributesInput {\n\t\t\t\tres := validInput\n\t\t\t\tres.forkVersion = version.Electra1()\n\t\t\t\treturn res\n\t\t\t},\n\t\t\twantErr: engineprimitives.ErrEmptyPrevProposerPubKey,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tin := tt.input()\n\t\t\tgot, err := engineprimitives.NewPayloadAttributes(\n\t\t\t\tin.forkVersion,\n\t\t\t\tin.timestamp,\n\t\t\t\tin.prevRandao,\n\t\t\t\tin.suggestedFeeRecipient,\n\t\t\t\tin.withdrawals,\n\t\t\t\tin.parentBeaconBlockRoot,\n\t\t\t\tin.parentProposerPubKey,\n\t\t\t)\n\t\t\tif tt.wantErr != nil {\n\t\t\t\trequire.ErrorIs(t, err, tt.wantErr)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, got)\n\t\t\t\trequire.Equal(\n\t\t\t\t\tt,\n\t\t\t\t\tin.suggestedFeeRecipient,\n\t\t\t\t\tgot.GetSuggestedFeeRecipient(),\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "engine-primitives/engine-primitives/blobs_bundle.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage engineprimitives\n\nimport \"github.com/berachain/beacon-kit/primitives/eip4844\"\n\n// Compile-time assertion to ensure BlobsBundleV1 implements BlobsBundle.\nvar _ BlobsBundle = (*BlobsBundleV1)(nil)\n\n// BlobsBundle is an interface for the blobs bundle.\n//\n// TODO: move interface definition to packages where it is used.\ntype BlobsBundle interface {\n\t// GetCommitments returns the commitments in the blobs bundle.\n\tGetCommitments() []eip4844.KZGCommitment\n\t// GetProofs returns the proofs in the blobs bundle.\n\tGetProofs() []eip4844.KZGProof\n\t// GetBlobs returns the blobs in the blobs bundle.\n\tGetBlobs() []*eip4844.Blob\n}\n\n// BlobsBundleV1 represents a collection of commitments, proofs, and blobs.\n// Each field is a slice of bytes that are serialized for transmission or\n// storage.\ntype BlobsBundleV1 struct {\n\t// Commitments are the KZG commitments included in the bundle.\n\tCommitments []eip4844.KZGCommitment `json:\"commitments\"`\n\t// Proofs are the KZG proofs corresponding to the commitments.\n\tProofs []eip4844.KZGProof `json:\"proofs\"`\n\t// Blobs are arbitrary data blobs included in the bundle.\n\tBlobs []*eip4844.Blob `json:\"blobs\"`\n}\n\n// GetCommitments returns the slice of commitments in the bundle.\nfunc (b *BlobsBundleV1) GetCommitments() []eip4844.KZGCommitment {\n\treturn b.Commitments\n}\n\n// GetProofs returns the slice of proofs in the bundle.\nfunc (b *BlobsBundleV1) GetProofs() []eip4844.KZGProof {\n\treturn b.Proofs\n}\n\n// GetBlobs returns the slice of data blobs in the bundle.\nfunc (b *BlobsBundleV1) GetBlobs() []*eip4844.Blob {\n\treturn b.Blobs\n}\n"
  },
  {
    "path": "engine-primitives/engine-primitives/blobs_bundle_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage engineprimitives_test\n\nimport (\n\t\"testing\"\n\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestBlobsBundleV1(t *testing.T) {\n\tt.Parallel()\n\tbundle := &engineprimitives.BlobsBundleV1{\n\t\tCommitments: []eip4844.KZGCommitment{{1, 2, 3}, {4, 5, 6}},\n\t\tProofs:      []eip4844.KZGProof{{7, 8, 9}, {10, 11, 12}},\n\t\tBlobs:       []*eip4844.Blob{{13, 14, 15}, {16, 17, 18}},\n\t}\n\n\tcommitments := bundle.GetCommitments()\n\trequire.Equal(t, bundle.Commitments, commitments)\n\n\tproofs := bundle.GetProofs()\n\trequire.Equal(t, bundle.Proofs, proofs)\n\n\tblobs := bundle.GetBlobs()\n\trequire.Equal(t, bundle.Blobs, blobs)\n}\n"
  },
  {
    "path": "engine-primitives/engine-primitives/engine.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//nolint:gochecknoglobals // alias.\npackage engineprimitives\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n)\n\n// ClientVersionV1 contains information which identifies a client\n// implementation.\ntype ClientVersionV1 struct {\n\tCode    string `json:\"code\"`\n\tName    string `json:\"name\"`\n\tVersion string `json:\"version\"`\n\tCommit  string `json:\"commit\"`\n}\n\nfunc (v *ClientVersionV1) String() string {\n\treturn fmt.Sprintf(\"%s-%s-%s-%s\", v.Code, v.Name, v.Version, v.Commit)\n}\n\nvar (\n\t// PayloadStatusValid is the status of a valid payload.\n\tPayloadStatusValid = \"VALID\"\n\t// PayloadStatusInvalid is the status of an invalid payload.\n\tPayloadStatusInvalid = \"INVALID\"\n\t// PayloadStatusSyncing is the status returned when the EL is syncing.\n\tPayloadStatusSyncing = \"SYNCING\"\n\t// PayloadStatusAccepted is the status returned when the EL has accepted the\n\t// payload.\n\tPayloadStatusAccepted = \"ACCEPTED\"\n)\n\n// ForkchoiceResponseV1 as per the EngineAPI Specification:\n// https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#response-2\ntype ForkchoiceResponseV1 struct {\n\t// PayloadStatus is the payload status.\n\tPayloadStatus PayloadStatusV1 `json:\"payloadStatus\"`\n\t// PayloadID isthe identifier of the payload build process, it\n\t// can also be `nil`.\n\tPayloadID *PayloadID `json:\"payloadId\"`\n}\n\n// ForkchoiceStateV1 as per the EngineAPI Specification:\n// https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#forkchoicestatev1\ntype ForkchoiceStateV1 struct {\n\t// HeadBlockHash is the desired block hash of the head of the canonical\n\t// chain.\n\tHeadBlockHash common.ExecutionHash `json:\"headBlockHash\"`\n\t// SafeBlockHash is  the \"safe\" block hash of the canonical chain under\n\t// certain\n\t// synchrony and honesty assumptions. This value MUST be either equal to\n\t// or an ancestor of `HeadBlockHash`.\n\tSafeBlockHash common.ExecutionHash `json:\"safeBlockHash\"`\n\t// FinalizedBlockHash is the desired block hash of the most recent finalized\n\t// block\n\tFinalizedBlockHash common.ExecutionHash `json:\"finalizedBlockHash\"`\n}\n\nfunc (fsv1 *ForkchoiceStateV1) Equals(rhs *ForkchoiceStateV1) bool {\n\tswitch {\n\tcase fsv1 != nil && rhs != nil:\n\t\treturn fsv1.HeadBlockHash == rhs.HeadBlockHash &&\n\t\t\tfsv1.SafeBlockHash == rhs.SafeBlockHash &&\n\t\t\tfsv1.FinalizedBlockHash == rhs.FinalizedBlockHash\n\tcase fsv1 == nil && rhs == nil:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// PayloadStatusV1 represents the status of a payload as per the EngineAPI\n// Specification. For more details, see:\n// https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#payloadstatusv1\ntype PayloadStatusV1 struct {\n\t// Status string of the payload.\n\tStatus string `json:\"status\"`\n\t// LatestValidHash is the hash of the most recent valid block\n\t// in the branch defined by payload and its ancestors\n\tLatestValidHash *common.ExecutionHash `json:\"latestValidHash\"`\n\t// ValidationError is a message providing additional details on\n\t// the validation error if the payload is classified as\n\t// INVALID or INVALID_BLOCK_HASH\n\tValidationError *string `json:\"validationError\"`\n}\n\n// PayloadID is an identifier for the payload build process.\ntype PayloadID = bytes.B8\n"
  },
  {
    "path": "engine-primitives/engine-primitives/engine_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage engineprimitives_test\n\nimport (\n\t\"testing\"\n\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestPayloadID(t *testing.T) {\n\tt.Parallel()\n\tpayloadID := engineprimitives.PayloadID{\n\t\t0x1,\n\t\t0x2,\n\t\t0x3,\n\t\t0x4,\n\t\t0x5,\n\t\t0x6,\n\t\t0x7,\n\t\t0x8,\n\t}\n\n\t// Test marshaling\n\tmarshaledID, err := json.Marshal(payloadID)\n\trequire.NoError(t, err)\n\trequire.Equal(t, \"\\\"0x0102030405060708\\\"\", string(marshaledID))\n\n\t// Test unmarshaling\n\tvar unmarshaledID engineprimitives.PayloadID\n\terr = json.Unmarshal(marshaledID, &unmarshaledID)\n\trequire.NoError(t, err)\n\trequire.Equal(t, payloadID, unmarshaledID)\n}\n\nfunc TestForkchoiceStateV1(t *testing.T) {\n\tt.Parallel()\n\tstate := &engineprimitives.ForkchoiceStateV1{\n\t\tHeadBlockHash:      common.ExecutionHash{0x1},\n\t\tSafeBlockHash:      common.ExecutionHash{0x2},\n\t\tFinalizedBlockHash: common.ExecutionHash{0x3},\n\t}\n\trequire.Equal(t, common.ExecutionHash{0x1}, state.HeadBlockHash)\n\trequire.Equal(t, common.ExecutionHash{0x2}, state.SafeBlockHash)\n\trequire.Equal(\n\t\tt,\n\t\tcommon.ExecutionHash{0x3},\n\t\tstate.FinalizedBlockHash,\n\t)\n\n\t// Test marshaling\n\tmarshaledState, err := json.Marshal(state)\n\trequire.NoError(t, err)\n\n\t// Test unmarshaling\n\tvar unmarshaledState engineprimitives.ForkchoiceStateV1\n\terr = json.Unmarshal(marshaledState, &unmarshaledState)\n\trequire.NoError(t, err)\n\trequire.Equal(t, state, &unmarshaledState)\n}\n\nfunc TestPayloadStatusV1(t *testing.T) {\n\tt.Parallel()\n\tstatus := &engineprimitives.PayloadStatusV1{\n\t\tStatus:          engineprimitives.PayloadStatusValid,\n\t\tLatestValidHash: &common.ExecutionHash{0x1},\n\t}\n\trequire.Equal(t, engineprimitives.PayloadStatusValid, status.Status)\n\trequire.Equal(t, &common.ExecutionHash{0x1}, status.LatestValidHash)\n\n\t// Test marshaling\n\tmarshaledStatus, err := json.Marshal(status)\n\trequire.NoError(t, err)\n\n\t// Test unmarshaling\n\tvar unmarshaledStatus engineprimitives.PayloadStatusV1\n\terr = json.Unmarshal(marshaledStatus, &unmarshaledStatus)\n\trequire.NoError(t, err)\n\trequire.Equal(t, status, &unmarshaledStatus)\n}\n"
  },
  {
    "path": "engine-primitives/engine-primitives/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage engineprimitives\n\nimport \"github.com/berachain/beacon-kit/errors\"\n\nvar (\n\t// ErrInvalidTimestamp indicates that the provided timestamp is not valid.\n\tErrInvalidTimestamp = errors.New(\"invalid timestamp\")\n\n\t// ErrNilWithdrawals indicates that the withdrawals are in a\n\t// Capella versioned payload.\n\tErrNilWithdrawals = errors.New(\"nil withdrawals post capella\")\n\n\t// ErrEmptyPrevRandao indicates that the previous RANDAO value is empty.\n\tErrEmptyPrevRandao = errors.New(\"empty randao\")\n\n\t// ErrInvalidVersionedHash indicates that the versioned hash is invalid.\n\tErrInvalidVersionedHash = errors.New(\"invalid versioned hash\")\n\n\t// ErrMismatchedNumVersionedHashes indicates that the number of blobs in the\n\t// payload does not match the expected number.\n\tErrMismatchedNumVersionedHashes = errors.New(\n\t\t\"mismatch in number of versioned hashes\",\n\t)\n\n\t// ErrPayloadBlockHashMismatch represents an error when the block hash\n\t// in the payload does not match from the assembled block.\n\tErrPayloadBlockHashMismatch = errors.New(\"block hash in payload does not match assembled block\")\n\n\t// ErrEmptyPrevProposerPubKey indicates that the previous proposer public key is empty.\n\tErrEmptyPrevProposerPubKey = errors.New(\"empty public key for previous block proposer\")\n\n\t// ErrNonEmptyPrevProposerPubKey indicates that the previous proposer public key is non-empty.\n\tErrNonEmptyPrevProposerPubKey = errors.New(\"non-empty public key for previous block proposer\")\n)\n"
  },
  {
    "path": "engine-primitives/engine-primitives/mocks/blobs_bundle.mock.go",
    "content": "// Code generated by mockery v2.53.5. DO NOT EDIT.\n\npackage mocks\n\nimport (\n\teip4844 \"github.com/berachain/beacon-kit/primitives/eip4844\"\n\n\tmock \"github.com/stretchr/testify/mock\"\n)\n\n// BlobsBundle is an autogenerated mock type for the BlobsBundle type\ntype BlobsBundle struct {\n\tmock.Mock\n}\n\ntype BlobsBundle_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *BlobsBundle) EXPECT() *BlobsBundle_Expecter {\n\treturn &BlobsBundle_Expecter{mock: &_m.Mock}\n}\n\n// GetBlobs provides a mock function with no fields\nfunc (_m *BlobsBundle) GetBlobs() []*eip4844.Blob {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetBlobs\")\n\t}\n\n\tvar r0 []*eip4844.Blob\n\tif rf, ok := ret.Get(0).(func() []*eip4844.Blob); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).([]*eip4844.Blob)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// BlobsBundle_GetBlobs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBlobs'\ntype BlobsBundle_GetBlobs_Call struct {\n\t*mock.Call\n}\n\n// GetBlobs is a helper method to define mock.On call\nfunc (_e *BlobsBundle_Expecter) GetBlobs() *BlobsBundle_GetBlobs_Call {\n\treturn &BlobsBundle_GetBlobs_Call{Call: _e.mock.On(\"GetBlobs\")}\n}\n\nfunc (_c *BlobsBundle_GetBlobs_Call) Run(run func()) *BlobsBundle_GetBlobs_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *BlobsBundle_GetBlobs_Call) Return(_a0 []*eip4844.Blob) *BlobsBundle_GetBlobs_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *BlobsBundle_GetBlobs_Call) RunAndReturn(run func() []*eip4844.Blob) *BlobsBundle_GetBlobs_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// GetCommitments provides a mock function with no fields\nfunc (_m *BlobsBundle) GetCommitments() []eip4844.KZGCommitment {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetCommitments\")\n\t}\n\n\tvar r0 []eip4844.KZGCommitment\n\tif rf, ok := ret.Get(0).(func() []eip4844.KZGCommitment); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).([]eip4844.KZGCommitment)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// BlobsBundle_GetCommitments_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCommitments'\ntype BlobsBundle_GetCommitments_Call struct {\n\t*mock.Call\n}\n\n// GetCommitments is a helper method to define mock.On call\nfunc (_e *BlobsBundle_Expecter) GetCommitments() *BlobsBundle_GetCommitments_Call {\n\treturn &BlobsBundle_GetCommitments_Call{Call: _e.mock.On(\"GetCommitments\")}\n}\n\nfunc (_c *BlobsBundle_GetCommitments_Call) Run(run func()) *BlobsBundle_GetCommitments_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *BlobsBundle_GetCommitments_Call) Return(_a0 []eip4844.KZGCommitment) *BlobsBundle_GetCommitments_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *BlobsBundle_GetCommitments_Call) RunAndReturn(run func() []eip4844.KZGCommitment) *BlobsBundle_GetCommitments_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// GetProofs provides a mock function with no fields\nfunc (_m *BlobsBundle) GetProofs() []eip4844.KZGProof {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetProofs\")\n\t}\n\n\tvar r0 []eip4844.KZGProof\n\tif rf, ok := ret.Get(0).(func() []eip4844.KZGProof); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).([]eip4844.KZGProof)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// BlobsBundle_GetProofs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetProofs'\ntype BlobsBundle_GetProofs_Call struct {\n\t*mock.Call\n}\n\n// GetProofs is a helper method to define mock.On call\nfunc (_e *BlobsBundle_Expecter) GetProofs() *BlobsBundle_GetProofs_Call {\n\treturn &BlobsBundle_GetProofs_Call{Call: _e.mock.On(\"GetProofs\")}\n}\n\nfunc (_c *BlobsBundle_GetProofs_Call) Run(run func()) *BlobsBundle_GetProofs_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *BlobsBundle_GetProofs_Call) Return(_a0 []eip4844.KZGProof) *BlobsBundle_GetProofs_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *BlobsBundle_GetProofs_Call) RunAndReturn(run func() []eip4844.KZGProof) *BlobsBundle_GetProofs_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewBlobsBundle creates a new instance of BlobsBundle. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewBlobsBundle(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *BlobsBundle {\n\tmock := &BlobsBundle{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "engine-primitives/engine-primitives/mocks/payload_attributer.mock.go",
    "content": "// Code generated by mockery v2.49.0. DO NOT EDIT.\n\npackage mocks\n\nimport (\n\tbytes \"github.com/berachain/beacon-kit/primitives/bytes\"\n\tcommon \"github.com/berachain/beacon-kit/primitives/common\"\n\n\tmock \"github.com/stretchr/testify/mock\"\n)\n\n// PayloadAttributer is an autogenerated mock type for the PayloadAttributer type\ntype PayloadAttributer struct {\n\tmock.Mock\n}\n\ntype PayloadAttributer_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *PayloadAttributer) EXPECT() *PayloadAttributer_Expecter {\n\treturn &PayloadAttributer_Expecter{mock: &_m.Mock}\n}\n\n// GetSuggestedFeeRecipient provides a mock function with given fields:\nfunc (_m *PayloadAttributer) GetSuggestedFeeRecipient() common.ExecutionAddress {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetSuggestedFeeRecipient\")\n\t}\n\n\tvar r0 common.ExecutionAddress\n\tif rf, ok := ret.Get(0).(func() common.ExecutionAddress); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(common.ExecutionAddress)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// PayloadAttributer_GetSuggestedFeeRecipient_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSuggestedFeeRecipient'\ntype PayloadAttributer_GetSuggestedFeeRecipient_Call struct {\n\t*mock.Call\n}\n\n// GetSuggestedFeeRecipient is a helper method to define mock.On call\nfunc (_e *PayloadAttributer_Expecter) GetSuggestedFeeRecipient() *PayloadAttributer_GetSuggestedFeeRecipient_Call {\n\treturn &PayloadAttributer_GetSuggestedFeeRecipient_Call{Call: _e.mock.On(\"GetSuggestedFeeRecipient\")}\n}\n\nfunc (_c *PayloadAttributer_GetSuggestedFeeRecipient_Call) Run(run func()) *PayloadAttributer_GetSuggestedFeeRecipient_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *PayloadAttributer_GetSuggestedFeeRecipient_Call) Return(_a0 common.ExecutionAddress) *PayloadAttributer_GetSuggestedFeeRecipient_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *PayloadAttributer_GetSuggestedFeeRecipient_Call) RunAndReturn(run func() common.ExecutionAddress) *PayloadAttributer_GetSuggestedFeeRecipient_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// IsNil provides a mock function with given fields:\nfunc (_m *PayloadAttributer) IsNil() bool {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for IsNil\")\n\t}\n\n\tvar r0 bool\n\tif rf, ok := ret.Get(0).(func() bool); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tr0 = ret.Get(0).(bool)\n\t}\n\n\treturn r0\n}\n\n// PayloadAttributer_IsNil_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsNil'\ntype PayloadAttributer_IsNil_Call struct {\n\t*mock.Call\n}\n\n// IsNil is a helper method to define mock.On call\nfunc (_e *PayloadAttributer_Expecter) IsNil() *PayloadAttributer_IsNil_Call {\n\treturn &PayloadAttributer_IsNil_Call{Call: _e.mock.On(\"IsNil\")}\n}\n\nfunc (_c *PayloadAttributer_IsNil_Call) Run(run func()) *PayloadAttributer_IsNil_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *PayloadAttributer_IsNil_Call) Return(_a0 bool) *PayloadAttributer_IsNil_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *PayloadAttributer_IsNil_Call) RunAndReturn(run func() bool) *PayloadAttributer_IsNil_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// Version provides a mock function with given fields:\nfunc (_m *PayloadAttributer) GetForkVersion() bytes.B4 {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetForkVersion\")\n\t}\n\n\tvar r0 bytes.B4\n\tif rf, ok := ret.Get(0).(func() bytes.B4); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(bytes.B4)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// PayloadAttributer_Version_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetForkVersion'\ntype PayloadAttributer_Version_Call struct {\n\t*mock.Call\n}\n\n// Version is a helper method to define mock.On call\nfunc (_e *PayloadAttributer_Expecter) Version() *PayloadAttributer_Version_Call {\n\treturn &PayloadAttributer_Version_Call{Call: _e.mock.On(\"GetForkVersion\")}\n}\n\nfunc (_c *PayloadAttributer_Version_Call) Run(run func()) *PayloadAttributer_Version_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *PayloadAttributer_Version_Call) Return(_a0 bytes.B4) *PayloadAttributer_Version_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *PayloadAttributer_Version_Call) RunAndReturn(run func() bytes.B4) *PayloadAttributer_Version_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewPayloadAttributer creates a new instance of PayloadAttributer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewPayloadAttributer(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *PayloadAttributer {\n\tmock := &PayloadAttributer{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "engine-primitives/engine-primitives/transactions.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage engineprimitives\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/karalabe/ssz\"\n)\n\nvar (\n\t_ ssz.DynamicObject       = (*Transactions)(nil)\n\t_ constraints.SSZRootable = (*Transactions)(nil)\n)\n\n// Transactions is a type alias for [][]byte, which is how\n// transactions are received in the execution payload.\ntype Transactions [][]byte\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// SizeSSZ returns the SSZ encoded size in bytes for the Transactions.\nfunc (txs Transactions) SizeSSZ(siz *ssz.Sizer, _ bool) uint32 {\n\treturn ssz.SizeSliceOfDynamicBytes(siz, txs)\n}\n\n// DefineSSZ defines the SSZ encoding for the Transactions object.\n// TODO: This can accidentally decouple from the definition in\n// ExecutionPayload and we should be cognizant of that and/or\n// make a PR to allow for them to be defined in one place.\nfunc (txs Transactions) DefineSSZ(codec *ssz.Codec) {\n\tcodec.DefineEncoder(func(*ssz.Encoder) {\n\t\tssz.DefineSliceOfDynamicBytesContent(\n\t\t\tcodec,\n\t\t\t(*[][]byte)(&txs),\n\t\t\tconstants.MaxTxsPerPayload,\n\t\t\tconstants.MaxBytesPerTx,\n\t\t)\n\t})\n\tcodec.DefineDecoder(func(*ssz.Decoder) {\n\t\tssz.DefineSliceOfDynamicBytesContent(\n\t\t\tcodec,\n\t\t\t(*[][]byte)(&txs),\n\t\t\tconstants.MaxTxsPerPayload,\n\t\t\tconstants.MaxBytesPerTx,\n\t\t)\n\t})\n\tcodec.DefineHasher(func(*ssz.Hasher) {\n\t\tssz.DefineSliceOfDynamicBytesOffset(\n\t\t\tcodec,\n\t\t\t(*[][]byte)(&txs),\n\t\t\tconstants.MaxTxsPerPayload,\n\t\t\tconstants.MaxBytesPerTx,\n\t\t)\n\t})\n}\n\n// HashTreeRoot returns the hash tree root of the Transactions object.\nfunc (txs Transactions) HashTreeRoot() common.Root {\n\treturn ssz.HashConcurrent(txs)\n}\n"
  },
  {
    "path": "engine-primitives/engine-primitives/transactions_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage engineprimitives_test\n\nimport (\n\t\"testing\"\n\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n)\n\n// Tests consistency of our HashTreeRoot implementation with Prysm's.\n// https://github.com/prysmaticlabs/prysm/blob/8070fc8ecef3c2003dea7e1fe6dba179ddf76151/encoding/ssz/htrutils_test.go#L67\n//\n//nolint:lll // link.\nvar prysmConsistencyTests = []struct {\n\tname    string\n\ttxs     [][]byte\n\twant    [32]byte\n\twantErr bool\n}{\n\t{\n\t\tname: \"nil\",\n\t\ttxs:  nil,\n\t\twant: [32]byte{\n\t\t\t127, 254, 36, 30, 166, 1, 135, 253, 176, 24, 123, 250, 34, 222,\n\t\t\t53, 209, 249, 190, 215, 171, 6, 29, 148, 1, 253, 71, 227, 74,\n\t\t\t84, 251, 237, 225,\n\t\t},\n\t},\n\t{\n\t\tname: \"empty\",\n\t\ttxs:  [][]byte{},\n\t\twant: [32]byte{\n\t\t\t127, 254, 36, 30, 166, 1, 135, 253, 176, 24, 123, 250, 34, 222,\n\t\t\t53, 209, 249, 190, 215, 171, 6, 29, 148, 1, 253, 71, 227, 74,\n\t\t\t84, 251, 237, 225,\n\t\t},\n\t},\n\t{\n\t\tname: \"3 non-nil txs\",\n\t\ttxs: [][]byte{\n\t\t\t[]byte(\"transaction1\"),\n\t\t\t[]byte(\"transaction2\"),\n\t\t\t[]byte(\"transaction3\"),\n\t\t},\n\t\twant: [32]byte{\n\t\t\t139, 213, 123, 109, 253, 176, 23, 93, 101, 51, 142, 198, 119,\n\t\t\t250, 13, 242, 79, 219, 180, 165, 254, 181, 9, 178, 4, 253,\n\t\t\t110, 75, 50, 25, 17, 141,\n\t\t},\n\t},\n\t{\n\t\tname: \"max bytes per tx\",\n\t\ttxs: func() [][]byte {\n\t\t\tvar tx []byte\n\t\t\tfor i := range constants.MaxBytesPerTx {\n\t\t\t\ttx = append(tx, byte(i))\n\t\t\t}\n\t\t\treturn [][]byte{tx}\n\t\t}(),\n\t\twant: [32]byte{\n\t\t\t120, 150, 59, 37, 152, 101, 206, 102, 229, 69, 62, 176, 208, 159,\n\t\t\t230, 109, 150, 65, 134, 25, 69, 61, 13, 45, 150, 78, 139, 155, 241,\n\t\t\t18, 248, 222,\n\t\t},\n\t},\n\t{\n\t\tname: \"one tx\",\n\t\ttxs:  [][]byte{{1, 2, 3}},\n\t\twant: [32]byte{\n\t\t\t102, 209, 140, 87, 217, 28, 68, 12, 133, 42, 77, 136, 191, 18,\n\t\t\t234, 105, 166, 228, 216, 235, 230, 95, 200, 73, 85, 33, 134,\n\t\t\t254, 219, 97, 82, 209,\n\t\t},\n\t},\n\t{\n\t\tname: \"max txs\",\n\t\ttxs: func() [][]byte {\n\t\t\tvar txs [][]byte\n\t\t\tfor range int(constants.MaxTxsPerPayload) {\n\t\t\t\ttxs = append(txs, []byte{0x01})\n\t\t\t}\n\t\t\treturn txs\n\t\t}(),\n\t\twant: [32]byte{\n\t\t\t168, 19, 62, 29, 232, 106, 28, 81, 99, 73, 236, 102, 94, 160, 44, 191, 122, 176, 38, 39, 139, 100, 136, 5, 48, 242, 34, 31, 60, 104, 191, 171,\n\t\t},\n\t},\n}\n\nfunc TestProperTransactions(t *testing.T) {\n\tt.Parallel()\n\tfor _, tt := range prysmConsistencyTests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot := engineprimitives.Transactions(\n\t\t\t\ttt.txs,\n\t\t\t).HashTreeRoot()\n\n\t\t\tfor i := range got {\n\t\t\t\tif got[i] != tt.want[i] {\n\t\t\t\t\tt.Errorf(\n\t\t\t\t\t\t\"TransactionsRoot() got = %v, want %v, off at byte %d\",\n\t\t\t\t\t\t[32]byte(got), tt.want, i,\n\t\t\t\t\t)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "engine-primitives/engine-primitives/withdrawal.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage engineprimitives\n\nimport (\n\t\"io\"\n\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tfastssz \"github.com/ferranbt/fastssz\"\n\t\"github.com/karalabe/ssz\"\n\tfastrlp \"github.com/umbracle/fastrlp\"\n)\n\n// withdrawalSize is the size of the Withdrawal in bytes.\nconst withdrawalSize = 44\n\nvar (\n\t_ ssz.StaticObject                    = (*Withdrawal)(nil)\n\t_ constraints.SSZMarshallableRootable = (*Withdrawal)(nil)\n)\n\n// Withdrawal represents a validator withdrawal from the consensus layer.\ntype Withdrawal struct {\n\t// Index is the unique identifier for the withdrawal.\n\tIndex math.U64 `json:\"index\"`\n\t// Validator is the index of the validator initiating the withdrawal.\n\tValidator math.ValidatorIndex `json:\"validatorIndex\"`\n\t// Address is the execution address where the withdrawal will be sent.\n\t// It has a fixed size of 20 bytes.\n\tAddress common.ExecutionAddress `json:\"address\"`\n\t// Amount is the amount of Gwei to be withdrawn.\n\tAmount math.Gwei `json:\"amount\"`\n}\n\nfunc NewWithdrawal(\n\tindex math.U64,\n\tvalidator math.ValidatorIndex,\n\taddress common.ExecutionAddress,\n\tamount math.Gwei,\n) *Withdrawal {\n\treturn &Withdrawal{\n\t\tIndex:     index,\n\t\tValidator: validator,\n\t\tAddress:   address,\n\t\tAmount:    amount,\n\t}\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// SizeSSZ returns the size of the Withdrawal in bytes when SSZ encoded.\nfunc (*Withdrawal) SizeSSZ(*ssz.Sizer) uint32 {\n\treturn withdrawalSize\n}\n\n// MarshalSSZ marshals the Withdrawal into SSZ format.\nfunc (w *Withdrawal) DefineSSZ(c *ssz.Codec) {\n\tssz.DefineUint64(c, &w.Index)        // Field  (0) -     Index -  8 bytes\n\tssz.DefineUint64(c, &w.Validator)    // Field  (1) - Validator -  8 bytes\n\tssz.DefineStaticBytes(c, &w.Address) // Field  (2) -   Address - 20 bytes\n\tssz.DefineUint64(c, &w.Amount)       // Field  (3) -    Amount -  8 bytes\n}\n\n// HashTreeRoot.\nfunc (w *Withdrawal) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(w)\n}\n\n// MarshalSSZ marshals the Withdrawal object to SSZ format.\nfunc (w *Withdrawal) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(w))\n\treturn buf, ssz.EncodeToBytes(buf, w)\n}\n\nfunc (*Withdrawal) ValidateAfterDecodingSSZ() error { return nil }\n\n/* -------------------------------------------------------------------------- */\n/*                                   FastSSZ                                  */\n/* -------------------------------------------------------------------------- */\n\n// MarshalSSZTo ssz marshals the Withdrawal object to a target array.\nfunc (w *Withdrawal) MarshalSSZTo(dst []byte) ([]byte, error) {\n\tbz, err := w.MarshalSSZ()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdst = append(dst, bz...)\n\treturn dst, nil\n}\n\n// HashTreeRootWith ssz hashes the Withdrawal object with a hasher.\nfunc (w *Withdrawal) HashTreeRootWith(hh fastssz.HashWalker) error {\n\tindx := hh.Index()\n\n\t// Field (0) 'Index'\n\thh.PutUint64(uint64(w.Index))\n\n\t// Field (1) 'Validator'\n\thh.PutUint64(uint64(w.Validator))\n\n\t// Field (2) 'Address'\n\thh.PutBytes(w.Address[:])\n\n\t// Field (3) 'Amount'\n\thh.PutUint64(uint64(w.Amount))\n\n\thh.Merkleize(indx)\n\treturn nil\n}\n\n// GetTree ssz hashes the Withdrawal object.\nfunc (w *Withdrawal) GetTree() (*fastssz.Node, error) {\n\treturn fastssz.ProofTree(w)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                     RLP                                    */\n/* -------------------------------------------------------------------------- */\n\n// SetIndex sets the unique identifier for the withdrawal.\nfunc (w Withdrawal) EncodeRLP(_w io.Writer) error {\n\ta := fastrlp.DefaultArenaPool.Get()\n\tdefer fastrlp.DefaultArenaPool.Put(a)\n\tv := a.NewArray()\n\tv.Set(a.NewUint(uint64(w.Index)))\n\tv.Set(a.NewUint(uint64(w.Validator)))\n\tv.Set(a.NewCopyBytes(w.Address[:]))\n\tv.Set(a.NewUint(uint64(w.Amount)))\n\t_, err := _w.Write(v.MarshalTo(nil))\n\treturn err\n}\n\n/* -------------------------------------------------------------------------- */\n/*                             Getters and Setters                            */\n/* -------------------------------------------------------------------------- */\n\n// Equals returns true if the Withdrawal is equal to the other.\nfunc (w *Withdrawal) Equals(rhs *Withdrawal) bool {\n\tswitch {\n\tcase w == nil && rhs == nil:\n\t\treturn true\n\tcase w != nil && rhs != nil:\n\t\treturn w.Index == rhs.Index &&\n\t\t\tw.Validator == rhs.Validator &&\n\t\t\tw.Address == rhs.Address &&\n\t\t\tw.Amount == rhs.Amount\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// GetIndex returns the unique identifier for the withdrawal.\nfunc (w *Withdrawal) GetIndex() math.U64 {\n\treturn w.Index\n}\n\n// GetValidatorIndex returns the index of the validator initiating the\n// withdrawal.\nfunc (w *Withdrawal) GetValidatorIndex() math.ValidatorIndex {\n\treturn w.Validator\n}\n\n// GetAddress returns the execution address where the withdrawal will be sent.\nfunc (w *Withdrawal) GetAddress() common.ExecutionAddress {\n\treturn w.Address\n}\n\n// GetAmount returns the amount of Gwei to be withdrawn.\nfunc (w *Withdrawal) GetAmount() math.Gwei {\n\treturn w.Amount\n}\n"
  },
  {
    "path": "engine-primitives/engine-primitives/withdrawal_ssz_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage engineprimitives_test\n\nimport (\n\t\"testing\"\n\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tkaralabessz \"github.com/karalabe/ssz\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestWithdrawalSSZ(t *testing.T) {\n\tt.Parallel()\n\twithdrawal := &engineprimitives.Withdrawal{\n\t\tIndex:     math.U64(1),\n\t\tValidator: math.ValidatorIndex(2),\n\t\tAddress:   [20]byte{},\n\t\tAmount:    math.Gwei(100),\n\t}\n\n\tdata, err := withdrawal.MarshalSSZ()\n\trequire.NoError(t, err)\n\trequire.NotNil(t, data)\n\n\tunmarshalled := new(engineprimitives.Withdrawal)\n\terr = ssz.Unmarshal(data, unmarshalled)\n\trequire.NoError(t, err)\n\trequire.Equal(t, withdrawal, unmarshalled)\n\n\tsize := karalabessz.Size(withdrawal)\n\trequire.Equal(t, uint32(44), size)\n\n\ttree := withdrawal.HashTreeRoot()\n\trequire.NotNil(t, tree)\n}\n\nfunc TestWithdrawalGetTree(t *testing.T) {\n\tt.Parallel()\n\twithdrawal := &engineprimitives.Withdrawal{\n\t\tIndex:     math.U64(1),\n\t\tValidator: math.ValidatorIndex(2),\n\t\tAddress:   [20]byte{},\n\t\tAmount:    math.Gwei(100),\n\t}\n\n\ttree, err := withdrawal.GetTree()\n\trequire.NoError(t, err)\n\trequire.NotNil(t, tree)\n}\n\nfunc TestWithdrawalUnmarshalSSZ(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tinput   []byte\n\t\twant    *engineprimitives.Withdrawal\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\tname: \"Valid input little endian\",\n\t\t\tinput: []byte{\n\t\t\t\t1, 0, 0, 0, 0, 0, 0, 0, // Index: 1\n\t\t\t\t2, 0, 0, 0, 0, 0, 0, 0, // Validator: 2\n\t\t\t\t1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,\n\t\t\t\t12, 13, 14, 15, 16, 17, 18, 19, 20, // Address\n\t\t\t\t100, 0, 0, 0, 0, 0, 0, 0, // Amount: 100\n\t\t\t},\n\t\t\twant: &engineprimitives.Withdrawal{\n\t\t\t\tIndex:     math.U64(1),\n\t\t\t\tValidator: math.ValidatorIndex(2),\n\t\t\t\tAddress: [20]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10,\n\t\t\t\t\t11, 12, 13, 14, 15, 16, 17, 18, 19, 20},\n\t\t\t\tAmount: math.Gwei(100),\n\t\t\t},\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"Invalid size - too short\",\n\t\t\tinput:   []byte{0, 1, 2, 3},\n\t\t\twant:    &engineprimitives.Withdrawal{},\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"Invalid size - too long\",\n\t\t\tinput:   make([]byte, 45),\n\t\t\twant:    &engineprimitives.Withdrawal{},\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname: \"Max values\",\n\t\t\tinput: []byte{\n\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, // Index: max uint64\n\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, // Validator: max uint64\n\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // Address\n\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, // Amount: max uint64\n\t\t\t},\n\t\t\twant: &engineprimitives.Withdrawal{\n\t\t\t\tIndex:     math.U64(^uint64(0)),\n\t\t\t\tValidator: math.ValidatorIndex(^uint64(0)),\n\t\t\t\tAddress: [20]byte{255, 255, 255, 255, 255, 255, 255,\n\t\t\t\t\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255},\n\t\t\t\tAmount: math.Gwei(^uint64(0)),\n\t\t\t},\n\t\t\twantErr: false,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar w engineprimitives.Withdrawal\n\t\t\terr := ssz.Unmarshal(tt.input, &w)\n\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.want.Index, w.Index)\n\t\t\t\trequire.Equal(t, tt.want.Validator, w.Validator)\n\t\t\t\trequire.Equal(t, tt.want.Address, w.Address)\n\t\t\t\trequire.Equal(t, tt.want.Amount, w.Amount)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "engine-primitives/engine-primitives/withdrawal_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage engineprimitives_test\n\nimport (\n\t\"testing\"\n\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestWithdrawal(t *testing.T) {\n\tt.Parallel()\n\twithdrawal := engineprimitives.NewWithdrawal(\n\t\tmath.U64(1),\n\t\tmath.ValidatorIndex(1),\n\t\tcommon.ExecutionAddress{1, 2, 3, 4, 5},\n\t\tmath.Gwei(1000),\n\t)\n\n\trequire.Equal(t, math.U64(1), withdrawal.GetIndex())\n\trequire.Equal(t, math.ValidatorIndex(1), withdrawal.GetValidatorIndex())\n\trequire.Equal(t,\n\t\tcommon.ExecutionAddress{1, 2, 3, 4, 5},\n\t\twithdrawal.GetAddress(),\n\t)\n\trequire.Equal(t, math.Gwei(1000), withdrawal.GetAmount())\n}\n\nfunc TestWithdrawal_Equals(t *testing.T) {\n\tt.Parallel()\n\twithdrawal1 := &engineprimitives.Withdrawal{\n\t\tIndex:     math.U64(1),\n\t\tValidator: math.ValidatorIndex(1),\n\t\tAddress:   common.ExecutionAddress{1, 2, 3, 4, 5},\n\t\tAmount:    math.Gwei(1000),\n\t}\n\n\twithdrawal2 := &engineprimitives.Withdrawal{\n\t\tIndex:     math.U64(1),\n\t\tValidator: math.ValidatorIndex(1),\n\t\tAddress:   common.ExecutionAddress{1, 2, 3, 4, 5},\n\t\tAmount:    math.Gwei(1000),\n\t}\n\n\twithdrawal3 := &engineprimitives.Withdrawal{\n\t\tIndex:     math.U64(2),\n\t\tValidator: math.ValidatorIndex(2),\n\t\tAddress:   common.ExecutionAddress{2, 3, 4, 5, 6},\n\t\tAmount:    math.Gwei(2000),\n\t}\n\n\t// Test that Equals returns true for two identical withdrawals\n\trequire.True(t, withdrawal1.Equals(withdrawal2))\n\n\t// Test that Equals returns false for two different withdrawals\n\trequire.False(t, withdrawal1.Equals(withdrawal3))\n}\n\nfunc TestWithdrawalMethods(t *testing.T) {\n\tt.Parallel()\n\twithdrawal := &engineprimitives.Withdrawal{\n\t\tIndex:     math.U64(1),\n\t\tValidator: math.ValidatorIndex(2),\n\t\tAddress:   [20]byte{1, 2, 3},\n\t\tAmount:    math.Gwei(100),\n\t}\n\n\tt.Run(\"Getters\", func(t *testing.T) {\n\t\tt.Parallel()\n\t\trequire.Equal(t, math.U64(1), withdrawal.GetIndex())\n\t\trequire.Equal(t, math.ValidatorIndex(2), withdrawal.GetValidatorIndex())\n\t\trequire.Equal(t, common.ExecutionAddress([20]byte{0x01, 0x02, 0x03}),\n\t\t\twithdrawal.GetAddress())\n\t\trequire.Equal(t, math.U64(100), withdrawal.GetAmount())\n\t})\n}\n"
  },
  {
    "path": "engine-primitives/engine-primitives/withdrawals.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage engineprimitives\n\nimport (\n\t\"bytes\"\n\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/karalabe/ssz\"\n)\n\nvar (\n\t_ ssz.StaticObject        = (*Withdrawals)(nil)\n\t_ constraints.SSZRootable = (*Withdrawals)(nil)\n)\n\n// Withdrawals represents a list of withdrawals.\ntype Withdrawals []*Withdrawal\n\n/* -------------------------------------------------------------------------- */\n/*                                     SSZ                                    */\n/* -------------------------------------------------------------------------- */\n\n// SizeSSZ returns the SSZ encoded size in bytes for the Withdrawals.\nfunc (w Withdrawals) SizeSSZ(siz *ssz.Sizer) uint32 {\n\treturn ssz.SizeSliceOfStaticObjects(siz, w)\n}\n\n// DefineSSZ defines the SSZ encoding for the Withdrawals object.\nfunc (w Withdrawals) DefineSSZ(codec *ssz.Codec) {\n\tcodec.DefineEncoder(func(*ssz.Encoder) {\n\t\tssz.DefineSliceOfStaticObjectsContent(\n\t\t\tcodec, (*[]*Withdrawal)(&w), constants.MaxWithdrawalsPerPayload)\n\t})\n\tcodec.DefineDecoder(func(*ssz.Decoder) {\n\t\tssz.DefineSliceOfStaticObjectsContent(\n\t\t\tcodec, (*[]*Withdrawal)(&w), constants.MaxWithdrawalsPerPayload)\n\t})\n\tcodec.DefineHasher(func(*ssz.Hasher) {\n\t\tssz.DefineSliceOfStaticObjectsOffset(\n\t\t\tcodec, (*[]*Withdrawal)(&w), constants.MaxWithdrawalsPerPayload)\n\t})\n}\n\n// HashTreeRoot returns the hash tree root of the Withdrawals.\nfunc (w Withdrawals) HashTreeRoot() common.Root {\n\treturn ssz.HashSequential(w)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                     RLP                                    */\n/* -------------------------------------------------------------------------- */\n\n// Len returns the length of s.\nfunc (w Withdrawals) Len() int { return len(w) }\n\n// EncodeIndex encodes the i'th withdrawal to w. Note that this does not check\n// for errors because we assume that *Withdrawal will only ever contain valid\n// withdrawals that were either\n// constructed by decoding or via public API in this package.\nfunc (w Withdrawals) EncodeIndex(i int, _w *bytes.Buffer) {\n\t// #nosec:G703 // its okay.\n\t_ = w[i].EncodeRLP(_w)\n}\n"
  },
  {
    "path": "engine-primitives/engine-primitives/withdrawals_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage engineprimitives_test\n\nimport (\n\t\"testing\"\n\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tkaralabessz \"github.com/karalabe/ssz\"\n\tzrntcommon \"github.com/protolambda/zrnt/eth2/beacon/common\"\n\tzspec \"github.com/protolambda/zrnt/eth2/configs\"\n\tztree \"github.com/protolambda/ztyp/tree\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestWithdrawals(t *testing.T) {\n\tt.Parallel()\n\tt.Run(\"SizeSSZ\", func(t *testing.T) {\n\t\tt.Parallel()\n\t\twithdrawals := engineprimitives.Withdrawals{\n\t\t\t{Index: 1, Validator: 2, Address: [20]byte{1, 2, 3}, Amount: 100},\n\t\t\t{Index: 3, Validator: 4, Address: [20]byte{4, 5, 6}, Amount: 200},\n\t\t}\n\t\trequire.Equal(t, uint32(len(withdrawals))*44, karalabessz.Size(withdrawals))\n\t})\n\n\tt.Run(\"HashTreeRoot\", func(t *testing.T) {\n\t\tt.Parallel()\n\t\twithdrawals := engineprimitives.Withdrawals{\n\t\t\t{Index: 1, Validator: 2, Address: [20]byte{1, 2, 3}, Amount: 100},\n\t\t\t{Index: 3, Validator: 4, Address: [20]byte{4, 5, 6}, Amount: 200},\n\t\t}\n\t\troot := withdrawals.HashTreeRoot()\n\t\trequire.NotEmpty(t, root)\n\t})\n\n\tt.Run(\"HashTreeRoot Comparison\", func(t *testing.T) {\n\t\tt.Parallel()\n\t\twithdrawals := engineprimitives.Withdrawals{\n\t\t\t{Index: 1, Validator: 2, Address: [20]byte{1, 2, 3}, Amount: 100},\n\t\t}\n\t\tzwithdrawals := zrntcommon.Withdrawals{\n\t\t\t{\n\t\t\t\tIndex:          zrntcommon.WithdrawalIndex(withdrawals[0].Index),\n\t\t\t\tValidatorIndex: zrntcommon.ValidatorIndex(withdrawals[0].Validator),\n\t\t\t\tAddress:        zrntcommon.Eth1Address(withdrawals[0].Address),\n\t\t\t\tAmount:         zrntcommon.Gwei(withdrawals[0].Amount),\n\t\t\t},\n\t\t}\n\t\troot := withdrawals.HashTreeRoot()\n\t\thFn := ztree.GetHashFn()\n\t\tspec := zspec.Mainnet\n\t\tzroot := zwithdrawals.HashTreeRoot(spec, hFn)\n\t\trequire.NotEmpty(t, root)\n\t\trequire.Equal(t, root[:], zroot[:])\n\t})\n\n\tt.Run(\"HashTreeRoot\", func(t *testing.T) {\n\t\tt.Parallel()\n\t\twithdrawals := engineprimitives.Withdrawals{\n\t\t\t{\n\t\t\t\tIndex:     math.U64(1),\n\t\t\t\tValidator: math.ValidatorIndex(2),\n\t\t\t\tAddress:   common.ExecutionAddress{1, 2, 3},\n\t\t\t\tAmount:    math.Gwei(100),\n\t\t\t},\n\t\t\t{\n\t\t\t\tIndex:     math.U64(3),\n\t\t\t\tValidator: math.ValidatorIndex(4),\n\t\t\t\tAddress:   common.ExecutionAddress{4, 5, 6},\n\t\t\t\tAmount:    math.Gwei(200),\n\t\t\t},\n\t\t}\n\n\t\troot := withdrawals.HashTreeRoot()\n\t\trequire.NotEmpty(t, root)\n\n\t\t// Verify that the root changes when the withdrawals change\n\t\twithdrawals[0].Amount = math.Gwei(150)\n\t\tnewRoot := withdrawals.HashTreeRoot()\n\t\trequire.NotEqual(t, root, newRoot)\n\n\t\t// Verify that the order of withdrawals matters\n\t\treversedWithdrawals := engineprimitives.Withdrawals{\n\t\t\twithdrawals[1],\n\t\t\twithdrawals[0],\n\t\t}\n\t\treversedRoot := reversedWithdrawals.HashTreeRoot()\n\t\trequire.NotEqual(t, newRoot, reversedRoot)\n\t})\n\n\tt.Run(\"HashTreeRoot of Empty List\", func(t *testing.T) {\n\t\tt.Parallel()\n\t\temptyWithdrawals := engineprimitives.Withdrawals{}\n\t\temptyRoot := emptyWithdrawals.HashTreeRoot()\n\t\trequire.NotEmpty(t, emptyRoot)\n\n\t\t// Verify that the root of an empty list is different from a non-empty\n\t\t// list\n\t\tnonEmptyWithdrawals := engineprimitives.Withdrawals{\n\t\t\t{\n\t\t\t\tIndex:     math.U64(1),\n\t\t\t\tValidator: math.ValidatorIndex(2),\n\t\t\t\tAddress:   common.ExecutionAddress{1, 2, 3},\n\t\t\t\tAmount:    math.Gwei(100),\n\t\t\t},\n\t\t}\n\t\tnonEmptyRoot := nonEmptyWithdrawals.HashTreeRoot()\n\t\trequire.NotEqual(t, emptyRoot, nonEmptyRoot)\n\t})\n}\n"
  },
  {
    "path": "engine-primitives/errors/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage errors\n\nimport (\n\t\"github.com/berachain/beacon-kit/errors\"\n)\n\nvar (\n\t// ErrPreDefinedJSONRPC is a catch-all error for all pre-defined json-rpc\n\t// errors.\n\tErrPreDefinedJSONRPC = errors.New(\n\t\t\"json-rpc error\",\n\t)\n\n\t// ErrUnknownPayload indicates an unavailable or non-existent payload\n\t// (JSON-RPC code -38001).\n\tErrUnknownPayload = errors.New(\n\t\t\"payload does not exist or is not available\")\n\n\t// ErrInvalidForkchoiceState indicates an invalid fork choice state\n\t// (JSON-RPC code -38002).\n\tErrInvalidForkchoiceState = errors.New(\n\t\t\"invalid forkchoice state\")\n\n\t// ErrInvalidPayloadAttributes indicates invalid or inconsistent payload\n\t// attributes\n\t// (JSON-RPC code -38003).\n\tErrInvalidPayloadAttributes = errors.New(\n\t\t\"payload attributes are invalid / inconsistent\")\n\n\t// ErrRequestTooLarge indicates that the request is too large\n\t// (JSON-RPC code -38004).\n\tErrRequestTooLarge = errors.New(\n\t\t\"request is too large\",\n\t)\n\n\t// ErrUnknownPayloadStatus indicates an unknown payload status.\n\tErrUnknownPayloadStatus = errors.New(\n\t\t\"unknown payload status\")\n\n\t// ErrAcceptedPayloadStatus indicates a payload status of ACCEPTED.\n\tErrAcceptedPayloadStatus = errors.New(\n\t\t\"payload status is ACCEPTED\")\n\n\t// ErrSyncingPayloadStatus indicates a payload status of SYNCING.\n\tErrSyncingPayloadStatus = errors.New(\n\t\t\"payload status is SYNCING\",\n\t)\n\n\t// ErrInvalidPayloadStatus indicates an invalid payload status.\n\tErrInvalidPayloadStatus = errors.New(\n\t\t\"payload status is INVALID\",\n\t)\n\t// ErrNilForkchoiceResponse indicates a nil forkchoice response.\n\tErrNilForkchoiceResponse = errors.New(\n\t\t\"nil forkchoice response\",\n\t)\n\t// ErrNilBlobsBundle is returned when nil blobs bundle is received.\n\tErrNilBlobsBundle = errors.New(\n\t\t\"nil blobs bundle received from execution client\")\n\n\t// ErrNilPayloadStatus is returned when nil payload status is received.\n\tErrNilPayloadStatus = errors.New(\n\t\t\"nil payload status received from execution client\",\n\t)\n\n\t// ErrEngineAPITimeout is returned when the engine API call times out.\n\tErrEngineAPITimeout = errors.New(\n\t\t\"engine API call timed out\",\n\t)\n)\n"
  },
  {
    "path": "errors/mod.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage errors\n\nimport (\n\tstderrors \"errors\"\n\t\"slices\"\n\n\t\"github.com/pkg/errors\"\n)\n\n// TODO: eventually swap out via build flags if we believe there is value\n// to doing so.\n//\n//nolint:gochecknoglobals // used an alias.\nvar (\n\tNew   = errors.New\n\tWrap  = errors.Wrap\n\tWrapf = errors.Wrapf\n\tIs    = errors.Is\n\tAs    = errors.As\n\tJoin  = stderrors.Join\n)\n\n// IsAny checks if the provided error is any of the provided errors.\nfunc IsAny(err error, errs ...error) bool {\n\tfor _, e := range errs {\n\t\tif errors.Is(err, e) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// DetailedError is a custom error type that includes a message and a flag\n// indicating if the error is fatal.\ntype DetailedError struct {\n\t// Msg is the error message.\n\terror\n\t// fatal indicates if the error is fatal.\n\tfatal bool\n}\n\n// WrapNonFatal returns the error message.\nfunc WrapNonFatal(err error) error {\n\treturn &DetailedError{\n\t\terror: err,\n\t\tfatal: false,\n\t}\n}\n\n// WrapFatal creates a new DetailedError with the\n// provided message and fatal flag.\nfunc WrapFatal(err error) error {\n\treturn &DetailedError{\n\t\terror: err,\n\t\tfatal: true,\n\t}\n}\n\n// IsFatal checks if the provided error is a\n// DetailedError and if it is fatal.\nfunc IsFatal(err error) bool {\n\t// If the error is nil, obviouisly it is not fatal.\n\tif err == nil {\n\t\treturn false\n\t}\n\n\t// Otherwise check for our custom error.\n\tvar customErr *DetailedError\n\tif errors.As(err, &customErr) {\n\t\tif customErr == nil {\n\t\t\treturn false\n\t\t}\n\n\t\t// If the underlying error is nil, we\n\t\t// return false.\n\t\tif customErr.error == nil {\n\t\t\treturn false\n\t\t}\n\n\t\t// Otherwise check the custom fatal field.\n\t\treturn customErr.fatal\n\t}\n\n\t// All other errors are fatal.\n\treturn true\n}\n\n// JoinFatal checks if any of the provided errors is a\n// DetailedError and if it is fatal.\nfunc JoinFatal(errs ...error) error {\n\tfatal := slices.ContainsFunc(errs, IsFatal)\n\tretErr := stderrors.Join(errs...)\n\tif fatal {\n\t\treturn WrapFatal(retErr)\n\t}\n\treturn WrapNonFatal(retErr)\n}\n"
  },
  {
    "path": "execution/README.md",
    "content": "# execution module\n\nThe execution module is responsible for housing the `engineclient`\nwhich allows the consensus client to connect to the execution client.\nIt also contains `engine` which implements the `ExecutionEngine` as\ndefined in the Ethereum 2.0 Specification.\n"
  },
  {
    "path": "execution/client/client.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage client\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"math/big\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n\tethclient \"github.com/berachain/beacon-kit/execution/client/ethclient\"\n\tethclientrpc \"github.com/berachain/beacon-kit/execution/client/ethclient/rpc\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/net/http\"\n\t\"github.com/berachain/beacon-kit/primitives/net/jwt\"\n)\n\n// EngineClient is a struct that holds a pointer to an Eth1Client.\ntype EngineClient struct {\n\t*ethclient.Client\n\t// cfg is the supplied configuration for the engine client.\n\tcfg *Config\n\t// logger is the logger for the engine client.\n\tlogger log.Logger\n\t// eth1ChainID is the chain ID of the execution client.\n\teth1ChainID *big.Int\n\t// clientMetrics is the metrics for the engine client.\n\tmetrics *clientMetrics\n\t// capabilities is a map of capabilities that the execution client has.\n\tcapabilities map[string]struct{}\n\t// connected will be set to true when we have successfully connected\n\t// to the execution client.\n\tconnectedMu sync.RWMutex\n\tconnected   bool\n}\n\n// New creates a new engine client EngineClient.\n// It takes an Eth1Client as an argument and returns a pointer  to an\n// EngineClient.\nfunc New(\n\tcfg *Config,\n\tlogger log.Logger,\n\tjwtSecret *jwt.Secret,\n\ttelemetrySink TelemetrySink,\n\teth1ChainID *big.Int,\n) *EngineClient {\n\tethClient := ethclientrpc.NewClient(\n\t\tcfg.RPCDialURL.String(),\n\t\tjwtSecret,\n\t\tcfg.RPCJWTRefreshInterval,\n\t\tlogger,\n\t)\n\n\t// Enforcing minimum rpc timeout\n\t// The reason we do it is that we previously suggested a\n\t// 900 ms default, which is unnecessarily strict.\n\t// TODO: Not great enforcing this here since, in principle,\n\t// other services may use this config (not currently the case)\n\t// and we pass cfg by pointer, hence we do a global change.\n\t// The altenative of validating every config in ProvideConfig\n\t// should be considered (but logging there is trickier)\n\tif cfg.RPCTimeout < MinRPCTimeout {\n\t\tlogger.Warn(\"Automatically raising RPCTimeout\",\n\t\t\t\"configured\", cfg.RPCTimeout,\n\t\t\t\"minimum\", MinRPCTimeout,\n\t\t)\n\t}\n\tcfg.RPCTimeout = max(MinRPCTimeout, cfg.RPCTimeout)\n\n\tif cfg.DeprecatedRPCRetries != 0 {\n\t\tlogger.Warn(\"ignoring deprecated setting rpc-retries\")\n\t}\n\n\treturn &EngineClient{\n\t\tcfg:          cfg,\n\t\tlogger:       logger,\n\t\tClient:       ethclient.New(ethClient),\n\t\tcapabilities: make(map[string]struct{}),\n\t\teth1ChainID:  eth1ChainID,\n\t\tmetrics:      newClientMetrics(telemetrySink, logger),\n\t\tconnected:    false,\n\t}\n}\n\n// Name returns the name of the engine client.\nfunc (s *EngineClient) Name() string {\n\treturn \"engine-client\"\n}\n\n// Start the engine client.\nfunc (s *EngineClient) Start(ctx context.Context) error {\n\t// Initialize the JWT token before making any RPC calls\n\tif err := s.Client.Initialize(); err != nil {\n\t\treturn fmt.Errorf(\"failed to initialize RPC client: %w\", err)\n\t}\n\n\t// Start the Client background refresh loop.\n\tgo s.Client.Start(ctx)\n\n\ts.logger.Info(\n\t\t\"Initializing connection to the execution client...\",\n\t\t\"dial_url\", s.cfg.RPCDialURL.String(),\n\t)\n\n\t// If the connection connection succeeds, we can skip the\n\t// connection initialization loop.\n\tif err := s.verifyChainIDAndConnection(ctx); err == nil {\n\t\treturn nil\n\t}\n\n\t// Attempt to initialize the connection to the execution client.\n\tticker := time.NewTicker(s.cfg.RPCStartupCheckInterval)\n\tdefer ticker.Stop()\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn ctx.Err()\n\t\tcase <-ticker.C:\n\t\t\ts.logger.Info(\n\t\t\t\t\"Waiting for execution client to start... 🍺🕔\",\n\t\t\t\t\"dial_url\", s.cfg.RPCDialURL,\n\t\t\t)\n\t\t\tif err := s.verifyChainIDAndConnection(ctx); err != nil {\n\t\t\t\tif errors.Is(err, ErrMismatchedEth1ChainID) {\n\t\t\t\t\ts.logger.Error(err.Error())\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ts.connectedMu.Lock()\n\t\t\ts.connected = true\n\t\t\ts.connectedMu.Unlock()\n\t\t\treturn nil\n\t\t}\n\t}\n}\n\nfunc (s *EngineClient) Stop() error {\n\treturn nil\n}\n\nfunc (s *EngineClient) IsConnected() bool {\n\ts.connectedMu.RLock()\n\tdefer s.connectedMu.RUnlock()\n\treturn s.connected\n}\n\nfunc (s *EngineClient) HasCapability(capability string) bool {\n\t_, ok := s.capabilities[capability]\n\treturn ok\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   Helpers                                  */\n/* -------------------------------------------------------------------------- */\n\n// verifyChainID dials the execution client and\n// ensures the chain ID is correct.\nfunc (s *EngineClient) verifyChainIDAndConnection(\n\tctx context.Context,\n) error {\n\tvar (\n\t\terr     error\n\t\tchainID math.U64\n\t)\n\n\tdefer func() {\n\t\tif err != nil {\n\t\t\terr = s.Client.Close()\n\t\t}\n\t}()\n\n\t// After the initial dial, check to make sure the chain ID is correct.\n\tchainID, err = s.Client.ChainID(ctx)\n\tif err != nil {\n\t\tif errors.Is(err, http.ErrUnauthorized) {\n\t\t\t// We always log this error as it is a critical error.\n\t\t\ts.logger.Error(UnauthenticatedConnectionErrorStr)\n\t\t}\n\t\treturn err\n\t}\n\n\t// TODO: consider validating once when config is set or\n\t// client is initialized\n\tif !s.eth1ChainID.IsUint64() {\n\t\terr = errors.Wrapf(\n\t\t\terrors.New(\"provided chain ID is not uint64\"),\n\t\t\ts.eth1ChainID.String(),\n\t\t)\n\t\treturn err\n\t}\n\tif chainID.Unwrap() != s.eth1ChainID.Uint64() {\n\t\terr = errors.Wrapf(\n\t\t\tErrMismatchedEth1ChainID,\n\t\t\t\"wanted chain ID %d, got %d\",\n\t\t\ts.eth1ChainID,\n\t\t\tchainID,\n\t\t)\n\t\treturn err\n\t}\n\n\t// Log the chain ID.\n\ts.logger.Info(\n\t\t\"Connected to execution client 🔌\",\n\t\t\"dial_url\", s.cfg.RPCDialURL.String(),\n\t\t\"chain_id\", chainID.Unwrap(),\n\t\t\"required_chain_id\", s.eth1ChainID,\n\t)\n\n\t// Exchange capabilities with the execution client.\n\tif _, err = s.ExchangeCapabilities(ctx); err != nil {\n\t\ts.logger.Error(\"failed to exchange capabilities\", \"err\", err)\n\t\treturn err\n\t}\n\treturn nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   Getters                                  */\n/* -------------------------------------------------------------------------- */\n\nfunc (s *EngineClient) GetRPCRetryInterval() time.Duration {\n\treturn s.cfg.RPCRetryInterval\n}\n\nfunc (s *EngineClient) GetRPCMaxRetryInterval() time.Duration {\n\treturn s.cfg.RPCMaxRetryInterval\n}\n"
  },
  {
    "path": "execution/client/config.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage client\n\nimport (\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/primitives/net/url\"\n)\n\nconst (\n\tMinRPCTimeout = 2 * time.Second\n\n\tdefaultDialURL                 = \"http://localhost:8551\"\n\tdefaultRPCRetryInterval        = 100 * time.Millisecond\n\tdefaultRPCMaxRetryInterval     = 10 * time.Second\n\tdefaultRPCStartupCheckInterval = 3 * time.Second\n\tdefaultRPCJWTRefreshInterval   = 30 * time.Second\n\t//#nosec:G101 // false positive.\n\tdefaultJWTSecretPath = \"./jwt.hex\"\n)\n\n// DefaultConfig is the default configuration for the engine client.\nfunc DefaultConfig() Config {\n\t//#nosec:G703 // ignoring on purpose since it is the default URL.\n\tdialURL, _ := url.NewFromRaw(defaultDialURL)\n\treturn Config{\n\t\tRPCDialURL:              dialURL,\n\t\tRPCRetryInterval:        defaultRPCRetryInterval,\n\t\tRPCMaxRetryInterval:     defaultRPCMaxRetryInterval,\n\t\tRPCTimeout:              MinRPCTimeout,\n\t\tRPCStartupCheckInterval: defaultRPCStartupCheckInterval,\n\t\tRPCJWTRefreshInterval:   defaultRPCJWTRefreshInterval,\n\t\tJWTSecretPath:           defaultJWTSecretPath,\n\t}\n}\n\n// Config is the configuration struct for the execution client.\ntype Config struct {\n\t// RPCDialURL is the HTTP url of the execution client JSON-RPC endpoint.\n\tRPCDialURL *url.ConnectionURL `mapstructure:\"rpc-dial-url\"`\n\t// DeprecatedRPCRetries is deprecated.\n\tDeprecatedRPCRetries uint64 `mapstructure:\"rpc-retries\"`\n\t// RPCRetryInterval is the initial RPC backoff for repeated execution client calls.\n\tRPCRetryInterval time.Duration `mapstructure:\"rpc-retry-interval\"`\n\t// MaxRPCRetryInterval is the maximum RPC backoff for repeated execution client calls.\n\tRPCMaxRetryInterval time.Duration `mapstructure:\"rpc-max-retry-interval\"`\n\t// RPCTimeout is the RPC timeout for individual execution client calls.\n\tRPCTimeout time.Duration `mapstructure:\"rpc-timeout\"`\n\t// RPCStartupCheckInterval is the Interval for the startup check.\n\tRPCStartupCheckInterval time.Duration `mapstructure:\"rpc-startup-check-interval\"`\n\t// JWTRefreshInterval is the Interval for the JWT refresh.\n\tRPCJWTRefreshInterval time.Duration `mapstructure:\"rpc-jwt-refresh-interval\"`\n\t// JWTSecretPath is the path to the JWT secret.\n\tJWTSecretPath string `mapstructure:\"jwt-secret-path\"`\n}\n"
  },
  {
    "path": "execution/client/engine.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage client\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\tengineerrors \"github.com/berachain/beacon-kit/engine-primitives/errors\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\tethclient \"github.com/berachain/beacon-kit/execution/client/ethclient\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                 NewPayload                                 */\n/* -------------------------------------------------------------------------- */\n\n// NewPayload calls the engine_newPayloadVX method via JSON-RPC.\nfunc (s *EngineClient) NewPayload(\n\tctx context.Context,\n\treq ctypes.NewPayloadRequest,\n) (*common.ExecutionHash, error) {\n\tvar (\n\t\tstartTime    = time.Now()\n\t\tcctx, cancel = s.createContextWithTimeout(ctx)\n\t)\n\tdefer s.metrics.measureNewPayloadDuration(startTime)\n\tdefer cancel()\n\n\t// Call the appropriate RPC method based on the payload version.\n\tresult, err := s.Client.NewPayload(cctx, req)\n\tif err != nil {\n\t\tif errors.Is(err, engineerrors.ErrEngineAPITimeout) {\n\t\t\ts.metrics.incrementNewPayloadTimeout()\n\t\t}\n\t\treturn nil, s.handleRPCError(err)\n\t}\n\tif result == nil {\n\t\treturn nil, engineerrors.ErrNilPayloadStatus\n\t}\n\n\t// This case is only true when the payload is invalid, so\n\t// `processPayloadStatusResult` below will return an error.\n\tif validationErr := result.ValidationError; validationErr != nil {\n\t\ts.logger.Error(\n\t\t\t\"Got a validation error in newPayload\",\n\t\t\t\"err\",\n\t\t\terrors.New(*validationErr),\n\t\t)\n\t}\n\n\treturn processPayloadStatusResult(result)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                              ForkchoiceUpdated                             */\n/* -------------------------------------------------------------------------- */\n\n// ForkchoiceUpdated calls the engine_forkchoiceUpdatedV1 method via JSON-RPC.\nfunc (s *EngineClient) ForkchoiceUpdated(\n\tctx context.Context,\n\tstate *engineprimitives.ForkchoiceStateV1,\n\tattrs *engineprimitives.PayloadAttributes,\n\tforkVersion common.Version,\n) (*engineprimitives.PayloadID, error) {\n\tvar (\n\t\tstartTime    = time.Now()\n\t\tcctx, cancel = s.createContextWithTimeout(ctx)\n\t)\n\tdefer s.metrics.measureForkchoiceUpdateDuration(startTime)\n\tdefer cancel()\n\n\t// If the suggested fee recipient is not set, log a warning.\n\tif attrs != nil &&\n\t\tattrs.GetSuggestedFeeRecipient() == (common.ExecutionAddress{}) {\n\t\ts.logger.Warn(\n\t\t\t\"Suggested fee recipient is not configured 🔆\",\n\t\t\t\"fee-recipient\", attrs.GetSuggestedFeeRecipient(),\n\t\t)\n\t}\n\n\tresult, err := s.Client.ForkchoiceUpdated(cctx, state, attrs, forkVersion)\n\tif err != nil {\n\t\tif errors.Is(err, engineerrors.ErrEngineAPITimeout) {\n\t\t\ts.metrics.incrementForkchoiceUpdateTimeout()\n\t\t}\n\t\treturn nil, s.handleRPCError(err)\n\t}\n\tif result == nil {\n\t\treturn nil, engineerrors.ErrNilForkchoiceResponse\n\t}\n\n\t_, err = processPayloadStatusResult(&result.PayloadStatus)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn result.PayloadID, nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                 GetPayload                                 */\n/* -------------------------------------------------------------------------- */\n\n// GetPayload calls the engine_getPayloadVX method via JSON-RPC. It returns\n// the execution data as well as the blobs bundle.\nfunc (s *EngineClient) GetPayload(\n\tctx context.Context,\n\tpayloadID engineprimitives.PayloadID,\n\tforkVersion common.Version,\n) (ctypes.BuiltExecutionPayloadEnv, error) {\n\tvar (\n\t\tstartTime    = time.Now()\n\t\tcctx, cancel = s.createContextWithTimeout(ctx)\n\t)\n\tdefer s.metrics.measureGetPayloadDuration(startTime)\n\tdefer cancel()\n\n\t// Call and check for errors.\n\tresult, err := s.Client.GetPayload(cctx, payloadID, forkVersion)\n\tif err != nil {\n\t\tif errors.Is(err, engineerrors.ErrEngineAPITimeout) {\n\t\t\ts.metrics.incrementGetPayloadTimeout()\n\t\t}\n\t\treturn result, s.handleRPCError(err)\n\t}\n\tif result == nil {\n\t\t// Engine API returns the Unknown Payload (-38001) error if a nil result is returned.\n\t\treturn result, engineerrors.ErrUnknownPayload\n\t}\n\tif result.GetBlobsBundle() == nil {\n\t\treturn result, engineerrors.ErrNilBlobsBundle\n\t}\n\n\treturn result, nil\n}\n\n// ExchangeCapabilities calls the engine_exchangeCapabilities method via\n// JSON-RPC.\nfunc (s *EngineClient) ExchangeCapabilities(\n\tctx context.Context,\n) ([]string, error) {\n\tresult, err := s.Client.ExchangeCapabilities(\n\t\tctx, ethclient.BeaconKitSupportedCapabilities(),\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Capture and log the capabilities that the execution client has.\n\tfor _, capability := range result {\n\t\ts.logger.Info(\"Exchanged capability\", \"capability\", capability)\n\t\ts.capabilities[capability] = struct{}{}\n\t}\n\n\t// Log the capabilities that the execution client does not have.\n\tfor _, capability := range ethclient.BeaconKitSupportedCapabilities() {\n\t\tif !s.HasCapability(capability) {\n\t\t\ts.logger.Warn(\n\t\t\t\t\"Your execution client may require an update 🚸\",\n\t\t\t\t\"unsupported_capability\", capability,\n\t\t\t)\n\t\t}\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "execution/client/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage client\n\nimport (\n\tengineerrors \"github.com/berachain/beacon-kit/engine-primitives/errors\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/net/http\"\n\tjsonrpc \"github.com/berachain/beacon-kit/primitives/net/json-rpc\"\n)\n\nconst (\n\tUnauthenticatedConnectionErrorStr = `could not verify execution chain ID as your\n\tconnection is not authenticated. If connecting to your execution client via HTTP, you\n\twill need to set up JWT authentication...`\n)\n\nvar (\n\n\t// ErrMismatchedEth1ChainID is returned when the chainID does not\n\t// match the expected chain ID.\n\tErrMismatchedEth1ChainID = errors.New(\"mismatched chain ID\")\n\n\t// ErrBadConnection indicates that the http.Client was unable to\n\t// establish a connection.\n\tErrBadConnection = errors.New(\"connection error\")\n)\n\n// Handles errors received from the RPC server according to the specification.\nfunc (s *EngineClient) handleRPCError(\n\terr error,\n) error {\n\tif err == nil {\n\t\t//nolint:nilerr // appease nilaway\n\t\treturn err\n\t}\n\n\t// Check for timeout errors.\n\tif errors.Is(err, engineerrors.ErrEngineAPITimeout) {\n\t\ts.metrics.incrementEngineAPITimeout()\n\t\treturn err\n\t}\n\tif http.IsTimeoutError(err) {\n\t\ts.metrics.incrementHTTPTimeoutCounter()\n\t\treturn http.ErrTimeout\n\t}\n\t// Check for authorization errors\n\tif errors.Is(err, http.ErrUnauthorized) {\n\t\treturn err\n\t}\n\t// Check for connection errors.\n\tvar e jsonrpc.Error\n\tok := errors.As(err, &e)\n\tif !ok || e == nil {\n\t\treturn errors.Join(ErrBadConnection, err)\n\t}\n\n\t// Otherwise check for our engine errors.\n\tswitch e.ErrorCode() {\n\tcase -32700:\n\t\ts.metrics.incrementParseErrorCounter()\n\t\treturn jsonrpc.ErrParse\n\tcase -32600:\n\t\ts.metrics.incrementInvalidRequestCounter()\n\t\treturn jsonrpc.ErrInvalidRequest\n\tcase -32601:\n\t\ts.metrics.incrementMethodNotFoundCounter()\n\t\treturn jsonrpc.ErrMethodNotFound\n\tcase -32602:\n\t\ts.metrics.incrementInvalidParamsCounter()\n\t\treturn jsonrpc.ErrInvalidParams\n\tcase -32603:\n\t\ts.metrics.incrementInternalErrorCounter()\n\t\treturn jsonrpc.ErrInternal\n\tcase -38001:\n\t\ts.metrics.incrementUnknownPayloadErrorCounter()\n\t\treturn engineerrors.ErrUnknownPayload\n\tcase -38002:\n\t\ts.metrics.incrementInvalidForkchoiceStateCounter()\n\t\treturn engineerrors.ErrInvalidForkchoiceState\n\tcase -38003:\n\t\ts.metrics.incrementInvalidPayloadAttributesCounter()\n\t\treturn engineerrors.ErrInvalidPayloadAttributes\n\tcase -38004:\n\t\ts.metrics.incrementRequestTooLargeCounter()\n\t\treturn engineerrors.ErrRequestTooLarge\n\tcase -32000:\n\t\ts.metrics.incrementInternalServerErrorCounter()\n\t\t// // Only -32000 status codes are data errors in the RPC specification.\n\t\t// var errWithData rpc.DataError\n\t\t// errWithData, ok = err.(rpc.DataError) //nolint:errorlint // from\n\t\t// prysm.\n\t\t// if !ok {\n\t\t// \treturn errors.Wrapf(\n\t\t// \t\terrors.Join(jsonrpc.ErrServer, err),\n\t\t// \t\t\"got an unexpected data error in JSON-RPC response\",\n\t\t// \t)\n\t\t// }\n\t\treturn errors.Wrapf(jsonrpc.ErrServer, \"%v\", e.Error())\n\tdefault:\n\t\treturn err\n\t}\n}\n\n// IsFatalError defines errors that indicate a bad request or an otherwise\n// unusable client.\nfunc IsFatalError(err error) bool {\n\treturn jsonrpc.IsPreDefinedError(err) || errors.IsAny(\n\t\terr,\n\t\tErrBadConnection,\n\t)\n}\n\n// IsNonFatalError defines errors that should be ephemeral and can be\n// recovered from simply by retrying.\nfunc IsNonFatalError(err error) bool {\n\treturn errors.IsAny(\n\t\terr,\n\t\tengineerrors.ErrEngineAPITimeout,\n\t\thttp.ErrTimeout,\n\t)\n}\n"
  },
  {
    "path": "execution/client/ethclient/constants.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage ethclient\n\n// BeaconKitSupportedCapabilities returns the full list of capabilities\n// of the beacon kit client.\nfunc BeaconKitSupportedCapabilities() []string {\n\treturn []string{\n\t\tNewPayloadMethodV3,\n\t\tNewPayloadMethodV4,\n\t\tNewPayloadMethodV4P11,\n\t\tForkchoiceUpdatedMethodV3,\n\t\tForkchoiceUpdatedMethodV3P11,\n\t\tGetPayloadMethodV3,\n\t\tGetPayloadMethodV4,\n\t\tGetPayloadMethodV4P11,\n\t\tGetClientVersionV1,\n\t}\n}\n\n// Constants for JSON-RPC method names.\nconst (\n\t// NewPayloadMethodV3 for creating a new payload in Deneb.\n\tNewPayloadMethodV3 = \"engine_newPayloadV3\"\n\t// NewPayloadMethodV4 for creating a new payload in Electra.\n\tNewPayloadMethodV4 = \"engine_newPayloadV4\"\n\t// NewPayloadMethodV4P11 for creating a new payload for Electra1 (Pectra11).\n\tNewPayloadMethodV4P11 = \"engine_newPayloadV4P11\"\n\t// ForkchoiceUpdatedMethodV3 for updating fork choice in Deneb.\n\tForkchoiceUpdatedMethodV3 = \"engine_forkchoiceUpdatedV3\"\n\t// ForkchoiceUpdatedMethodV4P11 for updating fork choice in Electra1 (Pectra11).\n\tForkchoiceUpdatedMethodV3P11 = \"engine_forkchoiceUpdatedV3P11\"\n\t// GetPayloadMethodV3 for retrieving a payload in Deneb.\n\tGetPayloadMethodV3 = \"engine_getPayloadV3\"\n\t// GetPayloadMethodV4 for retrieving a payload in Electra.\n\tGetPayloadMethodV4 = \"engine_getPayloadV4\"\n\t// GetPayloadMethodV4P11 for retrieving a payload in Electra1 (Pectra11).\n\tGetPayloadMethodV4P11 = \"engine_getPayloadV4P11\"\n\t// BlockByHashMethod for retrieving a block by its hash.\n\tBlockByHashMethod = \"eth_getBlockByHash\"\n\t// BlockByNumberMethod for retrieving a block by its number.\n\tBlockByNumberMethod = \"eth_getBlockByNumber\"\n\t// ExchangeCapabilities for exchanging capabilities with the peer.\n\tExchangeCapabilities = \"engine_exchangeCapabilities\"\n\t// GetClientVersionV1 for retrieving the capabilities of the peer.\n\tGetClientVersionV1 = \"engine_getClientVersionV1\"\n)\n"
  },
  {
    "path": "execution/client/ethclient/engine.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage ethclient\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/ethereum/go-ethereum/beacon/engine\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                 NewPayload                                 */\n/* -------------------------------------------------------------------------- */\n\n// NewPayload calls the appropriate version of the Engine API NewPayload method.\nfunc (s *Client) NewPayload(\n\tctx context.Context,\n\treq ctypes.NewPayloadRequest,\n) (*engineprimitives.PayloadStatusV1, error) {\n\tforkVersion := req.GetForkVersion()\n\tswitch {\n\tcase version.IsBefore(forkVersion, version.Deneb()):\n\t\t// Versions before Deneb are not supported for calling NewPayload.\n\t\treturn nil, ErrInvalidVersion\n\n\tcase version.Equals(forkVersion, version.Deneb()), version.Equals(forkVersion, version.Deneb1()):\n\t\t// Use V3 for Deneb versions (Deneb and Deneb1).\n\t\treturn s.NewPayloadV3(\n\t\t\tctx,\n\t\t\treq.GetExecutionPayload(),\n\t\t\treq.GetVersionedHashes(),\n\t\t\treq.GetParentBeaconBlockRoot(),\n\t\t)\n\n\tcase version.Equals(forkVersion, version.Electra()):\n\t\t// Use V4 for Electra versions.\n\t\texecutionRequests, err := req.GetEncodedExecutionRequests()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn s.NewPayloadV4(\n\t\t\tctx,\n\t\t\treq.GetExecutionPayload(),\n\t\t\treq.GetVersionedHashes(),\n\t\t\treq.GetParentBeaconBlockRoot(),\n\t\t\texecutionRequests,\n\t\t)\n\n\tcase version.Equals(forkVersion, version.Electra1()),\n\t\tversion.Equals(forkVersion, version.Fulu()):\n\t\t// Use V4P11 for Electra1 and Fulu versions.\n\t\texecutionRequests, err := req.GetEncodedExecutionRequests()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn s.NewPayloadV4P11(\n\t\t\tctx,\n\t\t\treq.GetExecutionPayload(),\n\t\t\treq.GetVersionedHashes(),\n\t\t\treq.GetParentBeaconBlockRoot(),\n\t\t\texecutionRequests,\n\t\t\treq.GetParentProposerPubkey(),\n\t\t)\n\n\tdefault:\n\t\treturn nil, ErrInvalidVersion\n\t}\n}\n\n// NewPayloadV3 calls the engine_newPayloadV3 via JSON-RPC.\nfunc (s *Client) NewPayloadV3(\n\tctx context.Context,\n\tpayload *ctypes.ExecutionPayload,\n\tversionedHashes []common.ExecutionHash,\n\tparentBlockRoot common.Root,\n) (*engineprimitives.PayloadStatusV1, error) {\n\tresult := &engineprimitives.PayloadStatusV1{}\n\tif err := s.Call(\n\t\tctx, result, NewPayloadMethodV3, payload, versionedHashes, parentBlockRoot,\n\t); err != nil {\n\t\treturn nil, err\n\t}\n\treturn result, nil\n}\n\n// NewPayloadV4 calls the engine_newPayloadV4 via JSON-RPC.\nfunc (s *Client) NewPayloadV4(\n\tctx context.Context,\n\tpayload *ctypes.ExecutionPayload,\n\tversionedHashes []common.ExecutionHash,\n\tparentBlockRoot common.Root,\n\texecutionRequests []ctypes.EncodedExecutionRequest,\n) (*engineprimitives.PayloadStatusV1, error) {\n\tresult := &engineprimitives.PayloadStatusV1{}\n\tif err := s.Call(\n\t\tctx, result, NewPayloadMethodV4, payload, versionedHashes, parentBlockRoot, executionRequests,\n\t); err != nil {\n\t\treturn nil, err\n\t}\n\treturn result, nil\n}\n\n// NewPayloadV4P11 calls the engine_newPayloadV4P11 via JSON-RPC.\nfunc (s *Client) NewPayloadV4P11(\n\tctx context.Context,\n\tpayload *ctypes.ExecutionPayload,\n\tversionedHashes []common.ExecutionHash,\n\tparentBlockRoot common.Root,\n\texecutionRequests []ctypes.EncodedExecutionRequest,\n\tparentProposerPubKey *crypto.BLSPubkey,\n) (*engineprimitives.PayloadStatusV1, error) {\n\tresult := &engineprimitives.PayloadStatusV1{}\n\tif err := s.Call(\n\t\tctx, result, NewPayloadMethodV4P11, payload, versionedHashes, parentBlockRoot, executionRequests, parentProposerPubKey,\n\t); err != nil {\n\t\treturn nil, err\n\t}\n\treturn result, nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                              ForkchoiceUpdated                             */\n/* -------------------------------------------------------------------------- */\n\n// ForkchoiceUpdated calls the appropriate version of the Engine API ForkchoiceUpdated method.\nfunc (s *Client) ForkchoiceUpdated(\n\tctx context.Context,\n\tstate *engineprimitives.ForkchoiceStateV1,\n\tattrs any,\n\tforkVersion common.Version,\n) (*engineprimitives.ForkchoiceResponseV1, error) {\n\t// V3 is used for beacon versions Deneb and onwards.\n\tswitch {\n\tcase version.IsBefore(forkVersion, version.Deneb()):\n\t\t// Versions before Deneb are not supported for calling ForkchoiceUpdated.\n\t\treturn nil, ErrInvalidVersion\n\n\tcase version.Equals(forkVersion, version.Deneb()),\n\t\tversion.Equals(forkVersion, version.Deneb1()),\n\t\tversion.Equals(forkVersion, version.Electra()):\n\t\t// Deneb versions and Electra use ForkchoiceUpdatedV3.\n\t\treturn s.ForkchoiceUpdatedV3(ctx, state, attrs)\n\n\tcase version.Equals(forkVersion, version.Electra1()),\n\t\tversion.Equals(forkVersion, version.Fulu()):\n\t\t// Electra1 and Fulu use ForkchoiceUpdatedV3P11.\n\t\treturn s.ForkchoiceUpdatedV3P11(ctx, state, attrs)\n\n\tdefault:\n\t\treturn nil, ErrInvalidVersion\n\t}\n}\n\n// ForkchoiceUpdatedV3 calls the engine_forkchoiceUpdatedV3 method via JSON-RPC.\nfunc (s *Client) ForkchoiceUpdatedV3(\n\tctx context.Context,\n\tstate *engineprimitives.ForkchoiceStateV1,\n\tattrs any,\n) (*engineprimitives.ForkchoiceResponseV1, error) {\n\tresult := &engineprimitives.ForkchoiceResponseV1{}\n\tif err := s.Call(\n\t\tctx, result, ForkchoiceUpdatedMethodV3, state, attrs,\n\t); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif (result.PayloadStatus == engineprimitives.PayloadStatusV1{}) {\n\t\treturn nil, ErrNilResponse\n\t}\n\n\treturn result, nil\n}\n\n// ForkchoiceUpdatedV3P11 calls the engine_forkchoiceUpdatedV3P11 method via JSON-RPC.\nfunc (s *Client) ForkchoiceUpdatedV3P11(\n\tctx context.Context,\n\tstate *engineprimitives.ForkchoiceStateV1,\n\tattrs any,\n) (*engineprimitives.ForkchoiceResponseV1, error) {\n\tresult := &engineprimitives.ForkchoiceResponseV1{}\n\tif err := s.Call(\n\t\tctx, result, ForkchoiceUpdatedMethodV3P11, state, attrs,\n\t); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif (result.PayloadStatus == engineprimitives.PayloadStatusV1{}) {\n\t\treturn nil, ErrNilResponse\n\t}\n\n\treturn result, nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                 GetPayload                                 */\n/* -------------------------------------------------------------------------- */\n\n// GetPayload calls the appropriate version of the Engine API GetPayload method.\nfunc (s *Client) GetPayload(\n\tctx context.Context,\n\tpayloadID engineprimitives.PayloadID,\n\tforkVersion common.Version,\n) (ctypes.BuiltExecutionPayloadEnv, error) {\n\tswitch {\n\tcase version.IsBefore(forkVersion, version.Deneb()):\n\t\t// Versions before Deneb are not supported for calling GetPayload.\n\t\treturn nil, ErrInvalidVersion\n\n\tcase version.Equals(forkVersion, version.Deneb()), version.Equals(forkVersion, version.Deneb1()):\n\t\treturn s.GetPayloadV3(ctx, payloadID, forkVersion)\n\n\tcase version.Equals(forkVersion, version.Electra()):\n\t\treturn s.GetPayloadV4(ctx, payloadID, forkVersion)\n\n\tcase version.Equals(forkVersion, version.Electra1()),\n\t\tversion.Equals(forkVersion, version.Fulu()):\n\t\treturn s.GetPayloadV4P11(ctx, payloadID, forkVersion)\n\n\tdefault:\n\t\treturn nil, ErrInvalidVersion\n\t}\n}\n\n// GetPayloadV3 calls the engine_getPayloadV3 method via JSON-RPC.\nfunc (s *Client) GetPayloadV3(\n\tctx context.Context,\n\tpayloadID engineprimitives.PayloadID,\n\tforkVersion common.Version,\n) (ctypes.BuiltExecutionPayloadEnv, error) {\n\tresult := ctypes.NewEmptyExecutionPayloadEnvelope[*engineprimitives.BlobsBundleV1](forkVersion)\n\tif err := s.Call(ctx, result, GetPayloadMethodV3, payloadID); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed GetPayloadV3 call: %w\", err)\n\t}\n\treturn result, nil\n}\n\n// GetPayloadV4 calls the engine_getPayloadV4 method via JSON-RPC.\nfunc (s *Client) GetPayloadV4(\n\tctx context.Context,\n\tpayloadID engineprimitives.PayloadID,\n\tforkVersion common.Version,\n) (ctypes.BuiltExecutionPayloadEnv, error) {\n\tresult := ctypes.NewEmptyExecutionPayloadEnvelope[*engineprimitives.BlobsBundleV1](forkVersion)\n\tif err := s.Call(ctx, result, GetPayloadMethodV4, payloadID); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed GetPayloadV4 call: %w\", err)\n\t}\n\treturn result, nil\n}\n\n// GetPayloadV4P11 calls the engine_getPayloadV4P11 method via JSON-RPC.\nfunc (s *Client) GetPayloadV4P11(\n\tctx context.Context,\n\tpayloadID engineprimitives.PayloadID,\n\tforkVersion common.Version,\n) (ctypes.BuiltExecutionPayloadEnv, error) {\n\tresult := ctypes.NewEmptyExecutionPayloadEnvelope[*engineprimitives.BlobsBundleV1](forkVersion)\n\tif err := s.Call(ctx, result, GetPayloadMethodV4P11, payloadID); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed GetPayloadV4P11 call: %w\", err)\n\t}\n\treturn result, nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    Other                                   */\n/* -------------------------------------------------------------------------- */\n\n// ExchangeCapabilities calls the engine_exchangeCapabilities method via JSON-RPC.\nfunc (s *Client) ExchangeCapabilities(\n\tctx context.Context,\n\tcapabilities []string,\n) ([]string, error) {\n\tresult := make([]string, 0)\n\tif err := s.Call(\n\t\tctx, &result, ExchangeCapabilities, &capabilities,\n\t); err != nil {\n\t\treturn nil, err\n\t}\n\treturn result, nil\n}\n\n// GetClientVersionV1 calls the engine_getClientVersionV1 method via JSON-RPC.\nfunc (s *Client) GetClientVersionV1(\n\tctx context.Context,\n) ([]engineprimitives.ClientVersionV1, error) {\n\tresult := make([]engineprimitives.ClientVersionV1, 0)\n\n\t// NOTE: although the ethereum spec does not require us passing a\n\t// clientversion as param, it seems some clients require it and even\n\t// enforce a valid Code.\n\tif err := s.Call(\n\t\tctx, &result, GetClientVersionV1, engine.ClientVersionV1{Code: \"GE\"},\n\t); err != nil {\n\t\treturn nil, err\n\t}\n\treturn result, nil\n}\n"
  },
  {
    "path": "execution/client/ethclient/engine_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage ethclient_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types/mocks\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/execution/client/ethclient\"\n\t\"github.com/berachain/beacon-kit/execution/client/ethclient/rpc\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/berachain/beacon-kit/testing/utils\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// TestGetPayloadV3NeverReturnsEmptyPayload shows that execution payload\n// returned by ethClient is not nil.\nfunc TestGetPayloadV3NeverReturnsEmptyPayload(t *testing.T) {\n\tt.Parallel()\n\tc := ethclient.New(&stubRPCClient{t: t})\n\n\tvar (\n\t\tctx         = t.Context()\n\t\tpayloadID   engineprimitives.PayloadID\n\t\tforkVersion = version.Deneb1()\n\t)\n\n\tpe, err := c.GetPayloadV3(ctx, payloadID, forkVersion)\n\trequire.NoError(t, err)\n\n\t// check that execution payload is not nil\n\trequire.NotNil(t, pe.GetExecutionPayload())\n}\n\n// TestNewPayloadWithValidVersion tests that NewPayload correctly handles Deneb version.\nfunc TestNewPayloadWithValidVersion(t *testing.T) {\n\tt.Parallel()\n\tc := ethclient.New(&stubRPCClient{t: t})\n\tctx := t.Context()\n\n\tblock := utils.GenerateValidBeaconBlock(t, version.Deneb1())\n\n\tnewPayloadRequest, err := ctypes.BuildNewPayloadRequestFromFork(block, nil)\n\tif err != nil {\n\t\treturn\n\t}\n\t_, err = c.NewPayload(ctx, newPayloadRequest)\n\trequire.NoError(t, err)\n}\n\n// TestNewPayloadWithInvalidVersion tests that NewPayload returns ErrInvalidVersion for Capella.\nfunc TestNewPayloadWithInvalidVersion(t *testing.T) {\n\tt.Parallel()\n\tc := ethclient.New(&stubRPCClient{t: t})\n\tctx := t.Context()\n\n\tn := mocks.NewPayloadRequest{}\n\tn.On(\"GetForkVersion\").Return(version.Capella())\n\t_, err := c.NewPayload(ctx, &n)\n\trequire.ErrorIs(t, err, ethclient.ErrInvalidVersion)\n}\n\n// TestForkchoiceUpdatedWithValidVersion tests that ForkchoiceUpdated correctly handles Deneb version.\nfunc TestForkchoiceUpdatedWithValidVersion(t *testing.T) {\n\tt.Parallel()\n\tc := ethclient.New(&stubRPCClient{t: t})\n\tctx := t.Context()\n\n\tstate := &engineprimitives.ForkchoiceStateV1{}\n\tattrs := struct{}{}\n\tforkVersion := version.Deneb1()\n\n\t_, err := c.ForkchoiceUpdated(ctx, state, attrs, forkVersion)\n\trequire.NoError(t, err)\n}\n\nfunc TestForkchoiceUpdatedWithValidVersion2(t *testing.T) {\n\tt.Parallel()\n\tc := ethclient.New(&stubRPCClient{t: t})\n\tctx := t.Context()\n\n\tstate := &engineprimitives.ForkchoiceStateV1{}\n\tattrs := struct{}{}\n\tforkVersion := version.Deneb1()\n\n\t_, err := c.ForkchoiceUpdated(ctx, state, attrs, forkVersion)\n\trequire.NoError(t, err)\n}\n\n// TestForkchoiceUpdatedWithInvalidVersion tests that ForkchoiceUpdated returns ErrInvalidVersion for Capella.\nfunc TestForkchoiceUpdatedWithInvalidVersion(t *testing.T) {\n\tt.Parallel()\n\tc := ethclient.New(&stubRPCClient{t: t})\n\tctx := t.Context()\n\n\tstate := &engineprimitives.ForkchoiceStateV1{}\n\tattrs := struct{}{}\n\tforkVersion := version.Capella()\n\n\t_, err := c.ForkchoiceUpdated(ctx, state, attrs, forkVersion)\n\trequire.ErrorIs(t, err, ethclient.ErrInvalidVersion)\n}\n\n// TestGetPayloadWithValidVersion tests that GetPayload correctly handles >= Deneb version.\nfunc TestGetPayloadWithValidVersion(t *testing.T) {\n\tt.Parallel()\n\tc := ethclient.New(&stubRPCClient{t: t})\n\tctx := t.Context()\n\n\tvar payloadID engineprimitives.PayloadID\n\tforkVersion := version.Deneb1()\n\n\t_, err := c.GetPayload(ctx, payloadID, forkVersion)\n\trequire.NoError(t, err)\n}\n\n// TestGetPayloadWithInvalidVersion tests that GetPayload returns ErrInvalidVersion for Capella.\nfunc TestGetPayloadWithInvalidVersion(t *testing.T) {\n\tt.Parallel()\n\tc := ethclient.New(&stubRPCClient{t: t})\n\tctx := t.Context()\n\n\tvar payloadID engineprimitives.PayloadID\n\tforkVersion := version.Capella()\n\n\t_, err := c.GetPayload(ctx, payloadID, forkVersion)\n\trequire.ErrorIs(t, err, ethclient.ErrInvalidVersion)\n}\n\nvar _ rpc.Client = (*stubRPCClient)(nil)\n\ntype stubRPCClient struct {\n\tt *testing.T\n}\n\nfunc (tc *stubRPCClient) Initialize() error     { return nil }\nfunc (tc *stubRPCClient) Start(context.Context) {}\nfunc (tc *stubRPCClient) Call(_ context.Context, target any, _ string, _ ...any) error {\n\ttc.t.Helper()\n\trequire.NotNil(tc.t, target)\n\n\t// If calling ForkchoiceUpdated, set the PayloadStatus to not empty to\n\t// avoid returning ErrNilResponse.\n\tif fcu, ok := target.(*engineprimitives.ForkchoiceResponseV1); ok {\n\t\tfcu.PayloadStatus = engineprimitives.PayloadStatusV1{\n\t\t\tStatus: \"not empty\",\n\t\t}\n\t}\n\n\treturn nil\n}\nfunc (tc *stubRPCClient) Close() error { return nil }\n"
  },
  {
    "path": "execution/client/ethclient/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage ethclient\n\nimport \"github.com/berachain/beacon-kit/errors\"\n\nvar (\n\t// ErrNilResponse is an error that is returned when the response is nil.\n\tErrNilResponse = errors.New(\"nil response\")\n\n\t// ErrNotImplemented is an error that is returned when a method is not\n\t// implemented.\n\tErrNotImplemented = errors.New(\"not implemented\")\n\n\t// ErrInvalidVersion is an error that is returned when the version is\n\t// invalid.\n\tErrInvalidVersion = errors.New(\"invalid version\")\n)\n"
  },
  {
    "path": "execution/client/ethclient/eth.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage ethclient\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"math/big\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/ethereum/go-ethereum\"\n\t\"github.com/ethereum/go-ethereum/common/hexutil\"\n\t\"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/ethereum/go-ethereum/rpc\"\n)\n\n// ChainID retrieves the current chain ID.\nfunc (s *Client) ChainID(\n\tctx context.Context,\n) (math.U64, error) {\n\tvar result math.U64\n\tif err := s.Call(ctx, &result, \"eth_chainId\"); err != nil {\n\t\treturn 0, err\n\t}\n\treturn result, nil\n}\n\n// TODO: Figure out how to unhood all this.\n\n// FilterLogs executes a filter query.\nfunc (s *Client) FilterLogs(\n\tctx context.Context,\n\tq ethereum.FilterQuery,\n) ([]types.Log, error) {\n\tvar result []types.Log\n\targ, err := toFilterArg(q)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn result, s.Call(ctx, &result, \"eth_getLogs\", arg)\n}\n\n// SubscribeFilterLogs(ctx context.Context, q FilterQuery, ch chan<- types.Log)\n// (Subscription, error)\nfunc (s *Client) SubscribeFilterLogs(\n\tcontext.Context,\n\tethereum.FilterQuery,\n\tchan<- types.Log,\n) (ethereum.Subscription, error) {\n\treturn nil, errors.New(\"not implemented\")\n}\n\nfunc toFilterArg(q ethereum.FilterQuery) (interface{}, error) {\n\targ := map[string]interface{}{\n\t\t\"address\": q.Addresses,\n\t\t\"topics\":  q.Topics,\n\t}\n\tif q.BlockHash != nil {\n\t\targ[\"blockHash\"] = *q.BlockHash\n\t\tif q.FromBlock != nil || q.ToBlock != nil {\n\t\t\treturn nil, errors.New(\n\t\t\t\t\"cannot specify both BlockHash and FromBlock/ToBlock\",\n\t\t\t)\n\t\t}\n\t} else {\n\t\tif q.FromBlock == nil {\n\t\t\targ[\"fromBlock\"] = \"0x0\"\n\t\t} else {\n\t\t\targ[\"fromBlock\"] = toBlockNumArg(q.FromBlock)\n\t\t}\n\t\targ[\"toBlock\"] = toBlockNumArg(q.ToBlock)\n\t}\n\treturn arg, nil\n}\n\nfunc toBlockNumArg(number *big.Int) string {\n\tif number == nil {\n\t\treturn \"latest\"\n\t}\n\tif number.Sign() >= 0 {\n\t\treturn hexutil.EncodeBig(number)\n\t}\n\t// It's negative.\n\tif number.IsInt64() {\n\t\treturn rpc.BlockNumber(number.Int64()).String()\n\t}\n\t// It's negative and large, which is invalid.\n\treturn fmt.Sprintf(\"<invalid %d>\", number)\n}\n"
  },
  {
    "path": "execution/client/ethclient/ethclient.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage ethclient\n\nimport (\n\t\"github.com/berachain/beacon-kit/execution/client/ethclient/rpc\"\n)\n\n// Client - Ethereum rpc client.\ntype Client struct {\n\trpc.Client\n}\n\n// New create new rpc client with given url.\nfunc New(client rpc.Client) *Client {\n\trpc := &Client{\n\t\tClient: client,\n\t}\n\n\treturn rpc\n}\n"
  },
  {
    "path": "execution/client/ethclient/rpc/client.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage rpc\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n\tbeaconhttp \"github.com/berachain/beacon-kit/primitives/net/http\"\n\t\"github.com/berachain/beacon-kit/primitives/net/jwt\"\n)\n\nvar _ Client = (*client)(nil)\n\ntype Client interface {\n\tInitialize() error\n\tStart(context.Context)\n\tCall(ctx context.Context, target any, method string, params ...any) error\n\tClose() error\n}\n\n// client is an Ethereum RPC client that provides a\n// convenient way to interact with an Ethereum node.\ntype client struct {\n\t// url is the URL of the RPC endpoint.\n\turl string\n\t// client is the HTTP client used to make RPC calls.\n\tclient *http.Client\n\t// reqPool is a sync.Pool for reusing RPC request objects.\n\treqPool *sync.Pool\n\t// jwtSecret is the JWT secret used for authentication.\n\tjwtSecret *jwt.Secret\n\t// jwtRefreshInterval is the interval at which the JWT token should be\n\t// refreshed.\n\tjwtRefreshInterval time.Duration\n\t// logger is the logger for the RPC client.\n\tlogger log.Logger\n\n\t// mu protects header for concurrent access.\n\tmu sync.RWMutex\n\n\t// header is the HTTP header used for RPC requests.\n\theader http.Header\n}\n\n// New create new rpc client with given url.\nfunc NewClient(\n\turl string,\n\tsecret *jwt.Secret,\n\tjwtRefreshInterval time.Duration,\n\tlogger log.Logger,\n) Client {\n\trpc := &client{\n\t\turl:    url,\n\t\tclient: http.DefaultClient,\n\t\treqPool: &sync.Pool{\n\t\t\tNew: func() any {\n\t\t\t\treturn &Request{\n\t\t\t\t\tID:      1,\n\t\t\t\t\tJSONRPC: \"2.0\",\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\tjwtSecret:          secret,\n\t\tjwtRefreshInterval: jwtRefreshInterval,\n\t\theader:             http.Header{\"Content-Type\": {\"application/json\"}},\n\t\tlogger:             logger,\n\t}\n\n\treturn rpc\n}\n\n// Start starts the rpc client.\nfunc (rpc *client) Start(ctx context.Context) {\n\tticker := time.NewTicker(rpc.jwtRefreshInterval)\n\tdefer ticker.Stop()\n\n\t// Initial JWT update is done in Initialize() now\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\tcase <-ticker.C:\n\t\t\tif err := rpc.updateHeader(); err != nil {\n\t\t\t\trpc.logger.Error(\"Failed to refresh JWT token\", \"error\", err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Initialize sets up the initial JWT token. This should be called before\n// making any RPC calls to ensure a fresh token is available.\nfunc (rpc *client) Initialize() error {\n\trpc.logger.Info(\"Initializing RPC client with fresh JWT token\")\n\tif err := rpc.updateHeader(); err != nil {\n\t\treturn fmt.Errorf(\"failed to initialize JWT token: %w\", err)\n\t}\n\treturn nil\n}\n\n// Close closes the RPC client.\nfunc (rpc *client) Close() error {\n\trpc.client.CloseIdleConnections()\n\treturn nil\n}\n\n// Call calls the given method with the given parameters.\nfunc (rpc *client) Call(\n\tctx context.Context,\n\ttarget any,\n\tmethod string,\n\tparams ...any,\n) error {\n\tresult, err := rpc.callRaw(ctx, method, params...)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif target == nil {\n\t\treturn nil\n\t}\n\n\treturn json.Unmarshal(result, target)\n}\n\n// Call returns raw response of method call.\nfunc (rpc *client) callRaw(\n\tctx context.Context,\n\tmethod string,\n\tparams ...any,\n) (json.RawMessage, error) {\n\t// Pull a request from the pool, we know that it already has the correct\n\t// JSONRPC version and ID set.\n\t//nolint:errcheck // this is safe.\n\trequest := rpc.reqPool.Get().(*Request)\n\tdefer rpc.reqPool.Put(request)\n\n\t// Update the request with the method and params.\n\trequest.Method = method\n\trequest.Params = params\n\n\tbody, err := json.Marshal(request)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treq, err := http.NewRequestWithContext(\n\t\tctx,\n\t\thttp.MethodPost,\n\t\trpc.url,\n\t\tbytes.NewBuffer(body),\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\trpc.mu.RLock()\n\treq.Header = rpc.header.Clone()\n\trpc.mu.RUnlock()\n\n\tresponse, err := rpc.client.Do(req) //#nosec:G704 // URL is operator-configured RPC endpoint.\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif response == nil {\n\t\treturn nil, ErrNilResponse\n\t}\n\tdefer response.Body.Close()\n\n\tdata, err := io.ReadAll(response.Body)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tswitch response.StatusCode {\n\tcase http.StatusOK:\n\t\t// OK: just proceed (no return)\n\tcase http.StatusUnauthorized:\n\t\treturn nil, beaconhttp.ErrUnauthorized\n\tdefault:\n\t\t// Return a default error\n\t\treturn nil, fmt.Errorf(\"unexpected status code %d: %s\", response.StatusCode, string(data))\n\t}\n\n\tresp := new(Response)\n\tif err = json.Unmarshal(data, resp); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif resp.Error != nil {\n\t\treturn nil, *resp.Error\n\t}\n\n\treturn resp.Result, nil\n}\n"
  },
  {
    "path": "execution/client/ethclient/rpc/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage rpc\n\nimport \"errors\"\n\nvar ErrNilResponse = errors.New(\"nil response\")\n"
  },
  {
    "path": "execution/client/ethclient/rpc/header.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage rpc\n\n// updateHeader builds an http.Header that has the JWT token\n// attached for authorization.\nfunc (rpc *client) updateHeader() error {\n\t// Build the JWT token.\n\ttoken, err := rpc.jwtSecret.BuildSignedToken()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Add the JWT token to the headers. Access header safely.\n\trpc.mu.Lock()\n\tdefer rpc.mu.Unlock()\n\trpc.header.Set(\"Authorization\", \"Bearer \"+token)\n\treturn nil\n}\n"
  },
  {
    "path": "execution/client/ethclient/rpc/types.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage rpc\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n)\n\n// Request represents an Ethereum JSON-RPC request.\ntype Request struct {\n\t// ID is the request ID.\n\tID int `json:\"id\"`\n\t// JSONRPC is the JSON-RPC version.\n\tJSONRPC string `json:\"jsonrpc\"`\n\t// Method is the RPC method to be called.\n\tMethod string `json:\"method\"`\n\t// Params are the parameters for the RPC method.\n\tParams any `json:\"params\"`\n}\n\n// Response represents an Ethereum JSON-RPC response.\ntype Response struct {\n\t// ID is the request ID.\n\tID int `json:\"id\"`\n\t// JSONRPC is the JSON-RPC version.\n\tJSONRPC string `json:\"jsonrpc\"`\n\t// Result is the raw JSON-RPC response result.\n\tResult json.RawMessage `json:\"result\"`\n\t// Error is the JSON-RPC error, if any.\n\tError *Error `json:\"error\"`\n}\n\n// Error represents an Ethereum JSON-RPC error.\ntype Error struct {\n\t// Code is the error code.\n\tCode int `json:\"code\"`\n\t// Message is the error message.\n\tMessage string `json:\"message\"`\n}\n\n// Error returns a formatted error string.\nfunc (err Error) Error() string {\n\treturn fmt.Sprintf(\"Error %d (%s)\", err.Code, err.Message)\n}\n\n// ErrorCode returns the number identifying the JSON-RPC error.\nfunc (err Error) ErrorCode() int {\n\treturn err.Code\n}\n"
  },
  {
    "path": "execution/client/helpers.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage client\n\nimport (\n\t\"context\"\n\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\tengineerrors \"github.com/berachain/beacon-kit/engine-primitives/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n)\n\n// createContextWithTimeout creates a context with a timeout and returns it\n// along with the cancel function.\nfunc (s *EngineClient) createContextWithTimeout(\n\tctx context.Context,\n) (context.Context, context.CancelFunc) {\n\tdctx, cancel := context.WithTimeoutCause(\n\t\tctx,\n\t\ts.cfg.RPCTimeout,\n\t\tengineerrors.ErrEngineAPITimeout,\n\t)\n\treturn dctx, cancel\n}\n\n// processPayloadStatusResult processes the payload status result and\n// returns the latest valid hash or an error.\nfunc processPayloadStatusResult(\n\tresult *engineprimitives.PayloadStatusV1,\n) (*common.ExecutionHash, error) {\n\tswitch result.Status {\n\tcase engineprimitives.PayloadStatusValid:\n\t\treturn result.LatestValidHash, nil\n\tcase engineprimitives.PayloadStatusAccepted:\n\t\treturn nil, engineerrors.ErrAcceptedPayloadStatus\n\tcase engineprimitives.PayloadStatusSyncing:\n\t\treturn nil, engineerrors.ErrSyncingPayloadStatus\n\tcase engineprimitives.PayloadStatusInvalid:\n\t\treturn nil, engineerrors.ErrInvalidPayloadStatus\n\tdefault:\n\t\treturn nil, engineerrors.ErrUnknownPayloadStatus\n\t}\n}\n"
  },
  {
    "path": "execution/client/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage client\n\nimport (\n\t\"time\"\n)\n\n// TelemetrySink is an interface for sending metrics to a telemetry backend.\ntype TelemetrySink interface {\n\t// IncrementCounter increments a counter metric identified by the provided\n\t// keys.\n\tIncrementCounter(key string, args ...string)\n\t// MeasureSince measures the time since the provided start time,\n\t// identified by the provided keys.\n\tMeasureSince(key string, start time.Time, args ...string)\n}\n"
  },
  {
    "path": "execution/client/metrics.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage client\n\nimport (\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/log\"\n)\n\n// clientMetrics is a struct that contains metrics for the engine.\ntype clientMetrics struct {\n\t// TelemetrySink is the sink for the metrics.\n\tsink TelemetrySink\n\t// logger is the logger for the engineMetrics.\n\tlogger log.Logger\n}\n\n// newClientMetrics creates a new engineMetrics.\nfunc newClientMetrics(\n\tsink TelemetrySink,\n\tlogger log.Logger,\n) *clientMetrics {\n\treturn &clientMetrics{\n\t\tsink:   sink,\n\t\tlogger: logger,\n\t}\n}\n\n// measureForkchoiceUpdateDuration measures the duration of the forkchoice\n// update.\nfunc (cm *clientMetrics) measureForkchoiceUpdateDuration(startTime time.Time) {\n\t// TODO: Add Labels.\n\tcm.sink.MeasureSince(\n\t\t\"beacon_kit.execution.client.forkchoice_update_duration\",\n\t\tstartTime,\n\t)\n}\n\n// measureNewPayloadDuration measures the duration of the new payload.\nfunc (cm *clientMetrics) measureNewPayloadDuration(startTime time.Time) {\n\t// TODO: Add Labels.\n\tcm.sink.MeasureSince(\n\t\t\"beacon_kit.execution.client.new_payload_duration\",\n\t\tstartTime,\n\t)\n}\n\n// measureGetPayloadDuration measures the duration of the get payload.\nfunc (cm *clientMetrics) measureGetPayloadDuration(startTime time.Time) {\n\t// TODO: Add Labels.\n\tcm.sink.MeasureSince(\n\t\t\"beacon_kit.execution.client.get_payload_duration\",\n\t\tstartTime,\n\t)\n}\n\n// incrementEngineAPITimeout increments the timeout counter for\n// general engine api timeouts.\nfunc (cm *clientMetrics) incrementEngineAPITimeout() {\n\tcm.incrementTimeoutCounter(\n\t\t\"beacon_kit.execution.client.engine_api\")\n}\n\n// incrementForkchoiceUpdateTimeout increments the timeout counter\n// for forkchoice update.\nfunc (cm *clientMetrics) incrementForkchoiceUpdateTimeout() {\n\tcm.incrementTimeoutCounter(\n\t\t\"beacon_kit.execution.client.forkchoice_update_duration\")\n}\n\n// incrementNewPayloadTimeout increments the timeout counter for\n// new payload.\nfunc (cm *clientMetrics) incrementNewPayloadTimeout() {\n\tcm.incrementTimeoutCounter(\n\t\t\"beacon_kit.execution.client.new_payload_duration\")\n}\n\n// incrementGetPayloadTimeout increments the timeout counter for\n// get payload.\nfunc (cm *clientMetrics) incrementGetPayloadTimeout() {\n\tcm.incrementTimeoutCounter(\n\t\t\"beacon_kit.execution.client.get_payload_duration\")\n}\n\n// incrementHTTPTimeout increments the timeout counter for HTTP.\nfunc (cm *clientMetrics) incrementHTTPTimeoutCounter() {\n\tcm.incrementTimeoutCounter(\"beacon_kit.execution.client.http\")\n}\n\n// incrementTimeoutCounter increments the timeout counter for\n// the given metric.\nfunc (cm *clientMetrics) incrementTimeoutCounter(metricName string) {\n\tcm.sink.IncrementCounter(metricName + \"_timeout\")\n}\n\n// incrementParseErrorCounter increments the parse error counter\n// for the given metric.\nfunc (cm *clientMetrics) incrementParseErrorCounter() {\n\tcm.sink.IncrementCounter(\"beacon_kit.execution.client.parse_error\")\n}\n\n// incrementInvalidRequestCounter increments the invalid request counter\n// for the given metric.\nfunc (cm *clientMetrics) incrementInvalidRequestCounter() {\n\tcm.incrementErrorCounter(\"beacon_kit.execution.client.invalid_request\")\n}\n\n// incrementMethodNotFoundCounter increments the method not found counter\n// for the given metric.\nfunc (cm *clientMetrics) incrementMethodNotFoundCounter() {\n\tcm.incrementErrorCounter(\"beacon_kit.execution.client.method_not_found\")\n}\n\n// incrementInvalidParamsCounter increments the invalid params counter\n// for the given metric.\nfunc (cm *clientMetrics) incrementInvalidParamsCounter() {\n\tcm.incrementErrorCounter(\"beacon_kit.execution.client.invalid_params\")\n}\n\n// incrementInternalErrorCounter increments the internal error counter\n// for the given metric.\nfunc (cm *clientMetrics) incrementInternalErrorCounter() {\n\tcm.incrementErrorCounter(\"beacon_kit.execution.client.internal_error\")\n}\n\n// incrementUnknownPayloadErrorCounter increments the unknown payload error\n// counter\n// for the given metric.\nfunc (cm *clientMetrics) incrementUnknownPayloadErrorCounter() {\n\tcm.incrementErrorCounter(\n\t\t\"beacon_kit.execution.client.unknown_payload_error\",\n\t)\n}\n\n// incrementInvalidForkchoiceStateCounter increments the invalid forkchoice\n// state counter\n// for the given metric.\nfunc (cm *clientMetrics) incrementInvalidForkchoiceStateCounter() {\n\tcm.incrementErrorCounter(\n\t\t\"beacon_kit.execution.client.invalid_forkchoice_state\",\n\t)\n}\n\n// incrementInvalidPayloadAttributesCounter increments the invalid payload\n// attributes counter\n// for the given metric.\nfunc (cm *clientMetrics) incrementInvalidPayloadAttributesCounter() {\n\tcm.incrementErrorCounter(\n\t\t\"beacon_kit.execution.client.invalid_payload_attributes\",\n\t)\n}\n\n// incrementRequestTooLargeCounter increments the request too large counter\n// for the given metric.\nfunc (cm *clientMetrics) incrementRequestTooLargeCounter() {\n\tcm.incrementErrorCounter(\"beacon_kit.execution.client.request_too_large\")\n}\n\n// incrementInternalServerErrorCounter increments the internal server error\n// counter\n// for the given metric.\nfunc (cm *clientMetrics) incrementInternalServerErrorCounter() {\n\tcm.incrementErrorCounter(\n\t\t\"beacon_kit.execution.client.internal_server_error\",\n\t)\n}\n\n// incrementErrorCounter increments the error counter for\n// the given metric.\nfunc (cm *clientMetrics) incrementErrorCounter(metricName string) {\n\tcm.sink.IncrementCounter(metricName)\n}\n"
  },
  {
    "path": "execution/deposit/contract.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage deposit\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/gethlib/deposit\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/ethereum/go-ethereum/accounts/abi/bind\"\n\tgethcommon \"github.com/ethereum/go-ethereum/common\"\n)\n\n// WrappedDepositContract is a struct that holds a pointer to an ABI.\ntype WrappedDepositContract struct {\n\t// DepositContractFilterer is a pointer to the codegen ABI binding.\n\tdeposit.DepositContractFilterer\n}\n\n// NewWrappedDepositContract creates a new DepositContract.\nfunc NewWrappedDepositContract(\n\taddress common.ExecutionAddress,\n\tclient bind.ContractFilterer,\n) (*WrappedDepositContract, error) {\n\tcontract, err := deposit.NewDepositContractFilterer(\n\t\tgethcommon.Address(address), client,\n\t)\n\n\tif err != nil {\n\t\treturn nil, err\n\t} else if contract == nil {\n\t\treturn nil, errors.New(\"contract must not be nil\")\n\t}\n\n\treturn &WrappedDepositContract{\n\t\tDepositContractFilterer: *contract,\n\t}, nil\n}\n\n// ReadDeposits reads deposits from the deposit contract.\nfunc (dc *WrappedDepositContract) ReadDeposits(\n\tctx context.Context,\n\tfromBlock math.U64,\n\ttoBlock math.U64,\n) ([]*ctypes.Deposit, error) {\n\tlogs, err := dc.FilterDeposit(\n\t\t&bind.FilterOpts{\n\t\t\tContext: ctx,\n\t\t\tStart:   fromBlock.Unwrap(),\n\t\t\tEnd:     toBlock.UnwrapPtr(),\n\t\t},\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdeposits := make([]*ctypes.Deposit, 0)\n\tfor logs.Next() {\n\t\tvar (\n\t\t\tcred   bytes.B32\n\t\t\tpubKey bytes.B48\n\t\t\tsign   bytes.B96\n\t\t)\n\t\tpubKey, err = bytes.ToBytes48(logs.Event.Pubkey)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed reading pub key: %w\", err)\n\t\t}\n\t\tcred, err = bytes.ToBytes32(logs.Event.Credentials)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed reading credentials: %w\", err)\n\t\t}\n\t\tsign, err = bytes.ToBytes96(logs.Event.Signature)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed reading signature: %w\", err)\n\t\t}\n\t\tdeposit := &ctypes.Deposit{\n\t\t\tPubkey:      pubKey,\n\t\t\tCredentials: ctypes.WithdrawalCredentials(cred),\n\t\t\tAmount:      math.U64(logs.Event.Amount),\n\t\t\tSignature:   sign,\n\t\t\tIndex:       logs.Event.Index,\n\t\t}\n\t\tdeposits = append(deposits, deposit)\n\t}\n\n\treturn deposits, nil\n}\n"
  },
  {
    "path": "execution/deposit/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage deposit\n\nimport (\n\t\"context\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// Contract is the ABI for the deposit contract.\ntype Contract interface {\n\t// ReadDeposits reads deposits from the deposit contract.\n\tReadDeposits(\n\t\tctx context.Context,\n\t\tfromBlock math.U64,\n\t\ttoBlock math.U64,\n\t) ([]*ctypes.Deposit, error)\n}\n"
  },
  {
    "path": "execution/engine/engine.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage engine\n\nimport (\n\t\"context\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\tengineerrors \"github.com/berachain/beacon-kit/engine-primitives/errors\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/execution/client\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/cenkalti/backoff/v5\"\n)\n\n// Engine is Beacon-Kit's implementation of the `ExecutionEngine`\n// from the Ethereum 2.0 Specification.\ntype Engine struct {\n\t// ec is the engine client that the engine will use to\n\t// interact with the execution layer.\n\tec *client.EngineClient\n\t// logger is the logger for the engine.\n\tlogger log.Logger\n\t// metrics is the metrics for the engine.\n\tmetrics *engineMetrics\n}\n\n// New creates a new Engine.\nfunc New(\n\tengineClient *client.EngineClient,\n\tlogger log.Logger,\n\ttelemtrySink TelemetrySink,\n) *Engine {\n\treturn &Engine{\n\t\tec:      engineClient,\n\t\tlogger:  logger,\n\t\tmetrics: newEngineMetrics(telemtrySink, logger),\n\t}\n}\n\n// GetPayload returns the payload and blobs bundle for the given slot.\nfunc (ee *Engine) GetPayload(\n\tctx context.Context,\n\treq *ctypes.GetPayloadRequest,\n) (ctypes.BuiltExecutionPayloadEnv, error) {\n\treturn ee.ec.GetPayload(\n\t\tctx, req.PayloadID,\n\t\treq.ForkVersion,\n\t)\n}\n\n// NotifyForkchoiceUpdate notifies the execution client of a forkchoice update.\nfunc (ee *Engine) NotifyForkchoiceUpdate(\n\tctx context.Context,\n\treq *ctypes.ForkchoiceUpdateRequest,\n) (*engineprimitives.PayloadID, error) {\n\tvar (\n\t\tengineAPIBackoff     = ee.newBackoff()\n\t\thasPayloadAttributes = req.PayloadAttributes != nil\n\t)\n\n\treturn backoff.Retry(\n\t\tctx,\n\t\tfunc() (*engineprimitives.PayloadID, error) {\n\t\t\t// Log and call the forkchoice update.\n\t\t\tee.metrics.markNotifyForkchoiceUpdateCalled(hasPayloadAttributes)\n\t\t\tpayloadID, err := ee.ec.ForkchoiceUpdated(\n\t\t\t\tctx, req.State, req.PayloadAttributes, req.ForkVersion,\n\t\t\t)\n\n\t\t\t// NotifyForkchoiceUpdate gets called under two circumstances:\n\t\t\t// 1. Payload Building (During PrepareProposal or\n\t\t\t//    optimistically in ProcessProposal)\n\t\t\t// 2. FinalizeBlock\n\t\t\t// We'll discriminate error handling based on these.\n\t\t\tswitch {\n\t\t\tcase err == nil:\n\t\t\t\tee.metrics.markForkchoiceUpdateValid(req.State, hasPayloadAttributes, payloadID)\n\n\t\t\t\t// If we reached here, we have a VALID status and a nil payload ID,\n\t\t\t\t// we should log a warning and error.\n\t\t\t\tif payloadID == nil && hasPayloadAttributes {\n\t\t\t\t\tee.logger.Warn(\n\t\t\t\t\t\t\"Received nil payload ID on VALID engine response\",\n\t\t\t\t\t\t\"head_eth1_hash\", req.State.HeadBlockHash,\n\t\t\t\t\t\t\"safe_eth1_hash\", req.State.SafeBlockHash,\n\t\t\t\t\t\t\"finalized_eth1_hash\", req.State.FinalizedBlockHash,\n\t\t\t\t\t)\n\t\t\t\t\t// Do not retry, return the error.\n\t\t\t\t\treturn nil, backoff.Permanent(ErrNilPayloadOnValidResponse)\n\t\t\t\t}\n\n\t\t\t\t// We've received a valid response, no more retries.\n\t\t\t\treturn payloadID, nil\n\n\t\t\tcase errors.IsAny(err, engineerrors.ErrSyncingPayloadStatus):\n\t\t\t\tee.logger.Info(\"NotifyForkchoiceUpdate: EL syncing. Retrying...\")\n\t\t\t\tee.metrics.markForkchoiceUpdateSyncing(req.State, err)\n\t\t\t\treturn nil, err\n\n\t\t\tcase client.IsNonFatalError(err):\n\t\t\t\tee.logger.Info(\n\t\t\t\t\t\"NotifyForkchoiceUpdate: EL returns non fatal error. Retrying...\",\n\t\t\t\t\t\"err\", err,\n\t\t\t\t)\n\t\t\t\tee.metrics.markForkchoiceUpdateNonFatalError(err)\n\t\t\t\treturn nil, err\n\n\t\t\tcase errors.Is(err, engineerrors.ErrInvalidPayloadStatus):\n\t\t\t\t// During payload building, then there is an invalid payload and should error.\n\t\t\t\t// During FinalizeBlock, something is broken because this should never happen.\n\t\t\t\tee.logger.Error(\"NotifyForkchoiceUpdate: EL returned invalid payload.\")\n\t\t\t\tee.metrics.markForkchoiceUpdateInvalid(req.State, err)\n\t\t\t\treturn nil, backoff.Permanent(err)\n\n\t\t\tcase client.IsFatalError(err):\n\t\t\t\tee.logger.Info(\n\t\t\t\t\t\"NotifyForkchoiceUpdate: EL returns fatal error.\",\n\t\t\t\t\t\"err\", err,\n\t\t\t\t)\n\t\t\t\tee.metrics.markForkchoiceUpdateFatalError(err)\n\t\t\t\treturn nil, backoff.Permanent(err)\n\n\t\t\tdefault:\n\t\t\t\tee.logger.Info(\n\t\t\t\t\t\"NotifyForkchoiceUpdate: EL returns unknown error.\",\n\t\t\t\t\t\"err\", err,\n\t\t\t\t)\n\t\t\t\tee.metrics.markForkchoiceUpdateUndefinedError(err)\n\t\t\t\treturn nil, backoff.Permanent(err)\n\t\t\t}\n\t\t},\n\t\tbackoff.WithBackOff(engineAPIBackoff),\n\t\tbackoff.WithMaxTries(0),       // 0 for infinite retries.\n\t\tbackoff.WithMaxElapsedTime(0), // 0 for infinite max elapsed time.\n\t)\n}\n\n// NotifyNewPayload notifies the execution client of the new payload.\n//\n//nolint:funlen // error handling and logs\nfunc (ee *Engine) NotifyNewPayload(\n\tctx context.Context,\n\treq ctypes.NewPayloadRequest,\n\tretryOnSyncingStatus bool,\n) error {\n\tvar (\n\t\tengineAPIBackoff  = ee.newBackoff()\n\t\tpayloadHash       = req.GetExecutionPayload().GetBlockHash()\n\t\tpayloadParentHash = req.GetExecutionPayload().GetParentHash()\n\t)\n\n\t_, err := backoff.Retry(\n\t\tctx,\n\t\tfunc() (*common.ExecutionHash, error) {\n\t\t\tee.metrics.markNewPayloadCalled(payloadHash, payloadParentHash)\n\t\t\tlastValidHash, err := ee.ec.NewPayload(\n\t\t\t\tctx, req,\n\t\t\t)\n\n\t\t\t// NotifyNewPayload gets called under three circumstances:\n\t\t\t// 1. ProcessProposal state transition\n\t\t\t// 2. FinalizeBlock state transition\n\t\t\t// We'll discriminate error handling based on these.\n\t\t\tswitch {\n\t\t\tcase err == nil:\n\t\t\t\tee.metrics.markNewPayloadValid(payloadHash, payloadParentHash)\n\t\t\t\t// We've received a valid response, no more retries.\n\t\t\t\treturn lastValidHash, nil\n\n\t\t\tcase errors.IsAny(err, engineerrors.ErrSyncingPayloadStatus, engineerrors.ErrAcceptedPayloadStatus):\n\t\t\t\tee.logger.Info(\n\t\t\t\t\t\"NotifyNewPayload: EL returns non valid status. Retrying...\",\n\t\t\t\t\t\"err\", err,\n\t\t\t\t)\n\t\t\t\tee.metrics.markNewPayloadAcceptedSyncingPayloadStatus(err, payloadHash, payloadParentHash)\n\t\t\t\t// During ProcessProposal, we must be able to verify the\n\t\t\t\t// block. Since we do not send a NotifyForkchoiceUpdate\n\t\t\t\t// during ProcessProposal, we must retry here until EL is\n\t\t\t\t// synced.\n\t\t\t\tif retryOnSyncingStatus {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\t// During FinalizeBlock, we do not need to verify the block.\n\t\t\t\t// We do not need to retry here, as the following call to\n\t\t\t\t// NotifyForkchoiceUpdate will inform the EL of the new head\n\t\t\t\t// and then wait for it to sync.\n\t\t\t\t// Don't return error here, because we want to send the forkchoice update regardless.\n\t\t\t\tee.logger.Warn(\n\t\t\t\t\t\"NotifyNewPayload: pushed new payload to SYNCING node.\",\n\t\t\t\t\t\"error\", err,\n\t\t\t\t\t\"blockNum\", req.GetExecutionPayload().GetNumber(),\n\t\t\t\t\t\"blockHash\", payloadHash,\n\t\t\t\t)\n\t\t\t\treturn &common.ExecutionHash{}, nil\n\n\t\t\tcase client.IsNonFatalError(err):\n\t\t\t\tee.logger.Info(\n\t\t\t\t\t\"NotifyNewPayload: EL returns non fatal error. Retrying...\",\n\t\t\t\t\t\"err\", err,\n\t\t\t\t)\n\t\t\t\t// Protect against possible nil value.\n\t\t\t\tif lastValidHash == nil {\n\t\t\t\t\tlastValidHash = &common.ExecutionHash{}\n\t\t\t\t}\n\t\t\t\tee.metrics.markNewPayloadNonFatalError(payloadHash, *lastValidHash, err)\n\t\t\t\treturn nil, err\n\n\t\t\tcase errors.Is(err, engineerrors.ErrInvalidPayloadStatus):\n\t\t\t\tee.logger.Error(\"NotifyNewPayload: EL returned invalid payload.\")\n\t\t\t\tee.metrics.markNewPayloadInvalidPayloadStatus(payloadHash)\n\t\t\t\t// During payload building, then there is an invalid\n\t\t\t\t// payload and should error.\n\t\t\t\t// During FinalizeBlock, something is broken because\n\t\t\t\t// this should never happen.\n\t\t\t\treturn nil, backoff.Permanent(err)\n\n\t\t\tcase client.IsFatalError(err):\n\t\t\t\tee.logger.Error(\n\t\t\t\t\t\"NotifyNewPayload: EL returns fatal error.\",\n\t\t\t\t\t\"err\", err,\n\t\t\t\t)\n\t\t\t\t// Protect against possible nil value.\n\t\t\t\tif lastValidHash == nil {\n\t\t\t\t\tlastValidHash = &common.ExecutionHash{}\n\t\t\t\t}\n\t\t\t\tee.metrics.markNewPayloadFatalError(payloadHash, *lastValidHash, err)\n\t\t\t\treturn nil, backoff.Permanent(err)\n\t\t\tdefault:\n\t\t\t\tee.logger.Error(\n\t\t\t\t\t\"NotifyNewPayload: EL returns unknown error.\",\n\t\t\t\t\t\"err\", err,\n\t\t\t\t)\n\t\t\t\tee.metrics.markNewPayloadUndefinedError(payloadHash, err)\n\t\t\t\t// Do not retry on unknown errors.\n\t\t\t\treturn nil, backoff.Permanent(err)\n\t\t\t}\n\t\t},\n\t\tbackoff.WithBackOff(engineAPIBackoff),\n\t\tbackoff.WithMaxTries(0),       // 0 for infinite retries.\n\t\tbackoff.WithMaxElapsedTime(0), // 0 for infinite max elapsed time.\n\t)\n\treturn err\n}\n\nfunc (ee *Engine) newBackoff() *backoff.ExponentialBackOff {\n\t// Configure backoff. This will retry maxRetries number of times.\n\t// Specifying 0 maxRetries will retry infinitely. Between each retry, it\n\t// will wait RPCRetryInterval amount of time. This backoff will increase\n\t// exponentially until it reaches RPCMaxRetryInterval.\n\tengineAPIBackoff := backoff.NewExponentialBackOff()\n\tengineAPIBackoff.InitialInterval = ee.ec.GetRPCRetryInterval()\n\tengineAPIBackoff.MaxInterval = ee.ec.GetRPCMaxRetryInterval()\n\treturn engineAPIBackoff\n}\n"
  },
  {
    "path": "execution/engine/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage engine\n\nimport \"github.com/berachain/beacon-kit/errors\"\n\nvar (\n\n\t// ErrBadBlockProduced represents an error when the beacon\n\t// chain has produced a bad block.\n\tErrBadBlockProduced = errors.New(\n\t\t\"proposer has produced a bad block, RIP walrus\",\n\t)\n\n\t// ErrNilPayloadOnValidResponse is returned when a nil payload ID is\n\t// received on a VALID engine response.\n\tErrNilPayloadOnValidResponse = errors.New(\n\t\t\"received nil payload ID on VALID engine response\",\n\t)\n)\n"
  },
  {
    "path": "execution/engine/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage engine\n\n// TelemetrySink is an interface for sending metrics to a telemetry backend.\ntype TelemetrySink interface {\n\t// IncrementCounter increments a counter metric identified by the provided\n\t// keys.\n\tIncrementCounter(key string, args ...string)\n}\n"
  },
  {
    "path": "execution/engine/metrics.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage engine\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\tengineerrors \"github.com/berachain/beacon-kit/engine-primitives/errors\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n)\n\n// engineMetrics is a struct that contains metrics for the engine.\ntype engineMetrics struct {\n\t// TelemetrySink is the sink for the metrics.\n\tsink TelemetrySink\n\t// logger is the logger for the engineMetrics.\n\tlogger log.Logger\n}\n\n// newEngineMetrics creates a new engineMetrics.\nfunc newEngineMetrics(\n\tsink TelemetrySink,\n\tlogger log.Logger,\n) *engineMetrics {\n\treturn &engineMetrics{\n\t\tsink:   sink,\n\t\tlogger: logger,\n\t}\n}\n\n// markNewPayloadCalled increments the counter for new payload calls.\nfunc (em *engineMetrics) markNewPayloadCalled(\n\tpayloadHash common.ExecutionHash,\n\tparentHash common.ExecutionHash,\n) {\n\tem.sink.IncrementCounter(\n\t\t\"beacon_kit.execution.engine.new_payload\",\n\t\t\"payload_block_hash\", payloadHash.Hex(),\n\t\t\"payload_parent_block_hash\", parentHash.Hex(),\n\t)\n}\n\n// markNewPayloadValid increments the counter for valid payloads.\nfunc (em *engineMetrics) markNewPayloadValid(\n\tpayloadHash common.ExecutionHash,\n\tparentHash common.ExecutionHash,\n) {\n\tem.logger.Debug(\n\t\t\"Inserted new payload into execution chain\",\n\t\t\"payload_block_hash\", payloadHash,\n\t\t\"payload_parent_block_hash\", parentHash,\n\t)\n\n\tem.sink.IncrementCounter(\n\t\t\"beacon_kit.execution.engine.new_payload_valid\",\n\t)\n}\n\n// markNewPayloadAcceptedSyncingPayloadStatus increments\n// the counter for accepted syncing payload status.\nfunc (em *engineMetrics) markNewPayloadAcceptedSyncingPayloadStatus(\n\terrStatus error,\n\tpayloadHash common.ExecutionHash,\n\tparentHash common.ExecutionHash,\n) {\n\tstatus := \"accepted\"\n\tif errors.Is(errStatus, engineerrors.ErrSyncingPayloadStatus) {\n\t\tstatus = \"syncing\"\n\t}\n\tem.logger.Warn(\n\t\tfmt.Sprintf(\"Received %s payload status during new payload. Awaiting execution client to finish sync.\", status),\n\t\t\"payload_block_hash\", payloadHash,\n\t\t\"parent_hash\", parentHash,\n\t)\n\n\tem.sink.IncrementCounter(\n\t\tfmt.Sprintf(\"beacon_kit.execution.engine.new_payload_%s_payload_status\", status),\n\t)\n}\n\n// markNewPayloadInvalidPayloadStatus increments the counter\n// for invalid payload status.\nfunc (em *engineMetrics) markNewPayloadInvalidPayloadStatus(\n\tpayloadHash common.ExecutionHash,\n) {\n\tem.logger.Error(\n\t\t\"Received invalid payload status during new payload call\",\n\t\t\"payload_block_hash\", payloadHash,\n\t\t\"parent_hash\", payloadHash,\n\t)\n\n\tem.sink.IncrementCounter(\n\t\t\"beacon_kit.execution.engine.new_payload_invalid_payload_status\",\n\t)\n}\n\n// markNewPayloadFatalError increments the counter for JSON-RPC errors.\nfunc (em *engineMetrics) markNewPayloadNonFatalError(\n\tpayloadHash common.ExecutionHash,\n\tlastValidHash common.ExecutionHash,\n\terr error,\n) {\n\tem.logger.Error(\n\t\t\"Received non-fatal error during new payload call\",\n\t\t\"payload_block_hash\", payloadHash,\n\t\t\"parent_hash\", payloadHash,\n\t\t\"last_valid_hash\", lastValidHash,\n\t\t\"error\", err,\n\t)\n\n\tem.sink.IncrementCounter(\n\t\t\"beacon_kit.execution.engine.new_payload_non_fatal_error\",\n\t\t\"error\", err.Error(),\n\t)\n}\n\n// markNewPayloadFatalError increments the counter for JSON-RPC errors.\nfunc (em *engineMetrics) markNewPayloadFatalError(\n\tpayloadHash common.ExecutionHash,\n\tlastValidHash common.ExecutionHash,\n\terr error,\n) {\n\tem.logger.Error(\n\t\t\"Received fatal error during new payload call\",\n\t\t\"payload_block_hash\", payloadHash,\n\t\t\"parent_hash\", payloadHash,\n\t\t\"last_valid_hash\", lastValidHash,\n\t\t\"error\", err,\n\t)\n\n\tem.sink.IncrementCounter(\n\t\t\"beacon_kit.execution.engine.new_payload_fatal_error\",\n\t\t\"error\", err.Error(),\n\t)\n}\n\n// markNewPayloadUndefinedError increments the counter for undefined errors.\nfunc (em *engineMetrics) markNewPayloadUndefinedError(\n\tpayloadHash common.ExecutionHash,\n\terr error,\n) {\n\tem.logger.Error(\n\t\t\"Received undefined error during new payload call\",\n\t\t\"payload_block_hash\", payloadHash,\n\t\t\"parent_hash\", payloadHash,\n\t\t\"error\", err,\n\t)\n\n\tem.sink.IncrementCounter(\n\t\t\"beacon_kit.execution.engine.new_payload_undefined_error\",\n\t\t\"error\", err.Error(),\n\t)\n}\n\n// markNotifyForkchoiceUpdateCalled increments the counter for\n// notify forkchoice update calls.\nfunc (em *engineMetrics) markNotifyForkchoiceUpdateCalled(\n\thasPayloadAttributes bool,\n) {\n\tem.sink.IncrementCounter(\n\t\t\"beacon_kit.execution.engine.forkchoice_update\",\n\t\t\"has_payload_attributes\", strconv.FormatBool(hasPayloadAttributes),\n\t)\n}\n\n// markForkchoiceUpdateValid increments the counter for valid forkchoice\n// updates.\nfunc (em *engineMetrics) markForkchoiceUpdateValid(\n\tstate *engineprimitives.ForkchoiceStateV1,\n\thasPayloadAttributes bool,\n\tpayloadID *engineprimitives.PayloadID,\n) {\n\targs := []any{\n\t\t\"head_block_hash\", state.HeadBlockHash,\n\t\t\"safe_block_hash\", state.SafeBlockHash,\n\t\t\"finalized_block_hash\", state.FinalizedBlockHash,\n\t\t\"with_attributes\", hasPayloadAttributes,\n\t}\n\tif hasPayloadAttributes {\n\t\targs = append(args, \"payload_id\", payloadID)\n\t}\n\tem.logger.Debug(\"Forkchoice updated\", args...)\n\n\tem.sink.IncrementCounter(\n\t\t\"beacon_kit.execution.engine.forkchoice_update_valid\",\n\t)\n}\n\n// markForkchoiceUpdateSyncing increments\n// the counter for accepted syncing forkchoice updates.\nfunc (em *engineMetrics) markForkchoiceUpdateSyncing(\n\tstate *engineprimitives.ForkchoiceStateV1,\n\terr error,\n) {\n\tem.logger.Warn(\n\t\t\"Received syncing payload status during forkchoice update. Awaiting execution client to finish sync.\",\n\t\t\"head_block_hash\",\n\t\tstate.HeadBlockHash,\n\t\t\"safe_block_hash\",\n\t\tstate.SafeBlockHash,\n\t\t\"finalized_block_hash\",\n\t\tstate.FinalizedBlockHash,\n\t)\n\n\tem.sink.IncrementCounter(\n\t\t\"beacon_kit.execution.engine.forkchoice_update_syncing\",\n\t\t\"error\",\n\t\terr.Error(),\n\t)\n}\n\n// markForkchoiceUpdateInvalid increments the counter\n// for invalid forkchoice updates.\nfunc (em *engineMetrics) markForkchoiceUpdateInvalid(\n\tstate *engineprimitives.ForkchoiceStateV1,\n\terr error,\n) {\n\tem.logger.Error(\n\t\t\"Received invalid payload status during forkchoice update call\",\n\t\t\"head_block_hash\", state.HeadBlockHash,\n\t\t\"safe_block_hash\", state.SafeBlockHash,\n\t\t\"finalized_block_hash\", state.FinalizedBlockHash,\n\t\t\"error\", err,\n\t)\n\n\tem.sink.IncrementCounter(\n\t\t\"beacon_kit.execution.engine.forkchoice_update_invalid\",\n\t\t\"error\",\n\t\terr.Error(),\n\t)\n}\n\n// markForkchoiceUpdateFatalError increments the counter for JSON-RPC errors\n// during forkchoice updates.\nfunc (em *engineMetrics) markForkchoiceUpdateFatalError(err error) {\n\tem.logger.Error(\n\t\t\"Received fatal error during forkchoice update call\",\n\t\t\"error\", err,\n\t)\n\n\tem.sink.IncrementCounter(\n\t\t\"beacon_kit.execution.engine.forkchoice_update_fatal_error\",\n\t\t\"error\", err.Error(),\n\t)\n}\n\n// markForkchoiceUpdateNonFatalError increments the counter for JSON-RPC errors\n// during forkchoice updates.\nfunc (em *engineMetrics) markForkchoiceUpdateNonFatalError(err error) {\n\tem.logger.Error(\n\t\t\"Received non-fatal error during forkchoice update call\",\n\t\t\"error\", err,\n\t)\n\n\tem.sink.IncrementCounter(\n\t\t\"beacon_kit.execution.engine.forkchoice_update_non_fatal_error\",\n\t\t\"error\", err.Error(),\n\t)\n}\n\n// markForkchoiceUpdateUndefinedError increments the counter for undefined\n// errors during forkchoice updates.\nfunc (em *engineMetrics) markForkchoiceUpdateUndefinedError(err error) {\n\tem.logger.Error(\n\t\t\"Received undefined execution engine error during forkchoice update call\",\n\t\t\"error\",\n\t\terr,\n\t)\n\n\tem.sink.IncrementCounter(\n\t\t\"beacon_kit.execution.engine.forkchoice_update_undefined_error\",\n\t\t\"error\", err.Error(),\n\t)\n}\n"
  },
  {
    "path": "execution/requests/eip7002/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage eip7002\n\nimport \"context\"\n\ntype rpcClient interface {\n\tCall(ctx context.Context, target any, method string, params ...any) error\n}\n"
  },
  {
    "path": "execution/requests/eip7002/withdrawal.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage eip7002\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/binary\"\n\t\"math/big\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n\tbeaconbytes \"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/ethereum/go-ethereum/params\"\n)\n\ntype feeOpts struct {\n\tTo string `json:\"to\"`\n}\n\n// GetWithdrawalFee returns the withdrawal fee in wei. See https://eips.ethereum.org/EIPS/eip-7002 for more.\n// Only expected to be used in test cases.\nfunc GetWithdrawalFee(ctx context.Context, client rpcClient) (*big.Int, error) {\n\tvar result string\n\tfeeInput := &feeOpts{\n\t\tTo: params.WithdrawalQueueAddress.String(),\n\t}\n\terr := client.Call(ctx, &result, \"eth_call\", feeInput)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tn, ok := new(big.Int).SetString(result, 0)\n\tif !ok {\n\t\treturn nil, errors.New(\"error converting hex string to big.Int\")\n\t}\n\treturn n, nil\n}\n\n// CreateWithdrawalRequestData returns the request body formatted as defined by the EIP-7002 specification.\n// Only expected to be used in test cases.\nfunc CreateWithdrawalRequestData(blsPubKey crypto.BLSPubkey, withdrawAmount math.Gwei) (beaconbytes.Bytes, error) {\n\t// Create a buffer to hold the packed encoding.\n\tvar packed bytes.Buffer\n\tif _, err := packed.Write(blsPubKey[:]); err != nil {\n\t\treturn nil, err\n\t}\n\t// Write the uint64 value in big-endian order.\n\tif err := binary.Write(&packed, binary.BigEndian, withdrawAmount); err != nil {\n\t\treturn nil, err\n\t}\n\treturn packed.Bytes(), nil\n}\n"
  },
  {
    "path": "execution/requests/eip7002/withdrawal_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage eip7002_test\n\nimport (\n\t\"encoding/hex\"\n\t\"math\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/execution/requests/eip7002\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\tbeaconmath \"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestCreateWithdrawalRequestData(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname           string\n\t\tpubKey         string\n\t\twithdrawAmount uint64\n\t\texpected       string\n\t}{\n\t\t{\n\t\t\tname:           \"Normal case\",\n\t\t\tpubKey:         \"acaf2e8ec309513be835104abc43c8ab27e0665701482d3ce11c592e6ec22910804e8378b0be0f6eb92f452d086599fd\",\n\t\t\twithdrawAmount: 10,\n\t\t\texpected:       \"0xacaf2e8ec309513be835104abc43c8ab27e0665701482d3ce11c592e6ec22910804e8378b0be0f6eb92f452d086599fd000000000000000a\",\n\t\t},\n\t\t{\n\t\t\tname:           \"All zeros pubkey with zero withdrawal\",\n\t\t\tpubKey:         \"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n\t\t\twithdrawAmount: 0,\n\t\t\texpected:       \"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n\t\t},\n\t\t{\n\t\t\tname:           \"All f's pubkey with max withdrawal\",\n\t\t\tpubKey:         \"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\",\n\t\t\twithdrawAmount: math.MaxUint64,\n\t\t\texpected:       \"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tblsPubKeyBytes, err := hex.DecodeString(tt.pubKey)\n\t\t\trequire.NoError(t, err)\n\t\t\tblsPubKey := crypto.BLSPubkey(blsPubKeyBytes)\n\t\t\t// Call the function under test.\n\t\t\tresult, err := eip7002.CreateWithdrawalRequestData(blsPubKey, beaconmath.U64(tt.withdrawAmount))\n\t\t\trequire.NoError(t, err)\n\t\t\t// Compare the resulting bytes with the expected output.\n\t\t\trequire.Equal(t, tt.expected, result.String())\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "execution/requests/eip7251/consolidation.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage eip7251\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"math/big\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n\tbeaconbytes \"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/ethereum/go-ethereum/params\"\n)\n\ntype feeOpts struct {\n\tTo string `json:\"to\"`\n}\n\n// GetConsolidationFee returns the consolidation fee in wei. See https://eips.ethereum.org/EIPS/eip-7251 for more.\n// This is only expected to be used in tests to form test scenarios.\nfunc GetConsolidationFee(ctx context.Context, client rpcClient) (*big.Int, error) {\n\tvar result string\n\tfeeInput := &feeOpts{\n\t\tTo: params.ConsolidationQueueAddress.String(),\n\t}\n\terr := client.Call(ctx, &result, \"eth_call\", feeInput)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tn, ok := new(big.Int).SetString(result, 0)\n\tif !ok {\n\t\treturn nil, errors.New(\"error converting hex string to big.Int\")\n\t}\n\treturn n, nil\n}\n\n// CreateConsolidationRequestData returns the request body formatted as defined by the EIP-7251 specification.\n// This is only expected to be used in tests to form test scenarios.\nfunc CreateConsolidationRequestData(sourcePubKey, targetPubKey crypto.BLSPubkey) (beaconbytes.Bytes, error) {\n\t// Create a buffer to hold the packed encoding.\n\tvar packed bytes.Buffer\n\tif _, err := packed.Write(sourcePubKey[:]); err != nil {\n\t\treturn nil, err\n\t}\n\tif _, err := packed.Write(targetPubKey[:]); err != nil {\n\t\treturn nil, err\n\t}\n\treturn packed.Bytes(), nil\n}\n"
  },
  {
    "path": "execution/requests/eip7251/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage eip7251\n\nimport \"context\"\n\ntype rpcClient interface {\n\tCall(ctx context.Context, target any, method string, params ...any) error\n}\n"
  },
  {
    "path": "gethlib/deposit/contract.abigen.go",
    "content": "// Code generated - DO NOT EDIT.\n// This file is a generated binding and any manual changes will be lost.\n\npackage deposit\n\nimport (\n\t\"errors\"\n\t\"math/big\"\n\t\"strings\"\n\n\tethereum \"github.com/ethereum/go-ethereum\"\n\t\"github.com/ethereum/go-ethereum/accounts/abi\"\n\t\"github.com/ethereum/go-ethereum/accounts/abi/bind\"\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/ethereum/go-ethereum/event\"\n)\n\n// Reference imports to suppress errors if they are not otherwise used.\nvar (\n\t_ = errors.New\n\t_ = big.NewInt\n\t_ = strings.NewReader\n\t_ = ethereum.NotFound\n\t_ = bind.Bind\n\t_ = common.Big1\n\t_ = types.BloomLookup\n\t_ = event.NewSubscription\n\t_ = abi.ConvertType\n)\n\n// DepositContractMetaData contains all meta data concerning the DepositContract contract.\nvar DepositContractMetaData = &bind.MetaData{\n\tABI: \"[{\\\"type\\\":\\\"function\\\",\\\"name\\\":\\\"acceptOperatorChange\\\",\\\"inputs\\\":[{\\\"name\\\":\\\"pubkey\\\",\\\"type\\\":\\\"bytes\\\",\\\"internalType\\\":\\\"bytes\\\"}],\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\"},{\\\"type\\\":\\\"function\\\",\\\"name\\\":\\\"cancelOperatorChange\\\",\\\"inputs\\\":[{\\\"name\\\":\\\"pubkey\\\",\\\"type\\\":\\\"bytes\\\",\\\"internalType\\\":\\\"bytes\\\"}],\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\"},{\\\"type\\\":\\\"function\\\",\\\"name\\\":\\\"deposit\\\",\\\"inputs\\\":[{\\\"name\\\":\\\"pubkey\\\",\\\"type\\\":\\\"bytes\\\",\\\"internalType\\\":\\\"bytes\\\"},{\\\"name\\\":\\\"credentials\\\",\\\"type\\\":\\\"bytes\\\",\\\"internalType\\\":\\\"bytes\\\"},{\\\"name\\\":\\\"signature\\\",\\\"type\\\":\\\"bytes\\\",\\\"internalType\\\":\\\"bytes\\\"},{\\\"name\\\":\\\"operator\\\",\\\"type\\\":\\\"address\\\",\\\"internalType\\\":\\\"address\\\"}],\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"payable\\\"},{\\\"type\\\":\\\"function\\\",\\\"name\\\":\\\"depositCount\\\",\\\"inputs\\\":[],\\\"outputs\\\":[{\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"uint64\\\",\\\"internalType\\\":\\\"uint64\\\"}],\\\"stateMutability\\\":\\\"view\\\"},{\\\"type\\\":\\\"function\\\",\\\"name\\\":\\\"genesisDepositsRoot\\\",\\\"inputs\\\":[],\\\"outputs\\\":[{\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"bytes32\\\",\\\"internalType\\\":\\\"bytes32\\\"}],\\\"stateMutability\\\":\\\"view\\\"},{\\\"type\\\":\\\"function\\\",\\\"name\\\":\\\"getOperator\\\",\\\"inputs\\\":[{\\\"name\\\":\\\"pubkey\\\",\\\"type\\\":\\\"bytes\\\",\\\"internalType\\\":\\\"bytes\\\"}],\\\"outputs\\\":[{\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"address\\\",\\\"internalType\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"view\\\"},{\\\"type\\\":\\\"function\\\",\\\"name\\\":\\\"queuedOperator\\\",\\\"inputs\\\":[{\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"bytes\\\",\\\"internalType\\\":\\\"bytes\\\"}],\\\"outputs\\\":[{\\\"name\\\":\\\"queuedTimestamp\\\",\\\"type\\\":\\\"uint96\\\",\\\"internalType\\\":\\\"uint96\\\"},{\\\"name\\\":\\\"newOperator\\\",\\\"type\\\":\\\"address\\\",\\\"internalType\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"view\\\"},{\\\"type\\\":\\\"function\\\",\\\"name\\\":\\\"requestOperatorChange\\\",\\\"inputs\\\":[{\\\"name\\\":\\\"pubkey\\\",\\\"type\\\":\\\"bytes\\\",\\\"internalType\\\":\\\"bytes\\\"},{\\\"name\\\":\\\"newOperator\\\",\\\"type\\\":\\\"address\\\",\\\"internalType\\\":\\\"address\\\"}],\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\"},{\\\"type\\\":\\\"function\\\",\\\"name\\\":\\\"supportsInterface\\\",\\\"inputs\\\":[{\\\"name\\\":\\\"interfaceId\\\",\\\"type\\\":\\\"bytes4\\\",\\\"internalType\\\":\\\"bytes4\\\"}],\\\"outputs\\\":[{\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"bool\\\",\\\"internalType\\\":\\\"bool\\\"}],\\\"stateMutability\\\":\\\"pure\\\"},{\\\"type\\\":\\\"event\\\",\\\"name\\\":\\\"Deposit\\\",\\\"inputs\\\":[{\\\"name\\\":\\\"pubkey\\\",\\\"type\\\":\\\"bytes\\\",\\\"indexed\\\":false,\\\"internalType\\\":\\\"bytes\\\"},{\\\"name\\\":\\\"credentials\\\",\\\"type\\\":\\\"bytes\\\",\\\"indexed\\\":false,\\\"internalType\\\":\\\"bytes\\\"},{\\\"name\\\":\\\"amount\\\",\\\"type\\\":\\\"uint64\\\",\\\"indexed\\\":false,\\\"internalType\\\":\\\"uint64\\\"},{\\\"name\\\":\\\"signature\\\",\\\"type\\\":\\\"bytes\\\",\\\"indexed\\\":false,\\\"internalType\\\":\\\"bytes\\\"},{\\\"name\\\":\\\"index\\\",\\\"type\\\":\\\"uint64\\\",\\\"indexed\\\":false,\\\"internalType\\\":\\\"uint64\\\"}],\\\"anonymous\\\":false},{\\\"type\\\":\\\"event\\\",\\\"name\\\":\\\"OperatorChangeCancelled\\\",\\\"inputs\\\":[{\\\"name\\\":\\\"pubkey\\\",\\\"type\\\":\\\"bytes\\\",\\\"indexed\\\":true,\\\"internalType\\\":\\\"bytes\\\"}],\\\"anonymous\\\":false},{\\\"type\\\":\\\"event\\\",\\\"name\\\":\\\"OperatorChangeQueued\\\",\\\"inputs\\\":[{\\\"name\\\":\\\"pubkey\\\",\\\"type\\\":\\\"bytes\\\",\\\"indexed\\\":true,\\\"internalType\\\":\\\"bytes\\\"},{\\\"name\\\":\\\"queuedOperator\\\",\\\"type\\\":\\\"address\\\",\\\"indexed\\\":false,\\\"internalType\\\":\\\"address\\\"},{\\\"name\\\":\\\"currentOperator\\\",\\\"type\\\":\\\"address\\\",\\\"indexed\\\":false,\\\"internalType\\\":\\\"address\\\"},{\\\"name\\\":\\\"queuedTimestamp\\\",\\\"type\\\":\\\"uint256\\\",\\\"indexed\\\":false,\\\"internalType\\\":\\\"uint256\\\"}],\\\"anonymous\\\":false},{\\\"type\\\":\\\"event\\\",\\\"name\\\":\\\"OperatorUpdated\\\",\\\"inputs\\\":[{\\\"name\\\":\\\"pubkey\\\",\\\"type\\\":\\\"bytes\\\",\\\"indexed\\\":true,\\\"internalType\\\":\\\"bytes\\\"},{\\\"name\\\":\\\"newOperator\\\",\\\"type\\\":\\\"address\\\",\\\"indexed\\\":false,\\\"internalType\\\":\\\"address\\\"},{\\\"name\\\":\\\"previousOperator\\\",\\\"type\\\":\\\"address\\\",\\\"indexed\\\":false,\\\"internalType\\\":\\\"address\\\"}],\\\"anonymous\\\":false},{\\\"type\\\":\\\"error\\\",\\\"name\\\":\\\"DepositNotMultipleOfGwei\\\",\\\"inputs\\\":[]},{\\\"type\\\":\\\"error\\\",\\\"name\\\":\\\"DepositValueTooHigh\\\",\\\"inputs\\\":[]},{\\\"type\\\":\\\"error\\\",\\\"name\\\":\\\"InsufficientDeposit\\\",\\\"inputs\\\":[]},{\\\"type\\\":\\\"error\\\",\\\"name\\\":\\\"InvalidCredentialsLength\\\",\\\"inputs\\\":[]},{\\\"type\\\":\\\"error\\\",\\\"name\\\":\\\"InvalidPubKeyLength\\\",\\\"inputs\\\":[]},{\\\"type\\\":\\\"error\\\",\\\"name\\\":\\\"InvalidSignatureLength\\\",\\\"inputs\\\":[]},{\\\"type\\\":\\\"error\\\",\\\"name\\\":\\\"NotEnoughTime\\\",\\\"inputs\\\":[]},{\\\"type\\\":\\\"error\\\",\\\"name\\\":\\\"NotNewOperator\\\",\\\"inputs\\\":[]},{\\\"type\\\":\\\"error\\\",\\\"name\\\":\\\"NotOperator\\\",\\\"inputs\\\":[]},{\\\"type\\\":\\\"error\\\",\\\"name\\\":\\\"OperatorAlreadySet\\\",\\\"inputs\\\":[]},{\\\"type\\\":\\\"error\\\",\\\"name\\\":\\\"ZeroAddress\\\",\\\"inputs\\\":[]},{\\\"type\\\":\\\"error\\\",\\\"name\\\":\\\"ZeroOperatorOnFirstDeposit\\\",\\\"inputs\\\":[]}]\",\n\tBin: \"0x6080604052348015600e575f80fd5b506110f28061001c5f395ff3fe608060405260043610610093575f3560e01c8063577212fe11610066578063c53925d91161004c578063c53925d914610231578063e12cf4cb14610250578063fea7ab7714610263575f80fd5b8063577212fe146101cc5780639eaffa96146101ed575f80fd5b806301ffc9a7146100975780632dfdf0b5146100cb5780633523f9bd14610103578063560036ec14610126575b5f80fd5b3480156100a2575f80fd5b506100b66100b1366004610c22565b610282565b60405190151581526020015b60405180910390f35b3480156100d6575f80fd5b505f546100ea9067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016100c2565b34801561010e575f80fd5b5061011860015481565b6040519081526020016100c2565b348015610131575f80fd5b50610193610140366004610c95565b80516020818301810180516003825292820191909301209152546bffffffffffffffffffffffff8116906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1682565b604080516bffffffffffffffffffffffff909316835273ffffffffffffffffffffffffffffffffffffffff9091166020830152016100c2565b3480156101d7575f80fd5b506101eb6101e6366004610dca565b61031a565b005b3480156101f8575f80fd5b5061020c610207366004610dca565b6103f0565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c2565b34801561023c575f80fd5b506101eb61024b366004610dca565b610431565b6101eb61025e366004610e2c565b610658565b34801561026e575f80fd5b506101eb61027d366004610edb565b6109ab565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f136f920d00000000000000000000000000000000000000000000000000000000145b92915050565b6002828260405161032c929190610f2b565b908152604051908190036020019020543373ffffffffffffffffffffffffffffffffffffffff9091161461038c576040517f7c214f0400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6003828260405161039e929190610f2b565b9081526040519081900360200181205f90556103bd9083908390610f2b565b604051908190038120907f1c0a7e1bd09da292425c039309671a03de56b89a0858598aab6df6ce84b006db905f90a25050565b5f60028383604051610403929190610f2b565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff16905092915050565b5f60038383604051610444929190610f2b565b908152604051908190036020019020805490915073ffffffffffffffffffffffffffffffffffffffff6c01000000000000000000000000820416906bffffffffffffffffffffffff163382146104c6576040517f819a0d0b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6bffffffffffffffffffffffff42166104e26201518083610f67565b6bffffffffffffffffffffffff161115610528576040517fe8966d7a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6002868660405161053b929190610f2b565b9081526040519081900360200181205473ffffffffffffffffffffffffffffffffffffffff16915083906002906105759089908990610f2b565b908152604051908190036020018120805473ffffffffffffffffffffffffffffffffffffffff939093167fffffffffffffffffffffffff0000000000000000000000000000000000000000909316929092179091556003906105da9088908890610f2b565b9081526040519081900360200181205f90556105f99087908790610f2b565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff808716845284166020840152917f0adffd98d3072c48341843974dffd7a910bb849ba6ca04163d43bb26feb17403910160405180910390a2505050505050565b60308614610692576040517f9f10647200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602084146106cc576040517fb39bca1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608214610706576040517f4be6321b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff166002888860405161072f929190610f2b565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff16036108765773ffffffffffffffffffffffffffffffffffffffff81166107a7576040517f51969a7a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600288886040516107ba929190610f2b565b908152604051908190036020018120805473ffffffffffffffffffffffffffffffffffffffff939093167fffffffffffffffffffffffff00000000000000000000000000000000000000009093169290921790915561081c9088908890610f2b565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff841683525f6020840152917f0adffd98d3072c48341843974dffd7a910bb849ba6ca04163d43bb26feb17403910160405180910390a26108c4565b73ffffffffffffffffffffffffffffffffffffffff8116156108c4576040517fc4142b4100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6108cd610b5d565b9050633b9aca0067ffffffffffffffff82161015610917576040517f0e1eddda00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80547f68af751683498a9f9be59fe8b0d52a64dd155255d85cdb29fea30b1e3f891d46918a918a918a918a9187918b918b9167ffffffffffffffff16908061095f83610f8b565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550604051610999989796959493929190610ffe565b60405180910390a15050505050505050565b5f600284846040516109be929190610f2b565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff169050338114610a1f576040517f7c214f0400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216610a6c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60038585604051610a7f929190610f2b565b908152604051908190036020018120426bffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff86166c01000000000000000000000000027fffffffffffffffffffffffffffffffffffffffff000000000000000000000000161781559150610af79086908690610f2b565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff8681168452851660208401524283830152905190917f7640ec3c8c4695deadda414dd20400acf275297a7c38715f9237657e97ddba5f919081900360600190a25050505050565b5f610b6c633b9aca0034611096565b15610ba3576040517f40567b3800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f610bb2633b9aca00346110a9565b905067ffffffffffffffff811115610bf6576040517f2aa6673400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c005f34610c05565b919050565b5f385f3884865af1610c1e5763b12d13eb5f526004601cfd5b5050565b5f60208284031215610c32575f80fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610c61575f80fd5b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f60208284031215610ca5575f80fd5b813567ffffffffffffffff811115610cbb575f80fd5b8201601f81018413610ccb575f80fd5b803567ffffffffffffffff811115610ce557610ce5610c68565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160116810181811067ffffffffffffffff82111715610d5157610d51610c68565b604052818152828201602001861015610d68575f80fd5b816020840160208301375f91810160200191909152949350505050565b5f8083601f840112610d95575f80fd5b50813567ffffffffffffffff811115610dac575f80fd5b602083019150836020828501011115610dc3575f80fd5b9250929050565b5f8060208385031215610ddb575f80fd5b823567ffffffffffffffff811115610df1575f80fd5b610dfd85828601610d85565b90969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610c00575f80fd5b5f805f805f805f6080888a031215610e42575f80fd5b873567ffffffffffffffff811115610e58575f80fd5b610e648a828b01610d85565b909850965050602088013567ffffffffffffffff811115610e83575f80fd5b610e8f8a828b01610d85565b909650945050604088013567ffffffffffffffff811115610eae575f80fd5b610eba8a828b01610d85565b9094509250610ecd905060608901610e09565b905092959891949750929550565b5f805f60408486031215610eed575f80fd5b833567ffffffffffffffff811115610f03575f80fd5b610f0f86828701610d85565b9094509250610f22905060208501610e09565b90509250925092565b818382375f9101908152919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b6bffffffffffffffffffffffff818116838216019081111561031457610314610f3a565b5f67ffffffffffffffff821667ffffffffffffffff8103610fae57610fae610f3a565b60010192915050565b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60a081525f61101160a083018a8c610fb7565b828103602084015261102481898b610fb7565b905067ffffffffffffffff871660408401528281036060840152611049818688610fb7565b91505067ffffffffffffffff831660808301529998505050505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f826110a4576110a4611069565b500690565b5f826110b7576110b7611069565b50049056fea264697066735822122069227307258cbe8f29985bb4f3e283b1b03d5c0cbab8add81bf3c22e3d13729664736f6c634300081a0033\",\n}\n\n// DepositContractABI is the input ABI used to generate the binding from.\n// Deprecated: Use DepositContractMetaData.ABI instead.\nvar DepositContractABI = DepositContractMetaData.ABI\n\n// DepositContractBin is the compiled bytecode used for deploying new contracts.\n// Deprecated: Use DepositContractMetaData.Bin instead.\nvar DepositContractBin = DepositContractMetaData.Bin\n\n// DeployDepositContract deploys a new Ethereum contract, binding an instance of DepositContract to it.\nfunc DeployDepositContract(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *DepositContract, error) {\n\tparsed, err := DepositContractMetaData.GetAbi()\n\tif err != nil {\n\t\treturn common.Address{}, nil, nil, err\n\t}\n\tif parsed == nil {\n\t\treturn common.Address{}, nil, nil, errors.New(\"GetABI returned nil\")\n\t}\n\n\taddress, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(DepositContractBin), backend)\n\tif err != nil {\n\t\treturn common.Address{}, nil, nil, err\n\t}\n\treturn address, tx, &DepositContract{DepositContractCaller: DepositContractCaller{contract: contract}, DepositContractTransactor: DepositContractTransactor{contract: contract}, DepositContractFilterer: DepositContractFilterer{contract: contract}}, nil\n}\n\n// DepositContract is an auto generated Go binding around an Ethereum contract.\ntype DepositContract struct {\n\tDepositContractCaller     // Read-only binding to the contract\n\tDepositContractTransactor // Write-only binding to the contract\n\tDepositContractFilterer   // Log filterer for contract events\n}\n\n// DepositContractCaller is an auto generated read-only Go binding around an Ethereum contract.\ntype DepositContractCaller struct {\n\tcontract *bind.BoundContract // Generic contract wrapper for the low level calls\n}\n\n// DepositContractTransactor is an auto generated write-only Go binding around an Ethereum contract.\ntype DepositContractTransactor struct {\n\tcontract *bind.BoundContract // Generic contract wrapper for the low level calls\n}\n\n// DepositContractFilterer is an auto generated log filtering Go binding around an Ethereum contract events.\ntype DepositContractFilterer struct {\n\tcontract *bind.BoundContract // Generic contract wrapper for the low level calls\n}\n\n// DepositContractSession is an auto generated Go binding around an Ethereum contract,\n// with pre-set call and transact options.\ntype DepositContractSession struct {\n\tContract     *DepositContract  // Generic contract binding to set the session for\n\tCallOpts     bind.CallOpts     // Call options to use throughout this session\n\tTransactOpts bind.TransactOpts // Transaction auth options to use throughout this session\n}\n\n// DepositContractCallerSession is an auto generated read-only Go binding around an Ethereum contract,\n// with pre-set call options.\ntype DepositContractCallerSession struct {\n\tContract *DepositContractCaller // Generic contract caller binding to set the session for\n\tCallOpts bind.CallOpts          // Call options to use throughout this session\n}\n\n// DepositContractTransactorSession is an auto generated write-only Go binding around an Ethereum contract,\n// with pre-set transact options.\ntype DepositContractTransactorSession struct {\n\tContract     *DepositContractTransactor // Generic contract transactor binding to set the session for\n\tTransactOpts bind.TransactOpts          // Transaction auth options to use throughout this session\n}\n\n// DepositContractRaw is an auto generated low-level Go binding around an Ethereum contract.\ntype DepositContractRaw struct {\n\tContract *DepositContract // Generic contract binding to access the raw methods on\n}\n\n// DepositContractCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.\ntype DepositContractCallerRaw struct {\n\tContract *DepositContractCaller // Generic read-only contract binding to access the raw methods on\n}\n\n// DepositContractTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.\ntype DepositContractTransactorRaw struct {\n\tContract *DepositContractTransactor // Generic write-only contract binding to access the raw methods on\n}\n\n// NewDepositContract creates a new instance of DepositContract, bound to a specific deployed contract.\nfunc NewDepositContract(address common.Address, backend bind.ContractBackend) (*DepositContract, error) {\n\tcontract, err := bindDepositContract(address, backend, backend, backend)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &DepositContract{DepositContractCaller: DepositContractCaller{contract: contract}, DepositContractTransactor: DepositContractTransactor{contract: contract}, DepositContractFilterer: DepositContractFilterer{contract: contract}}, nil\n}\n\n// NewDepositContractCaller creates a new read-only instance of DepositContract, bound to a specific deployed contract.\nfunc NewDepositContractCaller(address common.Address, caller bind.ContractCaller) (*DepositContractCaller, error) {\n\tcontract, err := bindDepositContract(address, caller, nil, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &DepositContractCaller{contract: contract}, nil\n}\n\n// NewDepositContractTransactor creates a new write-only instance of DepositContract, bound to a specific deployed contract.\nfunc NewDepositContractTransactor(address common.Address, transactor bind.ContractTransactor) (*DepositContractTransactor, error) {\n\tcontract, err := bindDepositContract(address, nil, transactor, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &DepositContractTransactor{contract: contract}, nil\n}\n\n// NewDepositContractFilterer creates a new log filterer instance of DepositContract, bound to a specific deployed contract.\nfunc NewDepositContractFilterer(address common.Address, filterer bind.ContractFilterer) (*DepositContractFilterer, error) {\n\tcontract, err := bindDepositContract(address, nil, nil, filterer)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &DepositContractFilterer{contract: contract}, nil\n}\n\n// bindDepositContract binds a generic wrapper to an already deployed contract.\nfunc bindDepositContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {\n\tparsed, err := DepositContractMetaData.GetAbi()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil\n}\n\n// Call invokes the (constant) contract method with params as input values and\n// sets the output to result. The result type might be a single field for simple\n// returns, a slice of interfaces for anonymous returns and a struct for named\n// returns.\nfunc (_DepositContract *DepositContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {\n\treturn _DepositContract.Contract.DepositContractCaller.contract.Call(opts, result, method, params...)\n}\n\n// Transfer initiates a plain transaction to move funds to the contract, calling\n// its default method if one is available.\nfunc (_DepositContract *DepositContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {\n\treturn _DepositContract.Contract.DepositContractTransactor.contract.Transfer(opts)\n}\n\n// Transact invokes the (paid) contract method with params as input values.\nfunc (_DepositContract *DepositContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {\n\treturn _DepositContract.Contract.DepositContractTransactor.contract.Transact(opts, method, params...)\n}\n\n// Call invokes the (constant) contract method with params as input values and\n// sets the output to result. The result type might be a single field for simple\n// returns, a slice of interfaces for anonymous returns and a struct for named\n// returns.\nfunc (_DepositContract *DepositContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {\n\treturn _DepositContract.Contract.contract.Call(opts, result, method, params...)\n}\n\n// Transfer initiates a plain transaction to move funds to the contract, calling\n// its default method if one is available.\nfunc (_DepositContract *DepositContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {\n\treturn _DepositContract.Contract.contract.Transfer(opts)\n}\n\n// Transact invokes the (paid) contract method with params as input values.\nfunc (_DepositContract *DepositContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {\n\treturn _DepositContract.Contract.contract.Transact(opts, method, params...)\n}\n\n// DepositCount is a free data retrieval call binding the contract method 0x2dfdf0b5.\n//\n// Solidity: function depositCount() view returns(uint64)\nfunc (_DepositContract *DepositContractCaller) DepositCount(opts *bind.CallOpts) (uint64, error) {\n\tvar out []interface{}\n\terr := _DepositContract.contract.Call(opts, &out, \"depositCount\")\n\n\tif err != nil {\n\t\treturn *new(uint64), err\n\t}\n\n\tout0 := *abi.ConvertType(out[0], new(uint64)).(*uint64)\n\n\treturn out0, err\n\n}\n\n// DepositCount is a free data retrieval call binding the contract method 0x2dfdf0b5.\n//\n// Solidity: function depositCount() view returns(uint64)\nfunc (_DepositContract *DepositContractSession) DepositCount() (uint64, error) {\n\treturn _DepositContract.Contract.DepositCount(&_DepositContract.CallOpts)\n}\n\n// DepositCount is a free data retrieval call binding the contract method 0x2dfdf0b5.\n//\n// Solidity: function depositCount() view returns(uint64)\nfunc (_DepositContract *DepositContractCallerSession) DepositCount() (uint64, error) {\n\treturn _DepositContract.Contract.DepositCount(&_DepositContract.CallOpts)\n}\n\n// GenesisDepositsRoot is a free data retrieval call binding the contract method 0x3523f9bd.\n//\n// Solidity: function genesisDepositsRoot() view returns(bytes32)\nfunc (_DepositContract *DepositContractCaller) GenesisDepositsRoot(opts *bind.CallOpts) ([32]byte, error) {\n\tvar out []interface{}\n\terr := _DepositContract.contract.Call(opts, &out, \"genesisDepositsRoot\")\n\n\tif err != nil {\n\t\treturn *new([32]byte), err\n\t}\n\n\tout0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)\n\n\treturn out0, err\n\n}\n\n// GenesisDepositsRoot is a free data retrieval call binding the contract method 0x3523f9bd.\n//\n// Solidity: function genesisDepositsRoot() view returns(bytes32)\nfunc (_DepositContract *DepositContractSession) GenesisDepositsRoot() ([32]byte, error) {\n\treturn _DepositContract.Contract.GenesisDepositsRoot(&_DepositContract.CallOpts)\n}\n\n// GenesisDepositsRoot is a free data retrieval call binding the contract method 0x3523f9bd.\n//\n// Solidity: function genesisDepositsRoot() view returns(bytes32)\nfunc (_DepositContract *DepositContractCallerSession) GenesisDepositsRoot() ([32]byte, error) {\n\treturn _DepositContract.Contract.GenesisDepositsRoot(&_DepositContract.CallOpts)\n}\n\n// GetOperator is a free data retrieval call binding the contract method 0x9eaffa96.\n//\n// Solidity: function getOperator(bytes pubkey) view returns(address)\nfunc (_DepositContract *DepositContractCaller) GetOperator(opts *bind.CallOpts, pubkey []byte) (common.Address, error) {\n\tvar out []interface{}\n\terr := _DepositContract.contract.Call(opts, &out, \"getOperator\", pubkey)\n\n\tif err != nil {\n\t\treturn *new(common.Address), err\n\t}\n\n\tout0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)\n\n\treturn out0, err\n\n}\n\n// GetOperator is a free data retrieval call binding the contract method 0x9eaffa96.\n//\n// Solidity: function getOperator(bytes pubkey) view returns(address)\nfunc (_DepositContract *DepositContractSession) GetOperator(pubkey []byte) (common.Address, error) {\n\treturn _DepositContract.Contract.GetOperator(&_DepositContract.CallOpts, pubkey)\n}\n\n// GetOperator is a free data retrieval call binding the contract method 0x9eaffa96.\n//\n// Solidity: function getOperator(bytes pubkey) view returns(address)\nfunc (_DepositContract *DepositContractCallerSession) GetOperator(pubkey []byte) (common.Address, error) {\n\treturn _DepositContract.Contract.GetOperator(&_DepositContract.CallOpts, pubkey)\n}\n\n// QueuedOperator is a free data retrieval call binding the contract method 0x560036ec.\n//\n// Solidity: function queuedOperator(bytes ) view returns(uint96 queuedTimestamp, address newOperator)\nfunc (_DepositContract *DepositContractCaller) QueuedOperator(opts *bind.CallOpts, arg0 []byte) (struct {\n\tQueuedTimestamp *big.Int\n\tNewOperator     common.Address\n}, error) {\n\tvar out []interface{}\n\terr := _DepositContract.contract.Call(opts, &out, \"queuedOperator\", arg0)\n\n\toutstruct := new(struct {\n\t\tQueuedTimestamp *big.Int\n\t\tNewOperator     common.Address\n\t})\n\tif err != nil {\n\t\treturn *outstruct, err\n\t}\n\n\toutstruct.QueuedTimestamp = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)\n\toutstruct.NewOperator = *abi.ConvertType(out[1], new(common.Address)).(*common.Address)\n\n\treturn *outstruct, err\n\n}\n\n// QueuedOperator is a free data retrieval call binding the contract method 0x560036ec.\n//\n// Solidity: function queuedOperator(bytes ) view returns(uint96 queuedTimestamp, address newOperator)\nfunc (_DepositContract *DepositContractSession) QueuedOperator(arg0 []byte) (struct {\n\tQueuedTimestamp *big.Int\n\tNewOperator     common.Address\n}, error) {\n\treturn _DepositContract.Contract.QueuedOperator(&_DepositContract.CallOpts, arg0)\n}\n\n// QueuedOperator is a free data retrieval call binding the contract method 0x560036ec.\n//\n// Solidity: function queuedOperator(bytes ) view returns(uint96 queuedTimestamp, address newOperator)\nfunc (_DepositContract *DepositContractCallerSession) QueuedOperator(arg0 []byte) (struct {\n\tQueuedTimestamp *big.Int\n\tNewOperator     common.Address\n}, error) {\n\treturn _DepositContract.Contract.QueuedOperator(&_DepositContract.CallOpts, arg0)\n}\n\n// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7.\n//\n// Solidity: function supportsInterface(bytes4 interfaceId) pure returns(bool)\nfunc (_DepositContract *DepositContractCaller) SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) {\n\tvar out []interface{}\n\terr := _DepositContract.contract.Call(opts, &out, \"supportsInterface\", interfaceId)\n\n\tif err != nil {\n\t\treturn *new(bool), err\n\t}\n\n\tout0 := *abi.ConvertType(out[0], new(bool)).(*bool)\n\n\treturn out0, err\n\n}\n\n// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7.\n//\n// Solidity: function supportsInterface(bytes4 interfaceId) pure returns(bool)\nfunc (_DepositContract *DepositContractSession) SupportsInterface(interfaceId [4]byte) (bool, error) {\n\treturn _DepositContract.Contract.SupportsInterface(&_DepositContract.CallOpts, interfaceId)\n}\n\n// SupportsInterface is a free data retrieval call binding the contract method 0x01ffc9a7.\n//\n// Solidity: function supportsInterface(bytes4 interfaceId) pure returns(bool)\nfunc (_DepositContract *DepositContractCallerSession) SupportsInterface(interfaceId [4]byte) (bool, error) {\n\treturn _DepositContract.Contract.SupportsInterface(&_DepositContract.CallOpts, interfaceId)\n}\n\n// AcceptOperatorChange is a paid mutator transaction binding the contract method 0xc53925d9.\n//\n// Solidity: function acceptOperatorChange(bytes pubkey) returns()\nfunc (_DepositContract *DepositContractTransactor) AcceptOperatorChange(opts *bind.TransactOpts, pubkey []byte) (*types.Transaction, error) {\n\treturn _DepositContract.contract.Transact(opts, \"acceptOperatorChange\", pubkey)\n}\n\n// AcceptOperatorChange is a paid mutator transaction binding the contract method 0xc53925d9.\n//\n// Solidity: function acceptOperatorChange(bytes pubkey) returns()\nfunc (_DepositContract *DepositContractSession) AcceptOperatorChange(pubkey []byte) (*types.Transaction, error) {\n\treturn _DepositContract.Contract.AcceptOperatorChange(&_DepositContract.TransactOpts, pubkey)\n}\n\n// AcceptOperatorChange is a paid mutator transaction binding the contract method 0xc53925d9.\n//\n// Solidity: function acceptOperatorChange(bytes pubkey) returns()\nfunc (_DepositContract *DepositContractTransactorSession) AcceptOperatorChange(pubkey []byte) (*types.Transaction, error) {\n\treturn _DepositContract.Contract.AcceptOperatorChange(&_DepositContract.TransactOpts, pubkey)\n}\n\n// CancelOperatorChange is a paid mutator transaction binding the contract method 0x577212fe.\n//\n// Solidity: function cancelOperatorChange(bytes pubkey) returns()\nfunc (_DepositContract *DepositContractTransactor) CancelOperatorChange(opts *bind.TransactOpts, pubkey []byte) (*types.Transaction, error) {\n\treturn _DepositContract.contract.Transact(opts, \"cancelOperatorChange\", pubkey)\n}\n\n// CancelOperatorChange is a paid mutator transaction binding the contract method 0x577212fe.\n//\n// Solidity: function cancelOperatorChange(bytes pubkey) returns()\nfunc (_DepositContract *DepositContractSession) CancelOperatorChange(pubkey []byte) (*types.Transaction, error) {\n\treturn _DepositContract.Contract.CancelOperatorChange(&_DepositContract.TransactOpts, pubkey)\n}\n\n// CancelOperatorChange is a paid mutator transaction binding the contract method 0x577212fe.\n//\n// Solidity: function cancelOperatorChange(bytes pubkey) returns()\nfunc (_DepositContract *DepositContractTransactorSession) CancelOperatorChange(pubkey []byte) (*types.Transaction, error) {\n\treturn _DepositContract.Contract.CancelOperatorChange(&_DepositContract.TransactOpts, pubkey)\n}\n\n// Deposit is a paid mutator transaction binding the contract method 0xe12cf4cb.\n//\n// Solidity: function deposit(bytes pubkey, bytes credentials, bytes signature, address operator) payable returns()\nfunc (_DepositContract *DepositContractTransactor) Deposit(opts *bind.TransactOpts, pubkey []byte, credentials []byte, signature []byte, operator common.Address) (*types.Transaction, error) {\n\treturn _DepositContract.contract.Transact(opts, \"deposit\", pubkey, credentials, signature, operator)\n}\n\n// Deposit is a paid mutator transaction binding the contract method 0xe12cf4cb.\n//\n// Solidity: function deposit(bytes pubkey, bytes credentials, bytes signature, address operator) payable returns()\nfunc (_DepositContract *DepositContractSession) Deposit(pubkey []byte, credentials []byte, signature []byte, operator common.Address) (*types.Transaction, error) {\n\treturn _DepositContract.Contract.Deposit(&_DepositContract.TransactOpts, pubkey, credentials, signature, operator)\n}\n\n// Deposit is a paid mutator transaction binding the contract method 0xe12cf4cb.\n//\n// Solidity: function deposit(bytes pubkey, bytes credentials, bytes signature, address operator) payable returns()\nfunc (_DepositContract *DepositContractTransactorSession) Deposit(pubkey []byte, credentials []byte, signature []byte, operator common.Address) (*types.Transaction, error) {\n\treturn _DepositContract.Contract.Deposit(&_DepositContract.TransactOpts, pubkey, credentials, signature, operator)\n}\n\n// RequestOperatorChange is a paid mutator transaction binding the contract method 0xfea7ab77.\n//\n// Solidity: function requestOperatorChange(bytes pubkey, address newOperator) returns()\nfunc (_DepositContract *DepositContractTransactor) RequestOperatorChange(opts *bind.TransactOpts, pubkey []byte, newOperator common.Address) (*types.Transaction, error) {\n\treturn _DepositContract.contract.Transact(opts, \"requestOperatorChange\", pubkey, newOperator)\n}\n\n// RequestOperatorChange is a paid mutator transaction binding the contract method 0xfea7ab77.\n//\n// Solidity: function requestOperatorChange(bytes pubkey, address newOperator) returns()\nfunc (_DepositContract *DepositContractSession) RequestOperatorChange(pubkey []byte, newOperator common.Address) (*types.Transaction, error) {\n\treturn _DepositContract.Contract.RequestOperatorChange(&_DepositContract.TransactOpts, pubkey, newOperator)\n}\n\n// RequestOperatorChange is a paid mutator transaction binding the contract method 0xfea7ab77.\n//\n// Solidity: function requestOperatorChange(bytes pubkey, address newOperator) returns()\nfunc (_DepositContract *DepositContractTransactorSession) RequestOperatorChange(pubkey []byte, newOperator common.Address) (*types.Transaction, error) {\n\treturn _DepositContract.Contract.RequestOperatorChange(&_DepositContract.TransactOpts, pubkey, newOperator)\n}\n\n// DepositContractDepositIterator is returned from FilterDeposit and is used to iterate over the raw logs and unpacked data for Deposit events raised by the DepositContract contract.\ntype DepositContractDepositIterator struct {\n\tEvent *DepositContractDeposit // Event containing the contract specifics and raw log\n\n\tcontract *bind.BoundContract // Generic contract to use for unpacking event data\n\tevent    string              // Event name to use for unpacking event data\n\n\tlogs chan types.Log        // Log channel receiving the found contract events\n\tsub  ethereum.Subscription // Subscription for errors, completion and termination\n\tdone bool                  // Whether the subscription completed delivering logs\n\tfail error                 // Occurred error to stop iteration\n}\n\n// Next advances the iterator to the subsequent event, returning whether there\n// are any more events found. In case of a retrieval or parsing error, false is\n// returned and Error() can be queried for the exact failure.\nfunc (it *DepositContractDepositIterator) Next() bool {\n\t// If the iterator failed, stop iterating\n\tif it.fail != nil {\n\t\treturn false\n\t}\n\t// If the iterator completed, deliver directly whatever's available\n\tif it.done {\n\t\tselect {\n\t\tcase log := <-it.logs:\n\t\t\tit.Event = new(DepositContractDeposit)\n\t\t\tif err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {\n\t\t\t\tit.fail = err\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tit.Event.Raw = log\n\t\t\treturn true\n\n\t\tdefault:\n\t\t\treturn false\n\t\t}\n\t}\n\t// Iterator still in progress, wait for either a data or an error event\n\tselect {\n\tcase log := <-it.logs:\n\t\tit.Event = new(DepositContractDeposit)\n\t\tif err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {\n\t\t\tit.fail = err\n\t\t\treturn false\n\t\t}\n\t\tit.Event.Raw = log\n\t\treturn true\n\n\tcase err := <-it.sub.Err():\n\t\tit.done = true\n\t\tit.fail = err\n\t\treturn it.Next()\n\t}\n}\n\n// Error returns any retrieval or parsing error occurred during filtering.\nfunc (it *DepositContractDepositIterator) Error() error {\n\treturn it.fail\n}\n\n// Close terminates the iteration process, releasing any pending underlying\n// resources.\nfunc (it *DepositContractDepositIterator) Close() error {\n\tit.sub.Unsubscribe()\n\treturn nil\n}\n\n// DepositContractDeposit represents a Deposit event raised by the DepositContract contract.\ntype DepositContractDeposit struct {\n\tPubkey      []byte\n\tCredentials []byte\n\tAmount      uint64\n\tSignature   []byte\n\tIndex       uint64\n\tRaw         types.Log // Blockchain specific contextual infos\n}\n\n// FilterDeposit is a free log retrieval operation binding the contract event 0x68af751683498a9f9be59fe8b0d52a64dd155255d85cdb29fea30b1e3f891d46.\n//\n// Solidity: event Deposit(bytes pubkey, bytes credentials, uint64 amount, bytes signature, uint64 index)\nfunc (_DepositContract *DepositContractFilterer) FilterDeposit(opts *bind.FilterOpts) (*DepositContractDepositIterator, error) {\n\n\tlogs, sub, err := _DepositContract.contract.FilterLogs(opts, \"Deposit\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &DepositContractDepositIterator{contract: _DepositContract.contract, event: \"Deposit\", logs: logs, sub: sub}, nil\n}\n\n// WatchDeposit is a free log subscription operation binding the contract event 0x68af751683498a9f9be59fe8b0d52a64dd155255d85cdb29fea30b1e3f891d46.\n//\n// Solidity: event Deposit(bytes pubkey, bytes credentials, uint64 amount, bytes signature, uint64 index)\nfunc (_DepositContract *DepositContractFilterer) WatchDeposit(opts *bind.WatchOpts, sink chan<- *DepositContractDeposit) (event.Subscription, error) {\n\n\tlogs, sub, err := _DepositContract.contract.WatchLogs(opts, \"Deposit\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn event.NewSubscription(func(quit <-chan struct{}) error {\n\t\tdefer sub.Unsubscribe()\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase log := <-logs:\n\t\t\t\t// New log arrived, parse the event and forward to the user\n\t\t\t\tevent := new(DepositContractDeposit)\n\t\t\t\tif err := _DepositContract.contract.UnpackLog(event, \"Deposit\", log); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tevent.Raw = log\n\n\t\t\t\tselect {\n\t\t\t\tcase sink <- event:\n\t\t\t\tcase err := <-sub.Err():\n\t\t\t\t\treturn err\n\t\t\t\tcase <-quit:\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\tcase err := <-sub.Err():\n\t\t\t\treturn err\n\t\t\tcase <-quit:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}), nil\n}\n\n// ParseDeposit is a log parse operation binding the contract event 0x68af751683498a9f9be59fe8b0d52a64dd155255d85cdb29fea30b1e3f891d46.\n//\n// Solidity: event Deposit(bytes pubkey, bytes credentials, uint64 amount, bytes signature, uint64 index)\nfunc (_DepositContract *DepositContractFilterer) ParseDeposit(log types.Log) (*DepositContractDeposit, error) {\n\tevent := new(DepositContractDeposit)\n\tif err := _DepositContract.contract.UnpackLog(event, \"Deposit\", log); err != nil {\n\t\treturn nil, err\n\t}\n\tevent.Raw = log\n\treturn event, nil\n}\n\n// DepositContractOperatorChangeCancelledIterator is returned from FilterOperatorChangeCancelled and is used to iterate over the raw logs and unpacked data for OperatorChangeCancelled events raised by the DepositContract contract.\ntype DepositContractOperatorChangeCancelledIterator struct {\n\tEvent *DepositContractOperatorChangeCancelled // Event containing the contract specifics and raw log\n\n\tcontract *bind.BoundContract // Generic contract to use for unpacking event data\n\tevent    string              // Event name to use for unpacking event data\n\n\tlogs chan types.Log        // Log channel receiving the found contract events\n\tsub  ethereum.Subscription // Subscription for errors, completion and termination\n\tdone bool                  // Whether the subscription completed delivering logs\n\tfail error                 // Occurred error to stop iteration\n}\n\n// Next advances the iterator to the subsequent event, returning whether there\n// are any more events found. In case of a retrieval or parsing error, false is\n// returned and Error() can be queried for the exact failure.\nfunc (it *DepositContractOperatorChangeCancelledIterator) Next() bool {\n\t// If the iterator failed, stop iterating\n\tif it.fail != nil {\n\t\treturn false\n\t}\n\t// If the iterator completed, deliver directly whatever's available\n\tif it.done {\n\t\tselect {\n\t\tcase log := <-it.logs:\n\t\t\tit.Event = new(DepositContractOperatorChangeCancelled)\n\t\t\tif err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {\n\t\t\t\tit.fail = err\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tit.Event.Raw = log\n\t\t\treturn true\n\n\t\tdefault:\n\t\t\treturn false\n\t\t}\n\t}\n\t// Iterator still in progress, wait for either a data or an error event\n\tselect {\n\tcase log := <-it.logs:\n\t\tit.Event = new(DepositContractOperatorChangeCancelled)\n\t\tif err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {\n\t\t\tit.fail = err\n\t\t\treturn false\n\t\t}\n\t\tit.Event.Raw = log\n\t\treturn true\n\n\tcase err := <-it.sub.Err():\n\t\tit.done = true\n\t\tit.fail = err\n\t\treturn it.Next()\n\t}\n}\n\n// Error returns any retrieval or parsing error occurred during filtering.\nfunc (it *DepositContractOperatorChangeCancelledIterator) Error() error {\n\treturn it.fail\n}\n\n// Close terminates the iteration process, releasing any pending underlying\n// resources.\nfunc (it *DepositContractOperatorChangeCancelledIterator) Close() error {\n\tit.sub.Unsubscribe()\n\treturn nil\n}\n\n// DepositContractOperatorChangeCancelled represents a OperatorChangeCancelled event raised by the DepositContract contract.\ntype DepositContractOperatorChangeCancelled struct {\n\tPubkey common.Hash\n\tRaw    types.Log // Blockchain specific contextual infos\n}\n\n// FilterOperatorChangeCancelled is a free log retrieval operation binding the contract event 0x1c0a7e1bd09da292425c039309671a03de56b89a0858598aab6df6ce84b006db.\n//\n// Solidity: event OperatorChangeCancelled(bytes indexed pubkey)\nfunc (_DepositContract *DepositContractFilterer) FilterOperatorChangeCancelled(opts *bind.FilterOpts, pubkey [][]byte) (*DepositContractOperatorChangeCancelledIterator, error) {\n\n\tvar pubkeyRule []interface{}\n\tfor _, pubkeyItem := range pubkey {\n\t\tpubkeyRule = append(pubkeyRule, pubkeyItem)\n\t}\n\n\tlogs, sub, err := _DepositContract.contract.FilterLogs(opts, \"OperatorChangeCancelled\", pubkeyRule)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &DepositContractOperatorChangeCancelledIterator{contract: _DepositContract.contract, event: \"OperatorChangeCancelled\", logs: logs, sub: sub}, nil\n}\n\n// WatchOperatorChangeCancelled is a free log subscription operation binding the contract event 0x1c0a7e1bd09da292425c039309671a03de56b89a0858598aab6df6ce84b006db.\n//\n// Solidity: event OperatorChangeCancelled(bytes indexed pubkey)\nfunc (_DepositContract *DepositContractFilterer) WatchOperatorChangeCancelled(opts *bind.WatchOpts, sink chan<- *DepositContractOperatorChangeCancelled, pubkey [][]byte) (event.Subscription, error) {\n\n\tvar pubkeyRule []interface{}\n\tfor _, pubkeyItem := range pubkey {\n\t\tpubkeyRule = append(pubkeyRule, pubkeyItem)\n\t}\n\n\tlogs, sub, err := _DepositContract.contract.WatchLogs(opts, \"OperatorChangeCancelled\", pubkeyRule)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn event.NewSubscription(func(quit <-chan struct{}) error {\n\t\tdefer sub.Unsubscribe()\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase log := <-logs:\n\t\t\t\t// New log arrived, parse the event and forward to the user\n\t\t\t\tevent := new(DepositContractOperatorChangeCancelled)\n\t\t\t\tif err := _DepositContract.contract.UnpackLog(event, \"OperatorChangeCancelled\", log); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tevent.Raw = log\n\n\t\t\t\tselect {\n\t\t\t\tcase sink <- event:\n\t\t\t\tcase err := <-sub.Err():\n\t\t\t\t\treturn err\n\t\t\t\tcase <-quit:\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\tcase err := <-sub.Err():\n\t\t\t\treturn err\n\t\t\tcase <-quit:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}), nil\n}\n\n// ParseOperatorChangeCancelled is a log parse operation binding the contract event 0x1c0a7e1bd09da292425c039309671a03de56b89a0858598aab6df6ce84b006db.\n//\n// Solidity: event OperatorChangeCancelled(bytes indexed pubkey)\nfunc (_DepositContract *DepositContractFilterer) ParseOperatorChangeCancelled(log types.Log) (*DepositContractOperatorChangeCancelled, error) {\n\tevent := new(DepositContractOperatorChangeCancelled)\n\tif err := _DepositContract.contract.UnpackLog(event, \"OperatorChangeCancelled\", log); err != nil {\n\t\treturn nil, err\n\t}\n\tevent.Raw = log\n\treturn event, nil\n}\n\n// DepositContractOperatorChangeQueuedIterator is returned from FilterOperatorChangeQueued and is used to iterate over the raw logs and unpacked data for OperatorChangeQueued events raised by the DepositContract contract.\ntype DepositContractOperatorChangeQueuedIterator struct {\n\tEvent *DepositContractOperatorChangeQueued // Event containing the contract specifics and raw log\n\n\tcontract *bind.BoundContract // Generic contract to use for unpacking event data\n\tevent    string              // Event name to use for unpacking event data\n\n\tlogs chan types.Log        // Log channel receiving the found contract events\n\tsub  ethereum.Subscription // Subscription for errors, completion and termination\n\tdone bool                  // Whether the subscription completed delivering logs\n\tfail error                 // Occurred error to stop iteration\n}\n\n// Next advances the iterator to the subsequent event, returning whether there\n// are any more events found. In case of a retrieval or parsing error, false is\n// returned and Error() can be queried for the exact failure.\nfunc (it *DepositContractOperatorChangeQueuedIterator) Next() bool {\n\t// If the iterator failed, stop iterating\n\tif it.fail != nil {\n\t\treturn false\n\t}\n\t// If the iterator completed, deliver directly whatever's available\n\tif it.done {\n\t\tselect {\n\t\tcase log := <-it.logs:\n\t\t\tit.Event = new(DepositContractOperatorChangeQueued)\n\t\t\tif err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {\n\t\t\t\tit.fail = err\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tit.Event.Raw = log\n\t\t\treturn true\n\n\t\tdefault:\n\t\t\treturn false\n\t\t}\n\t}\n\t// Iterator still in progress, wait for either a data or an error event\n\tselect {\n\tcase log := <-it.logs:\n\t\tit.Event = new(DepositContractOperatorChangeQueued)\n\t\tif err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {\n\t\t\tit.fail = err\n\t\t\treturn false\n\t\t}\n\t\tit.Event.Raw = log\n\t\treturn true\n\n\tcase err := <-it.sub.Err():\n\t\tit.done = true\n\t\tit.fail = err\n\t\treturn it.Next()\n\t}\n}\n\n// Error returns any retrieval or parsing error occurred during filtering.\nfunc (it *DepositContractOperatorChangeQueuedIterator) Error() error {\n\treturn it.fail\n}\n\n// Close terminates the iteration process, releasing any pending underlying\n// resources.\nfunc (it *DepositContractOperatorChangeQueuedIterator) Close() error {\n\tit.sub.Unsubscribe()\n\treturn nil\n}\n\n// DepositContractOperatorChangeQueued represents a OperatorChangeQueued event raised by the DepositContract contract.\ntype DepositContractOperatorChangeQueued struct {\n\tPubkey          common.Hash\n\tQueuedOperator  common.Address\n\tCurrentOperator common.Address\n\tQueuedTimestamp *big.Int\n\tRaw             types.Log // Blockchain specific contextual infos\n}\n\n// FilterOperatorChangeQueued is a free log retrieval operation binding the contract event 0x7640ec3c8c4695deadda414dd20400acf275297a7c38715f9237657e97ddba5f.\n//\n// Solidity: event OperatorChangeQueued(bytes indexed pubkey, address queuedOperator, address currentOperator, uint256 queuedTimestamp)\nfunc (_DepositContract *DepositContractFilterer) FilterOperatorChangeQueued(opts *bind.FilterOpts, pubkey [][]byte) (*DepositContractOperatorChangeQueuedIterator, error) {\n\n\tvar pubkeyRule []interface{}\n\tfor _, pubkeyItem := range pubkey {\n\t\tpubkeyRule = append(pubkeyRule, pubkeyItem)\n\t}\n\n\tlogs, sub, err := _DepositContract.contract.FilterLogs(opts, \"OperatorChangeQueued\", pubkeyRule)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &DepositContractOperatorChangeQueuedIterator{contract: _DepositContract.contract, event: \"OperatorChangeQueued\", logs: logs, sub: sub}, nil\n}\n\n// WatchOperatorChangeQueued is a free log subscription operation binding the contract event 0x7640ec3c8c4695deadda414dd20400acf275297a7c38715f9237657e97ddba5f.\n//\n// Solidity: event OperatorChangeQueued(bytes indexed pubkey, address queuedOperator, address currentOperator, uint256 queuedTimestamp)\nfunc (_DepositContract *DepositContractFilterer) WatchOperatorChangeQueued(opts *bind.WatchOpts, sink chan<- *DepositContractOperatorChangeQueued, pubkey [][]byte) (event.Subscription, error) {\n\n\tvar pubkeyRule []interface{}\n\tfor _, pubkeyItem := range pubkey {\n\t\tpubkeyRule = append(pubkeyRule, pubkeyItem)\n\t}\n\n\tlogs, sub, err := _DepositContract.contract.WatchLogs(opts, \"OperatorChangeQueued\", pubkeyRule)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn event.NewSubscription(func(quit <-chan struct{}) error {\n\t\tdefer sub.Unsubscribe()\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase log := <-logs:\n\t\t\t\t// New log arrived, parse the event and forward to the user\n\t\t\t\tevent := new(DepositContractOperatorChangeQueued)\n\t\t\t\tif err := _DepositContract.contract.UnpackLog(event, \"OperatorChangeQueued\", log); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tevent.Raw = log\n\n\t\t\t\tselect {\n\t\t\t\tcase sink <- event:\n\t\t\t\tcase err := <-sub.Err():\n\t\t\t\t\treturn err\n\t\t\t\tcase <-quit:\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\tcase err := <-sub.Err():\n\t\t\t\treturn err\n\t\t\tcase <-quit:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}), nil\n}\n\n// ParseOperatorChangeQueued is a log parse operation binding the contract event 0x7640ec3c8c4695deadda414dd20400acf275297a7c38715f9237657e97ddba5f.\n//\n// Solidity: event OperatorChangeQueued(bytes indexed pubkey, address queuedOperator, address currentOperator, uint256 queuedTimestamp)\nfunc (_DepositContract *DepositContractFilterer) ParseOperatorChangeQueued(log types.Log) (*DepositContractOperatorChangeQueued, error) {\n\tevent := new(DepositContractOperatorChangeQueued)\n\tif err := _DepositContract.contract.UnpackLog(event, \"OperatorChangeQueued\", log); err != nil {\n\t\treturn nil, err\n\t}\n\tevent.Raw = log\n\treturn event, nil\n}\n\n// DepositContractOperatorUpdatedIterator is returned from FilterOperatorUpdated and is used to iterate over the raw logs and unpacked data for OperatorUpdated events raised by the DepositContract contract.\ntype DepositContractOperatorUpdatedIterator struct {\n\tEvent *DepositContractOperatorUpdated // Event containing the contract specifics and raw log\n\n\tcontract *bind.BoundContract // Generic contract to use for unpacking event data\n\tevent    string              // Event name to use for unpacking event data\n\n\tlogs chan types.Log        // Log channel receiving the found contract events\n\tsub  ethereum.Subscription // Subscription for errors, completion and termination\n\tdone bool                  // Whether the subscription completed delivering logs\n\tfail error                 // Occurred error to stop iteration\n}\n\n// Next advances the iterator to the subsequent event, returning whether there\n// are any more events found. In case of a retrieval or parsing error, false is\n// returned and Error() can be queried for the exact failure.\nfunc (it *DepositContractOperatorUpdatedIterator) Next() bool {\n\t// If the iterator failed, stop iterating\n\tif it.fail != nil {\n\t\treturn false\n\t}\n\t// If the iterator completed, deliver directly whatever's available\n\tif it.done {\n\t\tselect {\n\t\tcase log := <-it.logs:\n\t\t\tit.Event = new(DepositContractOperatorUpdated)\n\t\t\tif err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {\n\t\t\t\tit.fail = err\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tit.Event.Raw = log\n\t\t\treturn true\n\n\t\tdefault:\n\t\t\treturn false\n\t\t}\n\t}\n\t// Iterator still in progress, wait for either a data or an error event\n\tselect {\n\tcase log := <-it.logs:\n\t\tit.Event = new(DepositContractOperatorUpdated)\n\t\tif err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {\n\t\t\tit.fail = err\n\t\t\treturn false\n\t\t}\n\t\tit.Event.Raw = log\n\t\treturn true\n\n\tcase err := <-it.sub.Err():\n\t\tit.done = true\n\t\tit.fail = err\n\t\treturn it.Next()\n\t}\n}\n\n// Error returns any retrieval or parsing error occurred during filtering.\nfunc (it *DepositContractOperatorUpdatedIterator) Error() error {\n\treturn it.fail\n}\n\n// Close terminates the iteration process, releasing any pending underlying\n// resources.\nfunc (it *DepositContractOperatorUpdatedIterator) Close() error {\n\tit.sub.Unsubscribe()\n\treturn nil\n}\n\n// DepositContractOperatorUpdated represents a OperatorUpdated event raised by the DepositContract contract.\ntype DepositContractOperatorUpdated struct {\n\tPubkey           common.Hash\n\tNewOperator      common.Address\n\tPreviousOperator common.Address\n\tRaw              types.Log // Blockchain specific contextual infos\n}\n\n// FilterOperatorUpdated is a free log retrieval operation binding the contract event 0x0adffd98d3072c48341843974dffd7a910bb849ba6ca04163d43bb26feb17403.\n//\n// Solidity: event OperatorUpdated(bytes indexed pubkey, address newOperator, address previousOperator)\nfunc (_DepositContract *DepositContractFilterer) FilterOperatorUpdated(opts *bind.FilterOpts, pubkey [][]byte) (*DepositContractOperatorUpdatedIterator, error) {\n\n\tvar pubkeyRule []interface{}\n\tfor _, pubkeyItem := range pubkey {\n\t\tpubkeyRule = append(pubkeyRule, pubkeyItem)\n\t}\n\n\tlogs, sub, err := _DepositContract.contract.FilterLogs(opts, \"OperatorUpdated\", pubkeyRule)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &DepositContractOperatorUpdatedIterator{contract: _DepositContract.contract, event: \"OperatorUpdated\", logs: logs, sub: sub}, nil\n}\n\n// WatchOperatorUpdated is a free log subscription operation binding the contract event 0x0adffd98d3072c48341843974dffd7a910bb849ba6ca04163d43bb26feb17403.\n//\n// Solidity: event OperatorUpdated(bytes indexed pubkey, address newOperator, address previousOperator)\nfunc (_DepositContract *DepositContractFilterer) WatchOperatorUpdated(opts *bind.WatchOpts, sink chan<- *DepositContractOperatorUpdated, pubkey [][]byte) (event.Subscription, error) {\n\n\tvar pubkeyRule []interface{}\n\tfor _, pubkeyItem := range pubkey {\n\t\tpubkeyRule = append(pubkeyRule, pubkeyItem)\n\t}\n\n\tlogs, sub, err := _DepositContract.contract.WatchLogs(opts, \"OperatorUpdated\", pubkeyRule)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn event.NewSubscription(func(quit <-chan struct{}) error {\n\t\tdefer sub.Unsubscribe()\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase log := <-logs:\n\t\t\t\t// New log arrived, parse the event and forward to the user\n\t\t\t\tevent := new(DepositContractOperatorUpdated)\n\t\t\t\tif err := _DepositContract.contract.UnpackLog(event, \"OperatorUpdated\", log); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tevent.Raw = log\n\n\t\t\t\tselect {\n\t\t\t\tcase sink <- event:\n\t\t\t\tcase err := <-sub.Err():\n\t\t\t\t\treturn err\n\t\t\t\tcase <-quit:\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\tcase err := <-sub.Err():\n\t\t\t\treturn err\n\t\t\tcase <-quit:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}), nil\n}\n\n// ParseOperatorUpdated is a log parse operation binding the contract event 0x0adffd98d3072c48341843974dffd7a910bb849ba6ca04163d43bb26feb17403.\n//\n// Solidity: event OperatorUpdated(bytes indexed pubkey, address newOperator, address previousOperator)\nfunc (_DepositContract *DepositContractFilterer) ParseOperatorUpdated(log types.Log) (*DepositContractOperatorUpdated, error) {\n\tevent := new(DepositContractOperatorUpdated)\n\tif err := _DepositContract.contract.UnpackLog(event, \"OperatorUpdated\", log); err != nil {\n\t\treturn nil, err\n\t}\n\tevent.Raw = log\n\treturn event, nil\n}\n"
  },
  {
    "path": "gethlib/deposit/contract.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage deposit\n\n// TODO: Remove ldflags=-checklinkname=0 override once fix is applied.\n//\n//go:generate abigen --abi=../../contracts/out/DepositContract.sol/DepositContract.abi.json --bin=../../contracts/out/DepositContract.sol/DepositContract.bin --pkg=deposit --type=DepositContract --out=contract.abigen.go\n"
  },
  {
    "path": "gethlib/ethclient/ethclient.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage ethclient\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math/big\"\n\n\t\"github.com/berachain/beacon-kit/gethlib/types\"\n\t\"github.com/ethereum/go-ethereum\"\n\tgethcommon \"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-ethereum/common/hexutil\"\n\tcoretypes \"github.com/ethereum/go-ethereum/core/types\"\n\tgethclient \"github.com/ethereum/go-ethereum/ethclient\"\n\t\"github.com/ethereum/go-ethereum/rpc\"\n)\n\n// Client is a wrapper around go-ethereum's ethclient which handles unmarhsalling\n// Berachain blocks and transactions.\ntype Client struct {\n\t*gethclient.Client\n}\n\n// Wrap wraps a go-ethereum's ethclient and returns a Berachain-specific ethclient.\nfunc Wrap(c *gethclient.Client) *Client {\n\treturn &Client{c}\n}\n\n// BlockByNumber overrides the original method to unmarshal the block.\nfunc (c *Client) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {\n\treturn c.getBlock(ctx, \"eth_getBlockByNumber\", toBlockNumArg(number), true)\n}\n\n// BlockByHash overrides the original method to unmarshal the block.\nfunc (c *Client) BlockByHash(ctx context.Context, hash gethcommon.Hash) (*types.Block, error) {\n\treturn c.getBlock(ctx, \"eth_getBlockByHash\", hash, true)\n}\n\n// TransactionByHash overrides the original method to unmarshal the transaction.\nfunc (c *Client) TransactionByHash(\n\tctx context.Context, hash gethcommon.Hash,\n) (*types.Transaction, bool, error) {\n\tvar jsonTx *rpcTransaction\n\terr := c.Client.Client().CallContext(ctx, &jsonTx, \"eth_getTransactionByHash\", hash)\n\tif err != nil {\n\t\treturn nil, false, err\n\t}\n\tif jsonTx == nil {\n\t\treturn nil, false, ethereum.NotFound\n\t}\n\tsigErr := ensureTransactionHasRequiredSignature(jsonTx.tx)\n\tif sigErr != nil {\n\t\treturn nil, false, sigErr\n\t}\n\treturn jsonTx.tx, jsonTx.BlockNumber == nil, nil\n}\n\n// TransactionInBlock overrides the original method to unmarshal the transaction.\nfunc (c *Client) TransactionInBlock(ctx context.Context, blockHash gethcommon.Hash, index uint) (*types.Transaction, error) {\n\tvar jsonTx *rpcTransaction\n\terr := c.Client.Client().CallContext(ctx, &jsonTx, \"eth_getTransactionByBlockHashAndIndex\", blockHash, hexutil.Uint64(index))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif jsonTx == nil {\n\t\treturn nil, ethereum.NotFound\n\t}\n\tsigErr := ensureTransactionHasRequiredSignature(jsonTx.tx)\n\tif sigErr != nil {\n\t\treturn nil, sigErr\n\t}\n\treturn jsonTx.tx, nil\n}\n\ntype rpcBlock struct {\n\tHash         *gethcommon.Hash        `json:\"hash\"`\n\tTransactions []rpcTransaction        `json:\"transactions\"`\n\tUncleHashes  []gethcommon.Hash       `json:\"uncles\"`\n\tWithdrawals  []*coretypes.Withdrawal `json:\"withdrawals,omitempty\"`\n}\n\ntype rpcTransaction struct {\n\ttx *types.Transaction\n\ttxExtraInfo\n}\n\ntype txExtraInfo struct {\n\tBlockNumber *string             `json:\"blockNumber,omitempty\"`\n\tBlockHash   *gethcommon.Hash    `json:\"blockHash,omitempty\"`\n\tFrom        *gethcommon.Address `json:\"from,omitempty\"`\n}\n\nfunc (tx *rpcTransaction) UnmarshalJSON(msg []byte) error {\n\tif err := json.Unmarshal(msg, &tx.tx); err != nil {\n\t\treturn err\n\t}\n\treturn json.Unmarshal(msg, &tx.txExtraInfo)\n}\n\ntype rpcHeader struct {\n\tParentHash           *gethcommon.Hash       `json:\"parentHash\"`\n\tUncleHash            *gethcommon.Hash       `json:\"sha3Uncles\"`\n\tCoinbase             *gethcommon.Address    `json:\"miner\"`\n\tRoot                 *gethcommon.Hash       `json:\"stateRoot\"`\n\tTxHash               *gethcommon.Hash       `json:\"transactionsRoot\"`\n\tReceiptHash          *gethcommon.Hash       `json:\"receiptsRoot\"`\n\tBloom                *coretypes.Bloom       `json:\"logsBloom\"`\n\tDifficulty           *hexutil.Big           `json:\"difficulty\"`\n\tNumber               *hexutil.Big           `json:\"number\"`\n\tGasLimit             *hexutil.Uint64        `json:\"gasLimit\"`\n\tGasUsed              *hexutil.Uint64        `json:\"gasUsed\"`\n\tTime                 *hexutil.Uint64        `json:\"timestamp\"`\n\tExtra                *hexutil.Bytes         `json:\"extraData\"`\n\tMixDigest            *gethcommon.Hash       `json:\"mixHash\"`\n\tNonce                *coretypes.BlockNonce  `json:\"nonce\"`\n\tBaseFee              *hexutil.Big           `json:\"baseFeePerGas,omitempty\"`\n\tWithdrawalsHash      *gethcommon.Hash       `json:\"withdrawalsRoot,omitempty\"`\n\tBlobGasUsed          *hexutil.Uint64        `json:\"blobGasUsed,omitempty\"`\n\tExcessBlobGas        *hexutil.Uint64        `json:\"excessBlobGas,omitempty\"`\n\tParentBeaconRoot     *gethcommon.Hash       `json:\"parentBeaconBlockRoot,omitempty\"`\n\tRequestsHash         *gethcommon.Hash       `json:\"requestsHash,omitempty\"`\n\tParentProposerPubkey *types.ExecutionPubkey `json:\"parentProposerPubkey,omitempty\"`\n}\n\n//nolint:gocognit,funlen // Validation mirrors strict geth header decoding requirements.\nfunc (h *rpcHeader) toHeader() (*types.Header, error) {\n\tif h == nil {\n\t\treturn nil, errors.New(\"missing header payload\")\n\t}\n\tif h.ParentHash == nil {\n\t\treturn nil, errors.New(\"missing required field 'parentHash' for Header\")\n\t}\n\tif h.UncleHash == nil {\n\t\treturn nil, errors.New(\"missing required field 'sha3Uncles' for Header\")\n\t}\n\tif h.Root == nil {\n\t\treturn nil, errors.New(\"missing required field 'stateRoot' for Header\")\n\t}\n\tif h.TxHash == nil {\n\t\treturn nil, errors.New(\"missing required field 'transactionsRoot' for Header\")\n\t}\n\tif h.ReceiptHash == nil {\n\t\treturn nil, errors.New(\"missing required field 'receiptsRoot' for Header\")\n\t}\n\tif h.Bloom == nil {\n\t\treturn nil, errors.New(\"missing required field 'logsBloom' for Header\")\n\t}\n\tif h.Difficulty == nil {\n\t\treturn nil, errors.New(\"missing required field 'difficulty' for Header\")\n\t}\n\tif h.Number == nil {\n\t\treturn nil, errors.New(\"missing required field 'number' for Header\")\n\t}\n\tif h.GasLimit == nil {\n\t\treturn nil, errors.New(\"missing required field 'gasLimit' for Header\")\n\t}\n\tif h.GasUsed == nil {\n\t\treturn nil, errors.New(\"missing required field 'gasUsed' for Header\")\n\t}\n\tif h.Time == nil {\n\t\treturn nil, errors.New(\"missing required field 'timestamp' for Header\")\n\t}\n\tif h.Extra == nil {\n\t\treturn nil, errors.New(\"missing required field 'extraData' for Header\")\n\t}\n\n\thead := &types.Header{\n\t\tParentHash:  *h.ParentHash,\n\t\tUncleHash:   *h.UncleHash,\n\t\tRoot:        *h.Root,\n\t\tTxHash:      *h.TxHash,\n\t\tReceiptHash: *h.ReceiptHash,\n\t\tBloom:       *h.Bloom,\n\t\tDifficulty:  (*big.Int)(h.Difficulty),\n\t\tNumber:      (*big.Int)(h.Number),\n\t\tGasLimit:    uint64(*h.GasLimit),\n\t\tGasUsed:     uint64(*h.GasUsed),\n\t\tTime:        uint64(*h.Time),\n\t\tExtra:       *h.Extra,\n\t}\n\tif h.Coinbase != nil {\n\t\thead.Coinbase = *h.Coinbase\n\t}\n\tif h.MixDigest != nil {\n\t\thead.MixDigest = *h.MixDigest\n\t}\n\tif h.Nonce != nil {\n\t\thead.Nonce = *h.Nonce\n\t}\n\tif h.BaseFee != nil {\n\t\thead.BaseFee = (*big.Int)(h.BaseFee)\n\t}\n\tif h.WithdrawalsHash != nil {\n\t\thash := *h.WithdrawalsHash\n\t\thead.WithdrawalsHash = &hash\n\t}\n\tif h.BlobGasUsed != nil {\n\t\tblobGasUsed := uint64(*h.BlobGasUsed)\n\t\thead.BlobGasUsed = &blobGasUsed\n\t}\n\tif h.ExcessBlobGas != nil {\n\t\texcessBlobGas := uint64(*h.ExcessBlobGas)\n\t\thead.ExcessBlobGas = &excessBlobGas\n\t}\n\tif h.ParentBeaconRoot != nil {\n\t\troot := *h.ParentBeaconRoot\n\t\thead.ParentBeaconRoot = &root\n\t}\n\tif h.RequestsHash != nil {\n\t\thash := *h.RequestsHash\n\t\thead.RequestsHash = &hash\n\t}\n\tif h.ParentProposerPubkey != nil {\n\t\tpubkey := *h.ParentProposerPubkey\n\t\thead.ParentProposerPubkey = &pubkey\n\t}\n\treturn head, nil\n}\n\nfunc (c *Client) getBlock(ctx context.Context, method string, args ...interface{}) (*types.Block, error) {\n\tvar raw json.RawMessage\n\tif err := c.Client.Client().CallContext(ctx, &raw, method, args...); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Decode header and transactions.\n\tvar rawHead *rpcHeader\n\tif err := json.Unmarshal(raw, &rawHead); err != nil {\n\t\treturn nil, err\n\t}\n\t// When the block is not found, the API returns JSON null.\n\tif rawHead == nil {\n\t\treturn nil, ethereum.NotFound\n\t}\n\thead, err := rawHead.toHeader()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar body rpcBlock\n\terr = json.Unmarshal(raw, &body)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// Pending blocks don't return a block hash. Compute it for consistency.\n\tif body.Hash == nil {\n\t\ttmp := head.Hash()\n\t\tbody.Hash = &tmp\n\t}\n\n\t// Quick-verify transaction and uncle lists.\n\tif head.UncleHash != coretypes.EmptyUncleHash || len(body.UncleHashes) > 0 {\n\t\treturn nil, errors.New(\"server returned non-empty uncle list, unsupported by Berachain\")\n\t}\n\tif head.TxHash == coretypes.EmptyTxsHash && len(body.Transactions) > 0 {\n\t\treturn nil, errors.New(\"server returned non-empty transaction list but block header indicates no transactions\")\n\t}\n\tif head.TxHash != coretypes.EmptyTxsHash && len(body.Transactions) == 0 {\n\t\treturn nil, errors.New(\"server returned empty transaction list but block header indicates transactions\")\n\t}\n\n\t// Fill transaction list.\n\ttxs := make([]*types.Transaction, len(body.Transactions))\n\tfor i, tx := range body.Transactions {\n\t\tsigErr := ensureTransactionHasRequiredSignature(tx.tx)\n\t\tif sigErr != nil {\n\t\t\treturn nil, sigErr\n\t\t}\n\t\ttxs[i] = tx.tx\n\t}\n\n\treturn types.NewBlockWithHeader(head).WithBody(\n\t\ttypes.Body{\n\t\t\tTransactions: txs,\n\t\t\tUncles:       nil, // Berachain doesn't support uncles.\n\t\t\tWithdrawals:  body.Withdrawals,\n\t\t}), nil\n}\n\nfunc ensureTransactionHasRequiredSignature(tx *types.Transaction) error {\n\tif tx == nil {\n\t\treturn errors.New(\"server returned null transaction\")\n\t}\n\tif tx.Type() == types.PoLTxType {\n\t\treturn nil\n\t}\n\t_, r, _ := tx.RawSignatureValues()\n\tif r == nil {\n\t\treturn errors.New(\"server returned transaction without signature\")\n\t}\n\treturn nil\n}\n\nfunc toBlockNumArg(number *big.Int) string {\n\tif number == nil {\n\t\treturn \"latest\"\n\t}\n\tif number.Sign() >= 0 {\n\t\treturn hexutil.EncodeBig(number)\n\t}\n\t// It's negative.\n\tif number.IsInt64() {\n\t\treturn rpc.BlockNumber(number.Int64()).String()\n\t}\n\t// It's negative and large, which is invalid.\n\treturn fmt.Sprintf(\"<invalid %d>\", number)\n}\n"
  },
  {
    "path": "gethlib/ethclient/ethclient_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage ethclient_test\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"math/big\"\n\t\"strings\"\n\t\"testing\"\n\n\tberaclient \"github.com/berachain/beacon-kit/gethlib/ethclient\"\n\t\"github.com/berachain/beacon-kit/gethlib/types\"\n\tgethcommon \"github.com/ethereum/go-ethereum/common\"\n\tcoretypes \"github.com/ethereum/go-ethereum/core/types\"\n\tgethclient \"github.com/ethereum/go-ethereum/ethclient\"\n\t\"github.com/ethereum/go-ethereum/rpc\"\n)\n\nvar (\n\ttestBlockHash    = gethcommon.HexToHash(\"0x1111111111111111111111111111111111111111111111111111111111111111\")\n\ttestParentHash   = gethcommon.HexToHash(\"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\")\n\ttestStateRoot    = gethcommon.HexToHash(\"0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\")\n\ttestReceiptsRoot = gethcommon.HexToHash(\"0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\")\n\ttestTxRoot       = gethcommon.HexToHash(\"0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\")\n\ttestTxHash       = gethcommon.HexToHash(\"0x2222222222222222222222222222222222222222222222222222222222222222\")\n\ttestFrom         = gethcommon.HexToAddress(\"0x1000000000000000000000000000000000000001\")\n\ttestTo           = gethcommon.HexToAddress(\"0x2000000000000000000000000000000000000002\")\n)\n\nfunc TestBlockByNumberWithPoLTransaction(t *testing.T) {\n\tt.Parallel()\n\n\tclient := newMockClient(t)\n\n\tblock, err := client.BlockByNumber(t.Context(), big.NewInt(2))\n\tif err != nil {\n\t\tt.Fatalf(\"BlockByNumber returned error: %v\", err)\n\t}\n\tif block == nil {\n\t\tt.Fatal(\"BlockByNumber returned nil block\")\n\t}\n\tif got := len(block.Transactions()); got != 1 {\n\t\tt.Fatalf(\"unexpected tx count: got %d want %d\", got, 1)\n\t}\n\tif txType := block.Transactions()[0].Type(); txType != types.PoLTxType {\n\t\tt.Fatalf(\"unexpected tx type: got 0x%x want 0x%x\", txType, types.PoLTxType)\n\t}\n}\n\nfunc TestBlockByHashWithPoLTransaction(t *testing.T) {\n\tt.Parallel()\n\n\tclient := newMockClient(t)\n\n\tblock, err := client.BlockByHash(t.Context(), testBlockHash)\n\tif err != nil {\n\t\tt.Fatalf(\"BlockByHash returned error: %v\", err)\n\t}\n\tif block == nil {\n\t\tt.Fatal(\"BlockByHash returned nil block\")\n\t}\n\tif got := len(block.Transactions()); got != 1 {\n\t\tt.Fatalf(\"unexpected tx count: got %d want %d\", got, 1)\n\t}\n\tif txType := block.Transactions()[0].Type(); txType != types.PoLTxType {\n\t\tt.Fatalf(\"unexpected tx type: got 0x%x want 0x%x\", txType, types.PoLTxType)\n\t}\n}\n\nfunc TestTransactionByHashWithPoLTransaction(t *testing.T) {\n\tt.Parallel()\n\n\tclient := newMockClient(t)\n\n\ttx, isPending, err := client.TransactionByHash(t.Context(), testTxHash)\n\tif err != nil {\n\t\tt.Fatalf(\"TransactionByHash returned error: %v\", err)\n\t}\n\tif tx == nil {\n\t\tt.Fatal(\"TransactionByHash returned nil transaction\")\n\t}\n\tif isPending {\n\t\tt.Fatal(\"TransactionByHash unexpectedly marked tx as pending\")\n\t}\n\tif txType := tx.Type(); txType != types.PoLTxType {\n\t\tt.Fatalf(\"unexpected tx type: got 0x%x want 0x%x\", txType, types.PoLTxType)\n\t}\n}\n\nfunc TestTransactionInBlockWithPoLTransaction(t *testing.T) {\n\tt.Parallel()\n\n\tclient := newMockClient(t)\n\n\ttx, err := client.TransactionInBlock(t.Context(), testBlockHash, 0)\n\tif err != nil {\n\t\tt.Fatalf(\"TransactionInBlock returned error: %v\", err)\n\t}\n\tif tx == nil {\n\t\tt.Fatal(\"TransactionInBlock returned nil transaction\")\n\t}\n\tif txType := tx.Type(); txType != types.PoLTxType {\n\t\tt.Fatalf(\"unexpected tx type: got 0x%x want 0x%x\", txType, types.PoLTxType)\n\t}\n}\n\ntype mockEthService struct{}\n\nfunc (s *mockEthService) GetBlockByNumber(ctx context.Context, number string, fullTx bool) (json.RawMessage, error) {\n\t_ = ctx\n\t_ = number\n\t_ = fullTx\n\treturn mockBlockJSON(), nil\n}\n\nfunc (s *mockEthService) GetBlockByHash(ctx context.Context, hash gethcommon.Hash, fullTx bool) (json.RawMessage, error) {\n\t_ = ctx\n\t_ = hash\n\t_ = fullTx\n\treturn mockBlockJSON(), nil\n}\n\nfunc (s *mockEthService) GetTransactionByHash(ctx context.Context, hash gethcommon.Hash) (json.RawMessage, error) {\n\t_ = ctx\n\t_ = hash\n\treturn mockTransactionJSON(), nil\n}\n\nfunc (s *mockEthService) GetTransactionByBlockHashAndIndex(\n\tctx context.Context,\n\tblockHash gethcommon.Hash,\n\tindex string,\n) (json.RawMessage, error) {\n\t_ = ctx\n\t_ = blockHash\n\t_ = index\n\treturn mockTransactionJSON(), nil\n}\n\nfunc newMockClient(t *testing.T) *beraclient.Client {\n\tt.Helper()\n\n\tsrv := rpc.NewServer()\n\tif err := srv.RegisterName(\"eth\", &mockEthService{}); err != nil {\n\t\tt.Fatalf(\"failed to register mock service: %v\", err)\n\t}\n\trpcClient := rpc.DialInProc(srv)\n\tclient := beraclient.Wrap(gethclient.NewClient(rpcClient))\n\tt.Cleanup(func() {\n\t\tclient.Close()\n\t\tsrv.Stop()\n\t})\n\treturn client\n}\n\nfunc mockTransactionJSON() json.RawMessage {\n\ttx := mockTransactionObject()\n\traw, err := json.Marshal(tx)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn raw\n}\n\nfunc mockTransactionObject() map[string]any {\n\treturn map[string]any{\n\t\t\"type\":             \"0x7e\",\n\t\t\"chainId\":          \"0x1\",\n\t\t\"from\":             testFrom.Hex(),\n\t\t\"to\":               testTo.Hex(),\n\t\t\"nonce\":            \"0x2\",\n\t\t\"gas\":              \"0x5208\",\n\t\t\"gasPrice\":         \"0x1\",\n\t\t\"input\":            \"0x1234\",\n\t\t\"hash\":             testTxHash.Hex(),\n\t\t\"blockHash\":        testBlockHash.Hex(),\n\t\t\"blockNumber\":      \"0x2\",\n\t\t\"transactionIndex\": \"0x0\",\n\t}\n}\n\nfunc mockBlockJSON() json.RawMessage {\n\tblock := map[string]any{\n\t\t\"hash\":             testBlockHash.Hex(),\n\t\t\"parentHash\":       testParentHash.Hex(),\n\t\t\"sha3Uncles\":       coretypes.EmptyUncleHash.Hex(),\n\t\t\"miner\":            gethcommon.Address{}.Hex(),\n\t\t\"stateRoot\":        testStateRoot.Hex(),\n\t\t\"transactionsRoot\": testTxRoot.Hex(),\n\t\t\"receiptsRoot\":     testReceiptsRoot.Hex(),\n\t\t\"logsBloom\":        \"0x\" + strings.Repeat(\"0\", 512),\n\t\t\"difficulty\":       \"0x1\",\n\t\t\"number\":           \"0x2\",\n\t\t\"gasLimit\":         \"0x1c9c380\",\n\t\t\"gasUsed\":          \"0x5208\",\n\t\t\"timestamp\":        \"0x1\",\n\t\t\"extraData\":        \"0x\",\n\t\t\"mixHash\":          gethcommon.Hash{}.Hex(),\n\t\t\"nonce\":            \"0x0000000000000000\",\n\t\t\"transactions\":     []any{mockTransactionObject()},\n\t\t\"uncles\":           []any{},\n\t}\n\traw, err := json.Marshal(block)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn raw\n}\n"
  },
  {
    "path": "gethlib/ssztest/contract.abigen.go",
    "content": "// Code generated - DO NOT EDIT.\n// This file is a generated binding and any manual changes will be lost.\n\npackage ssztest\n\nimport (\n\t\"errors\"\n\t\"math/big\"\n\t\"strings\"\n\n\tethereum \"github.com/ethereum/go-ethereum\"\n\t\"github.com/ethereum/go-ethereum/accounts/abi\"\n\t\"github.com/ethereum/go-ethereum/accounts/abi/bind\"\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/ethereum/go-ethereum/event\"\n)\n\n// Reference imports to suppress errors if they are not otherwise used.\nvar (\n\t_ = errors.New\n\t_ = big.NewInt\n\t_ = strings.NewReader\n\t_ = ethereum.NotFound\n\t_ = bind.Bind\n\t_ = common.Big1\n\t_ = types.BloomLookup\n\t_ = event.NewSubscription\n\t_ = abi.ConvertType\n)\n\n// SSZTestMetaData contains all meta data concerning the SSZTest contract.\nvar SSZTestMetaData = &bind.MetaData{\n\tABI: \"[{\\\"type\\\":\\\"function\\\",\\\"name\\\":\\\"BEACON_ROOTS\\\",\\\"inputs\\\":[],\\\"outputs\\\":[{\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"address\\\",\\\"internalType\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"view\\\"},{\\\"type\\\":\\\"function\\\",\\\"name\\\":\\\"getParentBlockRootAt\\\",\\\"inputs\\\":[{\\\"name\\\":\\\"ts\\\",\\\"type\\\":\\\"uint64\\\",\\\"internalType\\\":\\\"uint64\\\"}],\\\"outputs\\\":[{\\\"name\\\":\\\"root\\\",\\\"type\\\":\\\"bytes32\\\",\\\"internalType\\\":\\\"bytes32\\\"}],\\\"stateMutability\\\":\\\"view\\\"},{\\\"type\\\":\\\"function\\\",\\\"name\\\":\\\"mustVerifyProof\\\",\\\"inputs\\\":[{\\\"name\\\":\\\"proof\\\",\\\"type\\\":\\\"bytes32[]\\\",\\\"internalType\\\":\\\"bytes32[]\\\"},{\\\"name\\\":\\\"root\\\",\\\"type\\\":\\\"bytes32\\\",\\\"internalType\\\":\\\"bytes32\\\"},{\\\"name\\\":\\\"leaf\\\",\\\"type\\\":\\\"bytes32\\\",\\\"internalType\\\":\\\"bytes32\\\"},{\\\"name\\\":\\\"index\\\",\\\"type\\\":\\\"uint256\\\",\\\"internalType\\\":\\\"uint256\\\"}],\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"view\\\"},{\\\"type\\\":\\\"function\\\",\\\"name\\\":\\\"verifyProof\\\",\\\"inputs\\\":[{\\\"name\\\":\\\"proof\\\",\\\"type\\\":\\\"bytes32[]\\\",\\\"internalType\\\":\\\"bytes32[]\\\"},{\\\"name\\\":\\\"root\\\",\\\"type\\\":\\\"bytes32\\\",\\\"internalType\\\":\\\"bytes32\\\"},{\\\"name\\\":\\\"leaf\\\",\\\"type\\\":\\\"bytes32\\\",\\\"internalType\\\":\\\"bytes32\\\"},{\\\"name\\\":\\\"index\\\",\\\"type\\\":\\\"uint256\\\",\\\"internalType\\\":\\\"uint256\\\"}],\\\"outputs\\\":[{\\\"name\\\":\\\"isValid\\\",\\\"type\\\":\\\"bool\\\",\\\"internalType\\\":\\\"bool\\\"}],\\\"stateMutability\\\":\\\"view\\\"},{\\\"type\\\":\\\"error\\\",\\\"name\\\":\\\"RootNotFound\\\",\\\"inputs\\\":[]}]\",\n\tBin: \"0x6080604052348015600e575f80fd5b5061033f8061001c5f395ff3fe608060405234801561000f575f80fd5b506004361061004a575f3560e01c806341b703ff1461004e5780634fc36be61461006357806356d7e8fd1461008b578063e2c37a98146100ca575b5f80fd5b61006161005c366004610256565b6100eb565b005b610076610071366004610256565b610169565b60405190151581526020015b60405180910390f35b6100a5720f3df6d732807ef1319fb7b8bb8522d0beac0281565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610082565b6100dd6100d83660046102db565b610181565b604051908152602001610082565b6100f885858585856101bc565b610162576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f50726f6f6620697320696e76616c696400000000000000000000000000000000604482015260640160405180910390fd5b5050505050565b5f61017786868686866101bc565b9695505050505050565b5f815f5260205f60205f720f3df6d732807ef1319fb7b8bb8522d0beac025afa806101b357633033b0ff5f526004601cfd5b50505f51919050565b5f8415610218578460051b8601865b6001841660051b8460011c9450846101ea57635849603f5f526004601cfd5b85815281356020918218525f60408160025afa80610206575f80fd5b505f5194506020018181106101cb5750505b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82011561024d57631b6661c35f526004601cfd5b50501492915050565b5f805f805f6080868803121561026a575f80fd5b853567ffffffffffffffff811115610280575f80fd5b8601601f81018813610290575f80fd5b803567ffffffffffffffff8111156102a6575f80fd5b8860208260051b84010111156102ba575f80fd5b60209182019990985090870135966040810135965060600135945092505050565b5f602082840312156102eb575f80fd5b813567ffffffffffffffff81168114610302575f80fd5b939250505056fea26469706673582212204cc5111caf3fc9426b1119c431d63b522cbd3e75039cf6c038d28577712aac6464736f6c634300081a0033\",\n}\n\n// SSZTestABI is the input ABI used to generate the binding from.\n// Deprecated: Use SSZTestMetaData.ABI instead.\nvar SSZTestABI = SSZTestMetaData.ABI\n\n// SSZTestBin is the compiled bytecode used for deploying new contracts.\n// Deprecated: Use SSZTestMetaData.Bin instead.\nvar SSZTestBin = SSZTestMetaData.Bin\n\n// DeploySSZTest deploys a new Ethereum contract, binding an instance of SSZTest to it.\nfunc DeploySSZTest(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SSZTest, error) {\n\tparsed, err := SSZTestMetaData.GetAbi()\n\tif err != nil {\n\t\treturn common.Address{}, nil, nil, err\n\t}\n\tif parsed == nil {\n\t\treturn common.Address{}, nil, nil, errors.New(\"GetABI returned nil\")\n\t}\n\n\taddress, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(SSZTestBin), backend)\n\tif err != nil {\n\t\treturn common.Address{}, nil, nil, err\n\t}\n\treturn address, tx, &SSZTest{SSZTestCaller: SSZTestCaller{contract: contract}, SSZTestTransactor: SSZTestTransactor{contract: contract}, SSZTestFilterer: SSZTestFilterer{contract: contract}}, nil\n}\n\n// SSZTest is an auto generated Go binding around an Ethereum contract.\ntype SSZTest struct {\n\tSSZTestCaller     // Read-only binding to the contract\n\tSSZTestTransactor // Write-only binding to the contract\n\tSSZTestFilterer   // Log filterer for contract events\n}\n\n// SSZTestCaller is an auto generated read-only Go binding around an Ethereum contract.\ntype SSZTestCaller struct {\n\tcontract *bind.BoundContract // Generic contract wrapper for the low level calls\n}\n\n// SSZTestTransactor is an auto generated write-only Go binding around an Ethereum contract.\ntype SSZTestTransactor struct {\n\tcontract *bind.BoundContract // Generic contract wrapper for the low level calls\n}\n\n// SSZTestFilterer is an auto generated log filtering Go binding around an Ethereum contract events.\ntype SSZTestFilterer struct {\n\tcontract *bind.BoundContract // Generic contract wrapper for the low level calls\n}\n\n// SSZTestSession is an auto generated Go binding around an Ethereum contract,\n// with pre-set call and transact options.\ntype SSZTestSession struct {\n\tContract     *SSZTest          // Generic contract binding to set the session for\n\tCallOpts     bind.CallOpts     // Call options to use throughout this session\n\tTransactOpts bind.TransactOpts // Transaction auth options to use throughout this session\n}\n\n// SSZTestCallerSession is an auto generated read-only Go binding around an Ethereum contract,\n// with pre-set call options.\ntype SSZTestCallerSession struct {\n\tContract *SSZTestCaller // Generic contract caller binding to set the session for\n\tCallOpts bind.CallOpts  // Call options to use throughout this session\n}\n\n// SSZTestTransactorSession is an auto generated write-only Go binding around an Ethereum contract,\n// with pre-set transact options.\ntype SSZTestTransactorSession struct {\n\tContract     *SSZTestTransactor // Generic contract transactor binding to set the session for\n\tTransactOpts bind.TransactOpts  // Transaction auth options to use throughout this session\n}\n\n// SSZTestRaw is an auto generated low-level Go binding around an Ethereum contract.\ntype SSZTestRaw struct {\n\tContract *SSZTest // Generic contract binding to access the raw methods on\n}\n\n// SSZTestCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.\ntype SSZTestCallerRaw struct {\n\tContract *SSZTestCaller // Generic read-only contract binding to access the raw methods on\n}\n\n// SSZTestTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.\ntype SSZTestTransactorRaw struct {\n\tContract *SSZTestTransactor // Generic write-only contract binding to access the raw methods on\n}\n\n// NewSSZTest creates a new instance of SSZTest, bound to a specific deployed contract.\nfunc NewSSZTest(address common.Address, backend bind.ContractBackend) (*SSZTest, error) {\n\tcontract, err := bindSSZTest(address, backend, backend, backend)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &SSZTest{SSZTestCaller: SSZTestCaller{contract: contract}, SSZTestTransactor: SSZTestTransactor{contract: contract}, SSZTestFilterer: SSZTestFilterer{contract: contract}}, nil\n}\n\n// NewSSZTestCaller creates a new read-only instance of SSZTest, bound to a specific deployed contract.\nfunc NewSSZTestCaller(address common.Address, caller bind.ContractCaller) (*SSZTestCaller, error) {\n\tcontract, err := bindSSZTest(address, caller, nil, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &SSZTestCaller{contract: contract}, nil\n}\n\n// NewSSZTestTransactor creates a new write-only instance of SSZTest, bound to a specific deployed contract.\nfunc NewSSZTestTransactor(address common.Address, transactor bind.ContractTransactor) (*SSZTestTransactor, error) {\n\tcontract, err := bindSSZTest(address, nil, transactor, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &SSZTestTransactor{contract: contract}, nil\n}\n\n// NewSSZTestFilterer creates a new log filterer instance of SSZTest, bound to a specific deployed contract.\nfunc NewSSZTestFilterer(address common.Address, filterer bind.ContractFilterer) (*SSZTestFilterer, error) {\n\tcontract, err := bindSSZTest(address, nil, nil, filterer)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &SSZTestFilterer{contract: contract}, nil\n}\n\n// bindSSZTest binds a generic wrapper to an already deployed contract.\nfunc bindSSZTest(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {\n\tparsed, err := SSZTestMetaData.GetAbi()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil\n}\n\n// Call invokes the (constant) contract method with params as input values and\n// sets the output to result. The result type might be a single field for simple\n// returns, a slice of interfaces for anonymous returns and a struct for named\n// returns.\nfunc (_SSZTest *SSZTestRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {\n\treturn _SSZTest.Contract.SSZTestCaller.contract.Call(opts, result, method, params...)\n}\n\n// Transfer initiates a plain transaction to move funds to the contract, calling\n// its default method if one is available.\nfunc (_SSZTest *SSZTestRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {\n\treturn _SSZTest.Contract.SSZTestTransactor.contract.Transfer(opts)\n}\n\n// Transact invokes the (paid) contract method with params as input values.\nfunc (_SSZTest *SSZTestRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {\n\treturn _SSZTest.Contract.SSZTestTransactor.contract.Transact(opts, method, params...)\n}\n\n// Call invokes the (constant) contract method with params as input values and\n// sets the output to result. The result type might be a single field for simple\n// returns, a slice of interfaces for anonymous returns and a struct for named\n// returns.\nfunc (_SSZTest *SSZTestCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {\n\treturn _SSZTest.Contract.contract.Call(opts, result, method, params...)\n}\n\n// Transfer initiates a plain transaction to move funds to the contract, calling\n// its default method if one is available.\nfunc (_SSZTest *SSZTestTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {\n\treturn _SSZTest.Contract.contract.Transfer(opts)\n}\n\n// Transact invokes the (paid) contract method with params as input values.\nfunc (_SSZTest *SSZTestTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {\n\treturn _SSZTest.Contract.contract.Transact(opts, method, params...)\n}\n\n// BEACONROOTS is a free data retrieval call binding the contract method 0x56d7e8fd.\n//\n// Solidity: function BEACON_ROOTS() view returns(address)\nfunc (_SSZTest *SSZTestCaller) BEACONROOTS(opts *bind.CallOpts) (common.Address, error) {\n\tvar out []interface{}\n\terr := _SSZTest.contract.Call(opts, &out, \"BEACON_ROOTS\")\n\n\tif err != nil {\n\t\treturn *new(common.Address), err\n\t}\n\n\tout0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)\n\n\treturn out0, err\n\n}\n\n// BEACONROOTS is a free data retrieval call binding the contract method 0x56d7e8fd.\n//\n// Solidity: function BEACON_ROOTS() view returns(address)\nfunc (_SSZTest *SSZTestSession) BEACONROOTS() (common.Address, error) {\n\treturn _SSZTest.Contract.BEACONROOTS(&_SSZTest.CallOpts)\n}\n\n// BEACONROOTS is a free data retrieval call binding the contract method 0x56d7e8fd.\n//\n// Solidity: function BEACON_ROOTS() view returns(address)\nfunc (_SSZTest *SSZTestCallerSession) BEACONROOTS() (common.Address, error) {\n\treturn _SSZTest.Contract.BEACONROOTS(&_SSZTest.CallOpts)\n}\n\n// GetParentBlockRootAt is a free data retrieval call binding the contract method 0xe2c37a98.\n//\n// Solidity: function getParentBlockRootAt(uint64 ts) view returns(bytes32 root)\nfunc (_SSZTest *SSZTestCaller) GetParentBlockRootAt(opts *bind.CallOpts, ts uint64) ([32]byte, error) {\n\tvar out []interface{}\n\terr := _SSZTest.contract.Call(opts, &out, \"getParentBlockRootAt\", ts)\n\n\tif err != nil {\n\t\treturn *new([32]byte), err\n\t}\n\n\tout0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte)\n\n\treturn out0, err\n\n}\n\n// GetParentBlockRootAt is a free data retrieval call binding the contract method 0xe2c37a98.\n//\n// Solidity: function getParentBlockRootAt(uint64 ts) view returns(bytes32 root)\nfunc (_SSZTest *SSZTestSession) GetParentBlockRootAt(ts uint64) ([32]byte, error) {\n\treturn _SSZTest.Contract.GetParentBlockRootAt(&_SSZTest.CallOpts, ts)\n}\n\n// GetParentBlockRootAt is a free data retrieval call binding the contract method 0xe2c37a98.\n//\n// Solidity: function getParentBlockRootAt(uint64 ts) view returns(bytes32 root)\nfunc (_SSZTest *SSZTestCallerSession) GetParentBlockRootAt(ts uint64) ([32]byte, error) {\n\treturn _SSZTest.Contract.GetParentBlockRootAt(&_SSZTest.CallOpts, ts)\n}\n\n// MustVerifyProof is a free data retrieval call binding the contract method 0x41b703ff.\n//\n// Solidity: function mustVerifyProof(bytes32[] proof, bytes32 root, bytes32 leaf, uint256 index) view returns()\nfunc (_SSZTest *SSZTestCaller) MustVerifyProof(opts *bind.CallOpts, proof [][32]byte, root [32]byte, leaf [32]byte, index *big.Int) error {\n\tvar out []interface{}\n\terr := _SSZTest.contract.Call(opts, &out, \"mustVerifyProof\", proof, root, leaf, index)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn err\n\n}\n\n// MustVerifyProof is a free data retrieval call binding the contract method 0x41b703ff.\n//\n// Solidity: function mustVerifyProof(bytes32[] proof, bytes32 root, bytes32 leaf, uint256 index) view returns()\nfunc (_SSZTest *SSZTestSession) MustVerifyProof(proof [][32]byte, root [32]byte, leaf [32]byte, index *big.Int) error {\n\treturn _SSZTest.Contract.MustVerifyProof(&_SSZTest.CallOpts, proof, root, leaf, index)\n}\n\n// MustVerifyProof is a free data retrieval call binding the contract method 0x41b703ff.\n//\n// Solidity: function mustVerifyProof(bytes32[] proof, bytes32 root, bytes32 leaf, uint256 index) view returns()\nfunc (_SSZTest *SSZTestCallerSession) MustVerifyProof(proof [][32]byte, root [32]byte, leaf [32]byte, index *big.Int) error {\n\treturn _SSZTest.Contract.MustVerifyProof(&_SSZTest.CallOpts, proof, root, leaf, index)\n}\n\n// VerifyProof is a free data retrieval call binding the contract method 0x4fc36be6.\n//\n// Solidity: function verifyProof(bytes32[] proof, bytes32 root, bytes32 leaf, uint256 index) view returns(bool isValid)\nfunc (_SSZTest *SSZTestCaller) VerifyProof(opts *bind.CallOpts, proof [][32]byte, root [32]byte, leaf [32]byte, index *big.Int) (bool, error) {\n\tvar out []interface{}\n\terr := _SSZTest.contract.Call(opts, &out, \"verifyProof\", proof, root, leaf, index)\n\n\tif err != nil {\n\t\treturn *new(bool), err\n\t}\n\n\tout0 := *abi.ConvertType(out[0], new(bool)).(*bool)\n\n\treturn out0, err\n\n}\n\n// VerifyProof is a free data retrieval call binding the contract method 0x4fc36be6.\n//\n// Solidity: function verifyProof(bytes32[] proof, bytes32 root, bytes32 leaf, uint256 index) view returns(bool isValid)\nfunc (_SSZTest *SSZTestSession) VerifyProof(proof [][32]byte, root [32]byte, leaf [32]byte, index *big.Int) (bool, error) {\n\treturn _SSZTest.Contract.VerifyProof(&_SSZTest.CallOpts, proof, root, leaf, index)\n}\n\n// VerifyProof is a free data retrieval call binding the contract method 0x4fc36be6.\n//\n// Solidity: function verifyProof(bytes32[] proof, bytes32 root, bytes32 leaf, uint256 index) view returns(bool isValid)\nfunc (_SSZTest *SSZTestCallerSession) VerifyProof(proof [][32]byte, root [32]byte, leaf [32]byte, index *big.Int) (bool, error) {\n\treturn _SSZTest.Contract.VerifyProof(&_SSZTest.CallOpts, proof, root, leaf, index)\n}\n"
  },
  {
    "path": "gethlib/ssztest/contract.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage ssztest\n\n// TODO: Remove ldflags=-checklinkname=0 override once fix is applied.\n//\n//go:generate abigen --abi=../../contracts/out/SSZ.sol/SSZTest.abi.json --bin=../../contracts/out/SSZ.sol/SSZTest.bin --pkg=ssztest --type=SSZTest --out=contract.abigen.go\n"
  },
  {
    "path": "gethlib/types/block.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"math/big\"\n\t\"slices\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/ethereum/go-ethereum/beacon/engine\"\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-ethereum/common/hexutil\"\n\tcoretypes \"github.com/ethereum/go-ethereum/core/types\"\n)\n\n// Block represents a Berachain block.\n//\n// Note the Block type tries to be 'immutable', and contains certain caches that rely\n// on that. The rules around block immutability are as follows:\n//\n//   - We copy all data when the block is constructed. This makes references held inside\n//     the block independent of whatever value was passed in.\n//\n//   - We copy all header data on access. This is because any change to the header would mess\n//     up the cached hash and size values in the block. Calling code is expected to take\n//     advantage of this to avoid over-allocating!\n//\n//   - When new body data is attached to the block, a shallow copy of the block is returned.\n//     This ensures block modifications are race-free.\n//\n//   - We do not copy body data on access because it does not affect the caches, and also\n//     because it would be too expensive.\ntype Block struct {\n\theader       *Header\n\tuncles       []*Header\n\ttransactions Transactions\n\twithdrawals  coretypes.Withdrawals\n\n\t// caches\n\thash atomic.Pointer[common.Hash]\n\n\t// These fields are used by package eth to track\n\t// inter-peer block relay.\n\tReceivedAt   time.Time\n\tReceivedFrom interface{}\n}\n\n// Body is a simple (mutable, non-safe) data container for storing and moving\n// a block's data contents (transactions and uncles) together.\ntype Body struct {\n\tTransactions []*Transaction\n\tUncles       []*Header\n\tWithdrawals  []*coretypes.Withdrawal `rlp:\"optional\"`\n}\n\n// NewBlock creates a new block. The input data is copied, changes to header and to the\n// field values will not affect the block.\n//\n// The body elements and the receipts are used to recompute and overwrite the\n// relevant portions of the header.\n//\n// The receipt's bloom must already calculated for the block's bloom to be\n// correctly calculated.\nfunc NewBlock(header *Header, body *Body, receipts []*coretypes.Receipt, hasher coretypes.ListHasher) *Block {\n\tif body == nil {\n\t\tbody = &Body{}\n\t}\n\tvar (\n\t\tb           = NewBlockWithHeader(header)\n\t\ttxs         = body.Transactions\n\t\tuncles      = body.Uncles\n\t\twithdrawals = body.Withdrawals\n\t)\n\n\tif len(txs) == 0 {\n\t\tb.header.TxHash = coretypes.EmptyTxsHash\n\t} else {\n\t\tb.header.TxHash = coretypes.DeriveSha(Transactions(txs), hasher)\n\t\tb.transactions = make(Transactions, len(txs))\n\t\tcopy(b.transactions, txs)\n\t}\n\n\tif len(receipts) == 0 {\n\t\tb.header.ReceiptHash = coretypes.EmptyReceiptsHash\n\t} else {\n\t\tb.header.ReceiptHash = coretypes.DeriveSha(coretypes.Receipts(receipts), hasher)\n\t\t// Receipts must go through MakeReceipt to calculate the receipt's bloom\n\t\t// already. Merge the receipt's bloom together instead of recalculating\n\t\t// everything.\n\t\tb.header.Bloom = coretypes.MergeBloom(receipts)\n\t}\n\n\tif len(uncles) == 0 {\n\t\tb.header.UncleHash = coretypes.EmptyUncleHash\n\t} else {\n\t\tb.header.UncleHash = CalcUncleHash(uncles)\n\t\tb.uncles = make([]*Header, len(uncles))\n\t\tfor i := range uncles {\n\t\t\tb.uncles[i] = CopyHeader(uncles[i])\n\t\t}\n\t}\n\n\tswitch {\n\tcase withdrawals == nil:\n\t\tb.header.WithdrawalsHash = nil\n\tcase len(withdrawals) == 0:\n\t\tb.header.WithdrawalsHash = &coretypes.EmptyWithdrawalsHash\n\t\tb.withdrawals = coretypes.Withdrawals{}\n\tdefault:\n\t\thash := coretypes.DeriveSha(coretypes.Withdrawals(withdrawals), hasher)\n\t\tb.header.WithdrawalsHash = &hash\n\t\tb.withdrawals = slices.Clone(withdrawals)\n\t}\n\n\treturn b\n}\n\n// NewBlockWithHeader creates a block with the given header data. The\n// header data is copied, changes to header and to the field values\n// will not affect the block.\nfunc NewBlockWithHeader(header *Header) *Block {\n\treturn &Block{header: CopyHeader(header)}\n}\n\n// WithBody returns a new block with the original header and a deep copy of the\n// provided body.\nfunc (b *Block) WithBody(body Body) *Block {\n\tblock := &Block{\n\t\theader:       b.header,\n\t\ttransactions: slices.Clone(body.Transactions),\n\t\tuncles:       make([]*Header, len(body.Uncles)),\n\t\twithdrawals:  slices.Clone(body.Withdrawals),\n\t}\n\tfor i := range body.Uncles {\n\t\tblock.uncles[i] = CopyHeader(body.Uncles[i])\n\t}\n\treturn block\n}\n\n// Hash returns the keccak256 hash of b's header.\n// The hash is computed on the first call and cached thereafter.\nfunc (b *Block) Hash() common.Hash {\n\tif hash := b.hash.Load(); hash != nil {\n\t\treturn *hash\n\t}\n\th := b.header.Hash()\n\tb.hash.Store(&h)\n\treturn h\n}\n\n// Accessors for body data. These do not return a copy because the content\n// of the body slices does not affect the cached hash/size in block.\nfunc (b *Block) Transactions() Transactions         { return b.transactions }\nfunc (b *Block) Withdrawals() coretypes.Withdrawals { return b.withdrawals }\n\n// Header value accessors. These do copy!\nfunc (b *Block) GasLimit() uint64         { return b.header.GasLimit }\nfunc (b *Block) GasUsed() uint64          { return b.header.GasUsed }\nfunc (b *Block) Time() uint64             { return b.header.Time }\nfunc (b *Block) NumberU64() uint64        { return b.header.Number.Uint64() }\nfunc (b *Block) MixDigest() common.Hash   { return b.header.MixDigest }\nfunc (b *Block) Bloom() coretypes.Bloom   { return b.header.Bloom }\nfunc (b *Block) Coinbase() common.Address { return b.header.Coinbase }\nfunc (b *Block) Root() common.Hash        { return b.header.Root }\nfunc (b *Block) ParentHash() common.Hash  { return b.header.ParentHash }\nfunc (b *Block) ReceiptHash() common.Hash { return b.header.ReceiptHash }\nfunc (b *Block) Extra() []byte            { return common.CopyBytes(b.header.Extra) }\n\nfunc (b *Block) BaseFee() *big.Int {\n\tif b.header.BaseFee == nil {\n\t\treturn nil\n\t}\n\treturn new(big.Int).Set(b.header.BaseFee)\n}\n\nfunc (b *Block) ExcessBlobGas() *uint64 {\n\tvar excessBlobGas *uint64\n\tif b.header.ExcessBlobGas != nil {\n\t\texcessBlobGas = new(uint64)\n\t\t*excessBlobGas = *b.header.ExcessBlobGas\n\t}\n\treturn excessBlobGas\n}\n\nfunc (b *Block) BlobGasUsed() *uint64 {\n\tvar blobGasUsed *uint64\n\tif b.header.BlobGasUsed != nil {\n\t\tblobGasUsed = new(uint64)\n\t\t*blobGasUsed = *b.header.BlobGasUsed\n\t}\n\treturn blobGasUsed\n}\n\n// BlockToExecutableData constructs the ExecutableData structure by filling the\n// fields from the given block. It assumes the given block is post-merge block.\nfunc BlockToExecutableData(\n\tblock *Block,\n\tfees *big.Int,\n\tsidecars []*coretypes.BlobTxSidecar,\n\trequests [][]byte,\n) *engine.ExecutionPayloadEnvelope {\n\tdata := &engine.ExecutableData{\n\t\tBlockHash:     block.Hash(),\n\t\tParentHash:    block.ParentHash(),\n\t\tFeeRecipient:  block.Coinbase(),\n\t\tStateRoot:     block.Root(),\n\t\tNumber:        block.NumberU64(),\n\t\tGasLimit:      block.GasLimit(),\n\t\tGasUsed:       block.GasUsed(),\n\t\tBaseFeePerGas: block.BaseFee(),\n\t\tTimestamp:     block.Time(),\n\t\tReceiptsRoot:  block.ReceiptHash(),\n\t\tLogsBloom:     block.Bloom().Bytes(),\n\t\tTransactions:  encodeTransactions(block.Transactions()),\n\t\tRandom:        block.MixDigest(),\n\t\tExtraData:     block.Extra(),\n\t\tWithdrawals:   block.Withdrawals(),\n\t\tBlobGasUsed:   block.BlobGasUsed(),\n\t\tExcessBlobGas: block.ExcessBlobGas(),\n\t}\n\n\t// Add blobs.\n\tbundle := engine.BlobsBundle{\n\t\tCommitments: make([]hexutil.Bytes, 0),\n\t\tBlobs:       make([]hexutil.Bytes, 0),\n\t\tProofs:      make([]hexutil.Bytes, 0),\n\t}\n\tfor _, sidecar := range sidecars {\n\t\tfor j := range sidecar.Blobs {\n\t\t\tbundle.Blobs = append(bundle.Blobs, sidecar.Blobs[j][:])\n\t\t\tbundle.Commitments = append(bundle.Commitments, sidecar.Commitments[j][:])\n\t\t}\n\t\t// - Before the Osaka fork, only version-0 blob transactions should be packed,\n\t\t//   with the proof length equal to len(blobs).\n\t\t//\n\t\t// - After the Osaka fork, only version-1 blob transactions should be packed,\n\t\t//   with the proof length equal to CELLS_PER_EXT_BLOB * len(blobs).\n\t\t//\n\t\t// Ideally, length validation should be performed based on the bundle version.\n\t\t// In practice, this is unnecessary because blob transaction filtering is\n\t\t// already done during payload construction.\n\t\tfor _, proof := range sidecar.Proofs {\n\t\t\tbundle.Proofs = append(bundle.Proofs, proof[:])\n\t\t}\n\t}\n\n\treturn &engine.ExecutionPayloadEnvelope{\n\t\tExecutionPayload: data,\n\t\tBlockValue:       fees,\n\t\tBlobsBundle:      &bundle,\n\t\tRequests:         requests,\n\t\tOverride:         false,\n\t}\n}\n\nfunc encodeTransactions(txs []*Transaction) [][]byte {\n\tvar enc = make([][]byte, len(txs))\n\tfor i, tx := range txs {\n\t\tenc[i], _ = tx.MarshalBinary()\n\t}\n\treturn enc\n}\n"
  },
  {
    "path": "gethlib/types/config.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"math/big\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-ethereum/params\"\n)\n\n// ChainConfig is the core config which determines the blockchain settings.\n//\n// ChainConfig is stored in the database on a per block basis. This means\n// that any network, identified by its genesis block, can have its own\n// set of configuration options.\ntype ChainConfig struct {\n\tChainID *big.Int `json:\"chainId\"` // chainId identifies the current chain and is used for replay protection\n\n\tHomesteadBlock *big.Int `json:\"homesteadBlock,omitempty\"` // Homestead switch block (nil = no fork, 0 = already homestead)\n\n\tDAOForkBlock   *big.Int `json:\"daoForkBlock,omitempty\"`   // TheDAO hard-fork switch block (nil = no fork)\n\tDAOForkSupport bool     `json:\"daoForkSupport,omitempty\"` // Whether the nodes supports or opposes the DAO hard-fork\n\n\t// EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150)\n\tEIP150Block *big.Int `json:\"eip150Block,omitempty\"` // EIP150 HF block (nil = no fork)\n\tEIP155Block *big.Int `json:\"eip155Block,omitempty\"` // EIP155 HF block\n\tEIP158Block *big.Int `json:\"eip158Block,omitempty\"` // EIP158 HF block\n\n\tByzantiumBlock      *big.Int `json:\"byzantiumBlock,omitempty\"`      // Byzantium switch block (nil = no fork, 0 = already on byzantium)\n\tConstantinopleBlock *big.Int `json:\"constantinopleBlock,omitempty\"` // Constantinople switch block (nil = no fork, 0 = already activated)\n\tPetersburgBlock     *big.Int `json:\"petersburgBlock,omitempty\"`     // Petersburg switch block (nil = same as Constantinople)\n\tIstanbulBlock       *big.Int `json:\"istanbulBlock,omitempty\"`       // Istanbul switch block (nil = no fork, 0 = already on istanbul)\n\t// MuirGlacierBlock is EIP-2384 (difficulty bomb delay) switch block.\n\tMuirGlacierBlock *big.Int `json:\"muirGlacierBlock,omitempty\"` // nil = no fork, 0 = already activated\n\tBerlinBlock      *big.Int `json:\"berlinBlock,omitempty\"`      // Berlin switch block (nil = no fork, 0 = already on berlin)\n\tLondonBlock      *big.Int `json:\"londonBlock,omitempty\"`      // London switch block (nil = no fork, 0 = already on london)\n\t// ArrowGlacierBlock is EIP-4345 (difficulty bomb delay) switch block.\n\tArrowGlacierBlock *big.Int `json:\"arrowGlacierBlock,omitempty\"` // nil = no fork, 0 = already activated\n\t// GrayGlacierBlock is EIP-5133 (difficulty bomb delay) switch block.\n\tGrayGlacierBlock   *big.Int `json:\"grayGlacierBlock,omitempty\"`   // nil = no fork, 0 = already activated\n\tMergeNetsplitBlock *big.Int `json:\"mergeNetsplitBlock,omitempty\"` // Virtual fork after The Merge to use as a network splitter\n\n\t// Fork scheduling was switched from blocks to timestamps here\n\n\tShanghaiTime  *uint64 `json:\"shanghaiTime,omitempty\"`  // Shanghai switch time (nil = no fork, 0 = already on shanghai)\n\tCancunTime    *uint64 `json:\"cancunTime,omitempty\"`    // Cancun switch time (nil = no fork, 0 = already on cancun)\n\tPragueTime    *uint64 `json:\"pragueTime,omitempty\"`    // Prague switch time (nil = no fork, 0 = already on prague)\n\tOsakaTime     *uint64 `json:\"osakaTime,omitempty\"`     // Osaka switch time (nil = no fork, 0 = already on osaka)\n\tBPO1Time      *uint64 `json:\"bpo1Time,omitempty\"`      // BPO1 switch time (nil = no fork, 0 = already on bpo1)\n\tBPO2Time      *uint64 `json:\"bpo2Time,omitempty\"`      // BPO2 switch time (nil = no fork, 0 = already on bpo2)\n\tBPO3Time      *uint64 `json:\"bpo3Time,omitempty\"`      // BPO3 switch time (nil = no fork, 0 = already on bpo3)\n\tBPO4Time      *uint64 `json:\"bpo4Time,omitempty\"`      // BPO4 switch time (nil = no fork, 0 = already on bpo4)\n\tBPO5Time      *uint64 `json:\"bpo5Time,omitempty\"`      // BPO5 switch time (nil = no fork, 0 = already on bpo5)\n\tAmsterdamTime *uint64 `json:\"amsterdamTime,omitempty\"` // Amsterdam switch time (nil = no fork, 0 = already on amsterdam)\n\tVerkleTime    *uint64 `json:\"verkleTime,omitempty\"`    // Verkle switch time (nil = no fork, 0 = already on verkle)\n\n\t// TerminalTotalDifficulty is the amount of total difficulty reached by\n\t// the network that triggers the consensus upgrade.\n\tTerminalTotalDifficulty *big.Int `json:\"terminalTotalDifficulty,omitempty\"`\n\n\tDepositContractAddress common.Address `json:\"depositContractAddress,omitempty\"`\n\n\t// EnableVerkleAtGenesis is a flag that specifies whether the network uses\n\t// the Verkle tree starting from the genesis block. If set to true, the\n\t// genesis state will be committed using the Verkle tree, eliminating the\n\t// need for any Verkle transition later.\n\t//\n\t// This is a temporary flag only for verkle devnet testing, where verkle is\n\t// activated at genesis, and the configured activation date has already passed.\n\t//\n\t// In production networks (mainnet and public testnets), verkle activation\n\t// always occurs after the genesis block, making this flag irrelevant in\n\t// those cases.\n\tEnableVerkleAtGenesis bool `json:\"enableVerkleAtGenesis,omitempty\"`\n\n\t// Various consensus engines\n\tEthash             *params.EthashConfig       `json:\"ethash,omitempty\"`\n\tClique             *params.CliqueConfig       `json:\"clique,omitempty\"`\n\tBlobScheduleConfig *params.BlobScheduleConfig `json:\"blobSchedule,omitempty\"`\n\n\t// Berachain config\n\tBerachain BerachainConfig `json:\"berachain,omitempty\"`\n}\n\n// BerachainConfig is the berachain config.\ntype BerachainConfig struct {\n\t// Prague1 fork values.\n\tPrague1 Prague1Config `json:\"prague1,omitempty\"`\n\n\t// Prague2 fork values.\n\tPrague2 Prague2Config `json:\"prague2,omitempty\"`\n\n\t// Prague3 fork values.\n\tPrague3 Prague3Config `json:\"prague3,omitempty\"`\n\n\t// Prague4 fork values.\n\tPrague4 Prague4Config `json:\"prague4,omitempty\"`\n}\n\n// Prague1Config is the config values for the Prague1 fork on Berachain.\ntype Prague1Config struct {\n\t// Time is the time of the Prague1 fork.\n\tTime *uint64 `json:\"time,omitempty\"` // Prague1 switch time (0 = already on prague1, nil = no fork)\n\t// BaseFeeChangeDenominator is the base fee change denominator.\n\tBaseFeeChangeDenominator uint64 `json:\"baseFeeChangeDenominator,omitempty\"`\n\t// MinimumBaseFeeWei is the minimum base fee in wei.\n\tMinimumBaseFeeWei *big.Int `json:\"minimumBaseFeeWei,omitempty\"`\n\t// PoLDistributorAddress is the address of the PoL distributor.\n\tPoLDistributorAddress common.Address `json:\"polDistributorAddress,omitempty\"`\n}\n\n// Prague2Config is the config values for the Prague2 fork on Berachain.\ntype Prague2Config struct {\n\t// Time is the time of the Prague2 fork.\n\tTime *uint64 `json:\"time,omitempty\"` // Prague2 switch time (0 = already on prague2, nil = no fork)\n\t// MinimumBaseFeeWei is the minimum base fee in wei.\n\tMinimumBaseFeeWei *big.Int `json:\"minimumBaseFeeWei,omitempty\"`\n}\n\n// Prague3Config is the config values for the Prague3 fork on Berachain.\ntype Prague3Config struct {\n\t// Time is the time of the Prague3 fork.\n\tTime *uint64 `json:\"time,omitempty\"` // Prague3 switch time (0 = already on prague3, nil = no fork)\n\t// BexVaultAddress is the address of the BEX vault.\n\tBexVaultAddress common.Address `json:\"bexVaultAddress,omitempty\"`\n\t// BlockedAddresses is the list of addresses blocked from sending or receiving ERC20 transfers.\n\tBlockedAddresses []common.Address `json:\"blockedAddresses,omitempty\"`\n\t// RescueAddress is the only address that blocked addresses can send to.\n\tRescueAddress common.Address `json:\"rescueAddress,omitempty\"`\n}\n\n// Prague4Config is the config values for the Prague4 fork on Berachain.\ntype Prague4Config struct {\n\t// Time is the time of the Prague4 fork.\n\tTime *uint64 `json:\"time,omitempty\"` // Prague4 switch time (0 = already on prague4, nil = no fork)\n}\n\n// IsLondon returns whether num is either equal to the London fork block or greater.\nfunc (c *ChainConfig) IsLondon(num *big.Int) bool {\n\treturn isBlockForked(c.LondonBlock, num)\n}\n\n// IsShanghai returns whether time is either equal to the Shanghai fork time or greater.\nfunc (c *ChainConfig) IsShanghai(num *big.Int, time uint64) bool {\n\treturn c.IsLondon(num) && isTimestampForked(c.ShanghaiTime, time)\n}\n\n// IsCancun returns whether time is either equal to the Cancun fork time or greater.\nfunc (c *ChainConfig) IsCancun(num *big.Int, time uint64) bool {\n\treturn c.IsLondon(num) && isTimestampForked(c.CancunTime, time)\n}\n\n// IsPrague returns whether time is either equal to the Prague fork time or greater.\nfunc (c *ChainConfig) IsPrague(num *big.Int, time uint64) bool {\n\treturn c.IsLondon(num) && isTimestampForked(c.PragueTime, time)\n}\n\n// IsPrague1 returns whether time is either equal to the Prague1 fork time or greater.\n// NOTE: Prague1 is a Berachain fork and must be on Ethereum's Prague fork.\nfunc (c *ChainConfig) IsPrague1(num *big.Int, time uint64) bool {\n\treturn c.IsPrague(num, time) && isTimestampForked(c.Berachain.Prague1.Time, time)\n}\n\n// IsVerkleGenesis checks whether the verkle fork is activated at the genesis block.\n//\n// Verkle mode is considered enabled if the verkle fork time is configured,\n// regardless of whether the local time has surpassed the fork activation time.\n// This is a temporary workaround for verkle devnet testing, where verkle is\n// activated at genesis, and the configured activation date has already passed.\n//\n// In production networks (mainnet and public testnets), verkle activation\n// always occurs after the genesis block, making this function irrelevant in\n// those cases.\nfunc (c *ChainConfig) IsVerkleGenesis() bool {\n\treturn c.EnableVerkleAtGenesis\n}\n\n// isBlockForked returns whether a fork scheduled at block s is active at the\n// given head block. Whilst this method is the same as isTimestampForked, they\n// are explicitly separate for clearer reading.\nfunc isBlockForked(s, head *big.Int) bool {\n\tif s == nil || head == nil {\n\t\treturn false\n\t}\n\treturn s.Cmp(head) <= 0\n}\n\n// isTimestampForked returns whether a fork scheduled at timestamp s is active\n// at the given head timestamp. Whilst this method is the same as isBlockForked,\n// they are explicitly separate for clearer reading.\nfunc isTimestampForked(s *uint64, head uint64) bool {\n\tif s == nil {\n\t\treturn false\n\t}\n\treturn *s <= head\n}\n"
  },
  {
    "path": "gethlib/types/genesis.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"math/big\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-ethereum/common/hexutil\"\n\t\"github.com/ethereum/go-ethereum/common/math\"\n\t\"github.com/ethereum/go-ethereum/core/rawdb\"\n\t\"github.com/ethereum/go-ethereum/core/state\"\n\t\"github.com/ethereum/go-ethereum/core/tracing\"\n\t\"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/ethereum/go-ethereum/log\"\n\t\"github.com/ethereum/go-ethereum/params\"\n\t\"github.com/ethereum/go-ethereum/trie\"\n\t\"github.com/ethereum/go-ethereum/triedb\"\n\t\"github.com/ethereum/go-ethereum/triedb/pathdb\"\n\t\"github.com/holiman/uint256\"\n)\n\n// Genesis specifies the header fields, state of a genesis block. It also defines hard\n// fork switch-over blocks through the chain configuration.\ntype Genesis struct {\n\tConfig     *ChainConfig       `json:\"config\"`\n\tNonce      uint64             `json:\"nonce\"`\n\tTimestamp  uint64             `json:\"timestamp\"`\n\tExtraData  []byte             `json:\"extraData\"`\n\tGasLimit   uint64             `json:\"gasLimit\"   gencodec:\"required\"`\n\tDifficulty *big.Int           `json:\"difficulty\" gencodec:\"required\"`\n\tMixhash    common.Hash        `json:\"mixHash\"`\n\tCoinbase   common.Address     `json:\"coinbase\"`\n\tAlloc      types.GenesisAlloc `json:\"alloc\"      gencodec:\"required\"`\n\n\t// These fields are used for consensus tests. Please don't use them\n\t// in actual genesis blocks.\n\tNumber        uint64      `json:\"number\"`\n\tGasUsed       uint64      `json:\"gasUsed\"`\n\tParentHash    common.Hash `json:\"parentHash\"`\n\tBaseFee       *big.Int    `json:\"baseFeePerGas\"` // EIP-1559\n\tExcessBlobGas *uint64     `json:\"excessBlobGas\"` // EIP-4844\n\tBlobGasUsed   *uint64     `json:\"blobGasUsed\"`   // EIP-4844\n}\n\n// IsVerkle indicates whether the state is already stored in a verkle\n// tree at genesis time.\nfunc (g *Genesis) IsVerkle() bool {\n\treturn g.Config.IsVerkleGenesis()\n}\n\n// ToBlock returns the genesis block according to genesis specification.\nfunc (g *Genesis) ToBlock() *Block {\n\troot, err := hashAlloc(&g.Alloc, g.IsVerkle())\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn g.toBlockWithRoot(root)\n}\n\n// UnmarshalJSON unmarshals from JSON.\nfunc (g *Genesis) UnmarshalJSON(input []byte) error {\n\ttype Genesis struct {\n\t\tConfig        *ChainConfig                               `json:\"config\"`\n\t\tNonce         *math.HexOrDecimal64                       `json:\"nonce\"`\n\t\tTimestamp     *math.HexOrDecimal64                       `json:\"timestamp\"`\n\t\tExtraData     *hexutil.Bytes                             `json:\"extraData\"`\n\t\tGasLimit      *math.HexOrDecimal64                       `json:\"gasLimit\"      gencodec:\"required\"`\n\t\tDifficulty    *math.HexOrDecimal256                      `json:\"difficulty\"    gencodec:\"required\"`\n\t\tMixhash       *common.Hash                               `json:\"mixHash\"`\n\t\tCoinbase      *common.Address                            `json:\"coinbase\"`\n\t\tAlloc         map[common.UnprefixedAddress]types.Account `json:\"alloc\"         gencodec:\"required\"`\n\t\tNumber        *math.HexOrDecimal64                       `json:\"number\"`\n\t\tGasUsed       *math.HexOrDecimal64                       `json:\"gasUsed\"`\n\t\tParentHash    *common.Hash                               `json:\"parentHash\"`\n\t\tBaseFee       *math.HexOrDecimal256                      `json:\"baseFeePerGas\"`\n\t\tExcessBlobGas *math.HexOrDecimal64                       `json:\"excessBlobGas\"`\n\t\tBlobGasUsed   *math.HexOrDecimal64                       `json:\"blobGasUsed\"`\n\t}\n\tvar dec Genesis\n\tif err := json.Unmarshal(input, &dec); err != nil {\n\t\treturn err\n\t}\n\tif dec.Config != nil {\n\t\tg.Config = dec.Config\n\t}\n\tif dec.Nonce != nil {\n\t\tg.Nonce = uint64(*dec.Nonce)\n\t}\n\tif dec.Timestamp != nil {\n\t\tg.Timestamp = uint64(*dec.Timestamp)\n\t}\n\tif dec.ExtraData != nil {\n\t\tg.ExtraData = *dec.ExtraData\n\t}\n\tif dec.GasLimit == nil {\n\t\treturn errors.New(\"missing required field 'gasLimit' for Genesis\")\n\t}\n\tg.GasLimit = uint64(*dec.GasLimit)\n\tif dec.Difficulty == nil {\n\t\treturn errors.New(\"missing required field 'difficulty' for Genesis\")\n\t}\n\tg.Difficulty = (*big.Int)(dec.Difficulty)\n\tif dec.Mixhash != nil {\n\t\tg.Mixhash = *dec.Mixhash\n\t}\n\tif dec.Coinbase != nil {\n\t\tg.Coinbase = *dec.Coinbase\n\t}\n\tif dec.Alloc == nil {\n\t\treturn errors.New(\"missing required field 'alloc' for Genesis\")\n\t}\n\tg.Alloc = make(types.GenesisAlloc, len(dec.Alloc))\n\tfor k, v := range dec.Alloc {\n\t\tg.Alloc[common.Address(k)] = v\n\t}\n\tif dec.Number != nil {\n\t\tg.Number = uint64(*dec.Number)\n\t}\n\tif dec.GasUsed != nil {\n\t\tg.GasUsed = uint64(*dec.GasUsed)\n\t}\n\tif dec.ParentHash != nil {\n\t\tg.ParentHash = *dec.ParentHash\n\t}\n\tif dec.BaseFee != nil {\n\t\tg.BaseFee = (*big.Int)(dec.BaseFee)\n\t}\n\tif dec.ExcessBlobGas != nil {\n\t\tg.ExcessBlobGas = (*uint64)(dec.ExcessBlobGas)\n\t}\n\tif dec.BlobGasUsed != nil {\n\t\tg.BlobGasUsed = (*uint64)(dec.BlobGasUsed)\n\t}\n\treturn nil\n}\n\n// toBlockWithRoot constructs the genesis block with the given genesis state root.\n//\n//nolint:gocognit,nestif // Mirrors geth's fork-specific genesis initialization flow.\nfunc (g *Genesis) toBlockWithRoot(root common.Hash) *Block {\n\thead := &Header{\n\t\tNumber:     new(big.Int).SetUint64(g.Number),\n\t\tNonce:      types.EncodeNonce(g.Nonce),\n\t\tTime:       g.Timestamp,\n\t\tParentHash: g.ParentHash,\n\t\tExtra:      g.ExtraData,\n\t\tGasLimit:   g.GasLimit,\n\t\tGasUsed:    g.GasUsed,\n\t\tBaseFee:    g.BaseFee,\n\t\tDifficulty: g.Difficulty,\n\t\tMixDigest:  g.Mixhash,\n\t\tCoinbase:   g.Coinbase,\n\t\tRoot:       root,\n\t}\n\tif g.GasLimit == 0 {\n\t\thead.GasLimit = params.GenesisGasLimit\n\t}\n\tif g.Difficulty == nil {\n\t\tif g.Config != nil && g.Config.Ethash == nil {\n\t\t\thead.Difficulty = big.NewInt(0)\n\t\t} else if g.Mixhash == (common.Hash{}) {\n\t\t\thead.Difficulty = params.GenesisDifficulty\n\t\t}\n\t}\n\tif g.Config != nil && g.Config.IsLondon(common.Big0) {\n\t\tif g.BaseFee != nil {\n\t\t\thead.BaseFee = g.BaseFee\n\t\t} else {\n\t\t\thead.BaseFee = new(big.Int).SetUint64(params.InitialBaseFee)\n\t\t}\n\t}\n\tvar (\n\t\twithdrawals []*types.Withdrawal\n\t)\n\tif conf := g.Config; conf != nil {\n\t\tnum := new(big.Int).SetUint64(g.Number)\n\t\tif conf.IsShanghai(num, g.Timestamp) {\n\t\t\thead.WithdrawalsHash = &types.EmptyWithdrawalsHash\n\t\t\twithdrawals = make([]*types.Withdrawal, 0)\n\t\t}\n\t\tif conf.IsCancun(num, g.Timestamp) {\n\t\t\t// EIP-4788: The parentBeaconBlockRoot of the genesis block is always\n\t\t\t// the zero hash. This is because the genesis block does not have a parent\n\t\t\t// by definition.\n\t\t\thead.ParentBeaconRoot = new(common.Hash)\n\t\t\t// EIP-4844 fields\n\t\t\thead.ExcessBlobGas = g.ExcessBlobGas\n\t\t\thead.BlobGasUsed = g.BlobGasUsed\n\t\t\tif head.ExcessBlobGas == nil {\n\t\t\t\thead.ExcessBlobGas = new(uint64)\n\t\t\t}\n\t\t\tif head.BlobGasUsed == nil {\n\t\t\t\thead.BlobGasUsed = new(uint64)\n\t\t\t}\n\t\t} else if g.ExcessBlobGas != nil {\n\t\t\tlog.Warn(\"Invalid genesis, unexpected ExcessBlobGas set before Cancun, allowing it for testing purposes\")\n\t\t\thead.ExcessBlobGas = g.ExcessBlobGas\n\t\t}\n\t\tif conf.IsPrague(num, g.Timestamp) {\n\t\t\thead.RequestsHash = &types.EmptyRequestsHash\n\t\t}\n\t\tif conf.IsPrague1(num, g.Timestamp) {\n\t\t\t// BRIP-0004: The parentProposerPubkey of the genesis block is always\n\t\t\t// the zero pubkey. This is because the genesis block does not have a parent\n\t\t\t// by definition.\n\t\t\thead.ParentProposerPubkey = new(ExecutionPubkey)\n\t\t}\n\t}\n\treturn NewBlock(head, &Body{Withdrawals: withdrawals}, nil, trie.NewStackTrie(nil))\n}\n\n// hashAlloc computes the state root according to the genesis specification.\nfunc hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) {\n\t// If a genesis-time verkle trie is requested, create a trie config\n\t// with the verkle trie enabled so that the tree can be initialized\n\t// as such.\n\tvar config *triedb.Config\n\tif isVerkle {\n\t\tconfig = &triedb.Config{\n\t\t\tPathDB:   pathdb.Defaults,\n\t\t\tIsVerkle: true,\n\t\t}\n\t}\n\t// Create an ephemeral in-memory database for computing hash,\n\t// all the derived states will be discarded to not pollute disk.\n\temptyRoot := types.EmptyRootHash\n\tif isVerkle {\n\t\temptyRoot = types.EmptyVerkleHash\n\t}\n\tdb := rawdb.NewMemoryDatabase()\n\tstatedb, err := state.New(emptyRoot, state.NewDatabase(triedb.NewDatabase(db, config), nil))\n\tif err != nil {\n\t\treturn common.Hash{}, err\n\t}\n\tfor addr, account := range *ga {\n\t\tif account.Balance != nil {\n\t\t\tstatedb.AddBalance(addr, uint256.MustFromBig(account.Balance), tracing.BalanceIncreaseGenesisBalance)\n\t\t}\n\t\tstatedb.SetCode(addr, account.Code, tracing.CodeChangeGenesis)\n\t\tstatedb.SetNonce(addr, account.Nonce, tracing.NonceChangeGenesis)\n\t\tfor key, value := range account.Storage {\n\t\t\tstatedb.SetState(addr, key, value)\n\t\t}\n\t}\n\treturn statedb.Commit(0, false, false)\n}\n"
  },
  {
    "path": "gethlib/types/header.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"math/big\"\n\t\"sync\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\tcoretypes \"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/ethereum/go-ethereum/crypto\"\n)\n\n// hasherPool holds LegacyKeccak256 buffer for rlpHash.\n//\n//nolint:gochecknoglobals // Shared pool is required to avoid allocations in hash hot paths.\nvar hasherPool = sync.Pool{\n\tNew: func() interface{} { return crypto.NewKeccakState() },\n}\n\n// Header represents a block header in the Ethereum blockchain.\ntype Header struct {\n\tParentHash  common.Hash          `json:\"parentHash\"       gencodec:\"required\"`\n\tUncleHash   common.Hash          `json:\"sha3Uncles\"       gencodec:\"required\"`\n\tCoinbase    common.Address       `json:\"miner\"`\n\tRoot        common.Hash          `json:\"stateRoot\"        gencodec:\"required\"`\n\tTxHash      common.Hash          `json:\"transactionsRoot\" gencodec:\"required\"`\n\tReceiptHash common.Hash          `json:\"receiptsRoot\"     gencodec:\"required\"`\n\tBloom       coretypes.Bloom      `json:\"logsBloom\"        gencodec:\"required\"`\n\tDifficulty  *big.Int             `json:\"difficulty\"       gencodec:\"required\"`\n\tNumber      *big.Int             `json:\"number\"           gencodec:\"required\"`\n\tGasLimit    uint64               `json:\"gasLimit\"         gencodec:\"required\"`\n\tGasUsed     uint64               `json:\"gasUsed\"          gencodec:\"required\"`\n\tTime        uint64               `json:\"timestamp\"        gencodec:\"required\"`\n\tExtra       []byte               `json:\"extraData\"        gencodec:\"required\"`\n\tMixDigest   common.Hash          `json:\"mixHash\"`\n\tNonce       coretypes.BlockNonce `json:\"nonce\"`\n\n\t// BaseFee was added by EIP-1559 and is ignored in legacy headers.\n\tBaseFee *big.Int `json:\"baseFeePerGas\" rlp:\"optional\"`\n\n\t// WithdrawalsHash was added by EIP-4895 and is ignored in legacy headers.\n\tWithdrawalsHash *common.Hash `json:\"withdrawalsRoot\" rlp:\"optional\"`\n\n\t// BlobGasUsed was added by EIP-4844 and is ignored in legacy headers.\n\tBlobGasUsed *uint64 `json:\"blobGasUsed\" rlp:\"optional\"`\n\n\t// ExcessBlobGas was added by EIP-4844 and is ignored in legacy headers.\n\tExcessBlobGas *uint64 `json:\"excessBlobGas\" rlp:\"optional\"`\n\n\t// ParentBeaconRoot was added by EIP-4788 and is ignored in legacy headers.\n\tParentBeaconRoot *common.Hash `json:\"parentBeaconBlockRoot\" rlp:\"optional\"`\n\n\t// RequestsHash was added by EIP-7685 and is ignored in legacy headers.\n\tRequestsHash *common.Hash `json:\"requestsHash\" rlp:\"optional\"`\n\n\t// ParentProposerPubkey was added by BRIP-0004 and is ignored in legacy headers.\n\tParentProposerPubkey *ExecutionPubkey `json:\"parentProposerPubkey\" rlp:\"optional\"`\n}\n\n// CopyHeader creates a deep copy of a block header.\nfunc CopyHeader(h *Header) *Header {\n\tcpy := *h\n\tif cpy.Difficulty = new(big.Int); h.Difficulty != nil {\n\t\tcpy.Difficulty.Set(h.Difficulty)\n\t}\n\tif cpy.Number = new(big.Int); h.Number != nil {\n\t\tcpy.Number.Set(h.Number)\n\t}\n\tif h.BaseFee != nil {\n\t\tcpy.BaseFee = new(big.Int).Set(h.BaseFee)\n\t}\n\tif len(h.Extra) > 0 {\n\t\tcpy.Extra = make([]byte, len(h.Extra))\n\t\tcopy(cpy.Extra, h.Extra)\n\t}\n\tif h.WithdrawalsHash != nil {\n\t\tcpy.WithdrawalsHash = new(common.Hash)\n\t\t*cpy.WithdrawalsHash = *h.WithdrawalsHash\n\t}\n\tif h.ExcessBlobGas != nil {\n\t\tcpy.ExcessBlobGas = new(uint64)\n\t\t*cpy.ExcessBlobGas = *h.ExcessBlobGas\n\t}\n\tif h.BlobGasUsed != nil {\n\t\tcpy.BlobGasUsed = new(uint64)\n\t\t*cpy.BlobGasUsed = *h.BlobGasUsed\n\t}\n\tif h.ParentBeaconRoot != nil {\n\t\tcpy.ParentBeaconRoot = new(common.Hash)\n\t\t*cpy.ParentBeaconRoot = *h.ParentBeaconRoot\n\t}\n\tif h.RequestsHash != nil {\n\t\tcpy.RequestsHash = new(common.Hash)\n\t\t*cpy.RequestsHash = *h.RequestsHash\n\t}\n\tif h.ParentProposerPubkey != nil {\n\t\tcpy.ParentProposerPubkey = new(ExecutionPubkey)\n\t\t*cpy.ParentProposerPubkey = *h.ParentProposerPubkey\n\t}\n\treturn &cpy\n}\n\n// Hash returns the block hash of the header, which is simply the keccak256 hash of its\n// RLP encoding.\nfunc (h *Header) Hash() common.Hash {\n\treturn rlpHash(h)\n}\n"
  },
  {
    "path": "gethlib/types/pubkey.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"bytes\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"reflect\"\n\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/ethereum/go-ethereum/common/hexutil\"\n)\n\n// ExecutionPubkey represents a 48-byte BLS12-381 public key on the execution layer.\n// JSON and text serialization use 0x-prefixed hex strings.\ntype ExecutionPubkey [constants.BLSPubkeyLength]byte\n\nconst (\n\thexPrefixBytes  = 2\n\thexCharsPerByte = 2\n)\n\n// Bytes returns a copy of the underlying byte slice.\nfunc (p ExecutionPubkey) Bytes() []byte { return p[:] }\n\n// String returns the hex-encoded string representation of the pubkey.\nfunc (p ExecutionPubkey) String() string { return hexutil.Encode(p[:]) }\n\n// Format implements fmt.Formatter.\n// Pubkey supports the %v, %s, %q, %x, %X and %d format verbs.\n//\n// #nosec:G104 // copied from geth and fmt.State.Write errors are conventionally ignored\nfunc (p ExecutionPubkey) Format(s fmt.State, c rune) {\n\thexb := make([]byte, hexPrefixBytes+len(p)*hexCharsPerByte)\n\tcopy(hexb, \"0x\")\n\thex.Encode(hexb[hexPrefixBytes:], p[:])\n\n\tswitch c {\n\tcase 'x', 'X':\n\t\tif !s.Flag('#') {\n\t\t\thexb = hexb[hexPrefixBytes:]\n\t\t}\n\t\tif c == 'X' {\n\t\t\thexb = bytes.ToUpper(hexb)\n\t\t}\n\t\tfallthrough\n\tcase 'v', 's':\n\t\t_, _ = s.Write(hexb)\n\tcase 'q':\n\t\tq := []byte{'\"'}\n\t\t_, _ = s.Write(q)\n\t\t_, _ = s.Write(hexb)\n\t\t_, _ = s.Write(q)\n\tcase 'd':\n\t\tfmt.Fprint(s, ([len(p)]byte)(p))\n\tdefault:\n\t\tfmt.Fprintf(s, \"%%!%c(pubkey=%x)\", c, p)\n\t}\n}\n\n// MarshalText encodes the pubkey as a 0x-prefixed hex string.\nfunc (p ExecutionPubkey) MarshalText() ([]byte, error) {\n\treturn hexutil.Bytes(p[:]).MarshalText()\n}\n\n// UnmarshalText decodes a 0x-prefixed hex string into the pubkey.\nfunc (p *ExecutionPubkey) UnmarshalText(input []byte) error {\n\treturn hexutil.UnmarshalFixedText(\"Pubkey\", input, p[:])\n}\n\n// UnmarshalJSON decodes a JSON string containing the 0x-prefixed hex pubkey.\nfunc (p *ExecutionPubkey) UnmarshalJSON(input []byte) error {\n\treturn hexutil.UnmarshalFixedJSON(reflect.TypeOf(ExecutionPubkey{}), input, p[:])\n}\n"
  },
  {
    "path": "gethlib/types/transaction.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"math/big\"\n\t\"sync/atomic\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\tcoretypes \"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/ethereum/go-ethereum/rlp\"\n)\n\n// TxData is the underlying data of a transaction.\ntype TxData interface {\n\ttxType() byte // returns the type ID\n\n\tencode(*bytes.Buffer) error\n\tdecode([]byte) error\n}\n\n// Transaction is similar to coretypes.Transaction, with added support\n// for the BRIP-0004 PoL transaction type.\ntype Transaction struct {\n\tinner TxData // Consensus contents of a transaction\n\n\t// cache\n\thash atomic.Pointer[common.Hash]\n}\n\n// BlobHashes returns the hashes of the blob commitments for blob transactions, nil otherwise.\nfunc (tx *Transaction) BlobHashes() []common.Hash {\n\tif blobtx, ok := tx.inner.(*BlobTx); ok {\n\t\treturn blobtx.BlobHashes\n\t}\n\treturn nil\n}\n\n// Hash returns the transaction hash.\nfunc (tx *Transaction) Hash() common.Hash {\n\tif hash := tx.hash.Load(); hash != nil {\n\t\treturn *hash\n\t}\n\n\tvar h common.Hash\n\tif tx.Type() == coretypes.LegacyTxType {\n\t\th = rlpHash(tx.inner)\n\t} else {\n\t\th = prefixedRlpHash(tx.Type(), tx.inner)\n\t}\n\ttx.hash.Store(&h)\n\treturn h\n}\n\n// Type returns the transaction type.\nfunc (tx *Transaction) Type() uint8 {\n\treturn tx.inner.txType()\n}\n\n// RawSignatureValues returns the transaction signature values.\n// PoL transactions intentionally return nil values because they are unsigned.\nfunc (tx *Transaction) RawSignatureValues() (*big.Int, *big.Int, *big.Int) {\n\tswitch itx := tx.inner.(type) {\n\tcase *LegacyTx:\n\t\treturn itx.V, itx.R, itx.S\n\tcase *AccessListTx:\n\t\treturn itx.V, itx.R, itx.S\n\tcase *DynamicFeeTx:\n\t\treturn itx.V, itx.R, itx.S\n\tcase *BlobTx:\n\t\tif itx.V == nil || itx.R == nil || itx.S == nil {\n\t\t\treturn nil, nil, nil\n\t\t}\n\t\treturn itx.V.ToBig(), itx.R.ToBig(), itx.S.ToBig()\n\tcase *SetCodeTx:\n\t\tif itx.V == nil || itx.R == nil || itx.S == nil {\n\t\t\treturn nil, nil, nil\n\t\t}\n\t\treturn itx.V.ToBig(), itx.R.ToBig(), itx.S.ToBig()\n\tdefault:\n\t\treturn nil, nil, nil\n\t}\n}\n\n// MarshalBinary returns the canonical encoding of the transaction.\n// For legacy transactions, it returns the RLP encoding. For EIP-2718 typed\n// transactions, it returns the type and payload.\nfunc (tx *Transaction) MarshalBinary() ([]byte, error) {\n\tif tx.Type() == coretypes.LegacyTxType {\n\t\treturn rlp.EncodeToBytes(tx.inner)\n\t}\n\tvar buf bytes.Buffer\n\terr := tx.encodeTyped(&buf)\n\treturn buf.Bytes(), err\n}\n\n// UnmarshalBinary decodes the canonical encoding of transactions.\n// It supports legacy RLP transactions and EIP-2718 typed transactions.\nfunc (tx *Transaction) UnmarshalBinary(b []byte) error {\n\tif len(b) > 0 && b[0] > 0x7f {\n\t\t// It's a legacy transaction.\n\t\tvar data LegacyTx\n\t\terr := rlp.DecodeBytes(b, &data)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\ttx.setDecoded(&data)\n\t\treturn nil\n\t}\n\t// It's an EIP-2718 typed transaction envelope.\n\tinner, err := tx.decodeTyped(b)\n\tif err != nil {\n\t\treturn err\n\t}\n\ttx.setDecoded(inner)\n\treturn nil\n}\n\n// encodeTyped writes the canonical encoding of a typed transaction to w.\nfunc (tx *Transaction) encodeTyped(w *bytes.Buffer) error {\n\tw.WriteByte(tx.Type())\n\treturn tx.inner.encode(w)\n}\n\n// decodeTyped decodes a typed transaction from the canonical format.\nfunc (tx *Transaction) decodeTyped(b []byte) (TxData, error) {\n\tif len(b) <= 1 {\n\t\treturn nil, errors.New(\"typed transaction too short\")\n\t}\n\tvar inner TxData\n\tswitch b[0] {\n\tcase coretypes.AccessListTxType:\n\t\tinner = new(AccessListTx)\n\tcase coretypes.DynamicFeeTxType:\n\t\tinner = new(DynamicFeeTx)\n\tcase coretypes.BlobTxType:\n\t\tinner = new(BlobTx)\n\tcase coretypes.SetCodeTxType:\n\t\tinner = new(SetCodeTx)\n\tcase PoLTxType:\n\t\tinner = new(PoLTx)\n\tdefault:\n\t\treturn nil, coretypes.ErrTxTypeNotSupported\n\t}\n\terr := inner.decode(b[1:])\n\treturn inner, err\n}\n\n// setDecoded sets the inner transaction and clears hash cache.\nfunc (tx *Transaction) setDecoded(inner TxData) {\n\ttx.inner = inner\n\ttx.hash.Store(nil)\n}\n\n// Transactions implements DerivableList for transactions.\ntype Transactions []*Transaction\n\n// Len returns the length of s.\nfunc (s Transactions) Len() int { return len(s) }\n\n// EncodeIndex encodes the i'th transaction to w. Note that this does not check for errors\n// because we assume that *Transaction will only ever contain valid txs that were either\n// constructed by decoding or via public API in this package.\nfunc (s Transactions) EncodeIndex(i int, w *bytes.Buffer) {\n\ttx := s[i]\n\tif tx.Type() == coretypes.LegacyTxType {\n\t\t_ = rlp.Encode(w, tx.inner)\n\t} else {\n\t\t_ = tx.encodeTyped(w)\n\t}\n}\n"
  },
  {
    "path": "gethlib/types/transaction_marshalling.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"math/big\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-ethereum/common/hexutil\"\n\tcoretypes \"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/ethereum/go-ethereum/crypto\"\n\t\"github.com/ethereum/go-ethereum/crypto/kzg4844\"\n\t\"github.com/holiman/uint256\"\n)\n\nvar (\n\terrInvalidYParity   = errors.New(\"'yParity' field must be 0 or 1\")\n\terrVYParityMismatch = errors.New(\"'v' and 'yParity' fields do not match\")\n\terrVYParityMissing  = errors.New(\"missing 'yParity' or 'v' field in transaction\")\n)\n\nconst (\n\trecoveryIDByteLen      = 8\n\treplayProtectionBitLen = 64\n\tlegacyVValue27         = 27\n\tlegacyVValue28         = 28\n\treplayProtectionBase   = 35\n\tchainIDDivisor         = 2\n)\n\n// txJSON is the JSON representation of transactions.\ntype txJSON struct {\n\tType hexutil.Uint64 `json:\"type\"`\n\n\tChainID              *hexutil.Big                     `json:\"chainId,omitempty\"`\n\tFrom                 *common.Address                  `json:\"from,omitempty\"`\n\tNonce                *hexutil.Uint64                  `json:\"nonce\"`\n\tTo                   *common.Address                  `json:\"to\"`\n\tGas                  *hexutil.Uint64                  `json:\"gas\"`\n\tGasPrice             *hexutil.Big                     `json:\"gasPrice\"`\n\tMaxPriorityFeePerGas *hexutil.Big                     `json:\"maxPriorityFeePerGas\"`\n\tMaxFeePerGas         *hexutil.Big                     `json:\"maxFeePerGas\"`\n\tMaxFeePerBlobGas     *hexutil.Big                     `json:\"maxFeePerBlobGas,omitempty\"`\n\tValue                *hexutil.Big                     `json:\"value\"`\n\tInput                *hexutil.Bytes                   `json:\"input\"`\n\tAccessList           *coretypes.AccessList            `json:\"accessList,omitempty\"`\n\tBlobVersionedHashes  []common.Hash                    `json:\"blobVersionedHashes,omitempty\"`\n\tAuthorizationList    []coretypes.SetCodeAuthorization `json:\"authorizationList,omitempty\"`\n\tV                    *hexutil.Big                     `json:\"v\"`\n\tR                    *hexutil.Big                     `json:\"r\"`\n\tS                    *hexutil.Big                     `json:\"s\"`\n\tYParity              *hexutil.Uint64                  `json:\"yParity,omitempty\"`\n\n\t// Blob transaction sidecar encoding:\n\tBlobs       []kzg4844.Blob       `json:\"blobs,omitempty\"`\n\tCommitments []kzg4844.Commitment `json:\"commitments,omitempty\"`\n\tProofs      []kzg4844.Proof      `json:\"proofs,omitempty\"`\n\n\t// Only used for encoding:\n\tHash common.Hash `json:\"hash\"`\n}\n\n// yParityValue returns the YParity value from JSON. For backwards-compatibility reasons,\n// this can be given in the 'v' field or the 'yParity' field. If both exist, they must match.\nfunc (tx *txJSON) yParityValue() (*big.Int, error) {\n\tif tx.YParity != nil {\n\t\tval := uint64(*tx.YParity)\n\t\tif val != 0 && val != 1 {\n\t\t\treturn nil, errInvalidYParity\n\t\t}\n\t\tbigval := new(big.Int).SetUint64(val)\n\t\tif tx.V != nil && tx.V.ToInt().Cmp(bigval) != 0 {\n\t\t\treturn nil, errVYParityMismatch\n\t\t}\n\t\treturn bigval, nil\n\t}\n\tif tx.V != nil {\n\t\treturn tx.V.ToInt(), nil\n\t}\n\treturn nil, errVYParityMissing\n}\n\n// MarshalJSON marshals as JSON with a hash.\n//\n//nolint:funlen // Mirrors geth transaction JSON shape for wire compatibility.\nfunc (tx *Transaction) MarshalJSON() ([]byte, error) {\n\tvar enc txJSON\n\thash := tx.Hash()\n\n\t// These are set for all tx types.\n\tenc.Hash = hash\n\tenc.Type = hexutil.Uint64(tx.Type())\n\n\t// Other fields are set conditionally depending on tx type.\n\tswitch itx := tx.inner.(type) {\n\tcase *LegacyTx:\n\t\tenc.Nonce = (*hexutil.Uint64)(&itx.Nonce)\n\t\tenc.To = itx.To\n\t\tenc.Gas = (*hexutil.Uint64)(&itx.Gas)\n\t\tenc.GasPrice = (*hexutil.Big)(itx.GasPrice)\n\t\tenc.Value = (*hexutil.Big)(itx.Value)\n\t\tenc.Input = (*hexutil.Bytes)(&itx.Data)\n\t\tenc.V = (*hexutil.Big)(itx.V)\n\t\tenc.R = (*hexutil.Big)(itx.R)\n\t\tenc.S = (*hexutil.Big)(itx.S)\n\t\tif itx.V != nil && isProtectedV(itx.V) {\n\t\t\tenc.ChainID = (*hexutil.Big)(deriveChainID(itx.V))\n\t\t}\n\n\tcase *AccessListTx:\n\t\tenc.ChainID = (*hexutil.Big)(itx.ChainID)\n\t\tenc.Nonce = (*hexutil.Uint64)(&itx.Nonce)\n\t\tenc.To = itx.To\n\t\tenc.Gas = (*hexutil.Uint64)(&itx.Gas)\n\t\tenc.GasPrice = (*hexutil.Big)(itx.GasPrice)\n\t\tenc.Value = (*hexutil.Big)(itx.Value)\n\t\tenc.Input = (*hexutil.Bytes)(&itx.Data)\n\t\tenc.AccessList = &itx.AccessList\n\t\tenc.V = (*hexutil.Big)(itx.V)\n\t\tenc.R = (*hexutil.Big)(itx.R)\n\t\tenc.S = (*hexutil.Big)(itx.S)\n\t\tif itx.V != nil {\n\t\t\typarity := itx.V.Uint64()\n\t\t\tenc.YParity = (*hexutil.Uint64)(&yparity)\n\t\t}\n\n\tcase *DynamicFeeTx:\n\t\tenc.ChainID = (*hexutil.Big)(itx.ChainID)\n\t\tenc.Nonce = (*hexutil.Uint64)(&itx.Nonce)\n\t\tenc.To = itx.To\n\t\tenc.Gas = (*hexutil.Uint64)(&itx.Gas)\n\t\tenc.MaxFeePerGas = (*hexutil.Big)(itx.GasFeeCap)\n\t\tenc.MaxPriorityFeePerGas = (*hexutil.Big)(itx.GasTipCap)\n\t\tenc.Value = (*hexutil.Big)(itx.Value)\n\t\tenc.Input = (*hexutil.Bytes)(&itx.Data)\n\t\tenc.AccessList = &itx.AccessList\n\t\tenc.V = (*hexutil.Big)(itx.V)\n\t\tenc.R = (*hexutil.Big)(itx.R)\n\t\tenc.S = (*hexutil.Big)(itx.S)\n\t\tif itx.V != nil {\n\t\t\typarity := itx.V.Uint64()\n\t\t\tenc.YParity = (*hexutil.Uint64)(&yparity)\n\t\t}\n\n\tcase *BlobTx:\n\t\tenc.ChainID = (*hexutil.Big)(itx.ChainID.ToBig())\n\t\tenc.Nonce = (*hexutil.Uint64)(&itx.Nonce)\n\t\tenc.Gas = (*hexutil.Uint64)(&itx.Gas)\n\t\tenc.MaxFeePerGas = (*hexutil.Big)(itx.GasFeeCap.ToBig())\n\t\tenc.MaxPriorityFeePerGas = (*hexutil.Big)(itx.GasTipCap.ToBig())\n\t\tenc.MaxFeePerBlobGas = (*hexutil.Big)(itx.BlobFeeCap.ToBig())\n\t\tenc.Value = (*hexutil.Big)(itx.Value.ToBig())\n\t\tenc.Input = (*hexutil.Bytes)(&itx.Data)\n\t\tenc.AccessList = &itx.AccessList\n\t\tenc.BlobVersionedHashes = itx.BlobHashes\n\t\tenc.To = &itx.To\n\t\tenc.V = (*hexutil.Big)(itx.V.ToBig())\n\t\tenc.R = (*hexutil.Big)(itx.R.ToBig())\n\t\tenc.S = (*hexutil.Big)(itx.S.ToBig())\n\t\typarity := itx.V.Uint64()\n\t\tenc.YParity = (*hexutil.Uint64)(&yparity)\n\t\tif sidecar := itx.Sidecar; sidecar != nil {\n\t\t\tenc.Blobs = itx.Sidecar.Blobs\n\t\t\tenc.Commitments = itx.Sidecar.Commitments\n\t\t\tenc.Proofs = itx.Sidecar.Proofs\n\t\t}\n\n\tcase *SetCodeTx:\n\t\tenc.ChainID = (*hexutil.Big)(itx.ChainID.ToBig())\n\t\tenc.Nonce = (*hexutil.Uint64)(&itx.Nonce)\n\t\tenc.To = &itx.To\n\t\tenc.Gas = (*hexutil.Uint64)(&itx.Gas)\n\t\tenc.MaxFeePerGas = (*hexutil.Big)(itx.GasFeeCap.ToBig())\n\t\tenc.MaxPriorityFeePerGas = (*hexutil.Big)(itx.GasTipCap.ToBig())\n\t\tenc.Value = (*hexutil.Big)(itx.Value.ToBig())\n\t\tenc.Input = (*hexutil.Bytes)(&itx.Data)\n\t\tenc.AccessList = &itx.AccessList\n\t\tenc.AuthorizationList = itx.AuthList\n\t\tenc.V = (*hexutil.Big)(itx.V.ToBig())\n\t\tenc.R = (*hexutil.Big)(itx.R.ToBig())\n\t\tenc.S = (*hexutil.Big)(itx.S.ToBig())\n\t\typarity := itx.V.Uint64()\n\t\tenc.YParity = (*hexutil.Uint64)(&yparity)\n\n\tcase *PoLTx:\n\t\tenc.ChainID = (*hexutil.Big)(itx.ChainID)\n\t\tenc.From = &itx.From\n\t\tenc.To = &itx.To\n\t\tenc.Nonce = (*hexutil.Uint64)(&itx.Nonce)\n\t\tgas := hexutil.Uint64(itx.GasLimit)\n\t\tenc.Gas = &gas\n\t\tenc.GasPrice = (*hexutil.Big)(itx.GasPrice)\n\t\tenc.Input = (*hexutil.Bytes)(&itx.Data)\n\t}\n\treturn json.Marshal(&enc)\n}\n\n// UnmarshalJSON unmarshals from JSON.\n//\n//nolint:gocognit,funlen,gocyclo,cyclop,maintidx // Mirrors geth transaction JSON shape for wire compatibility.\nfunc (tx *Transaction) UnmarshalJSON(input []byte) error {\n\tvar dec txJSON\n\tif err := json.Unmarshal(input, &dec); err != nil {\n\t\treturn err\n\t}\n\n\t// Decode / verify fields according to transaction type.\n\tvar inner TxData\n\ttxType := uint64(dec.Type)\n\tswitch txType {\n\tcase uint64(coretypes.LegacyTxType):\n\t\tvar itx LegacyTx\n\t\tinner = &itx\n\t\tif dec.Nonce == nil {\n\t\t\treturn errors.New(\"missing required field 'nonce' in transaction\")\n\t\t}\n\t\titx.Nonce = uint64(*dec.Nonce)\n\t\tif dec.To != nil {\n\t\t\titx.To = dec.To\n\t\t}\n\t\tif dec.Gas == nil {\n\t\t\treturn errors.New(\"missing required field 'gas' in transaction\")\n\t\t}\n\t\titx.Gas = uint64(*dec.Gas)\n\t\tif dec.GasPrice == nil {\n\t\t\treturn errors.New(\"missing required field 'gasPrice' in transaction\")\n\t\t}\n\t\titx.GasPrice = (*big.Int)(dec.GasPrice)\n\t\tif dec.Value == nil {\n\t\t\treturn errors.New(\"missing required field 'value' in transaction\")\n\t\t}\n\t\titx.Value = (*big.Int)(dec.Value)\n\t\tif dec.Input == nil {\n\t\t\treturn errors.New(\"missing required field 'input' in transaction\")\n\t\t}\n\t\titx.Data = *dec.Input\n\n\t\t// signature R\n\t\tif dec.R == nil {\n\t\t\treturn errors.New(\"missing required field 'r' in transaction\")\n\t\t}\n\t\titx.R = (*big.Int)(dec.R)\n\t\t// signature S\n\t\tif dec.S == nil {\n\t\t\treturn errors.New(\"missing required field 's' in transaction\")\n\t\t}\n\t\titx.S = (*big.Int)(dec.S)\n\t\t// signature V\n\t\tif dec.V == nil {\n\t\t\treturn errors.New(\"missing required field 'v' in transaction\")\n\t\t}\n\t\titx.V = (*big.Int)(dec.V)\n\t\tif itx.V.Sign() != 0 || itx.R.Sign() != 0 || itx.S.Sign() != 0 {\n\t\t\tsigErr := sanityCheckSignature(itx.V, itx.R, itx.S, true)\n\t\t\tif sigErr != nil {\n\t\t\t\treturn sigErr\n\t\t\t}\n\t\t}\n\n\tcase uint64(coretypes.AccessListTxType):\n\t\tvar itx AccessListTx\n\t\tinner = &itx\n\t\tif dec.ChainID == nil {\n\t\t\treturn errors.New(\"missing required field 'chainId' in transaction\")\n\t\t}\n\t\titx.ChainID = (*big.Int)(dec.ChainID)\n\t\tif dec.Nonce == nil {\n\t\t\treturn errors.New(\"missing required field 'nonce' in transaction\")\n\t\t}\n\t\titx.Nonce = uint64(*dec.Nonce)\n\t\tif dec.To != nil {\n\t\t\titx.To = dec.To\n\t\t}\n\t\tif dec.Gas == nil {\n\t\t\treturn errors.New(\"missing required field 'gas' in transaction\")\n\t\t}\n\t\titx.Gas = uint64(*dec.Gas)\n\t\tif dec.GasPrice == nil {\n\t\t\treturn errors.New(\"missing required field 'gasPrice' in transaction\")\n\t\t}\n\t\titx.GasPrice = (*big.Int)(dec.GasPrice)\n\t\tif dec.Value == nil {\n\t\t\treturn errors.New(\"missing required field 'value' in transaction\")\n\t\t}\n\t\titx.Value = (*big.Int)(dec.Value)\n\t\tif dec.Input == nil {\n\t\t\treturn errors.New(\"missing required field 'input' in transaction\")\n\t\t}\n\t\titx.Data = *dec.Input\n\t\tif dec.AccessList != nil {\n\t\t\titx.AccessList = *dec.AccessList\n\t\t}\n\n\t\t// signature R\n\t\tif dec.R == nil {\n\t\t\treturn errors.New(\"missing required field 'r' in transaction\")\n\t\t}\n\t\titx.R = (*big.Int)(dec.R)\n\t\t// signature S\n\t\tif dec.S == nil {\n\t\t\treturn errors.New(\"missing required field 's' in transaction\")\n\t\t}\n\t\titx.S = (*big.Int)(dec.S)\n\t\t// signature V\n\t\tvParity, parityErr := dec.yParityValue()\n\t\tif parityErr != nil {\n\t\t\treturn parityErr\n\t\t}\n\t\titx.V = vParity\n\t\tif itx.V.Sign() != 0 || itx.R.Sign() != 0 || itx.S.Sign() != 0 {\n\t\t\tsigErr := sanityCheckSignature(itx.V, itx.R, itx.S, false)\n\t\t\tif sigErr != nil {\n\t\t\t\treturn sigErr\n\t\t\t}\n\t\t}\n\n\tcase uint64(coretypes.DynamicFeeTxType):\n\t\tvar itx DynamicFeeTx\n\t\tinner = &itx\n\t\tif dec.ChainID == nil {\n\t\t\treturn errors.New(\"missing required field 'chainId' in transaction\")\n\t\t}\n\t\titx.ChainID = (*big.Int)(dec.ChainID)\n\t\tif dec.Nonce == nil {\n\t\t\treturn errors.New(\"missing required field 'nonce' in transaction\")\n\t\t}\n\t\titx.Nonce = uint64(*dec.Nonce)\n\t\tif dec.To != nil {\n\t\t\titx.To = dec.To\n\t\t}\n\t\tif dec.Gas == nil {\n\t\t\treturn errors.New(\"missing required field 'gas' for txdata\")\n\t\t}\n\t\titx.Gas = uint64(*dec.Gas)\n\t\tif dec.MaxPriorityFeePerGas == nil {\n\t\t\treturn errors.New(\"missing required field 'maxPriorityFeePerGas' for txdata\")\n\t\t}\n\t\titx.GasTipCap = (*big.Int)(dec.MaxPriorityFeePerGas)\n\t\tif dec.MaxFeePerGas == nil {\n\t\t\treturn errors.New(\"missing required field 'maxFeePerGas' for txdata\")\n\t\t}\n\t\titx.GasFeeCap = (*big.Int)(dec.MaxFeePerGas)\n\t\tif dec.Value == nil {\n\t\t\treturn errors.New(\"missing required field 'value' in transaction\")\n\t\t}\n\t\titx.Value = (*big.Int)(dec.Value)\n\t\tif dec.Input == nil {\n\t\t\treturn errors.New(\"missing required field 'input' in transaction\")\n\t\t}\n\t\titx.Data = *dec.Input\n\t\tif dec.AccessList != nil {\n\t\t\titx.AccessList = *dec.AccessList\n\t\t}\n\n\t\t// signature R\n\t\tif dec.R == nil {\n\t\t\treturn errors.New(\"missing required field 'r' in transaction\")\n\t\t}\n\t\titx.R = (*big.Int)(dec.R)\n\t\t// signature S\n\t\tif dec.S == nil {\n\t\t\treturn errors.New(\"missing required field 's' in transaction\")\n\t\t}\n\t\titx.S = (*big.Int)(dec.S)\n\t\t// signature V\n\t\tvParity, parityErr := dec.yParityValue()\n\t\tif parityErr != nil {\n\t\t\treturn parityErr\n\t\t}\n\t\titx.V = vParity\n\t\tif itx.V.Sign() != 0 || itx.R.Sign() != 0 || itx.S.Sign() != 0 {\n\t\t\tsigErr := sanityCheckSignature(itx.V, itx.R, itx.S, false)\n\t\t\tif sigErr != nil {\n\t\t\t\treturn sigErr\n\t\t\t}\n\t\t}\n\n\tcase uint64(coretypes.BlobTxType):\n\t\tvar itx BlobTx\n\t\tinner = &itx\n\t\tif dec.ChainID == nil {\n\t\t\treturn errors.New(\"missing required field 'chainId' in transaction\")\n\t\t}\n\t\tvar overflow bool\n\t\titx.ChainID, overflow = uint256.FromBig(dec.ChainID.ToInt())\n\t\tif overflow {\n\t\t\treturn errors.New(\"'chainId' value overflows uint256\")\n\t\t}\n\t\tif dec.Nonce == nil {\n\t\t\treturn errors.New(\"missing required field 'nonce' in transaction\")\n\t\t}\n\t\titx.Nonce = uint64(*dec.Nonce)\n\t\tif dec.To == nil {\n\t\t\treturn errors.New(\"missing required field 'to' in transaction\")\n\t\t}\n\t\titx.To = *dec.To\n\t\tif dec.Gas == nil {\n\t\t\treturn errors.New(\"missing required field 'gas' for txdata\")\n\t\t}\n\t\titx.Gas = uint64(*dec.Gas)\n\t\tif dec.MaxPriorityFeePerGas == nil {\n\t\t\treturn errors.New(\"missing required field 'maxPriorityFeePerGas' for txdata\")\n\t\t}\n\t\titx.GasTipCap = uint256.MustFromBig((*big.Int)(dec.MaxPriorityFeePerGas))\n\t\tif dec.MaxFeePerGas == nil {\n\t\t\treturn errors.New(\"missing required field 'maxFeePerGas' for txdata\")\n\t\t}\n\t\titx.GasFeeCap = uint256.MustFromBig((*big.Int)(dec.MaxFeePerGas))\n\t\tif dec.MaxFeePerBlobGas == nil {\n\t\t\treturn errors.New(\"missing required field 'maxFeePerBlobGas' for txdata\")\n\t\t}\n\t\titx.BlobFeeCap = uint256.MustFromBig((*big.Int)(dec.MaxFeePerBlobGas))\n\t\tif dec.Value == nil {\n\t\t\treturn errors.New(\"missing required field 'value' in transaction\")\n\t\t}\n\t\titx.Value = uint256.MustFromBig((*big.Int)(dec.Value))\n\t\tif dec.Input == nil {\n\t\t\treturn errors.New(\"missing required field 'input' in transaction\")\n\t\t}\n\t\titx.Data = *dec.Input\n\t\tif dec.AccessList != nil {\n\t\t\titx.AccessList = *dec.AccessList\n\t\t}\n\t\tif dec.BlobVersionedHashes == nil {\n\t\t\treturn errors.New(\"missing required field 'blobVersionedHashes' in transaction\")\n\t\t}\n\t\titx.BlobHashes = dec.BlobVersionedHashes\n\n\t\t// signature R\n\t\tif dec.R == nil {\n\t\t\treturn errors.New(\"missing required field 'r' in transaction\")\n\t\t}\n\t\titx.R, overflow = uint256.FromBig((*big.Int)(dec.R))\n\t\tif overflow {\n\t\t\treturn errors.New(\"'r' value overflows uint256\")\n\t\t}\n\t\t// signature S\n\t\tif dec.S == nil {\n\t\t\treturn errors.New(\"missing required field 's' in transaction\")\n\t\t}\n\t\titx.S, overflow = uint256.FromBig((*big.Int)(dec.S))\n\t\tif overflow {\n\t\t\treturn errors.New(\"'s' value overflows uint256\")\n\t\t}\n\t\t// signature V\n\t\tvParity, parityErr := dec.yParityValue()\n\t\tif parityErr != nil {\n\t\t\treturn parityErr\n\t\t}\n\t\titx.V, overflow = uint256.FromBig(vParity)\n\t\tif overflow {\n\t\t\treturn errors.New(\"'v' value overflows uint256\")\n\t\t}\n\t\tif itx.V.Sign() != 0 || itx.R.Sign() != 0 || itx.S.Sign() != 0 {\n\t\t\tsigErr := sanityCheckSignature(vParity, itx.R.ToBig(), itx.S.ToBig(), false)\n\t\t\tif sigErr != nil {\n\t\t\t\treturn sigErr\n\t\t\t}\n\t\t}\n\n\tcase uint64(coretypes.SetCodeTxType):\n\t\tvar itx SetCodeTx\n\t\tinner = &itx\n\t\tif dec.ChainID == nil {\n\t\t\treturn errors.New(\"missing required field 'chainId' in transaction\")\n\t\t}\n\t\tvar overflow bool\n\t\titx.ChainID, overflow = uint256.FromBig(dec.ChainID.ToInt())\n\t\tif overflow {\n\t\t\treturn errors.New(\"'chainId' value overflows uint256\")\n\t\t}\n\t\tif dec.Nonce == nil {\n\t\t\treturn errors.New(\"missing required field 'nonce' in transaction\")\n\t\t}\n\t\titx.Nonce = uint64(*dec.Nonce)\n\t\tif dec.To == nil {\n\t\t\treturn errors.New(\"missing required field 'to' in transaction\")\n\t\t}\n\t\titx.To = *dec.To\n\t\tif dec.Gas == nil {\n\t\t\treturn errors.New(\"missing required field 'gas' for txdata\")\n\t\t}\n\t\titx.Gas = uint64(*dec.Gas)\n\t\tif dec.MaxPriorityFeePerGas == nil {\n\t\t\treturn errors.New(\"missing required field 'maxPriorityFeePerGas' for txdata\")\n\t\t}\n\t\titx.GasTipCap = uint256.MustFromBig((*big.Int)(dec.MaxPriorityFeePerGas))\n\t\tif dec.MaxFeePerGas == nil {\n\t\t\treturn errors.New(\"missing required field 'maxFeePerGas' for txdata\")\n\t\t}\n\t\titx.GasFeeCap = uint256.MustFromBig((*big.Int)(dec.MaxFeePerGas))\n\t\tif dec.Value == nil {\n\t\t\treturn errors.New(\"missing required field 'value' in transaction\")\n\t\t}\n\t\titx.Value = uint256.MustFromBig((*big.Int)(dec.Value))\n\t\tif dec.Input == nil {\n\t\t\treturn errors.New(\"missing required field 'input' in transaction\")\n\t\t}\n\t\titx.Data = *dec.Input\n\t\tif dec.AccessList != nil {\n\t\t\titx.AccessList = *dec.AccessList\n\t\t}\n\t\tif dec.AuthorizationList == nil {\n\t\t\treturn errors.New(\"missing required field 'authorizationList' in transaction\")\n\t\t}\n\t\titx.AuthList = dec.AuthorizationList\n\n\t\t// signature R\n\t\tif dec.R == nil {\n\t\t\treturn errors.New(\"missing required field 'r' in transaction\")\n\t\t}\n\t\titx.R, overflow = uint256.FromBig((*big.Int)(dec.R))\n\t\tif overflow {\n\t\t\treturn errors.New(\"'r' value overflows uint256\")\n\t\t}\n\t\t// signature S\n\t\tif dec.S == nil {\n\t\t\treturn errors.New(\"missing required field 's' in transaction\")\n\t\t}\n\t\titx.S, overflow = uint256.FromBig((*big.Int)(dec.S))\n\t\tif overflow {\n\t\t\treturn errors.New(\"'s' value overflows uint256\")\n\t\t}\n\t\t// signature V\n\t\tvParity, parityErr := dec.yParityValue()\n\t\tif parityErr != nil {\n\t\t\treturn parityErr\n\t\t}\n\t\titx.V, overflow = uint256.FromBig(vParity)\n\t\tif overflow {\n\t\t\treturn errors.New(\"'v' value overflows uint256\")\n\t\t}\n\t\tif itx.V.Sign() != 0 || itx.R.Sign() != 0 || itx.S.Sign() != 0 {\n\t\t\tsigErr := sanityCheckSignature(vParity, itx.R.ToBig(), itx.S.ToBig(), false)\n\t\t\tif sigErr != nil {\n\t\t\t\treturn sigErr\n\t\t\t}\n\t\t}\n\n\tcase uint64(PoLTxType):\n\t\tvar itx PoLTx\n\t\tinner = &itx\n\t\tif dec.ChainID == nil {\n\t\t\treturn errors.New(\"missing required field 'chainId' in transaction\")\n\t\t}\n\t\titx.ChainID = (*big.Int)(dec.ChainID)\n\t\tif dec.From == nil {\n\t\t\treturn errors.New(\"missing required field 'from' in transaction\")\n\t\t}\n\t\titx.From = *dec.From\n\t\tif dec.To == nil {\n\t\t\treturn errors.New(\"missing required field 'to' in transaction\")\n\t\t}\n\t\titx.To = *dec.To\n\t\tif dec.Nonce == nil {\n\t\t\treturn errors.New(\"missing required field 'nonce' in transaction\")\n\t\t}\n\t\titx.Nonce = uint64(*dec.Nonce)\n\t\tif dec.Gas == nil {\n\t\t\treturn errors.New(\"missing required field 'gas' in transaction\")\n\t\t}\n\t\titx.GasLimit = uint64(*dec.Gas)\n\t\tif dec.GasPrice == nil {\n\t\t\treturn errors.New(\"missing required field 'gasPrice' in transaction\")\n\t\t}\n\t\titx.GasPrice = (*big.Int)(dec.GasPrice)\n\t\tif dec.Input == nil {\n\t\t\treturn errors.New(\"missing required field 'input' in transaction\")\n\t\t}\n\t\titx.Data = *dec.Input\n\n\tdefault:\n\t\treturn coretypes.ErrTxTypeNotSupported\n\t}\n\n\t// Set the inner transaction.\n\ttx.setDecoded(inner)\n\treturn nil\n}\n\nfunc sanityCheckSignature(v *big.Int, r *big.Int, s *big.Int, maybeProtected bool) error {\n\tif isProtectedV(v) && !maybeProtected {\n\t\treturn coretypes.ErrUnexpectedProtection\n\t}\n\n\tvar plainV uint64\n\tswitch {\n\tcase isProtectedV(v):\n\t\tchainID := deriveChainID(v).Uint64()\n\t\tplainV = v.Uint64() - replayProtectionBase - chainIDDivisor*chainID\n\tcase maybeProtected:\n\t\t// Only EIP-155 signatures can be optionally protected. Since\n\t\t// we determined this v value is not protected, it must be a\n\t\t// raw 27 or 28.\n\t\tplainV = v.Uint64() - legacyVValue27\n\tdefault:\n\t\t// If the signature is not optionally protected, we assume it\n\t\t// must already be equal to the recovery id.\n\t\tplainV = v.Uint64()\n\t}\n\n\tvar recoveryID byte\n\tswitch plainV {\n\tcase 0:\n\t\trecoveryID = 0\n\tcase 1:\n\t\trecoveryID = 1\n\tdefault:\n\t\treturn coretypes.ErrInvalidSig\n\t}\n\tif !crypto.ValidateSignatureValues(recoveryID, r, s, false) {\n\t\treturn coretypes.ErrInvalidSig\n\t}\n\n\treturn nil\n}\n\nfunc isProtectedV(v *big.Int) bool {\n\tif v.BitLen() <= recoveryIDByteLen {\n\t\tval := v.Uint64()\n\t\treturn val != legacyVValue27 && val != legacyVValue28 && val != 1 && val != 0\n\t}\n\t// Anything not 27 or 28 is considered protected.\n\treturn true\n}\n\n// deriveChainID derives the chain ID from a signature v value.\nfunc deriveChainID(v *big.Int) *big.Int {\n\tif v.BitLen() <= replayProtectionBitLen {\n\t\tval := v.Uint64()\n\t\tif val == legacyVValue27 || val == legacyVValue28 {\n\t\t\treturn new(big.Int)\n\t\t}\n\t\treturn new(big.Int).SetUint64((val - replayProtectionBase) / chainIDDivisor)\n\t}\n\tvCopy := new(big.Int).Sub(v, big.NewInt(replayProtectionBase))\n\treturn vCopy.Rsh(vCopy, 1)\n}\n"
  },
  {
    "path": "gethlib/types/tx_types.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math/big\"\n\n\t\"github.com/ethereum/go-ethereum/common\"\n\tcoretypes \"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/ethereum/go-ethereum/crypto/kzg4844\"\n\t\"github.com/ethereum/go-ethereum/rlp\"\n\t\"github.com/holiman/uint256\"\n)\n\n// BRIP-0004 PoL transaction type.\nconst PoLTxType = 0x7E\n\n// AccessListTx is the data of EIP-2930 access list transactions.\ntype AccessListTx struct {\n\tChainID    *big.Int             // destination chain ID\n\tNonce      uint64               // nonce of sender account\n\tGasPrice   *big.Int             // wei per gas\n\tGas        uint64               // gas limit\n\tTo         *common.Address      `rlp:\"nil\"` // nil means contract creation\n\tValue      *big.Int             // wei amount\n\tData       []byte               // contract invocation input data\n\tAccessList coretypes.AccessList // EIP-2930 access list\n\tV, R, S    *big.Int             // signature values\n}\n\nfunc (tx *AccessListTx) txType() byte { return coretypes.AccessListTxType }\n\nfunc (tx *AccessListTx) encode(b *bytes.Buffer) error {\n\treturn rlp.Encode(b, tx)\n}\n\nfunc (tx *AccessListTx) decode(input []byte) error {\n\treturn rlp.DecodeBytes(input, tx)\n}\n\n// BlobTx represents an EIP-4844 transaction.\ntype BlobTx struct {\n\tChainID    *uint256.Int\n\tNonce      uint64\n\tGasTipCap  *uint256.Int // a.k.a. maxPriorityFeePerGas\n\tGasFeeCap  *uint256.Int // a.k.a. maxFeePerGas\n\tGas        uint64\n\tTo         common.Address\n\tValue      *uint256.Int\n\tData       []byte\n\tAccessList coretypes.AccessList\n\tBlobFeeCap *uint256.Int // a.k.a. maxFeePerBlobGas\n\tBlobHashes []common.Hash\n\n\t// A blob transaction can optionally contain blobs. This field must be set when BlobTx\n\t// is used to create a transaction for signing.\n\tSidecar *coretypes.BlobTxSidecar `rlp:\"-\"`\n\n\t// Signature values\n\tV *uint256.Int\n\tR *uint256.Int\n\tS *uint256.Int\n}\n\nfunc (tx *BlobTx) txType() byte { return coretypes.BlobTxType }\n\nfunc (tx *BlobTx) encode(b *bytes.Buffer) error {\n\tswitch {\n\tcase tx.Sidecar == nil:\n\t\treturn rlp.Encode(b, tx)\n\n\tcase tx.Sidecar.Version == coretypes.BlobSidecarVersion0:\n\t\treturn rlp.Encode(b, &blobTxWithBlobsV0{\n\t\t\tBlobTx:      tx,\n\t\t\tBlobs:       tx.Sidecar.Blobs,\n\t\t\tCommitments: tx.Sidecar.Commitments,\n\t\t\tProofs:      tx.Sidecar.Proofs,\n\t\t})\n\n\tcase tx.Sidecar.Version == coretypes.BlobSidecarVersion1:\n\t\treturn rlp.Encode(b, &blobTxWithBlobsV1{\n\t\t\tBlobTx:      tx,\n\t\t\tVersion:     tx.Sidecar.Version,\n\t\t\tBlobs:       tx.Sidecar.Blobs,\n\t\t\tCommitments: tx.Sidecar.Commitments,\n\t\t\tProofs:      tx.Sidecar.Proofs,\n\t\t})\n\n\tdefault:\n\t\treturn errors.New(\"unsupported sidecar version\")\n\t}\n}\n\nfunc (tx *BlobTx) decode(input []byte) error {\n\t// Here we need to support two outer formats: the network protocol encoding of the tx\n\t// (with blobs) or the canonical encoding without blobs.\n\t//\n\t// The canonical encoding is just a list of fields:\n\t//\n\t//     [chainID, nonce, ...]\n\t//\n\t// The network encoding is a list where the first element is the tx in the canonical encoding,\n\t// and the remaining elements are the 'sidecar':\n\t//\n\t//     [[chainID, nonce, ...], ...]\n\t//\n\t// The two outer encodings can be distinguished by checking whether the first element\n\t// of the input list is itself a list. If it's the canonical encoding, the first\n\t// element is the chainID, which is a number.\n\n\tfirstElem, _, err := rlp.SplitList(input)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfirstElemKind, _, secondElem, err := rlp.Split(firstElem)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif firstElemKind != rlp.List {\n\t\t// Blob tx without blobs.\n\t\treturn rlp.DecodeBytes(input, tx)\n\t}\n\n\t// Now we know it's the network encoding with the blob sidecar. Here we again need to\n\t// support multiple encodings: legacy sidecars (v0) with a blob proof, and versioned\n\t// sidecars.\n\t//\n\t// The legacy encoding is:\n\t//\n\t//     [tx, blobs, commitments, proofs]\n\t//\n\t// The versioned encoding is:\n\t//\n\t//     [tx, version, blobs, ...]\n\t//\n\t// We can tell the two apart by checking whether the second element is the version byte.\n\t// For legacy sidecar the second element is a list of blobs.\n\n\tsecondElemKind, _, _, err := rlp.Split(secondElem)\n\tif err != nil {\n\t\treturn err\n\t}\n\tvar payload blobTxWithBlobs\n\tif secondElemKind == rlp.List {\n\t\t// No version byte: blob sidecar v0.\n\t\tpayload = new(blobTxWithBlobsV0)\n\t} else {\n\t\t// It has a version byte. Decode as v1, version is checked by assign()\n\t\tpayload = new(blobTxWithBlobsV1)\n\t}\n\terr = rlp.DecodeBytes(input, payload)\n\tif err != nil {\n\t\treturn err\n\t}\n\tsc := new(coretypes.BlobTxSidecar)\n\terr = payload.assign(sc)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*tx = *payload.tx()\n\ttx.Sidecar = sc\n\treturn nil\n}\n\n// blobTxWithBlobs represents blob tx with its corresponding sidecar.\n// This is an interface because sidecars are versioned.\ntype blobTxWithBlobs interface {\n\ttx() *BlobTx\n\tassign(*coretypes.BlobTxSidecar) error\n}\n\ntype blobTxWithBlobsV0 struct {\n\tBlobTx      *BlobTx\n\tBlobs       []kzg4844.Blob\n\tCommitments []kzg4844.Commitment\n\tProofs      []kzg4844.Proof\n}\n\ntype blobTxWithBlobsV1 struct {\n\tBlobTx      *BlobTx\n\tVersion     byte\n\tBlobs       []kzg4844.Blob\n\tCommitments []kzg4844.Commitment\n\tProofs      []kzg4844.Proof\n}\n\nfunc (btx *blobTxWithBlobsV0) tx() *BlobTx {\n\treturn btx.BlobTx\n}\n\nfunc (btx *blobTxWithBlobsV0) assign(sc *coretypes.BlobTxSidecar) error {\n\tsc.Version = coretypes.BlobSidecarVersion0\n\tsc.Blobs = btx.Blobs\n\tsc.Commitments = btx.Commitments\n\tsc.Proofs = btx.Proofs\n\treturn nil\n}\n\nfunc (btx *blobTxWithBlobsV1) tx() *BlobTx {\n\treturn btx.BlobTx\n}\n\nfunc (btx *blobTxWithBlobsV1) assign(sc *coretypes.BlobTxSidecar) error {\n\tif btx.Version != coretypes.BlobSidecarVersion1 {\n\t\treturn fmt.Errorf(\"unsupported blob tx version %d\", btx.Version)\n\t}\n\tsc.Version = coretypes.BlobSidecarVersion1\n\tsc.Blobs = btx.Blobs\n\tsc.Commitments = btx.Commitments\n\tsc.Proofs = btx.Proofs\n\treturn nil\n}\n\n// DynamicFeeTx represents an EIP-1559 transaction.\ntype DynamicFeeTx struct {\n\tChainID    *big.Int\n\tNonce      uint64\n\tGasTipCap  *big.Int // a.k.a. maxPriorityFeePerGas\n\tGasFeeCap  *big.Int // a.k.a. maxFeePerGas\n\tGas        uint64\n\tTo         *common.Address `rlp:\"nil\"` // nil means contract creation\n\tValue      *big.Int\n\tData       []byte\n\tAccessList coretypes.AccessList\n\n\t// Signature values\n\tV *big.Int\n\tR *big.Int\n\tS *big.Int\n}\n\nfunc (tx *DynamicFeeTx) txType() byte { return coretypes.DynamicFeeTxType }\n\nfunc (tx *DynamicFeeTx) encode(b *bytes.Buffer) error {\n\treturn rlp.Encode(b, tx)\n}\n\nfunc (tx *DynamicFeeTx) decode(input []byte) error {\n\treturn rlp.DecodeBytes(input, tx)\n}\n\n// LegacyTx is the transaction data of the original Ethereum transactions.\ntype LegacyTx struct {\n\tNonce    uint64          // nonce of sender account\n\tGasPrice *big.Int        // wei per gas\n\tGas      uint64          // gas limit\n\tTo       *common.Address `rlp:\"nil\"` // nil means contract creation\n\tValue    *big.Int        // wei amount\n\tData     []byte          // contract invocation input data\n\tV, R, S  *big.Int        // signature values\n}\n\nfunc (tx *LegacyTx) txType() byte { return coretypes.LegacyTxType }\n\nfunc (tx *LegacyTx) encode(*bytes.Buffer) error {\n\tpanic(\"encode called on LegacyTx\")\n}\n\nfunc (tx *LegacyTx) decode([]byte) error {\n\tpanic(\"decode called on LegacyTx)\")\n}\n\n// PoLTx represents an BRIP-0004 transaction. No gas is consumed for execution.\ntype PoLTx struct {\n\tChainID  *big.Int\n\tFrom     common.Address // system address\n\tTo       common.Address // address of the PoL Distributor contract\n\tNonce    uint64         // block number distributing for\n\tGasLimit uint64         // artificial gas limit for the PoL tx, not consumed against the block gas limit\n\tGasPrice *big.Int       // gas price is set to the baseFee to make the tx valid for EIP-1559 rules\n\tData     []byte         // encodes the pubkey distributing for\n}\n\nfunc (*PoLTx) txType() byte { return PoLTxType }\n\nfunc (tx *PoLTx) encode(b *bytes.Buffer) error {\n\treturn rlp.Encode(b, tx)\n}\n\nfunc (tx *PoLTx) decode(input []byte) error {\n\treturn rlp.DecodeBytes(input, tx)\n}\n\n// SetCodeTx implements the EIP-7702 transaction type which temporarily installs\n// the code at the signer's address.\ntype SetCodeTx struct {\n\tChainID    *uint256.Int\n\tNonce      uint64\n\tGasTipCap  *uint256.Int // a.k.a. maxPriorityFeePerGas\n\tGasFeeCap  *uint256.Int // a.k.a. maxFeePerGas\n\tGas        uint64\n\tTo         common.Address\n\tValue      *uint256.Int\n\tData       []byte\n\tAccessList coretypes.AccessList\n\tAuthList   []coretypes.SetCodeAuthorization\n\n\t// Signature values\n\tV *uint256.Int\n\tR *uint256.Int\n\tS *uint256.Int\n}\n\nfunc (tx *SetCodeTx) txType() byte { return coretypes.SetCodeTxType }\n\nfunc (tx *SetCodeTx) encode(b *bytes.Buffer) error {\n\treturn rlp.Encode(b, tx)\n}\n\nfunc (tx *SetCodeTx) decode(input []byte) error {\n\treturn rlp.DecodeBytes(input, tx)\n}\n"
  },
  {
    "path": "gethlib/types/utils.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"github.com/ethereum/go-ethereum/common\"\n\tcoretypes \"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/ethereum/go-ethereum/crypto\"\n\t\"github.com/ethereum/go-ethereum/rlp\"\n)\n\nfunc CalcUncleHash(uncles []*Header) common.Hash {\n\tif len(uncles) == 0 {\n\t\treturn coretypes.EmptyUncleHash\n\t}\n\treturn rlpHash(uncles)\n}\n\n// rlpHash encodes x and hashes the encoded bytes.\nfunc rlpHash(x interface{}) common.Hash {\n\tvar h common.Hash\n\tsha, ok := hasherPool.Get().(crypto.KeccakState)\n\tif !ok {\n\t\tsha = crypto.NewKeccakState()\n\t}\n\tdefer hasherPool.Put(sha)\n\tsha.Reset()\n\t_ = rlp.Encode(sha, x)\n\t_, _ = sha.Read(h[:])\n\treturn h\n}\n\n// prefixedRlpHash writes the prefix into the hasher before rlp-encoding x.\n// It's used for typed transactions.\nfunc prefixedRlpHash(prefix byte, x interface{}) common.Hash {\n\tvar h common.Hash\n\tsha, ok := hasherPool.Get().(crypto.KeccakState)\n\tif !ok {\n\t\tsha = crypto.NewKeccakState()\n\t}\n\tdefer hasherPool.Put(sha)\n\tsha.Reset()\n\t_, _ = sha.Write([]byte{prefix})\n\t_ = rlp.Encode(sha, x)\n\t_, _ = sha.Read(h[:])\n\treturn h\n}\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/berachain/beacon-kit\n\ngo 1.26.2\n\nreplace (\n\tgithub.com/cometbft/cometbft => github.com/berachain/cometbft v1.0.1-0.20260417142533-880521c815b6\n\tgithub.com/cometbft/cometbft/api => github.com/berachain/cometbft/api v1.0.1-0.20260417142533-880521c815b6\n\tgithub.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.52.0-rc.1\n\tgithub.com/karalabe/ssz => github.com/berachain/karalabe-ssz v0.3.0-alpha.0\n)\n\nrequire (\n\tcosmossdk.io/collections v1.3.1\n\tcosmossdk.io/core v1.0.0\n\tcosmossdk.io/depinject v1.2.1\n\tcosmossdk.io/errors v1.0.2\n\tcosmossdk.io/log v1.6.1\n\tcosmossdk.io/math v1.5.3\n\tcosmossdk.io/store v1.10.0-rc.1.0.20241218084712-ca559989da43\n\tgithub.com/cenkalti/backoff/v5 v5.0.3\n\tgithub.com/cometbft/cometbft v1.0.1-0.20241220100824-07c737de00ff\n\tgithub.com/cometbft/cometbft/api v1.0.1-0.20241220100824-07c737de00ff\n\tgithub.com/cosmos/cosmos-db v1.1.3\n\tgithub.com/cosmos/cosmos-sdk v0.53.0\n\tgithub.com/cosmos/go-bip39 v1.0.0\n\tgithub.com/crate-crypto/go-kzg-4844 v1.1.0\n\tgithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc\n\tgithub.com/go-faster/xor v1.0.0\n\tgithub.com/go-playground/validator/v10 v10.28.0\n\tgithub.com/golang-jwt/jwt/v5 v5.3.0\n\tgithub.com/hashicorp/go-metrics v0.5.4\n\tgithub.com/hashicorp/golang-lru/v2 v2.0.7\n\tgithub.com/holiman/uint256 v1.3.2\n\tgithub.com/karalabe/ssz v0.2.1-0.20240724074312-3d1ff7a6f7c4\n\tgithub.com/labstack/echo/v4 v4.13.4\n\tgithub.com/minio/sha256-simd v1.0.1\n\tgithub.com/mitchellh/mapstructure v1.5.0\n\tgithub.com/ory/dockertest v3.3.5+incompatible\n\tgithub.com/phuslu/log v1.0.120\n\tgithub.com/pkg/errors v0.9.1\n\tgithub.com/prysmaticlabs/gohashtree v0.0.4-beta.0.20240624100937-73632381301b\n\tgithub.com/prysmaticlabs/prysm/v5 v5.3.0\n\tgithub.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8\n\tgithub.com/spf13/afero v1.15.0\n\tgithub.com/spf13/cast v1.10.0\n\tgithub.com/spf13/cobra v1.10.2\n\tgithub.com/spf13/pflag v1.0.10\n\tgithub.com/spf13/viper v1.21.0\n\tgithub.com/umbracle/fastrlp v0.1.0\n\tgo.uber.org/automaxprocs v1.6.0\n\tgolang.org/x/crypto v0.49.0\n\tgolang.org/x/sync v0.20.0\n\tsigs.k8s.io/yaml v1.6.0\n)\n\n// build/test dependencies\nrequire (\n\tgithub.com/attestantio/go-eth2-client v0.27.2\n\tgithub.com/cosmos/ics23/go v0.11.0\n\tgithub.com/ethereum/go-ethereum v1.17.0\n\tgithub.com/ferranbt/fastssz v0.1.5-0.20240903094032-455b54c08c81\n\tgithub.com/kurtosis-tech/kurtosis/api/golang v1.16.6\n\tgithub.com/protolambda/zrnt v0.34.1\n\tgithub.com/protolambda/ztyp v0.2.2\n\tgithub.com/rs/zerolog v1.34.0\n\tgithub.com/stretchr/testify v1.11.1\n)\n\nrequire (\n\tbuf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.36.0-20241120201313-68e42a58b301.1 // indirect\n\tbuf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.36.0-20240130113600-88ef6483f90f.1 // indirect\n\tcosmossdk.io/api v0.8.0-rc.3 // indirect\n\tcosmossdk.io/core/testing v0.0.1 // indirect\n\tcosmossdk.io/schema v1.1.0 // indirect\n\tcosmossdk.io/x/bank v0.0.0-20241218110910-47409028a73d // indirect\n\tcosmossdk.io/x/staking v0.0.0-20241218110910-47409028a73d // indirect\n\tcosmossdk.io/x/tx v1.0.0-alpha.3 // indirect\n\tfilippo.io/edwards25519 v1.1.0 // indirect\n\tgithub.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect\n\tgithub.com/99designs/keyring v1.2.2 // indirect\n\tgithub.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect\n\tgithub.com/DataDog/datadog-go v4.8.3+incompatible // indirect\n\tgithub.com/DataDog/zstd v1.5.7 // indirect\n\tgithub.com/Masterminds/semver/v3 v3.3.1 // indirect\n\tgithub.com/Microsoft/go-winio v0.6.2 // indirect\n\tgithub.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect\n\tgithub.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 // indirect\n\tgithub.com/VictoriaMetrics/fastcache v1.13.0 // indirect\n\tgithub.com/adrg/xdg v0.4.0 // indirect\n\tgithub.com/beorn7/perks v1.0.1 // indirect\n\tgithub.com/bgentry/speakeasy v0.2.0 // indirect\n\tgithub.com/bits-and-blooms/bitset v1.20.0 // indirect\n\tgithub.com/bufbuild/protocompile v0.14.1 // indirect\n\tgithub.com/bytedance/gopkg v0.1.3 // indirect\n\tgithub.com/bytedance/sonic v1.15.0 // indirect\n\tgithub.com/bytedance/sonic/loader v0.5.0 // indirect\n\tgithub.com/cenkalti/backoff v2.2.1+incompatible // indirect\n\tgithub.com/cespare/xxhash/v2 v2.3.0 // indirect\n\tgithub.com/cloudwego/base64x v0.1.6 // indirect\n\tgithub.com/cockroachdb/errors v1.12.0 // indirect\n\tgithub.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0 // indirect\n\tgithub.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506 // indirect\n\tgithub.com/cockroachdb/pebble v1.1.5 // indirect\n\tgithub.com/cockroachdb/redact v1.1.6 // indirect\n\tgithub.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect\n\tgithub.com/cometbft/cometbft-db v1.0.4 // indirect\n\tgithub.com/consensys/gnark-crypto v0.18.1 // indirect\n\tgithub.com/containerd/continuity v0.4.4 // indirect\n\tgithub.com/cosmos/btcutil v1.0.5 // indirect\n\tgithub.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect\n\tgithub.com/cosmos/gogogateway v1.2.0 // indirect\n\tgithub.com/cosmos/gogoproto v1.7.0 // indirect\n\tgithub.com/cosmos/iavl v1.3.4 // indirect\n\tgithub.com/cosmos/ledger-cosmos-go v0.13.3 // indirect\n\tgithub.com/crate-crypto/go-eth-kzg v1.4.0 // indirect\n\tgithub.com/danieljoos/wincred v1.2.1 // indirect\n\tgithub.com/deckarep/golang-set/v2 v2.6.0 // indirect\n\tgithub.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect\n\tgithub.com/dgraph-io/badger/v4 v4.5.1 // indirect\n\tgithub.com/dgraph-io/ristretto/v2 v2.1.0 // indirect\n\tgithub.com/docker/go-connections v0.5.0 // indirect\n\tgithub.com/docker/go-units v0.5.0 // indirect\n\tgithub.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect\n\tgithub.com/dustin/go-humanize v1.0.1 // indirect\n\tgithub.com/dvsekhvalnov/jose2go v1.7.0 // indirect\n\tgithub.com/emicklei/dot v1.6.4 // indirect\n\tgithub.com/ethereum/c-kzg-4844/v2 v2.1.5 // indirect\n\tgithub.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab // indirect\n\tgithub.com/fatih/color v1.18.0 // indirect\n\tgithub.com/felixge/httpsnoop v1.0.4 // indirect\n\tgithub.com/fsnotify/fsnotify v1.9.0 // indirect\n\tgithub.com/gabriel-vasile/mimetype v1.4.10 // indirect\n\tgithub.com/getsentry/sentry-go v0.33.0 // indirect\n\tgithub.com/ghodss/yaml v1.0.0 // indirect\n\tgithub.com/go-kit/log v0.2.1 // indirect\n\tgithub.com/go-logfmt/logfmt v0.6.0 // indirect\n\tgithub.com/go-logr/logr v1.4.3 // indirect\n\tgithub.com/go-logr/stdr v1.2.2 // indirect\n\tgithub.com/go-ole/go-ole v1.3.0 // indirect\n\tgithub.com/go-playground/locales v0.14.1 // indirect\n\tgithub.com/go-playground/universal-translator v0.18.1 // indirect\n\tgithub.com/go-viper/mapstructure/v2 v2.4.0 // indirect\n\tgithub.com/go-yaml/yaml v2.1.0+incompatible // indirect\n\tgithub.com/goccy/go-yaml v1.9.2 // indirect\n\tgithub.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect\n\tgithub.com/gofrs/flock v0.12.1 // indirect\n\tgithub.com/gogo/googleapis v1.4.1 // indirect\n\tgithub.com/gogo/protobuf v1.3.2 // indirect\n\tgithub.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect\n\tgithub.com/golang/protobuf v1.5.4 // indirect\n\tgithub.com/golang/snappy v1.0.0 // indirect\n\tgithub.com/google/btree v1.1.3 // indirect\n\tgithub.com/google/flatbuffers v25.1.24+incompatible // indirect\n\tgithub.com/google/go-cmp v0.7.0 // indirect\n\tgithub.com/google/gofuzz v1.2.0 // indirect\n\tgithub.com/google/orderedcode v0.0.1 // indirect\n\tgithub.com/google/uuid v1.6.0 // indirect\n\tgithub.com/gorilla/handlers v1.5.2 // indirect\n\tgithub.com/gorilla/mux v1.8.1 // indirect\n\tgithub.com/gorilla/websocket v1.5.3 // indirect\n\tgithub.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect\n\tgithub.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect\n\tgithub.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect\n\tgithub.com/hashicorp/go-hclog v1.6.3 // indirect\n\tgithub.com/hashicorp/go-immutable-radix v1.3.1 // indirect\n\tgithub.com/hashicorp/go-plugin v1.6.2 // indirect\n\tgithub.com/hashicorp/golang-lru v1.0.2 // indirect\n\tgithub.com/hashicorp/yamux v0.1.2 // indirect\n\tgithub.com/hdevalence/ed25519consensus v0.2.0 // indirect\n\tgithub.com/holiman/bloomfilter/v2 v2.0.3 // indirect\n\tgithub.com/huandu/go-clone v1.6.0 // indirect\n\tgithub.com/huandu/skiplist v1.2.1 // indirect\n\tgithub.com/iancoleman/strcase v0.3.0 // indirect\n\tgithub.com/inconshreveable/mousetrap v1.1.0 // indirect\n\tgithub.com/jmhodges/levigo v1.0.0 // indirect\n\tgithub.com/kilic/bls12-381 v0.1.0 // indirect\n\tgithub.com/klauspost/compress v1.18.0 // indirect\n\tgithub.com/klauspost/cpuid/v2 v2.2.10 // indirect\n\tgithub.com/kr/pretty v0.3.1 // indirect\n\tgithub.com/kr/text v0.2.0 // indirect\n\tgithub.com/kurtosis-tech/kurtosis-portal/api/golang v0.0.0-20230818182330-1a86869414d2 // indirect\n\tgithub.com/kurtosis-tech/kurtosis/contexts-config-store v0.0.0-20230818184218-f4e3e773463b // indirect\n\tgithub.com/kurtosis-tech/kurtosis/grpc-file-transfer/golang v0.0.0-20230803130419-099ee7a4e3dc // indirect\n\tgithub.com/kurtosis-tech/kurtosis/path-compression v0.0.0-20240307154559-64d2929cd265 // indirect\n\tgithub.com/kurtosis-tech/stacktrace v0.0.0-20211028211901-1c67a77b5409 // indirect\n\tgithub.com/labstack/gommon v0.4.2 // indirect\n\tgithub.com/leodido/go-urn v1.4.0 // indirect\n\tgithub.com/lib/pq v1.10.9 // indirect\n\tgithub.com/linxGnu/grocksdb v1.9.8 // indirect\n\tgithub.com/mattn/go-colorable v0.1.14 // indirect\n\tgithub.com/mattn/go-isatty v0.0.20 // indirect\n\tgithub.com/mattn/go-runewidth v0.0.16 // indirect\n\tgithub.com/mholt/archiver v3.1.1+incompatible // indirect\n\tgithub.com/minio/highwayhash v1.0.3 // indirect\n\tgithub.com/moby/sys/user v0.3.0 // indirect\n\tgithub.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect\n\tgithub.com/mtibben/percent v0.2.1 // indirect\n\tgithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect\n\tgithub.com/nwaples/rardecode v1.1.3 // indirect\n\tgithub.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect\n\tgithub.com/oklog/run v1.1.0 // indirect\n\tgithub.com/onsi/gomega v1.34.2 // indirect\n\tgithub.com/opencontainers/go-digest v1.0.0 // indirect\n\tgithub.com/opencontainers/image-spec v1.1.0 // indirect\n\tgithub.com/opencontainers/runc v1.2.8 // indirect\n\tgithub.com/pelletier/go-toml/v2 v2.2.4 // indirect\n\tgithub.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect\n\tgithub.com/pierrec/lz4 v2.6.1+incompatible // indirect\n\tgithub.com/pk910/dynamic-ssz v0.0.4 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect\n\tgithub.com/prometheus/client_golang v1.20.5 // indirect\n\tgithub.com/prometheus/client_model v0.6.1 // indirect\n\tgithub.com/prometheus/common v0.62.0 // indirect\n\tgithub.com/prometheus/procfs v0.15.1 // indirect\n\tgithub.com/protolambda/bls12-381-util v0.1.0 // indirect\n\tgithub.com/prysmaticlabs/fastssz v0.0.0-20241008181541-518c4ce73516 // indirect\n\tgithub.com/prysmaticlabs/go-bitfield v0.0.0-20240618144021-706c95b2dd15 // indirect\n\tgithub.com/r3labs/sse/v2 v2.10.0 // indirect\n\tgithub.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect\n\tgithub.com/rogpeppe/go-internal v1.14.1 // indirect\n\tgithub.com/rs/cors v1.11.1 // indirect\n\tgithub.com/sagikazarmark/locafero v0.11.0 // indirect\n\tgithub.com/sasha-s/go-deadlock v0.3.5 // indirect\n\tgithub.com/shirou/gopsutil v3.21.11+incompatible // indirect\n\tgithub.com/sirupsen/logrus v1.9.3 // indirect\n\tgithub.com/stretchr/objx v0.5.2 // indirect\n\tgithub.com/subosito/gotenv v1.6.0 // indirect\n\tgithub.com/supranational/blst v0.3.16-0.20250831170142-f48500c1fdbe // indirect\n\tgithub.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect\n\tgithub.com/tendermint/go-amino v0.16.0 // indirect\n\tgithub.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e // indirect\n\tgithub.com/tidwall/btree v1.7.0 // indirect\n\tgithub.com/tklauser/go-sysconf v0.3.14 // indirect\n\tgithub.com/tklauser/numcpus v0.8.0 // indirect\n\tgithub.com/twitchyliquid64/golang-asm v0.15.1 // indirect\n\tgithub.com/ulikunitz/xz v0.5.14 // indirect\n\tgithub.com/valyala/bytebufferpool v1.0.0 // indirect\n\tgithub.com/valyala/fasttemplate v1.2.2 // indirect\n\tgithub.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect\n\tgithub.com/yusufpapurcu/wmi v1.2.4 // indirect\n\tgithub.com/zondax/hid v0.9.2 // indirect\n\tgithub.com/zondax/ledger-go v0.14.3 // indirect\n\tgitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b // indirect\n\tgitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect\n\tgo.etcd.io/bbolt v1.4.0 // indirect\n\tgo.opencensus.io v0.24.0 // indirect\n\tgo.opentelemetry.io/auto/sdk v1.2.1 // indirect\n\tgo.opentelemetry.io/otel v1.39.0 // indirect\n\tgo.opentelemetry.io/otel/metric v1.39.0 // indirect\n\tgo.opentelemetry.io/otel/trace v1.39.0 // indirect\n\tgo.yaml.in/yaml/v2 v2.4.2 // indirect\n\tgo.yaml.in/yaml/v3 v3.0.4 // indirect\n\tgolang.org/x/arch v0.17.0 // indirect\n\tgolang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect\n\tgolang.org/x/net v0.52.0 // indirect\n\tgolang.org/x/sys v0.42.0 // indirect\n\tgolang.org/x/term v0.41.0 // indirect\n\tgolang.org/x/text v0.35.0 // indirect\n\tgolang.org/x/time v0.11.0 // indirect\n\tgolang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect\n\tgoogle.golang.org/genproto v0.0.0-20240624140628-dc46fd24d27d // indirect\n\tgoogle.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b // indirect\n\tgoogle.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect\n\tgoogle.golang.org/grpc v1.79.3 // indirect\n\tgoogle.golang.org/protobuf v1.36.11 // indirect\n\tgopkg.in/Knetic/govaluate.v3 v3.0.0 // indirect\n\tgopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect\n\tgopkg.in/yaml.v2 v2.4.0 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n\tgotest.tools/v3 v3.5.2 // indirect\n\tpgregory.net/rapid v1.2.0 // indirect\n)\n"
  },
  {
    "path": "go.sum",
    "content": "buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.36.0-20241120201313-68e42a58b301.1 h1:LBP+N3ehp1hseHYlIIHlU0gMM3aGYDcgx/H//Pk12ko=\nbuf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.36.0-20241120201313-68e42a58b301.1/go.mod h1:pab5p7+q6IAI+R+Z2MQ+hP7ZV+FP2mcbucv6xs5WFPk=\nbuf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.36.0-20240130113600-88ef6483f90f.1 h1:5wJBiYyPUS2xpqLJKm7ZEKx1VhesPOXXx5y+JxgVSX4=\nbuf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.36.0-20240130113600-88ef6483f90f.1/go.mod h1:VItWFs9dzQsqOin45pYbA4O/SRdqMPDs4XPZBHL+u2w=\ncloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncosmossdk.io/api v0.8.0-rc.3 h1:BNVMqBO7jO20fQCLKzAYLI9RPTq9bVn30ncq9vF8SBk=\ncosmossdk.io/api v0.8.0-rc.3/go.mod h1:1hADc5N9rDJ4RTH7z3sp6+PXI+shznzk0Frf0/k3ilE=\ncosmossdk.io/collections v1.3.1 h1:09e+DUId2brWsNOQ4nrk+bprVmMUaDH9xvtZkeqIjVw=\ncosmossdk.io/collections v1.3.1/go.mod h1:ynvkP0r5ruAjbmedE+vQ07MT6OtJ0ZIDKrtJHK7Q/4c=\ncosmossdk.io/core v1.0.0 h1:e7XBbISOytLBOXMVwpRPixThXqEkeLGlg8no/qpgS8U=\ncosmossdk.io/core v1.0.0/go.mod h1:mKIp3RkoEmtqdEdFHxHwWAULRe+79gfdOvmArrLDbDc=\ncosmossdk.io/core/testing v0.0.1 h1:gYCTaftcRrz+HoNXmK7r9KgbG1jgBJ8pNzm/Pa/erFQ=\ncosmossdk.io/core/testing v0.0.1/go.mod h1:2VDNz/25qtxgPa0+j8LW5e8Ev/xObqoJA7QuJS9/wIQ=\ncosmossdk.io/depinject v1.2.1 h1:eD6FxkIjlVaNZT+dXTQuwQTKZrFZ4UrfCq1RKgzyhMw=\ncosmossdk.io/depinject v1.2.1/go.mod h1:lqQEycz0H2JXqvOgVwTsjEdMI0plswI7p6KX+MVqFOM=\ncosmossdk.io/errors v1.0.2 h1:wcYiJz08HThbWxd/L4jObeLaLySopyyuUFB5w4AGpCo=\ncosmossdk.io/errors v1.0.2/go.mod h1:0rjgiHkftRYPj//3DrD6y8hcm40HcPv/dR4R/4efr0k=\ncosmossdk.io/log v1.6.1 h1:YXNwAgbDwMEKwDlCdH8vPcoggma48MgZrTQXCfmMBeI=\ncosmossdk.io/log v1.6.1/go.mod h1:gMwsWyyDBjpdG9u2avCFdysXqxq28WJapJvu+vF1y+E=\ncosmossdk.io/math v1.5.3 h1:WH6tu6Z3AUCeHbeOSHg2mt9rnoiUWVWaQ2t6Gkll96U=\ncosmossdk.io/math v1.5.3/go.mod h1:uqcZv7vexnhMFJF+6zh9EWdm/+Ylyln34IvPnBauPCQ=\ncosmossdk.io/schema v1.1.0 h1:mmpuz3dzouCoyjjcMcA/xHBEmMChN+EHh8EHxHRHhzE=\ncosmossdk.io/schema v1.1.0/go.mod h1:Gb7pqO+tpR+jLW5qDcNOSv0KtppYs7881kfzakguhhI=\ncosmossdk.io/store v1.10.0-rc.1.0.20241218084712-ca559989da43 h1:glZ6MpmD+5AhwJYV4jzx+rn7cgUB2owHgk9o+93luz0=\ncosmossdk.io/store v1.10.0-rc.1.0.20241218084712-ca559989da43/go.mod h1:XCWpgfueHSBY+B7Cf2Aq/CcsU+6XoFH+EmseCKglFrU=\ncosmossdk.io/x/bank v0.0.0-20241218110910-47409028a73d h1:8Sw9mmz+P/H0iURZkRHKmpkmr9Lm3eGM2yRZveU2GWs=\ncosmossdk.io/x/bank v0.0.0-20241218110910-47409028a73d/go.mod h1:C5yLe3vDDDHcWMSfa1lfgglczjjMGfOc4nYDmk69U2w=\ncosmossdk.io/x/staking v0.0.0-20241218110910-47409028a73d h1:Ey5BddfuPEQACiDgeb9SqvHr533RH7rd2GDNIgV45hk=\ncosmossdk.io/x/staking v0.0.0-20241218110910-47409028a73d/go.mod h1:ZvgV4cHXyDsKYdDDz5srMizpi9ylVI1wuvgmj53ug18=\ncosmossdk.io/x/tx v1.0.0-alpha.3 h1:+55/JFH5QRqnFhOI2heH3DKsaNL0RpXcJOQNzUvHiaQ=\ncosmossdk.io/x/tx v1.0.0-alpha.3/go.mod h1:h4pQ/j6Gfu8goB1R3Jbl4qY4RjYVNAsoylcleTXdSRg=\nfilippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=\nfilippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=\ngithub.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs=\ngithub.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4=\ngithub.com/99designs/keyring v1.2.2 h1:pZd3neh/EmUzWONb35LxQfvuY7kiSXAq3HQd97+XBn0=\ngithub.com/99designs/keyring v1.2.2/go.mod h1:wes/FrByc8j7lFOAGLGSNEg8f/PaI3cgTBqhFkHUrPk=\ngithub.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=\ngithub.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs=\ngithub.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=\ngithub.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=\ngithub.com/DataDog/datadog-go v4.8.3+incompatible h1:fNGaYSuObuQb5nzeTQqowRAd9bpDIRRV4/gUtIBjh8Q=\ngithub.com/DataDog/datadog-go v4.8.3+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=\ngithub.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE=\ngithub.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=\ngithub.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4=\ngithub.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=\ngithub.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=\ngithub.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=\ngithub.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=\ngithub.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=\ngithub.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 h1:1zYrtlhrZ6/b6SAjLSfKzWtdgqK0U+HtH/VcBWh1BaU=\ngithub.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6/go.mod h1:ioLG6R+5bUSO1oeGSDxOV3FADARuMoytZCSX6MEMQkI=\ngithub.com/VictoriaMetrics/fastcache v1.13.0 h1:AW4mheMR5Vd9FkAPUv+NH6Nhw+fmbTMGMsNAoA/+4G0=\ngithub.com/VictoriaMetrics/fastcache v1.13.0/go.mod h1:hHXhl4DA2fTL2HTZDJFXWgW0LNjo6B+4aj2Wmng3TjU=\ngithub.com/adlio/schema v1.3.6 h1:k1/zc2jNfeiZBA5aFTRy37jlBIuCkXCm0XmvpzCKI9I=\ngithub.com/adlio/schema v1.3.6/go.mod h1:qkxwLgPBd1FgLRHYVCmQT/rrBr3JH38J9LjmVzWNudg=\ngithub.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls=\ngithub.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E=\ngithub.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=\ngithub.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=\ngithub.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=\ngithub.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=\ngithub.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=\ngithub.com/attestantio/go-eth2-client v0.27.2 h1:VjA9R39ovy8ryb7IpFfD5eLYBg/20biztxh6fKZ7/K0=\ngithub.com/attestantio/go-eth2-client v0.27.2/go.mod h1:i56XBegxVt7wXupnLBOj9IyGwy5cqaoTsCSKlwTubEU=\ngithub.com/bazelbuild/rules_go v0.23.2 h1:Wxu7JjqnF78cKZbsBsARLSXx/jlGaSLCnUV3mTlyHvM=\ngithub.com/bazelbuild/rules_go v0.23.2/go.mod h1:MC23Dc/wkXEyk3Wpq6lCqz0ZAYOZDw2DR5y3N1q2i7M=\ngithub.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=\ngithub.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=\ngithub.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=\ngithub.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=\ngithub.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=\ngithub.com/berachain/cometbft v1.0.1-0.20260417142533-880521c815b6 h1:pCfZDheMbkXRE+VbERz/bPFibp96Yd5V3RVDJLLib2A=\ngithub.com/berachain/cometbft v1.0.1-0.20260417142533-880521c815b6/go.mod h1:AB3j5W0TQmQSuwRdzWvIBQPAKquFo7VnckwETlAsuwk=\ngithub.com/berachain/cometbft/api v1.0.1-0.20260417142533-880521c815b6 h1:HS1NYR8xeqNR9ABrfvS84clBgujpXOUunGKEaKP1l+k=\ngithub.com/berachain/cometbft/api v1.0.1-0.20260417142533-880521c815b6/go.mod h1:QaK8NCB4rHDs0MdS+L+QOQsL4UM3YJ9OMCNrH+CGdA0=\ngithub.com/berachain/karalabe-ssz v0.3.0-alpha.0 h1:SVMU5PSuMB2fgmFTf1rSBY9rEHpQv24DJcqxSrD7jf8=\ngithub.com/berachain/karalabe-ssz v0.3.0-alpha.0/go.mod h1:7BZG/jckt43eKw7sl/AF6gTcL0oxgFPme39m54v8rDI=\ngithub.com/bgentry/speakeasy v0.2.0 h1:tgObeVOf8WAvtuAX6DhJ4xks4CFNwPDZiqzGqIHE51E=\ngithub.com/bgentry/speakeasy v0.2.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=\ngithub.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3MdfoPyRVU=\ngithub.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=\ngithub.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=\ngithub.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=\ngithub.com/btcsuite/btcd/btcutil v1.1.6 h1:zFL2+c3Lb9gEgqKNzowKUPQNb8jV7v5Oaodi/AYFd6c=\ngithub.com/btcsuite/btcd/btcutil v1.1.6/go.mod h1:9dFymx8HpuLqBnsPELrImQeTQfKBQqzqGbbV3jK55aE=\ngithub.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=\ngithub.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=\ngithub.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=\ngithub.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=\ngithub.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE=\ngithub.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k=\ngithub.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE=\ngithub.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=\ngithub.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=\ngithub.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=\ngithub.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=\ngithub.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=\ngithub.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU=\ngithub.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=\ngithub.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=\ngithub.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=\ngithub.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=\ngithub.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=\ngithub.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=\ngithub.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=\ngithub.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=\ngithub.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=\ngithub.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=\ngithub.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=\ngithub.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4=\ngithub.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU=\ngithub.com/cockroachdb/errors v1.12.0 h1:d7oCs6vuIMUQRVbi6jWWWEJZahLCfJpnJSVobd1/sUo=\ngithub.com/cockroachdb/errors v1.12.0/go.mod h1:SvzfYNNBshAVbZ8wzNc/UPK3w1vf0dKDUP41ucAIf7g=\ngithub.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0 h1:pU88SPhIFid6/k0egdR5V6eALQYq2qbSmukrkgIh/0A=\ngithub.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M=\ngithub.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506 h1:ASDL+UJcILMqgNeV5jiqR4j+sTuvQNHdf2chuKj1M5k=\ngithub.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506/go.mod h1:Mw7HqKr2kdtu6aYGn3tPmAftiP3QPX63LdK/zcariIo=\ngithub.com/cockroachdb/pebble v1.1.5 h1:5AAWCBWbat0uE0blr8qzufZP5tBjkRyy/jWe1QWLnvw=\ngithub.com/cockroachdb/pebble v1.1.5/go.mod h1:17wO9el1YEigxkP/YtV8NtCivQDgoCyBg5c4VR/eOWo=\ngithub.com/cockroachdb/redact v1.1.6 h1:zXJBwDZ84xJNlHl1rMyCojqyIxv+7YUpQiJLQ7n4314=\ngithub.com/cockroachdb/redact v1.1.6/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=\ngithub.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo=\ngithub.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ=\ngithub.com/cometbft/cometbft-db v1.0.4 h1:cezb8yx/ZWcF124wqUtAFjAuDksS1y1yXedvtprUFxs=\ngithub.com/cometbft/cometbft-db v1.0.4/go.mod h1:M+BtHAGU2XLrpUxo3Nn1nOCcnVCiLM9yx5OuT0u5SCA=\ngithub.com/consensys/gnark-crypto v0.18.1 h1:RyLV6UhPRoYYzaFnPQA4qK3DyuDgkTgskDdoGqFt3fI=\ngithub.com/consensys/gnark-crypto v0.18.1/go.mod h1:L3mXGFTe1ZN+RSJ+CLjUt9x7PNdx8ubaYfDROyp2Z8c=\ngithub.com/containerd/continuity v0.4.4 h1:/fNVfTJ7wIl/YPMHjf+5H32uFhl63JucB34PlCpMKII=\ngithub.com/containerd/continuity v0.4.4/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE=\ngithub.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=\ngithub.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk=\ngithub.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis=\ngithub.com/cosmos/cosmos-db v1.1.3 h1:7QNT77+vkefostcKkhrzDK9uoIEryzFrU9eoMeaQOPY=\ngithub.com/cosmos/cosmos-db v1.1.3/go.mod h1:kN+wGsnwUJZYn8Sy5Q2O0vCYA99MJllkKASbs6Unb9U=\ngithub.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA=\ngithub.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec=\ngithub.com/cosmos/cosmos-sdk v0.52.0-rc.1 h1:HgHOUYbxvjvyiX5CQF4eLT0u1wvjxajwgClOGzAmNoQ=\ngithub.com/cosmos/cosmos-sdk v0.52.0-rc.1/go.mod h1:2Z6V16EhPG1NI6Q+b9Xue7dgabx76JQpUtlcCnYbI90=\ngithub.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY=\ngithub.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw=\ngithub.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE=\ngithub.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI=\ngithub.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU=\ngithub.com/cosmos/gogoproto v1.7.0 h1:79USr0oyXAbxg3rspGh/m4SWNyoz/GLaAh0QlCe2fro=\ngithub.com/cosmos/gogoproto v1.7.0/go.mod h1:yWChEv5IUEYURQasfyBW5ffkMHR/90hiHgbNgrtp4j0=\ngithub.com/cosmos/iavl v1.3.4 h1:A0RUAms7TZ0L6EFrrBIPg4Dy7qD9vvD5lJKUxEXURLM=\ngithub.com/cosmos/iavl v1.3.4/go.mod h1:T6SfBcyhulVIY2G/ZtAtQm/QiJvsuhIos52V4dWYk88=\ngithub.com/cosmos/ics23/go v0.11.0 h1:jk5skjT0TqX5e5QJbEnwXIS2yI2vnmLOgpQPeM5RtnU=\ngithub.com/cosmos/ics23/go v0.11.0/go.mod h1:A8OjxPE67hHST4Icw94hOxxFEJMBG031xIGF/JHNIY0=\ngithub.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM=\ngithub.com/cosmos/ledger-cosmos-go v0.13.3/go.mod h1:HENcEP+VtahZFw38HZ3+LS3Iv5XV6svsnkk9vdJtLr8=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=\ngithub.com/crate-crypto/go-eth-kzg v1.4.0 h1:WzDGjHk4gFg6YzV0rJOAsTK4z3Qkz5jd4RE3DAvPFkg=\ngithub.com/crate-crypto/go-eth-kzg v1.4.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI=\ngithub.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4=\ngithub.com/crate-crypto/go-kzg-4844 v1.1.0/go.mod h1:JolLjpSff1tCCJKaJx4psrlEdlXuJEC996PL3tTAFks=\ngithub.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=\ngithub.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U=\ngithub.com/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo=\ngithub.com/danieljoos/wincred v1.2.1 h1:dl9cBrupW8+r5250DYkYxocLeZ1Y4vB1kxgtjxw8GQs=\ngithub.com/danieljoos/wincred v1.2.1/go.mod h1:uGaFL9fDn3OLTvzCGulzE+SzjEe5NGlh5FdCcyfPwps=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/dchest/siphash v1.2.3 h1:QXwFc8cFOR2dSa/gE6o/HokBMWtLUaNDVd+22aKHeEA=\ngithub.com/dchest/siphash v1.2.3/go.mod h1:0NvQU092bT0ipiFN++/rXm69QG9tVxLAlQHIXMPAkHc=\ngithub.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM=\ngithub.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=\ngithub.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=\ngithub.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=\ngithub.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=\ngithub.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=\ngithub.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU=\ngithub.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw=\ngithub.com/dgraph-io/badger/v4 v4.5.1 h1:7DCIXrQjo1LKmM96YD+hLVJ2EEsyyoWxJfpdd56HLps=\ngithub.com/dgraph-io/badger/v4 v4.5.1/go.mod h1:qn3Be0j3TfV4kPbVoK0arXCD1/nr1ftth6sbL5jxdoA=\ngithub.com/dgraph-io/ristretto/v2 v2.1.0 h1:59LjpOJLNDULHh8MC4UaegN52lC4JnO2dITsie/Pa8I=\ngithub.com/dgraph-io/ristretto/v2 v2.1.0/go.mod h1:uejeqfYXpUomfse0+lO+13ATz4TypQYLJZzBSAemuB4=\ngithub.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y=\ngithub.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=\ngithub.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=\ngithub.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=\ngithub.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=\ngithub.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=\ngithub.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY=\ngithub.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s=\ngithub.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=\ngithub.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=\ngithub.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=\ngithub.com/dvsekhvalnov/jose2go v1.7.0 h1:bnQc8+GMnidJZA8zc6lLEAb4xNrIqHwO+9TzqvtQZPo=\ngithub.com/dvsekhvalnov/jose2go v1.7.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU=\ngithub.com/emicklei/dot v1.6.4 h1:cG9ycT67d9Yw22G+mAb4XiuUz6E6H1S0zePp/5Cwe/c=\ngithub.com/emicklei/dot v1.6.4/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s=\ngithub.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=\ngithub.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=\ngithub.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=\ngithub.com/ethereum/c-kzg-4844/v2 v2.1.5 h1:aVtoLK5xwJ6c5RiqO8g8ptJ5KU+2Hdquf6G3aXiHh5s=\ngithub.com/ethereum/c-kzg-4844/v2 v2.1.5/go.mod h1:u59hRTTah4Co6i9fDWtiCjTrblJv0UwsqZKCc0GfgUs=\ngithub.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab h1:rvv6MJhy07IMfEKuARQ9TKojGqLVNxQajaXEp/BoqSk=\ngithub.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab/go.mod h1:IuLm4IsPipXKF7CW5Lzf68PIbZ5yl7FFd74l/E0o9A8=\ngithub.com/ethereum/go-ethereum v1.17.0 h1:2D+1Fe23CwZ5tQoAS5DfwKFNI1HGcTwi65/kRlAVxes=\ngithub.com/ethereum/go-ethereum v1.17.0/go.mod h1:2W3msvdosS/MCWytpqTcqgFiRYbTH59FxDJzqah120o=\ngithub.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=\ngithub.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=\ngithub.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=\ngithub.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=\ngithub.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=\ngithub.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=\ngithub.com/ferranbt/fastssz v0.1.5-0.20240903094032-455b54c08c81 h1:SNHNj7UyVnQV3AAi1LweOKnU6+OJ2CmxgaHpRmU7+mc=\ngithub.com/ferranbt/fastssz v0.1.5-0.20240903094032-455b54c08c81/go.mod h1:Ea3+oeoRGGLGm5shYAeDgu6PGUlcvQhE2fILyD9+tGg=\ngithub.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=\ngithub.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=\ngithub.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=\ngithub.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=\ngithub.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=\ngithub.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=\ngithub.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=\ngithub.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=\ngithub.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=\ngithub.com/gabriel-vasile/mimetype v1.4.10 h1:zyueNbySn/z8mJZHLt6IPw0KoZsiQNszIpU+bX4+ZK0=\ngithub.com/gabriel-vasile/mimetype v1.4.10/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=\ngithub.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays=\ngithub.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=\ngithub.com/getsentry/sentry-go v0.33.0 h1:YWyDii0KGVov3xOaamOnF0mjOrqSjBqwv48UEzn7QFg=\ngithub.com/getsentry/sentry-go v0.33.0/go.mod h1:C55omcY9ChRQIUcVcGcs+Zdy4ZpQGvNJ7JYHIoSWOtE=\ngithub.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=\ngithub.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=\ngithub.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=\ngithub.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=\ngithub.com/go-faster/xor v1.0.0 h1:2o8vTOgErSGHP3/7XwA5ib1FTtUsNtwCoLLBjl31X38=\ngithub.com/go-faster/xor v1.0.0/go.mod h1:x5CaDY9UKErKzqfRfFZdfu+OSTfoZny3w5Ak7UxcipQ=\ngithub.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=\ngithub.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=\ngithub.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=\ngithub.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=\ngithub.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=\ngithub.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=\ngithub.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=\ngithub.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=\ngithub.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=\ngithub.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=\ngithub.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=\ngithub.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=\ngithub.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=\ngithub.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=\ngithub.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=\ngithub.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=\ngithub.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=\ngithub.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=\ngithub.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=\ngithub.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=\ngithub.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=\ngithub.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=\ngithub.com/go-playground/validator/v10 v10.28.0 h1:Q7ibns33JjyW48gHkuFT91qX48KG0ktULL6FgHdG688=\ngithub.com/go-playground/validator/v10 v10.28.0/go.mod h1:GoI6I1SjPBh9p7ykNE/yj3fFYbyDOpwMn5KXd+m2hUU=\ngithub.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=\ngithub.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=\ngithub.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=\ngithub.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=\ngithub.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o=\ngithub.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=\ngithub.com/goccy/go-yaml v1.9.2 h1:2Njwzw+0+pjU2gb805ZC1B/uBuAs2VcZ3K+ZgHwDs7w=\ngithub.com/goccy/go-yaml v1.9.2/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA=\ngithub.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0=\ngithub.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=\ngithub.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=\ngithub.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E=\ngithub.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0=\ngithub.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=\ngithub.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0=\ngithub.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4=\ngithub.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=\ngithub.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=\ngithub.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=\ngithub.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=\ngithub.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=\ngithub.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=\ngithub.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=\ngithub.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=\ngithub.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=\ngithub.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=\ngithub.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=\ngithub.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=\ngithub.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=\ngithub.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=\ngithub.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=\ngithub.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=\ngithub.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=\ngithub.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=\ngithub.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=\ngithub.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=\ngithub.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=\ngithub.com/google/flatbuffers v25.1.24+incompatible h1:4wPqL3K7GzBd1CwyhSd3usxLKOaJN/AC6puCca6Jm7o=\ngithub.com/google/flatbuffers v25.1.24+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=\ngithub.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=\ngithub.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us=\ngithub.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20=\ngithub.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=\ngithub.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=\ngithub.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=\ngithub.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=\ngithub.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=\ngithub.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=\ngithub.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI=\ngithub.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY=\ngithub.com/grafana/pyroscope-go v1.2.7 h1:VWBBlqxjyR0Cwk2W6UrE8CdcdD80GOFNutj0Kb1T8ac=\ngithub.com/grafana/pyroscope-go v1.2.7/go.mod h1:o/bpSLiJYYP6HQtvcoVKiE9s5RiNgjYTj1DhiddP2Pc=\ngithub.com/grafana/pyroscope-go/godeltaprof v0.1.9 h1:c1Us8i6eSmkW+Ez05d3co8kasnuOY813tbMN8i/a3Og=\ngithub.com/grafana/pyroscope-go/godeltaprof v0.1.9/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU=\ngithub.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0=\ngithub.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=\ngithub.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=\ngithub.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=\ngithub.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=\ngithub.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=\ngithub.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU=\ngithub.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0=\ngithub.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE=\ngithub.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0=\ngithub.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=\ngithub.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=\ngithub.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=\ngithub.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=\ngithub.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=\ngithub.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=\ngithub.com/hashicorp/go-metrics v0.5.4 h1:8mmPiIJkTPPEbAiV97IxdAGNdRdaWwVap1BU6elejKY=\ngithub.com/hashicorp/go-metrics v0.5.4/go.mod h1:CG5yz4NZ/AI/aQt9Ucm/vdBnbh7fvmv4lxZ350i+QQI=\ngithub.com/hashicorp/go-plugin v1.6.2 h1:zdGAEd0V1lCaU0u+MxWQhtSDQmahpkwOun8U8EiRVog=\ngithub.com/hashicorp/go-plugin v1.6.2/go.mod h1:CkgLQ5CZqNmdL9U9JzM532t8ZiYQ35+pj3b1FD37R0Q=\ngithub.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=\ngithub.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE=\ngithub.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=\ngithub.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=\ngithub.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=\ngithub.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=\ngithub.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=\ngithub.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8=\ngithub.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns=\ngithub.com/hdevalence/ed25519consensus v0.2.0 h1:37ICyZqdyj0lAZ8P4D1d1id3HqbbG1N3iBb1Tb4rdcU=\ngithub.com/hdevalence/ed25519consensus v0.2.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo=\ngithub.com/herumi/bls-eth-go-binary v1.31.0 h1:9eeW3EA4epCb7FIHt2luENpAW69MvKGL5jieHlBiP+w=\ngithub.com/herumi/bls-eth-go-binary v1.31.0/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U=\ngithub.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db h1:IZUYC/xb3giYwBLMnr8d0TGTzPKFGNTCGgGLoyeX330=\ngithub.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db/go.mod h1:xTEYN9KCHxuYHs+NmrmzFcnvHMzLLNiGFafCb1n3Mfg=\ngithub.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao=\ngithub.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA=\ngithub.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=\ngithub.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA=\ngithub.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=\ngithub.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=\ngithub.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c=\ngithub.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U=\ngithub.com/huandu/go-clone v1.6.0 h1:HMo5uvg4wgfiy5FoGOqlFLQED/VGRm2D9Pi8g1FXPGc=\ngithub.com/huandu/go-clone v1.6.0/go.mod h1:ReGivhG6op3GYr+UY3lS6mxjKp7MIGTknuU5TbTVaXE=\ngithub.com/huandu/go-clone/generic v1.6.0 h1:Wgmt/fUZ28r16F2Y3APotFD59sHk1p78K0XLdbUYN5U=\ngithub.com/huandu/go-clone/generic v1.6.0/go.mod h1:xgd9ZebcMsBWWcBx5mVMCoqMX24gLWr5lQicr+nVXNs=\ngithub.com/huandu/skiplist v1.2.1 h1:dTi93MgjwErA/8idWTzIw4Y1kZsMWx35fmI2c8Rij7w=\ngithub.com/huandu/skiplist v1.2.1/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w=\ngithub.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc=\ngithub.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8=\ngithub.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=\ngithub.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=\ngithub.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=\ngithub.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=\ngithub.com/influxdata/influxdb-client-go/v2 v2.4.0 h1:HGBfZYStlx3Kqvsv1h2pJixbCl/jhnFtxpKFAv9Tu5k=\ngithub.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8=\ngithub.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c h1:qSHzRbhzK8RdXOsAdfDgO49TtqC1oZ+acxPrkfTxcCs=\ngithub.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=\ngithub.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 h1:vilfsDSy7TDxedi9gyBkMvAirat/oRcL0lFdJBf6tdM=\ngithub.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=\ngithub.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=\ngithub.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=\ngithub.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94=\ngithub.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8=\ngithub.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U=\ngithub.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ=\ngithub.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=\ngithub.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=\ngithub.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=\ngithub.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=\ngithub.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=\ngithub.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=\ngithub.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4=\ngithub.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig=\ngithub.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=\ngithub.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=\ngithub.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=\ngithub.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=\ngithub.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=\ngithub.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=\ngithub.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/kurtosis-tech/kurtosis-portal/api/golang v0.0.0-20230818182330-1a86869414d2 h1:izciXrFyFR+ihJ7nLTOkoIX5GzBPIp8gVKlw94gIc98=\ngithub.com/kurtosis-tech/kurtosis-portal/api/golang v0.0.0-20230818182330-1a86869414d2/go.mod h1:bWSMQK3WHVTGHX9CjxPAb/LtzcmfOxID2wdzakSWQxo=\ngithub.com/kurtosis-tech/kurtosis/api/golang v1.16.6 h1:uy03mqQ5eCFtOtBKDsOpUk8fw5SJ2v+VBstBiVQ55D8=\ngithub.com/kurtosis-tech/kurtosis/api/golang v1.16.6/go.mod h1:7jsreUn/zOtlJbNJcGPfjXsh7GWMgDd08Vn4ypUN78o=\ngithub.com/kurtosis-tech/kurtosis/contexts-config-store v0.0.0-20230818184218-f4e3e773463b h1:hMoIM99QKcYQqsnK4AF7Lovi9ZD9ac6lZLZ5D/jx2x8=\ngithub.com/kurtosis-tech/kurtosis/contexts-config-store v0.0.0-20230818184218-f4e3e773463b/go.mod h1:4pFdrRwDz5R+Fov2ZuTaPhAVgjA2jhGh1Izf832sX7A=\ngithub.com/kurtosis-tech/kurtosis/grpc-file-transfer/golang v0.0.0-20230803130419-099ee7a4e3dc h1:7IlEpSehmWcNXOFpNP24Cu5HQI3af7GCBQw//m+LnvQ=\ngithub.com/kurtosis-tech/kurtosis/grpc-file-transfer/golang v0.0.0-20230803130419-099ee7a4e3dc/go.mod h1:TOWMQgvAJH/NiWWERGXg/plT9lS7aFcXFxCa0M5sfHo=\ngithub.com/kurtosis-tech/kurtosis/path-compression v0.0.0-20240307154559-64d2929cd265 h1:uSDftcGStwuAjHv8fV2TleNCKSWPvUKe7EaplFG3yBI=\ngithub.com/kurtosis-tech/kurtosis/path-compression v0.0.0-20240307154559-64d2929cd265/go.mod h1:aDMrPeS7Gii8W6SDKSKyrBNgEQAUYidriyeKGf+Ml3I=\ngithub.com/kurtosis-tech/stacktrace v0.0.0-20211028211901-1c67a77b5409 h1:YQTATifMUwZEtZYb0LVA7DK2pj8s71iY8rzweuUQ5+g=\ngithub.com/kurtosis-tech/stacktrace v0.0.0-20211028211901-1c67a77b5409/go.mod h1:y5weVs5d9wXXHcDA1awRxkIhhHC1xxYJN8a7aXnE6S8=\ngithub.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=\ngithub.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=\ngithub.com/labstack/echo/v4 v4.13.4 h1:oTZZW+T3s9gAu5L8vmzihV7/lkXGZuITzTQkTEhcXEA=\ngithub.com/labstack/echo/v4 v4.13.4/go.mod h1:g63b33BZ5vZzcIUF8AtRH40DrTlXnx4UMC8rBdndmjQ=\ngithub.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=\ngithub.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=\ngithub.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4=\ngithub.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c=\ngithub.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=\ngithub.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=\ngithub.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=\ngithub.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=\ngithub.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=\ngithub.com/linxGnu/grocksdb v1.9.8 h1:vOIKv9/+HKiqJAElJIEYv3ZLcihRxyP7Suu/Mu8Dxjs=\ngithub.com/linxGnu/grocksdb v1.9.8/go.mod h1:C3CNe9UYc9hlEM2pC82AqiGS3LRW537u9LFV4wIZuHk=\ngithub.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM=\ngithub.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=\ngithub.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=\ngithub.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=\ngithub.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=\ngithub.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=\ngithub.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=\ngithub.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=\ngithub.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=\ngithub.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=\ngithub.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=\ngithub.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=\ngithub.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=\ngithub.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=\ngithub.com/mholt/archiver v3.1.1+incompatible h1:1dCVxuqs0dJseYEhi5pl7MYPH9zDa1wBi7mF09cbNkU=\ngithub.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU=\ngithub.com/minio/highwayhash v1.0.3 h1:kbnuUMoHYyVl7szWjSxJnxw11k2U709jqFPPmIUyD6Q=\ngithub.com/minio/highwayhash v1.0.3/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ=\ngithub.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=\ngithub.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=\ngithub.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=\ngithub.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=\ngithub.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A=\ngithub.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4=\ngithub.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo=\ngithub.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=\ngithub.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=\ngithub.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=\ngithub.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs=\ngithub.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=\ngithub.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=\ngithub.com/nwaples/rardecode v1.1.3 h1:cWCaZwfM5H7nAD6PyEdcVnczzV8i/JtotnyW/dD9lEc=\ngithub.com/nwaples/rardecode v1.1.3/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=\ngithub.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=\ngithub.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=\ngithub.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=\ngithub.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a h1:dlRvE5fWabOchtH7znfiFCcOvmIYgOeAS5ifBXBlh9Q=\ngithub.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s=\ngithub.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=\ngithub.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=\ngithub.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=\ngithub.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=\ngithub.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=\ngithub.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=\ngithub.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=\ngithub.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=\ngithub.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=\ngithub.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=\ngithub.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=\ngithub.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8=\ngithub.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc=\ngithub.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=\ngithub.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=\ngithub.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=\ngithub.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=\ngithub.com/opencontainers/runc v1.2.8 h1:RnEICeDReapbZ5lZEgHvj7E9Q3Eex9toYmaGBsbvU5Q=\ngithub.com/opencontainers/runc v1.2.8/go.mod h1:cC0YkmZcuvr+rtBZ6T7NBoVbMGNAdLa/21vIElJDOzI=\ngithub.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=\ngithub.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=\ngithub.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=\ngithub.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA=\ngithub.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs=\ngithub.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=\ngithub.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=\ngithub.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=\ngithub.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=\ngithub.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=\ngithub.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=\ngithub.com/peterh/liner v1.2.0 h1:w/UPXyl5GfahFxcTOz2j9wCIHNI+pUPr2laqpojKNCg=\ngithub.com/peterh/liner v1.2.0/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=\ngithub.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 h1:Dx7Ovyv/SFnMFw3fD4oEoeorXc6saIiQ23LrGLth0Gw=\ngithub.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=\ngithub.com/phuslu/log v1.0.120 h1:ok+KEfGEz4RM9iyiJ5NhMa0KspywxT55EkpIL2YOzzo=\ngithub.com/phuslu/log v1.0.120/go.mod h1:F8osGJADo5qLK/0F88djWwdyoZZ9xDJQL1HYRHFEkS0=\ngithub.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM=\ngithub.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=\ngithub.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=\ngithub.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=\ngithub.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk=\ngithub.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE=\ngithub.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=\ngithub.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=\ngithub.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4=\ngithub.com/pion/stun/v2 v2.0.0 h1:A5+wXKLAypxQri59+tmQKVs7+l6mMM+3d+eER9ifRU0=\ngithub.com/pion/stun/v2 v2.0.0/go.mod h1:22qRSh08fSEttYUmJZGlriq9+03jtVmXNODgLccj8GQ=\ngithub.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q=\ngithub.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E=\ngithub.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM=\ngithub.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0=\ngithub.com/pk910/dynamic-ssz v0.0.4 h1:DT29+1055tCEPCaR4V/ez+MOKW7BzBsmjyFvBRqx0ME=\ngithub.com/pk910/dynamic-ssz v0.0.4/go.mod h1:b6CrLaB2X7pYA+OSEEbkgXDEcRnjLOZIxZTsMuO/Y9c=\ngithub.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=\ngithub.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=\ngithub.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=\ngithub.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=\ngithub.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=\ngithub.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=\ngithub.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=\ngithub.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=\ngithub.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=\ngithub.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=\ngithub.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=\ngithub.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=\ngithub.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=\ngithub.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=\ngithub.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=\ngithub.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=\ngithub.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=\ngithub.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=\ngithub.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=\ngithub.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=\ngithub.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=\ngithub.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=\ngithub.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=\ngithub.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=\ngithub.com/protolambda/bls12-381-util v0.1.0 h1:05DU2wJN7DTU7z28+Q+zejXkIsA/MF8JZQGhtBZZiWk=\ngithub.com/protolambda/bls12-381-util v0.1.0/go.mod h1:cdkysJTRpeFeuUVx/TXGDQNMTiRAalk1vQw3TYTHcE4=\ngithub.com/protolambda/zrnt v0.34.1 h1:qW55rnhZJDnOb3TwFiFRJZi3yTXFrJdGOFQM7vCwYGg=\ngithub.com/protolambda/zrnt v0.34.1/go.mod h1:A0fezkp9Tt3GBLATSPIbuY4ywYESyAuc/FFmPKg8Lqs=\ngithub.com/protolambda/ztyp v0.2.2 h1:rVcL3vBu9W/aV646zF6caLS/dyn9BN8NYiuJzicLNyY=\ngithub.com/protolambda/ztyp v0.2.2/go.mod h1:9bYgKGqg3wJqT9ac1gI2hnVb0STQq7p/1lapqrqY1dU=\ngithub.com/prysmaticlabs/fastssz v0.0.0-20241008181541-518c4ce73516 h1:xuVAdtz5ShYblG2sPyb4gw01DF8InbOI/kBCQjk7NiM=\ngithub.com/prysmaticlabs/fastssz v0.0.0-20241008181541-518c4ce73516/go.mod h1:h2OlIZD/M6wFvV3YMZbW16lFgh3Rsye00G44J2cwLyU=\ngithub.com/prysmaticlabs/go-bitfield v0.0.0-20240618144021-706c95b2dd15 h1:lC8kiphgdOBTcbTvo8MwkvpKjO0SlAgjv4xIK5FGJ94=\ngithub.com/prysmaticlabs/go-bitfield v0.0.0-20240618144021-706c95b2dd15/go.mod h1:8svFBIKKu31YriBG/pNizo9N0Jr9i5PQ+dFkxWg3x5k=\ngithub.com/prysmaticlabs/gohashtree v0.0.4-beta.0.20240624100937-73632381301b h1:VK7thFOnhxAZ/5aolr5Os4beiubuD08WiuiHyRqgwks=\ngithub.com/prysmaticlabs/gohashtree v0.0.4-beta.0.20240624100937-73632381301b/go.mod h1:HRuvtXLZ4WkaB1MItToVH2e8ZwKwZPY5/Rcby+CvvLY=\ngithub.com/prysmaticlabs/prysm/v5 v5.3.0 h1:7Lr8ndapBTZg00YE+MgujN6+yvJR6Bdfn28ZDSJ00II=\ngithub.com/prysmaticlabs/prysm/v5 v5.3.0/go.mod h1:r1KhlduqDMIGZ1GhR5pjZ2Ko8Q89noTDYTRoPKwf1+c=\ngithub.com/r3labs/sse/v2 v2.10.0 h1:hFEkLLFY4LDifoHdiCN/LlGBAdVJYsANaLqNYa1l/v0=\ngithub.com/r3labs/sse/v2 v2.10.0/go.mod h1:Igau6Whc+F17QUgML1fYe1VPZzTV6EMCnYktEmkNJ7I=\ngithub.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=\ngithub.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=\ngithub.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=\ngithub.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=\ngithub.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=\ngithub.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=\ngithub.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=\ngithub.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=\ngithub.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=\ngithub.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=\ngithub.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=\ngithub.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=\ngithub.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=\ngithub.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=\ngithub.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=\ngithub.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=\ngithub.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=\ngithub.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=\ngithub.com/sasha-s/go-deadlock v0.3.5 h1:tNCOEEDG6tBqrNDOX35j/7hL5FcFViG6awUGROb2NsU=\ngithub.com/sasha-s/go-deadlock v0.3.5/go.mod h1:bugP6EGbdGYObIlx7pUZtWqlvo8k9H6vCBBsiChJQ5U=\ngithub.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=\ngithub.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=\ngithub.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=\ngithub.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=\ngithub.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=\ngithub.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=\ngithub.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=\ngithub.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=\ngithub.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=\ngithub.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=\ngithub.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=\ngithub.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=\ngithub.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=\ngithub.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=\ngithub.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=\ngithub.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=\ngithub.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=\ngithub.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=\ngithub.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=\ngithub.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=\ngithub.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngithub.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=\ngithub.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=\ngithub.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=\ngithub.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=\ngithub.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=\ngithub.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=\ngithub.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=\ngithub.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=\ngithub.com/supranational/blst v0.3.16-0.20250831170142-f48500c1fdbe h1:nbdqkIGOGfUAD54q1s2YBcBz/WcsxCO9HUQ4aGV5hUw=\ngithub.com/supranational/blst v0.3.16-0.20250831170142-f48500c1fdbe/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=\ngithub.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs=\ngithub.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48=\ngithub.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E=\ngithub.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME=\ngithub.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e h1:cR8/SYRgyQCt5cNCMniB/ZScMkhI9nk8U5C7SbISXjo=\ngithub.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e/go.mod h1:Tu4lItkATkonrYuvtVjG0/rhy15qrNGNTjPdaphtZ/8=\ngithub.com/tidwall/btree v1.7.0 h1:L1fkJH/AuEh5zBnnBbmTwQ5Lt+bRJ5A8EWecslvo9iI=\ngithub.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY=\ngithub.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU=\ngithub.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY=\ngithub.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY=\ngithub.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE=\ngithub.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=\ngithub.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=\ngithub.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=\ngithub.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=\ngithub.com/ulikunitz/xz v0.5.14 h1:uv/0Bq533iFdnMHZdRBTOlaNMdb1+ZxXIlHDZHIHcvg=\ngithub.com/ulikunitz/xz v0.5.14/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=\ngithub.com/umbracle/fastrlp v0.1.0 h1:V0W3f6ZKWqbu1KggdhnRWOi+t7+PfL3VyAffJqayI5s=\ngithub.com/umbracle/fastrlp v0.1.0/go.mod h1:5RHgqiFjd4vLJESMWagP/E7su+5Gzk0iqqmrotR8WdA=\ngithub.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk=\ngithub.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=\ngithub.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=\ngithub.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=\ngithub.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=\ngithub.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=\ngithub.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=\ngithub.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=\ngithub.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=\ngithub.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=\ngithub.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=\ngithub.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=\ngithub.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=\ngithub.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U=\ngithub.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM=\ngithub.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw=\ngithub.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI=\ngitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b h1:CzigHMRySiX3drau9C6Q5CAbNIApmLdat5jPMqChvDA=\ngitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b/go.mod h1:/y/V339mxv2sZmYYR64O07VuCpdNZqCTwO8ZcouTMI8=\ngitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 h1:qwDnMxjkyLmAFgcfgTnfJrmYKWhHnci3GjDqcZp1M3Q=\ngitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02/go.mod h1:JTnUj0mpYiAsuZLmKjTx/ex3AtMowcCgnE7YNyCEP0I=\ngo.etcd.io/bbolt v1.4.0 h1:TU77id3TnN/zKr7CO/uk+fBCwF2jGcMuw2B/FMAzYIk=\ngo.etcd.io/bbolt v1.4.0/go.mod h1:AsD+OCi/qPN1giOX1aiLAha3o1U8rAz65bvN4j0sRuk=\ngo.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=\ngo.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=\ngo.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=\ngo.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=\ngo.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=\ngo.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=\ngo.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=\ngo.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=\ngo.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=\ngo.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=\ngo.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=\ngo.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=\ngo.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=\ngo.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=\ngo.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=\ngo.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=\ngo.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=\ngo.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=\ngo.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=\ngo.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=\ngo.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=\ngo.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=\ngo.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=\ngo.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=\ngo.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=\ngo.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=\ngo.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=\ngo.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=\ngo.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=\ngolang.org/x/arch v0.17.0 h1:4O3dfLzd+lQewptAHqjewQZQDyEdejz3VwgeYwkZneU=\ngolang.org/x/arch v0.17.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=\ngolang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=\ngolang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=\ngolang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA=\ngolang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU=\ngolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20191116160921-f9c825593386/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=\ngolang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=\ngolang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=\ngolang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=\ngolang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=\ngolang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=\ngolang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=\ngolang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=\ngolang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU=\ngolang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=\ngolang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=\ngolang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=\ngolang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=\ngolang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=\ngolang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=\ngolang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=\ngonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=\ngonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=\ngoogle.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=\ngoogle.golang.org/genproto v0.0.0-20240624140628-dc46fd24d27d h1:PksQg4dV6Sem3/HkBX+Ltq8T0ke0PKIRBNBatoDTVls=\ngoogle.golang.org/genproto v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:s7iA721uChleev562UJO2OYB0PPT9CMFjV+Ce7VJH5M=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b h1:uA40e2M6fYRBf0+8uN5mLlqUtV192iiksiICIBkYJ1E=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:Xa7le7qx2vmqB/SzWUBa7KdMjpdpAHlh5QCSnjessQk=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=\ngoogle.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=\ngoogle.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=\ngoogle.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=\ngoogle.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=\ngoogle.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=\ngoogle.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=\ngoogle.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=\ngoogle.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=\ngoogle.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=\ngoogle.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=\ngoogle.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=\ngoogle.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=\ngoogle.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngoogle.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=\ngoogle.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=\ngoogle.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=\ngopkg.in/Knetic/govaluate.v3 v3.0.0 h1:18mUyIt4ZlRlFZAAfVetz4/rzlJs9yhN+U02F4u1AOc=\ngopkg.in/Knetic/govaluate.v3 v3.0.0/go.mod h1:csKLBORsPbafmSCGTEh3U7Ozmsuq8ZSIlKk1bcqph0E=\ngopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=\ngopkg.in/cenkalti/backoff.v1 v1.1.0 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y=\ngopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UDAkHu8BrjI=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=\ngopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=\ngopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=\ngopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=\ngopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=\ngopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=\ngopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=\ngopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=\ngopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=\ngotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=\ngotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=\ngotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nk8s.io/apimachinery v0.30.4 h1:5QHQI2tInzr8LsT4kU/2+fSeibH1eIHswNx480cqIoY=\nk8s.io/apimachinery v0.30.4/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=\nk8s.io/client-go v0.30.4 h1:eculUe+HPQoPbixfwmaSZGsKcOf7D288tH6hDAdd+wY=\nk8s.io/client-go v0.30.4/go.mod h1:IBS0R/Mt0LHkNHF4E6n+SUDPG7+m2po6RZU7YHeOpzc=\nk8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=\nk8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=\nk8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=\nk8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=\npgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk=\npgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=\nsigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=\nsigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=\nsigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=\nsigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=\nsigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=\nsigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=\n"
  },
  {
    "path": "kurtosis/Makefile",
    "content": "#!/usr/bin/make -f\n\n###############################################################################\n###                                Kurtosis                                 ###\n###############################################################################\n\n# This Makefile uses bash specific syntax. Makefile usually runs commands in\n# /bin/sh. This is fine on Macos since /bin/sh is bash. However, on Ubuntu,\n# /bin/sh is dash, so many of the commands here will fail without this (env\n# variables like PATH not set, STDERR redirect does not work, etc).\nSHELL := /bin/bash\n\nBLOCKSCOUT_VERIF_GHCR = ghcr.io/blockscout/smart-contract-verifier:v1.10.0\nBLOCKSCOUT_VERIF_LOCAL = blockscout-sc-verifier:v1.10.0\n\n# Installs Kurtosis if not already installed\ninstall-kurtosis:\n\t@echo \"Checking for Kurtosis installation...\"\n\t@if ! command -v kurtosis &> /dev/null; then \\\n\t\techo \"Kurtosis could not be found, installing...\"; \\\n\t\tOS=$$(uname -s | tr A-Z a-z); \\\n\t\tif [ \"$$OS\" = \"darwin\" ]; then \\\n\t\t\tbrew install kurtosis-tech/tap/kurtosis-cli; \\\n\t\telif [ \"$$OS\" = \"linux\" ]; then \\\n\t\t\tARCH=$$(uname -m); \\\n\t\t\tif [ \"$$ARCH\" = \"x86_64\" ]; then ARCH=\"amd64\"; \\\n\t\t\telif [ \"$$ARCH\" = \"arm64\" ]; then ARCH=\"arm64\"; \\\n\t\t\telse echo \"Unsupported architecture $$ARCH for Kurtosis installation\" && exit 1; fi; \\\n\t\t\tTAG=`curl -s \"https://api.github.com/repos/kurtosis-tech/kurtosis-cli-release-artifacts/releases/latest\" | grep '\"tag_name\":' | sed -E 's/.*\"([^\"]+)\".*/\\1/'`; \\\n\t\t\tcurl -Lo kurtosis.tar.gz \"https://github.com/kurtosis-tech/kurtosis-cli-release-artifacts/releases/download/$TAG/kurtosis-cli_${TAG}_${OS}_${ARCH}.tar.gz\"; \\\n\t\t\ttar -xzf kurtosis.tar.gz; \\\n\t\t\trm kurtosis.tar.gz; \\\n\t\t\tchmod +x kurtosis; \\\n\t\t\tsudo mv kurtosis /usr/local/bin/; \\\n\t\telse \\\n\t\t\techo \"Unsupported OS $$OS for Kurtosis installation\" && exit 1; \\\n\t\tfi; \\\n\telse \\\n\t\techo \"Kurtosis is already installed\"; \\\n\tfi\n\n# Starts a Kurtosis enclave containing a local devnet.\nstart-devnet: install-kurtosis\n\t$(MAKE) build-docker VERSION=kurtosis-local start-devnet-no-build\n\n# Removes and restarts a Kurtosis enclave containing a local devnet.\nrestart-devnet:\n\t-$(MAKE) rm-devnet\n\tkurtosis engine restart\n\t$(MAKE) start-devnet\n\n# Pre-pulls GHCR images that require credential-helper auth and re-tags them\n# to local-only names so the Kurtosis engine can resolve them without GHCR access.\npull-blockscout-images:\n\t@echo \"Pre-pulling blockscout images for local devnet...\"\n\t@docker pull $(BLOCKSCOUT_VERIF_GHCR)\n\t@docker tag $(BLOCKSCOUT_VERIF_GHCR) $(BLOCKSCOUT_VERIF_LOCAL)\n\n# Starts a Kurtosis enclave containing a local devnet without building the image\nstart-devnet-no-build: pull-blockscout-images\n\tkurtosis run ./kurtosis --args-file ./kurtosis/beaconkit-local.yaml \\\n\t\t--enclave my-local-devnet --parallelism 200\n\n# Starts a Kurtosis enclave in the cloud using the latest image tag\nstart-devnet-cloud: install-kurtosis\n\tkurtosis run ./kurtosis --args-file ./kurtosis/beaconkit-cloud.yaml \\\n\t\t--enclave my-cloud-devnet-$(shell whoami) --parallelism 200 --production --image-download always\n\n# Remove the running Kurtosis enclave on GCP\nrm-devnet-cloud:\n\tkurtosis enclave rm my-cloud-devnet-$(shell whoami) --force\n\n# Stops the running Kurtosis enclave\nstop-devnet:\n\tkurtosis enclave stop my-local-devnet\n\n# Removes the specified Kurtosis enclave\nrm-devnet:\n\tkurtosis enclave rm my-local-devnet --force\n\n# Installs buildifier, a tool for linting and formatting starlark files.\nbuildifier-install:\n\t@echo \"--> Installing buildifier\"\n\t@go install github.com/bazelbuild/buildtools/buildifier@latest\n\n# Lints Starlark (.star) files in the Kurtosis directory using buildifier\nstar-lint: buildifier-install\n\t@echo \"--> Running buildifier to format starlark files...\"\n\tfind ./kurtosis -name \"*.star\" -exec buildifier -mode=check {} +\n\n# Automatically fixes formatting issues in Starlark (.star) files using buildifier\nstar-fix: buildifier-install\n\t@echo \"--> Running buildifier to format starlark files...\"\n\tfind ./kurtosis -name \"*.star\" -exec buildifier --mode=fix {} +\n\n# Marks targets as not being associated with files\n.PHONY: start-devnet stop-devnet start-devnet-cloud rm-devnet-cloud reset-devnet rm-devnet buildifier-install \\\n  star-lint star-fix install-kurtosis pull-blockscout-images"
  },
  {
    "path": "kurtosis/README.md",
    "content": "# Running BeaconKit with Kurtosis\n\n## What is Kurtosis\n\n[Kurtosis](https://www.kurtosis.com/) is a platform for running distributed\nsystems on Docker / Kubernetes. It provides a simple, powerful framework for\nspinning up and tearing down distributed systems programmatically.\n\n## How to Use\n\nTo use BeaconKit with Kurtosis, you'll first need to install the Kurtosis CLI\nand its dependencies. You can find instructions for doing so\n[here](https://docs.kurtosis.com/install).\n\n### Docker/local environment\n\nOnce you've installed the Kurtosis CLI, you can use it to spin up a Beacon\nnetwork with the following command from within the root directory of the\n`beacon-kit` repository:\n\n```sh\nmake start-devnet\n```\n\nThis will automatically build your `beacond` Docker image from the local\nsource code and spin up a Kurtosis network based on the config file in\n`kurtosis/beaconkit-local.yaml`. Once complete, this will output all the\nnetwork information for your nodes, like so:\n\n![Example Network](./img/example-network.png)\n\nWhen you want to tear down your network, you can do so with the following\ncommands:\n\n```sh\nmake stop-devnet\nmake rm-devnet\n```\n\nAnd that's it!\n\n## Deploy Devnet to Kubernetes Networks\n\n### Deploy to a Google Cloud Network\n\nThis will allow you to deploy a network orchestrated in the same way as\n`make start-devnet`, but on a cloud environment. A similar approach can be\ntaken for a local Kubernetes environment (alternative commands will be\ncommented with [Docker Desktop K8s]).\n\n- First, open your Kurtosis config:\n\n   ```sh\n   kurtosis config path\n\n   # The command will output a path which you need to open in an editor\n   /Users/.../kurtosis-config.yml\n   ```\n\n- Update the Kurtosis config with the following, replacing the entire file:\n\n   ```yaml\n   config-version: 2\n   should-send-metrics: true\n   kurtosis-clusters:\n     docker:\n       type: \"docker\"\n     docker-desktop:\n       type: \"kubernetes\"\n       config:\n         kubernetes-cluster-name: \"docker-desktop\"\n         storage-class: \"hostpath\"\n     cloud:\n       type: \"kubernetes\"\n       config:\n         kubernetes-cluster-name: \"cloud\"\n         storage-class: \"premium-rwo\"\n   ```\n\n- Next, ensure Kurtosis is using the correct config so it deploys to the\n   cloud instead of local Docker Desktop:\n\n   ```sh\n   kurtosis cluster set cloud\n\n   # [Docker Desktop K8s]: kurtosis config use-context docker-desktop\n   ```\n\n- Now ensure your Kubernetes config is using the correct context, i.e., the\n   one context you wish to deploy to:\n\n   ```sh\n   kubectl config use-context gke_prj-.....\n\n   # [Docker Desktop K8s]: kubectl config use-context docker-desktop\n   ```\n\n- Run Kurtosis Gateway. This command will start a local \"gateway\" to connect\n   your local machine to your remote Kubernetes cluster. Run this in a\n   separate shell:\n\n   ```sh\n   kurtosis gateway\n   ```\n\n- Cloud-based deployments require a Docker image, as local Docker images\n   cannot be pulled from the remote instance. If you want to update the image,\n   edit:\n\n   ```yaml\n   # Found in beacon-kit/kurtosis/beaconkit-cloud.yaml\n   images:\n     beaconkit: ghcr.io/berachain/beacon-kit:main\n   ```\n\n- Deploy. Note that re-executing the same command twice will start the\n   network from zero again unless you change the enclave name in the `Makefile`:\n\n   ```sh\n   make start-devnet-cloud\n   ```\n\n- View your deployment in K9s, navigating to the relevant namespace. It\n   should be named `kt-my-cloud-devnet-${whoami}`.\n\n## Helper Commands\n\nIf you want to start from a clean state and remove all existing pods:\n\n```sh\n# Everything is wrecked\nkurtosis clean -a\nkurtosis engine restart\n```\n\nIf you manually kill a pod and want to restart it:\n\n```sh\n# Note that for the namespace, you should remove the \"kt-\" prefix\nkurtosis service start {namespace} {podname}\n```\n"
  },
  {
    "path": "kurtosis/beaconkit-cloud.yaml",
    "content": "# SPDX-License-Identifier: MIT\n#\n# Copyright (c) 2025 Berachain Foundation\n#\n# Permission is hereby granted, free of charge, to any person\n# obtaining a copy of this software and associated documentation\n# files (the \"Software\"), to deal in the Software without\n# restriction, including without limitation the rights to use,\n# copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the\n# Software is furnished to do so, subject to the following\n# conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n# OTHER DEALINGS IN THE SOFTWARE.\n\n# This is the configuration is identical to beaconkit-local.yaml with the exception that the image is pulled from a public registry\n# As remote environments cannot access the image created locally. It also sets explicit min_cpu and min_memory values for the nodes\n# as in Kubernetes, the 0 value is interpreted as the max value. This is not the case for the local Docker environment.\nnetwork_configuration:\n  chain_id: 80087\n  chain_spec: \"devnet\"\n  validators:\n    type: \"validator\"\n    nodes:\n      - el_type: reth\n        kzg_impl: crate-crypto/go-kzg-4844\n        replicas: 5\n  full_nodes:\n    type: \"full\"\n    nodes:\n      - el_type: reth\n        kzg_impl: crate-crypto/go-kzg-4844\n        replicas: 5\n  seed_nodes:\n    type: \"seed\"\n    nodes:\n      - el_type: reth\n        replicas: 1\nnode_settings:\n  consensus_settings:\n    specs:\n      min_cpu: 1000\n      max_cpu: 2000\n      min_memory: 1024\n      max_memory: 2048\n    images:\n      beaconkit: ghcr.io/berachain/beacon-kit:main\n    config:\n      timeout_propose: 2s\n      timeout_prevote: 2s\n      timeout_precommit: 2s\n      max_num_inbound_peers: 40\n      max_num_outbound_peers: 10\n    app:\n      payload_timeout: 850ms\n  execution_settings:\n    specs:\n      min_cpu: 1000\n      max_cpu: 2000\n      min_memory: 1024\n      max_memory: 2048\n    images:\n      reth: ghcr.io/berachain/bera-reth:nightly\nadditional_services:\n  - name: \"spamoor\"\n  - name: \"tx-fuzz\"\n    replicas: 16\n  - name: \"prometheus\"\n  - name: \"grafana\"\n  - name: \"pyroscope\"\n  - name: \"blockscout\"\n    client: \"el-full-reth-0\"\n"
  },
  {
    "path": "kurtosis/beaconkit-local.yaml",
    "content": "# SPDX-License-Identifier: MIT\n#\n# Copyright (c) 2025 Berachain Foundation\n#\n# Permission is hereby granted, free of charge, to any person\n# obtaining a copy of this software and associated documentation\n# files (the \"Software\"), to deal in the Software without\n# restriction, including without limitation the rights to use,\n# copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the\n# Software is furnished to do so, subject to the following\n# conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n# OTHER DEALINGS IN THE SOFTWARE.\n\nnetwork_configuration:\n  chain_id: 80087\n  chain_spec: \"devnet\"\n  validators:\n    type: \"validator\"\n    nodes:\n      - el_type: reth\n        kzg_impl: crate-crypto/go-kzg-4844\n        replicas: 5\n  full_nodes:\n    type: \"full\"\n    nodes:\n      - el_type: reth\n        kzg_impl: crate-crypto/go-kzg-4844\n        replicas: 5\n  seed_nodes:\n    type: \"seed\"\n    nodes:\n      - el_type: reth\n        replicas: 1\nnode_settings:\n  consensus_settings:\n    specs:\n      min_cpu: 0\n      max_cpu: 2000\n      min_memory: 0\n      max_memory: 2048\n    images:\n      beaconkit: beacond:kurtosis-local\n    config:\n      timeout_propose: 2s\n      timeout_prevote: 2s\n      timeout_precommit: 2s\n      max_num_inbound_peers: 40\n      max_num_outbound_peers: 10\n    app:\n      payload_timeout: 850ms\n  execution_settings:\n    specs:\n      min_cpu: 0\n      max_cpu: 2000\n      min_memory: 0\n      max_memory: 2048\n    images:\n      reth: ghcr.io/berachain/bera-reth:nightly\nadditional_services:\n  - name: \"spamoor\"\n  - name: \"tx-fuzz\"\n    replicas: 16\n  - name: \"prometheus\"\n  - name: \"grafana\"\n  - name: \"pyroscope\"\n  - name: \"blockscout\"\n    client: \"el-full-reth-0\"\n    verifier_image: \"blockscout-sc-verifier:v1.10.0\"\n"
  },
  {
    "path": "kurtosis/kurtosis-params.yaml",
    "content": "# SPDX-License-Identifier: MIT\n#\n# Copyright (c) 2025 Berachain Foundation\n#\n# Permission is hereby granted, free of charge, to any person\n# obtaining a copy of this software and associated documentation\n# files (the \"Software\"), to deal in the Software without\n# restriction, including without limitation the rights to use,\n# copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the\n# Software is furnished to do so, subject to the following\n# conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n# OTHER DEALINGS IN THE SOFTWARE.\n\nnetwork_params:\n  network_name: \"kurtosis\"\n  network_id: \"80087\""
  },
  {
    "path": "kurtosis/kurtosis.yml",
    "content": "# SPDX-License-Identifier: MIT\n#\n# Copyright (c) 2025 Berachain Foundation\n#\n# Permission is hereby granted, free of charge, to any person\n# obtaining a copy of this software and associated documentation\n# files (the \"Software\"), to deal in the Software without\n# restriction, including without limitation the rights to use,\n# copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the\n# Software is furnished to do so, subject to the following\n# conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n# OTHER DEALINGS IN THE SOFTWARE.\n\nname: github.com/berachain/beacon-kit/kurtosis\ndescription: |\n  A package for running a basic beacon-kit devnet with kurtosis\nreplace:\n  # Fix to a specific version of kurtosis ethereum package to avoid breaking changes\n  github.com/ethpandaops/ethereum-package: github.com/ethpandaops/ethereum-package@cda5ddac51e4ce2228f2a4da1d242b2fcb7eeccd\n"
  },
  {
    "path": "kurtosis/main.star",
    "content": "el_cl_genesis_data_generator = import_module(\n    \"github.com/ethpandaops/ethereum-package/src/prelaunch_data_generator/el_cl_genesis/el_cl_genesis_generator.star\",\n)\n\nexecution = import_module(\"./src/nodes/execution/execution.star\")\nservice_module = import_module(\"./src/services/service.star\")\nbeacond = import_module(\"./src/nodes/consensus/beacond/launcher.star\")\nnetworks = import_module(\"./src/networks/networks.star\")\nport_spec_lib = import_module(\"./src/lib/port_spec.star\")\nnodes = import_module(\"./src/nodes/nodes.star\")\nconstants = import_module(\"./src/constants.star\")\nspamoor = import_module(\"./src/services/spamoor/launcher.star\")\nprometheus = import_module(\"./src/observability/prometheus/prometheus.star\")\ngrafana = import_module(\"./src/observability/grafana/grafana.star\")\npyroscope = import_module(\"./src/observability/pyroscope/pyroscope.star\")\ntx_fuzz = import_module(\"./src/services/tx_fuzz/launcher.star\")\nblockscout = import_module(\"./src/services/blockscout/launcher.star\")\n\ndef run(plan, network_configuration = {}, node_settings = {}, additional_services = [], metrics_enabled_services = []):\n    \"\"\"\n    Initiates the execution plan with the specified number of validators and arguments.\n\n    Args:\n    plan: The execution plan to be run.\n    network_configuration: Network configuration including validators, full nodes, seed nodes.\n    node_settings: Node-specific settings.\n    additional_services: Additional services to launch.\n    metrics_enabled_services: Services with metrics enabled.\n    \"\"\"\n\n    # all_node_types = [validators[\"type\"], full_nodes[\"type\"], seed_nodes[\"type\"]]\n    # all_node_settings = nodes.parse_node_settings(node_settings, all_node_types)\n\n    # Get chain configuration from network_configuration, if not provided, use default values\n    chain_id = network_configuration.get(\"chain_id\", 80087)\n    chain_spec = network_configuration.get(\"chain_spec\", \"devnet\")\n\n    plan.print(\"CHAIN_ID: {}\".format(chain_id), \"CHAIN_SPEC: {}\".format(chain_spec))\n\n    next_free_prefunded_account = 0\n    validators = nodes.parse_nodes_from_dict(network_configuration[\"validators\"], node_settings)\n    full_nodes = nodes.parse_nodes_from_dict(network_configuration[\"full_nodes\"], node_settings)\n    seed_nodes = nodes.parse_nodes_from_dict(network_configuration[\"seed_nodes\"], node_settings)\n    num_validators = len(validators)\n\n    # 1. Initialize EVM genesis data\n    evm_genesis_data = networks.get_genesis_data(plan)\n\n    all_nodes = []\n    all_nodes.extend(validators)\n    all_nodes.extend(seed_nodes)\n    all_nodes.extend(full_nodes)\n    node_modules = {}\n    for node in all_nodes:\n        if node.el_type not in node_modules.keys():\n            node_path = \"./src/nodes/execution/{}/config.star\".format(node.el_type)\n            node_module = import_module(node_path)\n            node_modules[node.el_type] = node_module\n\n    # 2. Upload files\n    jwt_file, kzg_trusted_setup = execution.upload_global_files(plan, node_modules, chain_id)\n\n    # 3. Perform genesis ceremony for the CL genesis deposits.\n    genesis_result = beacond.perform_genesis_deposits_ceremony(plan, validators, jwt_file, chain_id, chain_spec)\n    stored_configs = genesis_result.configs\n\n    # 4 a. Create genesis files only once and pass it to the node configs\n    genesis_files = nodes.create_genesis_files_part1(plan, chain_id)\n\n    # 4b. Modify the eth genesis file with the premined deposits && finalize CL genesis file.\n    # Get the deposit storage values stored in env variables\n    env_vars = beacond.modify_genesis_files_deposits(plan, validators, genesis_files, chain_id, chain_spec, stored_configs)\n\n    # Extract values from env_vars\n    genesis_deposits_root = env_vars.get(\"GENESIS_DEPOSITS_ROOT\")\n    genesis_deposit_count_hex = env_vars.get(\"GENESIS_DEPOSIT_COUNT_HEX\")\n\n    # 4c. Modify the eth genesis files with the ENV VARS\n    genesis_files = nodes.create_genesis_files_part2(plan, chain_id, genesis_deposits_root, genesis_deposit_count_hex)\n\n    el_enode_addrs = []\n    metrics_enabled_services = metrics_enabled_services[:]\n\n    consensus_node_peering_info = []\n    all_consensus_peering_info = {}\n\n    # Start seed nodes\n    seed_node_el_client_configs = []\n    for n, seed in enumerate(seed_nodes):\n        el_client_config = execution.generate_node_config(plan, node_modules, seed, chain_id, chain_spec, genesis_files)\n        seed_node_el_client_configs.append(el_client_config)\n    if seed_node_el_client_configs != []:\n        seed_node_el_clients = execution.deploy_nodes(plan, seed_node_el_client_configs)\n    for n, seed in enumerate(seed_nodes):\n        enode_addr = execution.get_enode_addr(plan, seed.el_service_name)\n        el_enode_addrs.append(enode_addr)\n        metrics_enabled_services = execution.add_metrics(metrics_enabled_services, seed, seed.el_service_name, seed_node_el_clients[seed.el_service_name], node_modules)\n    seed_node_configs = {}\n    for n, seed in enumerate(seed_nodes):\n        seed_node_config = beacond.create_node_config(plan, seed, consensus_node_peering_info, seed.el_service_name, chain_id, chain_spec, genesis_deposits_root, genesis_deposit_count_hex, jwt_file, kzg_trusted_setup)\n        seed_node_configs[seed.cl_service_name] = seed_node_config\n    seed_nodes_clients = {}\n    if seed_node_configs != {}:\n        seed_nodes_clients = plan.add_services(\n            configs = seed_node_configs,\n        )\n    for n, seed_client in enumerate(seed_nodes):\n        peer_info = beacond.get_peer_info(plan, seed_client.cl_service_name)\n        consensus_node_peering_info.append(peer_info)\n        metrics_enabled_services.append({\n            \"name\": seed_client.cl_service_name,\n            \"service\": seed_nodes_clients[seed_client.cl_service_name],\n            \"metrics_path\": beacond.METRICS_PATH,\n        })\n\n    # 5. Start full nodes (rpcs)\n    full_node_configs = {}\n    full_node_el_client_configs = []\n    full_node_el_clients = {}\n\n    for n, full in enumerate(full_nodes):\n        el_client_config = execution.generate_node_config(plan, node_modules, full, chain_id, chain_spec, genesis_files, el_enode_addrs)\n        full_node_el_client_configs.append(el_client_config)\n\n    if full_node_el_client_configs != []:\n        full_node_el_clients = execution.deploy_nodes(plan, full_node_el_client_configs, True)\n\n    for n, full in enumerate(full_nodes):\n        metrics_enabled_services = execution.add_metrics(metrics_enabled_services, full, full.el_service_name, full_node_el_clients[full.el_service_name], node_modules)\n\n    for n, full in enumerate(full_nodes):\n        # 5b. Launch CL\n        full_node_config = beacond.create_node_config(plan, full, consensus_node_peering_info, full.el_service_name, chain_id, chain_spec, genesis_deposits_root, genesis_deposit_count_hex, jwt_file, kzg_trusted_setup)\n        full_node_configs[full.cl_service_name] = full_node_config\n\n    if full_node_configs != {}:\n        services = plan.add_services(\n            configs = full_node_configs,\n        )\n    for n, full_node in enumerate(full_nodes):\n        peer_info = beacond.get_peer_info(plan, full_node.cl_service_name)\n        all_consensus_peering_info[full_node.cl_service_name] = peer_info\n        metrics_enabled_services.append({\n            \"name\": full_node.cl_service_name,\n            \"service\": services[full_node.cl_service_name],\n            \"metrics_path\": beacond.METRICS_PATH,\n        })\n\n    # 7. Start network validators\n    validator_node_el_clients = []\n\n    for n, validator in enumerate(validators):\n        el_client_config = execution.generate_node_config(plan, node_modules, validator, chain_id, chain_spec, genesis_files, el_enode_addrs)\n        validator_node_el_clients.append(el_client_config)\n\n    validator_el_clients = execution.deploy_nodes(plan, validator_node_el_clients)\n\n    for n, validator in enumerate(validators):\n        metrics_enabled_services = execution.add_metrics(metrics_enabled_services, validator, validator.el_service_name, validator_el_clients[validator.el_service_name], node_modules)\n\n    validator_node_configs = {}\n    for n, validator in enumerate(validators):\n        validator_node_config = beacond.create_node_config(plan, validator, consensus_node_peering_info, validator.el_service_name, chain_id, chain_spec, genesis_deposits_root, genesis_deposit_count_hex, jwt_file, kzg_trusted_setup)\n        validator_node_configs[validator.cl_service_name] = validator_node_config\n\n    cl_clients = plan.add_services(\n        configs = validator_node_configs,\n    )\n\n    for n, validator in enumerate(validators):\n        peer_info = beacond.get_peer_info(plan, validator.cl_service_name)\n        all_consensus_peering_info[validator.cl_service_name] = peer_info\n        metrics_enabled_services.append({\n            \"name\": validator.cl_service_name,\n            \"service\": cl_clients[validator.cl_service_name],\n            \"metrics_path\": beacond.METRICS_PATH,\n        })\n\n    for n, seed_node in enumerate(seed_nodes):\n        beacond.dial_unsafe_peers(plan, seed_node.cl_service_name, all_consensus_peering_info)\n\n    # If no seed nodes exist, bootstrap peering from the first validator\n    # so that nodes can discover each other via PEX.\n    if len(seed_nodes) == 0 and len(validators) > 0:\n        beacond.dial_unsafe_peers(plan, validators[0].cl_service_name, all_consensus_peering_info)\n\n        # Bootstrap EL peering: use first validator as a static peer so\n        # all EL nodes can discover each other via devp2p.\n        bootstrap_enode = execution.get_enode_addr(plan, validators[0].el_service_name)\n        el_services_to_peer = []\n        for node in full_nodes:\n            el_services_to_peer.append(node.el_service_name)\n        for node in validators[1:]:\n            el_services_to_peer.append(node.el_service_name)\n        for el_name in el_services_to_peer:\n            execution.add_peer(plan, el_name, bootstrap_enode)\n\n    # 8. Start additional services\n    prometheus_url = \"\"\n    for s_dict in additional_services:\n        s = service_module.parse_service_from_dict(s_dict)\n        if s.name == \"spamoor\":\n            plan.print(\"Launching spamoor\")\n            first_full_el_name = full_nodes[0].el_service_name\n            first_full_el = full_node_el_clients[first_full_el_name]\n            ip_spamoor = first_full_el.ip_address\n            port_spamoor = first_full_el.ports[\"eth-json-rpc\"].number\n            spamoor.launch_spamoor(\n                plan,\n                constants.PRE_FUNDED_ACCOUNTS[next_free_prefunded_account],\n                \"http://{}:{}\".format(ip_spamoor, port_spamoor),\n            )\n            next_free_prefunded_account += 1\n            plan.print(\"Successfully launched spamoor\")\n        elif s.name == \"tx-fuzz\":\n            plan.print(\"Launching tx-fuzz\")\n            if \"replicas\" not in s_dict:\n                s.replicas = 1\n            next_free_prefunded_account = tx_fuzz.launch_tx_fuzzes(plan, s.replicas, next_free_prefunded_account, full_node_el_client_configs, full_node_el_clients, [])\n\n        elif s.name == \"prometheus\":\n            prometheus_url = prometheus.start(plan, metrics_enabled_services)\n        elif s.name == \"grafana\":\n            grafana.start(plan, prometheus_url)\n        elif s.name == \"pyroscope\":\n            pyroscope.run(plan)\n        elif s.name == \"blockscout\":\n            plan.print(\"Launching blockscout\")\n            blockscout.launch_blockscout(\n                plan,\n                full_node_el_clients,\n                s.client,\n                False,\n                s.verifier_image,\n            )\n\n    plan.print(\"Successfully launched development network\")\n"
  },
  {
    "path": "kurtosis/src/constants.star",
    "content": "KURTOSIS_IP_ADDRESS_PLACEHOLDER = \"KURTOSIS_IP_ADDR_PLACEHOLDER\"\n\nGLOBAL_LOG_LEVEL = struct(\n    info = \"info\",\n    error = \"error\",\n    warn = \"warn\",\n    debug = \"debug\",\n    trace = \"trace\",\n)\n\nJWT_MOUNT_PATH_ON_CONTAINER = \"/jwt/jwt-secret.hex\"\nJWT_FILEPATH = \"/kurtosis/src/nodes/jwt-secret.hex\"\nKZG_TRUSTED_SETUP_FILEPATH = \"/kurtosis/src/nodes/kzg-trusted-setup.json\"\n\ndef new_prefunded_account(address, private_key):\n    return struct(address = address, private_key = private_key)\n\nPRE_FUNDED_ACCOUNTS = [\n    new_prefunded_account(\n        \"0x20f33ce90a13a4b5e7697e3544c3083b8f8a51d4\",\n        \"fffdbb37105441e14b0ee6330d855d8504ff39e705c3afa8f859ac9865f99306\",\n    ),\n    new_prefunded_account(\n        \"0x56898d1aFb10cad584961eb96AcD476C6826e41E\",\n        \"9b9bc88a144fff869ae2f4ea8e252f2494d9b52ea1008d0b3537dad27ab489d5\",\n    ),\n\n    # Starting here we use this mnemonic 'brass gallery tennis vintage crack virus outside bike fossil shock sword panda ritual about cover clap fruit festival parrot capable high vacant orchard hurt'\n    new_prefunded_account(\n        \"0x1e2e53c2451d0f9ED4B7952991BE0c95165D5c01\",\n        \"0x23b19fd0ba67f921bc1f5a133bfe452060d129f025fcf1be75c6964551b1208a\",\n    ),\n    new_prefunded_account(\n        \"0x3bd0E8f1B1E8Ec99a4E1762F4058F9884C93af31\",\n        \"0x0e67856b2a42ca52862a60d11e3ac57871988aefe7a28ecd20bd8c2dec55da25\",\n    ),\n    new_prefunded_account(\n        \"0xD073a84e2ccDF91a9025179330438485E886D206\",\n        \"0xa901724fadf8e33b97e907d903dda50553969f6c8be510199878989c459b629a\",\n    ),\n    new_prefunded_account(\n        \"0x8a88215ae882dfA519730c40109556c1C235729f\",\n        \"0x110ecfb76a8a19b4fc32d7842548e00d7d6c1ba48bbc5d760eb97c9cd6fdbdc6\",\n    ),\n    new_prefunded_account(\n        \"0x1a0A57e5e6a66aD732295ddAF0aed286a4e64310\",\n        \"0xc6b45ae662b588d7419202030581e1c104414dcd79b2c7d43b29908190b4b983\",\n    ),\n    new_prefunded_account(\n        \"0x185F4Eebd01614aE3d12a5E49b184B054C46d37B\",\n        \"0x668eedaaaa05e87a9e62364f4ee75aba0aa78e13fb0142882ecb5beb2b58eb09\",\n    ),\n    new_prefunded_account(\n        \"0xdb96E9cDD1e457b602f97d33e51736D7a5216496\",\n        \"0x11c442db1d30e3f926f7e8c4a4208574d682669c6d720cb7d4eec910c0cfc863\",\n    ),\n    new_prefunded_account(\n        \"0x44a5FBfa7d6f3Fd92cca01f6764509f8Fc33dfa5\",\n        \"0x2ad0867fb0a18a3c0d8ef4dfce28e5356575f7a4a583ea1be7e50b0294d44614\",\n    ),\n    new_prefunded_account(\n        \"0x3649839562C8dA64E6215EB0f5371629Ead9729D\",\n        \"0x79ffac4f8ea5fcab09114a00e83e36b4c509ed46cdf20e5f9ba080a43fa1ebb6\",\n    ),\n    new_prefunded_account(\n        \"0x51e15e71c865FE702C9347610667f83658A20e00\",\n        \"0xe8a6d4a8d7e48ad04111ef3c0727c77548a4e3f63ffae670a9a795c3c4273889\",\n    ),\n    new_prefunded_account(\n        \"0xBC9BC89b295a14F3976234Cc37C73e3D286f3a49\",\n        \"0x306e4df414d24524c01716fc26162506e760503a6ec8646fbdc7711a603608aa\",\n    ),\n    new_prefunded_account(\n        \"0x12De044207a90709Ef2602D3D9D945d64dAe6147\",\n        \"0x51dd5ac7fa687e86670623dbe48d19733fc89ed4ffec78effa6db68956afd3e5\",\n    ),\n    new_prefunded_account(\n        \"0x4Afe0DFDAcc91F0fA2AEe39F9eAd66b64d03EbD6\",\n        \"0xde57bd35f2dec5cd25c524f0bf0d62dcca84709fb1a9371a7efcd30a9af945cb\",\n    ),\n    new_prefunded_account(\n        \"0xBC3c03b4185A6F10618CC4E7B9f4AdD59AB5FbbA\",\n        \"0xd9a59c0514630682109fa233df2e86399835f72c1b30220af7e8fea11a971592\",\n    ),\n    new_prefunded_account(\n        \"0xDc6De65f6070b409125217a12Cf576A208Cc1998\",\n        \"0x00e89a500a096d53e2b2d1dfebc9f024ddc9ba5b2d3aeced79c87917cd3bddfc\",\n    ),\n    new_prefunded_account(\n        \"0xF60fD8632Fc77E19b3A0637d115d0fdd06F36968\",\n        \"0x634cffbe3f71b9dc4227563a4cb80204940dad303af48b0e66c9ef0ae0a6dd7c\",\n    ),\n    new_prefunded_account(\n        \"0xbcC90AD39D377cA0b7b4F36eC463103E2728C33F\",\n        \"0x00da370da5af1511feea6fbe327ce13d6f1355957781698fd5f31c4b7e68f568\",\n    ),\n    new_prefunded_account(\n        \"0x6F69542fC88fF84C480FFf510aB7108120447247\",\n        \"0x3536343125036f602508e7c5e05b102133360dcfbe98fb36ef76cebcfd3626d4\",\n    ),\n    new_prefunded_account(\n        \"0x2f6eB3D9a41157322dE01A6E707F6F118Cb00A7b\",\n        \"0x5612e01bb58597611457dfca072325b84d612be3b04378ba4be76a9ea681f5ec\",\n    ),\n    new_prefunded_account(\n        \"0x187bE38A1f448b0F42423151A683dCAea949008B\",\n        \"0x92b11cad0aa9a1c894157f4ff51bb905a13d0c47445e3033a0c46af802f2cd96\",\n    ),\n    new_prefunded_account(\n        \"0xA1d283f1a11A36D20FF38F29e12CA8F7Cf8709c1\",\n        \"0xb60dc9ebb4a6a301f28d69df14dfa48a699c941ae88bef1226d22034e7be4f90\",\n    ),\n    new_prefunded_account(\n        \"0x868a33C94F91398B6245e1f0E4CF128B2F28714B\",\n        \"0xa53464fd5ce1ad3f74bd2fef45fd81a4f8430b73900354b979a8cec409a6ddf0\",\n    ),\n    new_prefunded_account(\n        \"0x67c942Ef50Fc690eA779067a6A0d444a8234baB5\",\n        \"0x0310a72661205364e7f341b3a338d3a3bf6f2876403a3bd618be4f2f01af8b91\",\n    ),\n    new_prefunded_account(\n        \"0xDE8E0E641E2Fb52c22460e6a1533c6BD13A00B37\",\n        \"0x25e28dea3bc8c317608c6c8f6c394bce47fd5ff29ef8c101ec6f2bb678fc5093\",\n    ),\n    new_prefunded_account(\n        \"0x9beFa0FB7a1A9E6cC7596204DbB8962E87091D64\",\n        \"0x90e03f14c68e4c14b58b68668a68b8512bb21994cf05cb2c1af4d3e454a01999\",\n    ),\n    new_prefunded_account(\n        \"0x62cB9bF32EA104f6D5eBf6879e876439f9492E4B\",\n        \"0xa44b22fb3a02ec16a5c31b37878600647e5d43f51e2bb7e76fd0c6e2653db0a0\",\n    ),\n    new_prefunded_account(\n        \"0xdb9cB94B166DfdC9F337EA63b32B448d993d7008\",\n        \"0x71e76153038a529f306872ce3f01d246aa80982906d8c6092543fa8df76e0d73\",\n    ),\n    new_prefunded_account(\n        \"0x7c4d7dB81c544B768E1f4782011077202B74B5C0\",\n        \"0xe39d434543ebcc9db6467b4fc121220f06dad303df4f3cc0a51aff235273932f\",\n    ),\n    new_prefunded_account(\n        \"0xaEf63D7F7e2637c99FeA1B63366b244B4da12D70\",\n        \"0xb76ea4844f198d945449c28f795fa199f70f1bd37d0a1b4f489bf7f79639e6d0\",\n    ),\n    new_prefunded_account(\n        \"0x3DFb4173ec41EB976260fd689E5AB9772C66beaf\",\n        \"0x79b28c32e7b04ca737c6b9e9b2629ac8292285afa10ae73ee42706bea07a6940\",\n    ),\n    new_prefunded_account(\n        \"0x5145b1B855bca67A119CB02A42aF4Bdbc66B725C\",\n        \"0xa6e875f1d2991796746acada577196a56095ee2f684a00bb74b463336f3c0f0e\",\n    ),\n    new_prefunded_account(\n        \"0xf4b2eb959A4C4b0E148340676999FC0446D446D4\",\n        \"0x47b6a89108b41866932fa7448ad0feedec22b3baa9ab7f69c7564edf252420d4\",\n    ),\n    new_prefunded_account(\n        \"0xb86d37333072eFb48cEaa46C67271A27CA5Bda82\",\n        \"0x4ae54fa2370d6c515c30d9b0c04724dee47e684d1df754c775f5bf3d6ea03269\",\n    ),\n    new_prefunded_account(\n        \"0x6CBcF4198fDA91D00fD469340E6DF6df086159e3\",\n        \"0x9defa91490f3d1b6c67a682f06066bd72c7027dfd396e49aa9c10ab9c54b6196\",\n    ),\n    new_prefunded_account(\n        \"0xE7F444b5f772281384117674002d540131e533Ca\",\n        \"0xb0f3c0cea50abb97f50fa0777f7937ccfb4d558807a90c7eb4b0f674e7e74768\",\n    ),\n    new_prefunded_account(\n        \"0x719Be866A77CeEc1BaC4FD37910c0975eFd52f55\",\n        \"0x1c4e0bceb9d758e1aca207f430ef2963d483aeb6d5b073da049d8823ffe98a94\",\n    ),\n    new_prefunded_account(\n        \"0x0e10cDAd84D788843aF48673C5b260A02ef78742\",\n        \"0x20127f5feedc14aa3e3a6ac38d464e5c550093cc6b6d338f4a34bb9538e36e4c\",\n    ),\n    new_prefunded_account(\n        \"0xcB6632daA65e6c921c2963C37320f63f54fC8fE3\",\n        \"0x18500f6a8cf63787326c992e34d6d9ffad599ad14c62e8e9b383f889de935d7f\",\n    ),\n    new_prefunded_account(\n        \"0xDe5C7198e2416baB7e7a1EA758858Cd7301740bF\",\n        \"0x196df6fdda754bafd85228004b3c2173ccf6d42bdcd332ff78366185758aa44e\",\n    ),\n    new_prefunded_account(\n        \"0x25fc16D8E2314B305dF05C032E617638284801D6\",\n        \"0x0bb8e01ef0afe7715d1e0ee9ff33981862e680ae3299c32dc455ad256996ebbb\",\n    ),\n    new_prefunded_account(\n        \"0xD2a3b89AE8D2c3bD39E2F24612ecFCD8600360C9\",\n        \"0x7d3d3ace1f1164a8307c5187f43fe620d180be936391e36c435b0c594866d57f\",\n    ),\n    new_prefunded_account(\n        \"0x2F4fD8a82A1400E654eeEC59b0e588445ffE0F96\",\n        \"0x7916a06ca827d932627c7a82e9a68b7d79b1d64c139cfab14b97f9f0299cc576\",\n    ),\n    new_prefunded_account(\n        \"0x10FdFa4EFc83d6CC42F5ef14c13da8b98E458214\",\n        \"0x7f73e04379f0816b4eb5a579d575f34297f4a73713ffcfaf60a5b6116d6c1637\",\n    ),\n    new_prefunded_account(\n        \"0x49cE37B2019bb2d0B8b6a094ef87a6Dd625454A0\",\n        \"0x6174d6f44b02fac531b5cb0001b5c6a8ef7a94c349b70f2f1658f9e64120a9c5\",\n    ),\n    new_prefunded_account(\n        \"0x800830F031ab1dd5895a5ec5B561427AD18f9ea8\",\n        \"0xbb9de8caf4cd75f2775e2303f2f7d14127da8a32c029b3b6be195d0cb175cb34\",\n    ),\n    new_prefunded_account(\n        \"0x3124d9885b11B52c56A2aee610AfCf5740d484F0\",\n        \"0x67730ed1e0992a4541f1e24fe62e7356ee1affa9fa1e063025f803d594b796d0\",\n    ),\n    new_prefunded_account(\n        \"0xA6177defF3b768b1D678EdF7583b8cf210C777c0\",\n        \"0x5d3b93032a2a8422bc8188dcd86732e104a7e145ce1c417a425057ad84700a6d\",\n    ),\n    new_prefunded_account(\n        \"0xF99139D2FCc5E25F57B0B91fd382a21B3AFF9cbA\",\n        \"0xaedb174cee8faf87cfc89d1b0b8d3f71ce4fa093c1d3f6f95d66ca6d56c07a18\",\n    ),\n    new_prefunded_account(\n        \"0xC4DD08191B4d5173e3698491A11e05b63F9Ee097\",\n        \"0x794b0f636acc2d481d8a007c5c814b5ab0285b0f2dc4f09249cb140d232440c9\",\n    ),\n    new_prefunded_account(\n        \"0xB8865B4B8C56861534CC07ebBD2EA569a9a16323\",\n        \"0x5242412b3f8cfc334085ff367f7b0edcd9147128db5372f5af1c4a1653f65526\",\n    ),\n    new_prefunded_account(\n        \"0x2B9935698dc5c19Ab7414AE22f27Da5F4478008a\",\n        \"0x6c1f3aeff292aa72c4b3b29126acc1a3d221fb15cdd21a91afdea30197a3f693\",\n    ),\n    new_prefunded_account(\n        \"0xAC3c80F41C3049A89Aba8072FFbFc38a90fb6D8c\",\n        \"0x2a54bc87952ecdb225fecf5e17cda5e34a7af57a04f52f6cb3ea0fd73034b504\",\n    ),\n    new_prefunded_account(\n        \"0xD6D4Fb22B91FAa54700852a05698B37d45514166\",\n        \"0x5f5aafe935bdb54b7963f0a1198b5aa40fb076bb042d8cbb473202d223d4f661\",\n    ),\n    new_prefunded_account(\n        \"0xAf325Ccc92ae883DEF1634D499d8B093192D7a0c\",\n        \"0x12042bc310f17a3e138aed39d36db6a3fd79fc34af82d4579cb453bb106e20fd\",\n    ),\n    new_prefunded_account(\n        \"0x7469CeEf99FB67e4990c5F1c085a1B39b2902331\",\n        \"0x4763d00f07519325799eb96f1afc2b6495c962839f42c8947fcbb0fcb7714cb5\",\n    ),\n    new_prefunded_account(\n        \"0x14DA5251a1EB236238969575ccE943e2Fb0f4AA1\",\n        \"0x360d7a4c43661dc20b6b45aecc74731157820febd977d0e3f361c241505c2646\",\n    ),\n    new_prefunded_account(\n        \"0xF9f58a87C3f0B3A4a0592938c80C41a7c659f855\",\n        \"0x05ad2e2038fbbe5175b32ce433058ced25dcda16c1a9096a2babc67c6aded430\",\n    ),\n    new_prefunded_account(\n        \"0x1CF7e940A657eE706718CF180eb21864DE9672C3\",\n        \"0x77a7ea3cb368bfa6fafbb030fad7a8d1a5bb7522aaa6812f93cd48078cc9d777\",\n    ),\n    new_prefunded_account(\n        \"0x440C37b22e8D7469128Ea7De6ac2f31419B4A8b1\",\n        \"0x4eeb502b10d35d16f453e2c0c2047ec28040ca2535d1c3ef07e8a0df672a38d4\",\n    ),\n    new_prefunded_account(\n        \"0x4bD04ABA9fc709835b1EE4789195d10E9e8E53F5\",\n        \"0x7f3bc64adc04bb815c5308879e00adc474a6e5398753b2884d457dae9702edd7\",\n    ),\n    new_prefunded_account(\n        \"0x4dC3aC871b22F8a98197B0aae976a8dE08e5Bebe\",\n        \"0x4bb60046eed4f37440632278668a0f2137cd6853d716186b0feff56d3fac53d0\",\n    ),\n    new_prefunded_account(\n        \"0x1f1D0FCa7e19b799c315d4fDf31bA50e6A2AB153\",\n        \"0xaf68c285514858fdeb576b9a0b8429cad69d3a5b5e443b9da98a96a10b6e322b\",\n    ),\n    new_prefunded_account(\n        \"0x28879749Dda99387bdB43295B28bdF251d999F3b\",\n        \"0x411fad907c3951644ff9c1789488c70de8794913d53d946a5cb9af2f019f2396\",\n    ),\n    new_prefunded_account(\n        \"0xC4eD09A472B82516daa3A4d8D1E38AE94CF4855C\",\n        \"0x349d0efb83a78c04878e1b84dc50ba61f51d82dbcd4a93d6aa8469ed0bf36a76\",\n    ),\n    new_prefunded_account(\n        \"0xf22FbA9cBeB75ED353931418E9eca71EF1Ab9921\",\n        \"0x4b850afd62171d5152fd3ae606e9a54504331f5e05d2afd4425c8bb0593bc663\",\n    ),\n    new_prefunded_account(\n        \"0xC59D8935c0570E75BA0E55E3C661f535C86e368B\",\n        \"0x6df174e811caed865c56b85249da60ed6012d4a85defda84342080219408e615\",\n    ),\n    new_prefunded_account(\n        \"0xf97a36c417D33D1fC60a9163A8715e1aecb29102\",\n        \"0x4d2686dca939e451ada1c2c60b43ec51751a043013613e99a7f2657dc7e71857\",\n    ),\n    new_prefunded_account(\n        \"0x4245537d9e3fb36fBBf054247FfFB28b0d931503\",\n        \"0x771675f7f662ce044421ef85e9f4d01b67cbf4dc49bcd8c66ba051b58cfa36b1\",\n    ),\n    new_prefunded_account(\n        \"0xFeb1eafa0154D291e28e393FAF10Bc89e5cCbB22\",\n        \"0x2bad44bacec98635554cceec959a4913ed70bbc22c41652432ed8449c3ba8659\",\n    ),\n    new_prefunded_account(\n        \"0xf11D16e2EE6BefED82Fbca0b005906E09303aB95\",\n        \"0xc090fc69382106e7b4563b5132d1791950144611ace0a13c74660512f04d262f\",\n    ),\n    new_prefunded_account(\n        \"0x9C75eD1A37ae420b4FC0a1F4c26B673227Fd3AFa\",\n        \"0xf128a6a5e4465a627b97b0e5456a098550fcbac6688a9d7ec8f327934ee9f493\",\n    ),\n    new_prefunded_account(\n        \"0x6a354C708fd248FD778F6adF75E41AA554700F68\",\n        \"0xc3cc22368afd808e703e3679043a8803f9185e5be4c27a99805b3156970bcc62\",\n    ),\n    new_prefunded_account(\n        \"0xea94749deFcc40dC5992687974b1C84B1bB9D6df\",\n        \"0x1ea128368d1cd5ff6f548cf22e1e9f8a60acd5937dd5a77280cebe75705ba362\",\n    ),\n    new_prefunded_account(\n        \"0x7689BE67b205EB5d32811d95D60587Eae4F3036F\",\n        \"0x177933fe33ff1be7e031cdcbc90bd8c686aa8e809dbe9eaae4da2e7e659281ca\",\n    ),\n    new_prefunded_account(\n        \"0xdBfb742BD2e0e6E353cb61E75B9e11257aC8fB1A\",\n        \"0x4afe37059cee4b8dff36e6ede45fa47e96971a77a45e6e3e4a64ae204ab01ff4\",\n    ),\n    new_prefunded_account(\n        \"0x2E5f031578e8FF82199aaF16f42c44D43Fe61819\",\n        \"0x18bceb845b15b430b2fdb4dfa19bcf6a2ca9fc99f215df9d44c715ee7efe8067\",\n    ),\n    new_prefunded_account(\n        \"0x611a42A2EF62c2461D123e3F0B64b93938bc4781\",\n        \"0x206ff78c78e9301bc8b11fc658a9bbc722152b6739038938347e02ec4d0e9bc6\",\n    ),\n    new_prefunded_account(\n        \"0x1a0c826048DF0E4661E3c53bBd447d497E3f701F\",\n        \"0x40e62b0f968d1185354a33e2d63087f86e8925e1158419e467a327d4d115f732\",\n    ),\n    new_prefunded_account(\n        \"0x7f0E54bc3C1a72405646F5dFbBE0D4565c649fe2\",\n        \"0x62fd8b90b047849fed591bf2ff867a8437bd20c759376ceb587e7fb9b5eefef8\",\n    ),\n    new_prefunded_account(\n        \"0x54e1F990Dc0B7367F1E8eD96dA63BC4bca0E8061\",\n        \"0xaa4273b5eaf92f77bd98944d362a51001101b35c708b7a144074b8e6c05c8831\",\n    ),\n    new_prefunded_account(\n        \"0xbE651bc261b9Da5499a24Bf4214fD494c6e1F5Ac\",\n        \"0x95695009fe4132a590cfce1cc0a9980a51e730ea2ec8449c3f94531d55063d70\",\n    ),\n    new_prefunded_account(\n        \"0xD3c5dAC705289cD005C402C79C8445a47502d8be\",\n        \"0xcf89fbd9ef2d93c5839fded6a80be8af79c95cc9c62255c660e47fe03531789d\",\n    ),\n    new_prefunded_account(\n        \"0xE5981AA0807eb05611cDb666e32e53b2001bd61d\",\n        \"0xa511d7ddbd3de692c29330d9dfa9dbb6d910607848fb40f14f19107d07982d9a\",\n    ),\n    new_prefunded_account(\n        \"0x0fb648Cb08e21602AF61AF53fE104E29d46433F7\",\n        \"0x8b9e4e5748ac1768c78292daa4c4791af24fe0d67e8a98aab5ef02501d3dfa29\",\n    ),\n    new_prefunded_account(\n        \"0x0474f52d25529c4db5f4E72F43303dA71B3541C6\",\n        \"0x3c9ccc6a117204e9dca913ffc04b2ce235cafba8feb6dac15c47594c315d525d\",\n    ),\n    new_prefunded_account(\n        \"0xe3024d098953661638d59E06f7FcD0B61c424854\",\n        \"0xbaaf13a119fb0dfe196452d25b9452dd9ac6e2d9b18dc25ab141edab71433252\",\n    ),\n    new_prefunded_account(\n        \"0x8b1e58f651CacaAa40291d2a6E0a6404d7Ed99e6\",\n        \"0x5f3b3f4b7df21eb2032b9c5340ead919fe4b33788428c1634812e77b1f736da2\",\n    ),\n    new_prefunded_account(\n        \"0x8724C57fb8f38A1FccA7177543dd1D8FcD49E5aa\",\n        \"0xc24373d037a7e85f0b24fd0664fe9466955c04f97dad338bde0b6711e83db961\",\n    ),\n    new_prefunded_account(\n        \"0xd0F043dED28773953562f824334C4cbb84210AE7\",\n        \"0x5e66a59b22d0284554824c42043bca69d96b41693c8504228332743191fb5c41\",\n    ),\n    new_prefunded_account(\n        \"0xE3d2b9191EaBD3636A5dd057D522335cfae8c7CF\",\n        \"0x33663a07dcae30eabe33966af3c7346d7e6fda84d4f5f2d5c6ecb7182875255e\",\n    ),\n    new_prefunded_account(\n        \"0x3f51B3BB6A18141282Ba002F7709c7E2f337F961\",\n        \"0x1a9c0e36f536927b1bb371479e3e66da1d76c3cef38dc8df6abcd7f885eb2b37\",\n    ),\n    new_prefunded_account(\n        \"0xf6B6A52aA9BD788837c6682f47ACE009BD84b6fc\",\n        \"0x9d4f7b83d269e83cab82a829a4af8cdfc75f222266b59da05659fe81f0a9160a\",\n    ),\n    new_prefunded_account(\n        \"0x795B761Db5969B7ba53472d5D37c230C859a472F\",\n        \"0xb4f6c92d12dcaa5dde866306ba3bf13ee6a2f93579b9b5659df84e55043473cc\",\n    ),\n    new_prefunded_account(\n        \"0x7d7f187C2A05cDDCF700dCF2E02c96E7eF03f9B0\",\n        \"0xf5ef0b476332f7384b0d22dfe04079b71b75396ea31df7af83372dbddc34a758\",\n    ),\n    new_prefunded_account(\n        \"0x2d88ECD4d8F4b0A954886eE8C0802aE14684cd07\",\n        \"0x92765a2ecd92b6166663763194d31e89d6609b24222b5634cabf4b4813ac973d\",\n    ),\n    new_prefunded_account(\n        \"0x92B3feac5b7816Dcef96a303c1D5112271A70D2c\",\n        \"0x2846ec46730e70b54a766caac56d13832d19bdccf57254931cf195a54595d36c\",\n    ),\n    new_prefunded_account(\n        \"0x5DD7bc3BEE395831ce499315ecAFE81DE0556F99\",\n        \"0x9408db8dbf6eb04ce9d35b332dab7f82d9092c18f8bc591fa97fb3ed300f3254\",\n    ),\n    new_prefunded_account(\n        \"0x5227aaebCA3E5e893547A667666E2e4e12Ca20e0\",\n        \"0xb4eadccdc48d78d5c2bf1f608b68e971b27b49c984ada2c1237c092f823f1511\",\n    ),\n    new_prefunded_account(\n        \"0x47575DAE85403cD408d4639068D1187C427B9897\",\n        \"0x3f380d57c59b08cc54e5daa9edc2bbeb9946ed55800513ecac6c36e3216df1df\",\n    ),\n    new_prefunded_account(\n        \"0xE69ac59e1DF47291AaB8DEc540C796f81De7c892\",\n        \"0xe4f5eff00c76ec509ac9fc9f0dd4c90df9d275d72200da735ff318d7da102efc\",\n    ),\n    new_prefunded_account(\n        \"0xb87fb371Bd3C2093b608cd0E7a8dDD60Bb05C995\",\n        \"0x778b9f67675f289c9aeea78c80799ec5a625d655932733463e3a890f8f9d7e69\",\n    ),\n]\n"
  },
  {
    "path": "kurtosis/src/lib/bash.star",
    "content": "def exec_on_service(plan, service_name, command):\n    return plan.exec(\n        service_name = service_name,\n        recipe = ExecRecipe(\n            command = [\"bash\", \"-c\", command],\n        ),\n    )\n"
  },
  {
    "path": "kurtosis/src/lib/builtins.star",
    "content": "\"\"\"\nHelper library for type comparisons\n\nTypical usage examples:\n    type(None) == builtins.types.none # True\n\n    hello = \"hello\"\n    type(hello) == builtins.types.bool # False\n\"\"\"\n\ntypes = struct(\n    none = \"NoneType\",  # the type of None\n    bool = \"bool\",  # True or False\n    int = \"int\",  # a signed integer of arbitrary magnitude\n    float = \"float\",  # an IEEE 754 double-precision floating-point number\n    string = \"string\",  # a text string, with Unicode encoded as UTF-8 or UTF-16\n    bytes = \"bytes\",  # a byte string\n    list = \"list\",  # a fixed-length sequence of values\n    tuple = \"tuple\",  # a fixed-length sequence of values, unmodifiable\n    dict = \"dict\",  # a mapping from values to values\n    function = \"function\",  # a function\n    serviceConfig = \"ServiceConfig\",  # a service configuration object\n    portSpec = \"PortSpec\",  # a port spec object\n    directory = \"Directory\",  # a directory object\n    execRecipe = \"ExecRecipe\",  # an exec recipe object\n    getHttpRequestRecipe = \"GetHttpRequestRecipe\",  # a get http request recipe object\n    imageBuildSpec = \"ImageBuildSpec\",  # an image build spec object\n    module = \"module\",  # a module\n    # TODO(types): add remaining kurtosis types\n)\n\n# Types that can be used as keys in a dictionary due to being hashable\n# Note: tuples can also be hashable but only if they contain hashable elements\nhashable = [types.none, types.bool, types.int, types.float, types.string, types.bytes]\n"
  },
  {
    "path": "kurtosis/src/lib/helpers.star",
    "content": "def stop_service(plan, service_name):\n    plan.stop_service(service_name)\n\ndef start_service(plan, service_name):\n    plan.start_service(service_name)\n"
  },
  {
    "path": "kurtosis/src/lib/port_spec.star",
    "content": "builtins = import_module(\"./builtins.star\")\n\nDEFAULT_TRANSPORT_PROTOCOL = \"tcp\"\nDEFAULT_APPLICATION_PROTOCOL = \"\"\nDEFAULT_WAIT = \"15s\"\n\ndef get_port_spec_template(\n        number,\n        transport_protocol = DEFAULT_TRANSPORT_PROTOCOL,\n        application_protocol = DEFAULT_APPLICATION_PROTOCOL,\n        wait = DEFAULT_WAIT):\n    port_spec = {\n        \"number\": number,\n        \"transport_protocol\": transport_protocol,\n        \"application_protocol\": application_protocol,\n        \"wait\": wait,\n    }\n\n    validate_port_spec(port_spec)\n    return port_spec\n\ndef validate_port_spec(port_spec):\n    if type(port_spec) != builtins.types.dict:\n        fail(\"Port spec must be a dict, not {0}\".format(type(port_spec)))\n\n    if type(port_spec[\"number\"]) != builtins.types.int:\n        fail(\"Port spec number must be an int, not {0}\".format(type(port_spec[\"number\"])))\n\n    if port_spec[\"transport_protocol\"] != None:\n        if type(port_spec[\"transport_protocol\"]) != builtins.types.string:\n            fail(\"Port spec transport_protocol must be a string, not {0}\".format(type(port_spec[\"transport_protocol\"])))\n\n    if port_spec[\"application_protocol\"] != None:\n        if type(port_spec[\"application_protocol\"]) != builtins.types.string:\n            fail(\"Port spec application_protocol must be a string, not {0}\".format(type(port_spec[\"application_protocol\"])))\n\n    if port_spec[\"wait\"] != None:\n        if type(port_spec[\"wait\"]) != builtins.types.string:\n            fail(\"Port spec wait must be a bool, not {0}\".format(type(port_spec[\"wait\"])))\n\ndef create_port_specs_from_config(config):\n    ports = {}\n    for port_key, port_spec in config[\"ports\"].items():\n        ports[port_key] = create_port_spec(port_spec)\n\n    return ports\n\ndef create_port_spec(port_spec_dict):\n    return PortSpec(\n        number = port_spec_dict[\"number\"],\n        transport_protocol = port_spec_dict[\"transport_protocol\"],\n        application_protocol = port_spec_dict[\"application_protocol\"],\n        wait = port_spec_dict[\"wait\"],\n    )\n"
  },
  {
    "path": "kurtosis/src/lib/service_config.star",
    "content": "\"\"\"\nA library for manipulating Service Configs as dictionaries, prior to instantiating the actual ServiceConfig object\n\nThis is necessary because Starlark structs are largely immutable. To pass a config around and make manipulations to it\nwe represent the Service Config as a dictionary, and then convert it to a ServiceConfig object when we're ready to use it.\nWe additionally support validations to ensure that the dictionary is well-formed.\n\nReferences:\n    - https://docs.kurtosis.com/api-reference/starlark-reference/service-config/\n    - https://github.com/kurtosis-tech/kurtosis/blob/473d0ee07f2b16c39cf9a453c3c28afdb1e2493d/core/server/api_container/server/startosis_engine/kurtosis_types/service_config/service_config.go\n\"\"\"\n\nbuiltins = import_module(\"./builtins.star\")\nport_spec_lib = import_module(\"./port_spec.star\")\n\nDEFAULT_PRIVATE_IP_ADDRESS_PLACEHOLDER = \"KURTOSIS_IP_ADDR_PLACEHOLDER\"\nDEFAULT_MAX_CPU = 2000  # 2 cores\nDEFAULT_MAX_MEMORY = 2048  # 2 GB\n\ndef get_service_config_template(\n        name,\n        image,\n        ports = None,\n        public_ports = None,\n        files = None,\n        entrypoint = None,\n        cmd = None,\n        env_vars = None,\n        private_ip_address_placeholder = None,\n        max_cpu = None,\n        min_cpu = None,\n        max_memory = None,\n        min_memory = None,\n        ready_conditions = None,\n        labels = None,\n        user = None,\n        tolerations = None,\n        node_selectors = None):\n    service_config = {\n        \"name\": name,\n        \"image\": image,\n        \"ports\": ports,\n        \"public_ports\": public_ports,\n        \"files\": files,\n        \"entrypoint\": entrypoint,\n        \"cmd\": cmd,\n        \"env_vars\": env_vars,\n        \"private_ip_address_placeholder\": private_ip_address_placeholder,\n        \"max_cpu\": max_cpu,\n        \"min_cpu\": min_cpu,\n        \"max_memory\": max_memory,\n        \"min_memory\": min_memory,\n        \"ready_conditions\": ready_conditions,\n        \"labels\": labels,\n        \"user\": user,\n        \"tolerations\": tolerations,\n        \"node_selectors\": node_selectors,\n    }\n\n    # validate_service_config_types(service_config)\n    return service_config\n\ndef validate_service_config_types(service_config):\n    if type(service_config) != builtins.types.dict:\n        fail(\"Service config must be a dict, not {0}\".format(type(service_config)))\n\n    if type(service_config[\"name\"]) != builtins.types.string:\n        fail(\"Service config name must be a string, not {0}\".format(type(service_config[\"name\"])))\n\n    if type(service_config[\"image\"]) != builtins.types.string:\n        fail(\"Service config image must be a string, not {0}\".format(type(service_config[\"image\"])))\n\n    if service_config[\"ports\"] != None:\n        if type(service_config[\"ports\"]) != builtins.types.dict:\n            fail(\"Service config ports must be a dict, not {0}\".format(type(service_config[\"ports\"])))\n        for port_key, port_spec in service_config[\"ports\"].items():\n            if type(port_key) != builtins.types.string:\n                fail(\"Service config port key must be an int, not {0}\".format(type(port_key)))\n            port_spec_lib.validate_port_spec(port_spec)\n\n    if service_config[\"files\"] != None:\n        if type(service_config[\"files\"]) != builtins.types.dict:\n            fail(\"Service config files must be a dict, not {0}\".format(type(service_config[\"files\"])))\n        for path, content in service_config[\"files\"].items():\n            if type(path) != builtins.types.string:\n                fail(\"Service config file path must be a string, not {0}\".format(type(path)))\n            if type(content) not in [builtins.types.string, builtins.types.directory]:\n                fail(\"Service config file content must be a string or a Directory object, not {0}\".format(type(content)))\n\n    if service_config[\"entrypoint\"] != None:\n        if type(service_config[\"entrypoint\"]) != builtins.types.list:\n            fail(\"Service config entrypoint must be a list, not {0}\".format(type(service_config[\"entrypoint\"])))\n        for entrypoint in service_config[\"entrypoint\"]:\n            if type(entrypoint) != builtins.types.string:\n                fail(\"Service config entrypoint must be a string, not {0}\".format(type(entrypoint)))\n\n    if service_config[\"cmd\"] != None:\n        if type(service_config[\"cmd\"]) != builtins.types.list:\n            fail(\"Service config cmd must be a list, not {0}\".format(type(service_config[\"cmd\"])))\n        for cmd in service_config[\"cmd\"]:\n            if type(cmd) != builtins.types.string:\n                fail(\"Service config cmd must be a string, not {0}\".format(type(cmd)))\n\n    if service_config[\"env_vars\"] != None:\n        if type(service_config[\"env_vars\"]) != builtins.types.dict:\n            fail(\"Service config env_vars must be a dict, not {0}\".format(type(service_config[\"env_vars\"])))\n        for env_var_key, env_var_value in service_config[\"env_vars\"].items():\n            if type(env_var_key) != builtins.types.string:\n                fail(\"Service config env_var key must be a string, not {0}\".format(type(env_var_key)))\n            if type(env_var_value) != builtins.types.string:\n                fail(\"Service config env_var value must be a string, not {0}\".format(type(env_var_value)))\n\n    if service_config[\"private_ip_address_placeholder\"] != None:\n        if type(service_config[\"private_ip_address_placeholder\"]) != builtins.types.string:\n            fail(\"Service config private_ip_address_placeholder must be a string, not {0}\".format(type(service_config[\"private_ip_address_placeholder\"])))\n\n    if service_config[\"max_cpu\"] != None:\n        if type(service_config[\"max_cpu\"]) != builtins.types.int:\n            fail(\"Service config max_cpu must be a int, not {0}\".format(type(service_config[\"max_cpu\"])))\n    if service_config[\"min_cpu\"] != None:\n        if type(service_config[\"min_cpu\"]) != builtins.types.int:\n            fail(\"Service config min_cpu must be a int, not {0}\".format(type(service_config[\"min_cpu\"])))\n    if service_config[\"max_memory\"] != None:\n        if type(service_config[\"max_memory\"]) != builtins.types.int:\n            fail(\"Service config max_memory must be a int, not {0}\".format(type(service_config[\"max_memory\"])))\n    if service_config[\"min_memory\"] != None:\n        if type(service_config[\"min_memory\"]) != builtins.types.int:\n            fail(\"Service config min_memory must be a int, not {0}\".format(type(service_config[\"min_memory\"])))\n\n    # TODO(validation): Implement validation for ready_conditions\n    # TODO(validation): Implement validation for labels\n    # TODO(validation): Implement validation for user\n    # TODO(validation): Implement validation for tolerations\n    # TODO(validation): Implement validation for node_selectors\n\ndef create_public_port_specs_from_config(config, is_full_node):\n    ports = {}\n    if is_full_node:\n        ports = {}\n        for port_key, port_spec in config[\"public_ports\"].items():\n            ports[port_key] = port_spec_lib.create_port_spec(port_spec)\n\n    return ports\n\ndef create_from_config(config, is_full_node = False):\n    validate_service_config_types(config)\n\n    return ServiceConfig(\n        image = config[\"image\"],\n        ports = port_spec_lib.create_port_specs_from_config(config),\n        # public port exposed for full node\n        public_ports = create_public_port_specs_from_config(config, is_full_node) if config[\"public_ports\"] else {},\n        files = config[\"files\"] if config[\"files\"] else {},\n        entrypoint = config[\"entrypoint\"] if config[\"entrypoint\"] else [],\n        cmd = [\" \".join(config[\"cmd\"])] if config[\"cmd\"] else [],\n        env_vars = config[\"env_vars\"] if config[\"env_vars\"] else {},\n        private_ip_address_placeholder = config[\"private_ip_address_placeholder\"] if config[\"private_ip_address_placeholder\"] else DEFAULT_PRIVATE_IP_ADDRESS_PLACEHOLDER,\n        max_cpu = config[\"max_cpu\"] if config[\"max_cpu\"] else DEFAULT_MAX_CPU,  # Needs a default, as 0 does not flag as optional\n        min_cpu = config[\"min_cpu\"] if config[\"min_cpu\"] else 0,\n        max_memory = config[\"max_memory\"] if config[\"max_memory\"] else DEFAULT_MAX_MEMORY,  # Needs a default, as 0 does not flag as optional\n        min_memory = config[\"min_memory\"] if config[\"min_memory\"] else 0,\n        #ready_conditions=config['ready_conditions'], Ready conditions not yet supported\n        labels = config[\"labels\"] if config[\"labels\"] else {},\n        #user=config['user'], User config not yet supported\n        tolerations = config[\"tolerations\"] if config[\"tolerations\"] else [],\n        node_selectors = config[\"node_selectors\"] if config[\"node_selectors\"] else {},\n    )\n"
  },
  {
    "path": "kurtosis/src/networks/kurtosis-devnet/README.md",
    "content": "# kurtosis-devnet\n\nThis contains all of the required files to spin up a `kurtosis-devnet`\non your local machine.\n"
  },
  {
    "path": "kurtosis/src/networks/kurtosis-devnet/network-configs/genesis.json.template",
    "content": "{\n  \"config\": {\n    \"chainId\": {{.CHAIN_ID}},\n    \"homesteadBlock\": 0,\n    \"daoForkBlock\": 0,\n    \"daoForkSupport\": true,\n    \"eip150Block\": 0,\n    \"eip155Block\": 0,\n    \"eip158Block\": 0,\n    \"byzantiumBlock\": 0,\n    \"constantinopleBlock\": 0,\n    \"petersburgBlock\": 0,\n    \"istanbulBlock\": 0,\n    \"muirGlacierBlock\": 0,\n    \"berlinBlock\": 0,\n    \"londonBlock\": 0,\n    \"arrowGlacierBlock\": 0,\n    \"grayGlacierBlock\": 0,\n    \"mergeNetsplitBlock\": 0,\n    \"shanghaiTime\": 0,\n    \"cancunTime\": 0,\n    \"pragueTime\": 0,\n    \"terminalTotalDifficulty\": 0,\n    \"terminalTotalDifficultyPassed\": true,\n    \"ethash\": {},\n    \"blobSchedule\": {\n      \"cancun\": {\n        \"target\": 3,\n        \"max\": 6,\n        \"baseFeeUpdateFraction\": 3338477\n      },\n      \"prague\": {\n        \"target\": 3,\n        \"max\": 6,\n        \"baseFeeUpdateFraction\": 3338477\n      }\n    },\n    \"berachain\": {\n      \"prague1\": {\n        \"time\": 0,\n        \"baseFeeChangeDenominator\": 48,\n        \"minimumBaseFeeWei\": 1000000000,\n        \"polDistributorAddress\": \"0x4200000000000000000000000000000000000042\"\n      },\n      \"prague2\": {\n        \"time\": 0,\n        \"minimumBaseFeeWei\": 0\n      }\n    }\n  },\n  \"coinbase\": \"0x0000000000000000000000000000000000000000\",\n  \"difficulty\": \"0x0\",\n  \"extraData\": \"0x0000000000000000000000000000000000000000000000000000000000000000658bdf435d810c91414ec09147daa6db624063790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n  \"gasLimit\": \"0x1c9c380\",\n  \"nonce\": \"0x0000000000000000\",\n  \"timestamp\": \"0x0\",\n  \"alloc\": {\n    \"0x4200000000000000000000000000000000000042\": {\n      \"code\": \"0x608060405234801561000f575f80fd5b5060043610610034575f3560e01c8063163db71b1461003857806360644a6b14610052575b5f80fd5b6100405f5481565b60405190815260200160405180910390f35b610065610060366004610137565b610067565b005b336002600160a01b031461008e57604051632f3a162d60e11b815260040160405180910390fd5b5f8054908061009c836101a5565b909155505060405163999da65b60e01b81526043602160991b019063999da65b906100cd90859085906004016101c9565b5f604051808303815f87803b1580156100e4575f80fd5b505af11580156100f6573d5f803e3d5ffd5b505050507f60b106db8802e863a4a9dc4af78cb0dd63feb55ad4ee60f0453c13309bfdbdd4828260405161012b9291906101c9565b60405180910390a15050565b5f8060208385031215610148575f80fd5b823567ffffffffffffffff81111561015e575f80fd5b8301601f8101851361016e575f80fd5b803567ffffffffffffffff811115610184575f80fd5b856020828401011115610195575f80fd5b6020919091019590945092505050565b5f600182016101c257634e487b7160e01b5f52601160045260245ffd5b5060010190565b60208152816020820152818360408301375f818301604090810191909152601f909201601f1916010191905056fea2646970667358221220c2930abe9036c3b4b2592fab2f2fd516d3698f5c696d82745ddc0af43f7096a764736f6c634300081a0033\",\n      \"nonce\": \"0x1\",\n      \"balance\": \"0x0\"\n    },\n    \"0x4200000000000000000000000000000000000043\": {\n      \"code\": \"0x608060405234801561000f575f80fd5b5060043610610034575f3560e01c80634b28f9a214610038578063999da65b14610052575b5f80fd5b6100405f5481565b60405190815260200160405180910390f35b6100656100603660046100b8565b610067565b005b5f8054908061007583610126565b91905055507fb3a8fa51f8d3759f320e88b7f8d3fb73a2a51b31b3324b37833c4816cf41e7c45f546040516100ac91815260200190565b60405180910390a15050565b5f80602083850312156100c9575f80fd5b823567ffffffffffffffff8111156100df575f80fd5b8301601f810185136100ef575f80fd5b803567ffffffffffffffff811115610105575f80fd5b856020828401011115610116575f80fd5b6020919091019590945092505050565b5f6001820161014357634e487b7160e01b5f52601160045260245ffd5b506001019056fea2646970667358221220350dbb7eed9e4d6e4ff72594b0582b0b2e4c1d6b11c3e5ad382201b47a638cc664736f6c634300081a0033\",\n      \"nonce\": \"0x1\",\n      \"balance\": \"0x0\"\n    },\n    \"0x00000961Ef480Eb55e80D19ad83579A64c007002\": {\n      \"code\": \"0x3373fffffffffffffffffffffffffffffffffffffffe1460cb5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f457600182026001905f5b5f82111560685781019083028483029004916001019190604d565b909390049250505036603814608857366101f457346101f4575f5260205ff35b34106101f457600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160df575060105b5f5b8181146101835782810160030260040181604c02815460601b8152601401816001015481526020019060020154807fffffffffffffffffffffffffffffffff00000000000000000000000000000000168252906010019060401c908160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160e1565b910180921461019557906002556101a0565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101cd57505f5b6001546002828201116101e25750505f6101e8565b01600290035b5f555f600155604c025ff35b5f5ffd\",\n      \"nonce\": \"0x1\",\n      \"balance\": \"0x0\",\n      \"storage\": {\n        \"0x0000000000000000000000000000000000000000000000000000000000000000\": \"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"\n      }\n    },\n    \"0x0000BBdDc7CE488642fb579F8B00f3a590007251\": {\n      \"code\": \"0x3373fffffffffffffffffffffffffffffffffffffffe1460d35760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f82111560685781019083028483029004916001019190604d565b9093900492505050366060146088573661019a573461019a575f5260205ff35b341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060021160e7575060025b5f5b8181146101295782810160040260040181607402815460601b815260140181600101548152602001816002015481526020019060030154905260010160e9565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd\",\n      \"nonce\": \"0x1\",\n      \"balance\": \"0x0\",\n      \"storage\": {\n        \"0x0000000000000000000000000000000000000000000000000000000000000000\": \"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"\n      }\n    },\n    \"0x20f33ce90a13a4b5e7697e3544c3083b8f8a51d4\": {\n      \"balance\": \"0x7E37BE2022C0914B2680000000\"\n    },\n    \"0x56898d1aFb10cad584961eb96AcD476C6826e41E\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1e2e53c2451d0f9ED4B7952991BE0c95165D5c01\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3bd0E8f1B1E8Ec99a4E1762F4058F9884C93af31\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xD073a84e2ccDF91a9025179330438485E886D206\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x8a88215ae882dfA519730c40109556c1C235729f\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1a0A57e5e6a66aD732295ddAF0aed286a4e64310\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x185F4Eebd01614aE3d12a5E49b184B054C46d37B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xdb96E9cDD1e457b602f97d33e51736D7a5216496\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x44a5FBfa7d6f3Fd92cca01f6764509f8Fc33dfa5\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3649839562C8dA64E6215EB0f5371629Ead9729D\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x51e15e71c865FE702C9347610667f83658A20e00\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xBC9BC89b295a14F3976234Cc37C73e3D286f3a49\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x12De044207a90709Ef2602D3D9D945d64dAe6147\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x4Afe0DFDAcc91F0fA2AEe39F9eAd66b64d03EbD6\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xBC3c03b4185A6F10618CC4E7B9f4AdD59AB5FbbA\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xDc6De65f6070b409125217a12Cf576A208Cc1998\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xF60fD8632Fc77E19b3A0637d115d0fdd06F36968\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xbcC90AD39D377cA0b7b4F36eC463103E2728C33F\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x6F69542fC88fF84C480FFf510aB7108120447247\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2f6eB3D9a41157322dE01A6E707F6F118Cb00A7b\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x187bE38A1f448b0F42423151A683dCAea949008B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xA1d283f1a11A36D20FF38F29e12CA8F7Cf8709c1\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x868a33C94F91398B6245e1f0E4CF128B2F28714B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x67c942Ef50Fc690eA779067a6A0d444a8234baB5\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xDE8E0E641E2Fb52c22460e6a1533c6BD13A00B37\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x9beFa0FB7a1A9E6cC7596204DbB8962E87091D64\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x62cB9bF32EA104f6D5eBf6879e876439f9492E4B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xdb9cB94B166DfdC9F337EA63b32B448d993d7008\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7c4d7dB81c544B768E1f4782011077202B74B5C0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xaEf63D7F7e2637c99FeA1B63366b244B4da12D70\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3DFb4173ec41EB976260fd689E5AB9772C66beaf\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x5145b1B855bca67A119CB02A42aF4Bdbc66B725C\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf4b2eb959A4C4b0E148340676999FC0446D446D4\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xb86d37333072eFb48cEaa46C67271A27CA5Bda82\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x6CBcF4198fDA91D00fD469340E6DF6df086159e3\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xE7F444b5f772281384117674002d540131e533Ca\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x719Be866A77CeEc1BaC4FD37910c0975eFd52f55\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x0e10cDAd84D788843aF48673C5b260A02ef78742\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xcB6632daA65e6c921c2963C37320f63f54fC8fE3\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xDe5C7198e2416baB7e7a1EA758858Cd7301740bF\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x25fc16D8E2314B305dF05C032E617638284801D6\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xD2a3b89AE8D2c3bD39E2F24612ecFCD8600360C9\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2F4fD8a82A1400E654eeEC59b0e588445ffE0F96\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x10FdFa4EFc83d6CC42F5ef14c13da8b98E458214\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x49cE37B2019bb2d0B8b6a094ef87a6Dd625454A0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x800830F031ab1dd5895a5ec5B561427AD18f9ea8\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3124d9885b11B52c56A2aee610AfCf5740d484F0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xA6177defF3b768b1D678EdF7583b8cf210C777c0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xF99139D2FCc5E25F57B0B91fd382a21B3AFF9cbA\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xC4DD08191B4d5173e3698491A11e05b63F9Ee097\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xB8865B4B8C56861534CC07ebBD2EA569a9a16323\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2B9935698dc5c19Ab7414AE22f27Da5F4478008a\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xAC3c80F41C3049A89Aba8072FFbFc38a90fb6D8c\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xD6D4Fb22B91FAa54700852a05698B37d45514166\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xAf325Ccc92ae883DEF1634D499d8B093192D7a0c\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7469CeEf99FB67e4990c5F1c085a1B39b2902331\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x14DA5251a1EB236238969575ccE943e2Fb0f4AA1\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xF9f58a87C3f0B3A4a0592938c80C41a7c659f855\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1CF7e940A657eE706718CF180eb21864DE9672C3\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x440C37b22e8D7469128Ea7De6ac2f31419B4A8b1\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x4bD04ABA9fc709835b1EE4789195d10E9e8E53F5\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x4dC3aC871b22F8a98197B0aae976a8dE08e5Bebe\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1f1D0FCa7e19b799c315d4fDf31bA50e6A2AB153\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x28879749Dda99387bdB43295B28bdF251d999F3b\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xC4eD09A472B82516daa3A4d8D1E38AE94CF4855C\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf22FbA9cBeB75ED353931418E9eca71EF1Ab9921\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xC59D8935c0570E75BA0E55E3C661f535C86e368B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf97a36c417D33D1fC60a9163A8715e1aecb29102\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x4245537d9e3fb36fBBf054247FfFB28b0d931503\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xFeb1eafa0154D291e28e393FAF10Bc89e5cCbB22\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf11D16e2EE6BefED82Fbca0b005906E09303aB95\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x9C75eD1A37ae420b4FC0a1F4c26B673227Fd3AFa\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x6a354C708fd248FD778F6adF75E41AA554700F68\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xea94749deFcc40dC5992687974b1C84B1bB9D6df\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7689BE67b205EB5d32811d95D60587Eae4F3036F\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xdBfb742BD2e0e6E353cb61E75B9e11257aC8fB1A\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2E5f031578e8FF82199aaF16f42c44D43Fe61819\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x611a42A2EF62c2461D123e3F0B64b93938bc4781\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1a0c826048DF0E4661E3c53bBd447d497E3f701F\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7f0E54bc3C1a72405646F5dFbBE0D4565c649fe2\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x54e1F990Dc0B7367F1E8eD96dA63BC4bca0E8061\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xbE651bc261b9Da5499a24Bf4214fD494c6e1F5Ac\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xD3c5dAC705289cD005C402C79C8445a47502d8be\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xE5981AA0807eb05611cDb666e32e53b2001bd61d\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x0fb648Cb08e21602AF61AF53fE104E29d46433F7\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x0474f52d25529c4db5f4E72F43303dA71B3541C6\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xe3024d098953661638d59E06f7FcD0B61c424854\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x8b1e58f651CacaAa40291d2a6E0a6404d7Ed99e6\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x8724C57fb8f38A1FccA7177543dd1D8FcD49E5aa\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xd0F043dED28773953562f824334C4cbb84210AE7\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xE3d2b9191EaBD3636A5dd057D522335cfae8c7CF\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3f51B3BB6A18141282Ba002F7709c7E2f337F961\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf6B6A52aA9BD788837c6682f47ACE009BD84b6fc\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x795B761Db5969B7ba53472d5D37c230C859a472F\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7d7f187C2A05cDDCF700dCF2E02c96E7eF03f9B0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2d88ECD4d8F4b0A954886eE8C0802aE14684cd07\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x92B3feac5b7816Dcef96a303c1D5112271A70D2c\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x5DD7bc3BEE395831ce499315ecAFE81DE0556F99\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x5227aaebCA3E5e893547A667666E2e4e12Ca20e0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x47575DAE85403cD408d4639068D1187C427B9897\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xE69ac59e1DF47291AaB8DEc540C796f81De7c892\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xb87fb371Bd3C2093b608cd0E7a8dDD60Bb05C995\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02\": {\n      \"balance\": \"0x0\",\n      \"nonce\": \"0x1\",\n      \"code\": \"0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500\"\n    }, \n    \"0x4e59b44847b379578588920cA78FbF26c0B4956C\": {\n      \"balance\": \"0x0\",\n      \"nonce\": \"0x1\",\n      \"code\": \"0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3\"\n    },\n    \"0x4242424242424242424242424242424242424242\": {\n      \"balance\": \"0x0\",\n      \"nonce\": \"0x1\",\n      \"code\": \"0x608060405260043610610093575f3560e01c8063577212fe11610066578063c53925d91161004c578063c53925d914610231578063e12cf4cb14610250578063fea7ab7714610263575f80fd5b8063577212fe146101cc5780639eaffa96146101ed575f80fd5b806301ffc9a7146100975780632dfdf0b5146100cb5780633523f9bd14610103578063560036ec14610126575b5f80fd5b3480156100a2575f80fd5b506100b66100b1366004610bb7565b610282565b60405190151581526020015b60405180910390f35b3480156100d6575f80fd5b505f546100ea9067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016100c2565b34801561010e575f80fd5b5061011860015481565b6040519081526020016100c2565b348015610131575f80fd5b50610193610140366004610c2a565b80516020818301810180516003825292820191909301209152546bffffffffffffffffffffffff8116906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1682565b604080516bffffffffffffffffffffffff909316835273ffffffffffffffffffffffffffffffffffffffff9091166020830152016100c2565b3480156101d7575f80fd5b506101eb6101e6366004610d5f565b61031a565b005b3480156101f8575f80fd5b5061020c610207366004610d5f565b6103e7565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c2565b34801561023c575f80fd5b506101eb61024b366004610d5f565b610428565b6101eb61025e366004610dc1565b61063d565b34801561026e575f80fd5b506101eb61027d366004610e70565b61095c565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f136f920d00000000000000000000000000000000000000000000000000000000145b92915050565b6002828260405161032c929190610ec0565b908152604051908190036020019020543373ffffffffffffffffffffffffffffffffffffffff90911614610383576103837f7c214f0400000000000000000000000000000000000000000000000000000000610afc565b60038282604051610395929190610ec0565b9081526040519081900360200181205f90556103b49083908390610ec0565b604051908190038120907f1c0a7e1bd09da292425c039309671a03de56b89a0858598aab6df6ce84b006db905f90a25050565b5f600283836040516103fa929190610ec0565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff16905092915050565b5f6003838360405161043b929190610ec0565b908152604051908190036020019020805490915073ffffffffffffffffffffffffffffffffffffffff6c01000000000000000000000000820416906bffffffffffffffffffffffff163382146104b4576104b47f819a0d0b00000000000000000000000000000000000000000000000000000000610afc565b6bffffffffffffffffffffffff42166104d06201518083610efc565b6bffffffffffffffffffffffff16111561050d5761050d7fe8966d7a00000000000000000000000000000000000000000000000000000000610afc565b5f60028686604051610520929190610ec0565b9081526040519081900360200181205473ffffffffffffffffffffffffffffffffffffffff169150839060029061055a9089908990610ec0565b908152604051908190036020018120805473ffffffffffffffffffffffffffffffffffffffff939093167fffffffffffffffffffffffff0000000000000000000000000000000000000000909316929092179091556003906105bf9088908890610ec0565b9081526040519081900360200181205f90556105de9087908790610ec0565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff808716845284166020840152917f0adffd98d3072c48341843974dffd7a910bb849ba6ca04163d43bb26feb17403910160405180910390a2505050505050565b6030861461066e5761066e7f9f10647200000000000000000000000000000000000000000000000000000000610afc565b6020841461069f5761069f7fb39bca1600000000000000000000000000000000000000000000000000000000610afc565b606082146106d0576106d07f4be6321b00000000000000000000000000000000000000000000000000000000610afc565b5f73ffffffffffffffffffffffffffffffffffffffff16600288886040516106f9929190610ec0565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff16036108375773ffffffffffffffffffffffffffffffffffffffff8116610768576107687f51969a7a00000000000000000000000000000000000000000000000000000000610afc565b806002888860405161077b929190610ec0565b908152604051908190036020018120805473ffffffffffffffffffffffffffffffffffffffff939093167fffffffffffffffffffffffff0000000000000000000000000000000000000000909316929092179091556107dd9088908890610ec0565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff841683525f6020840152917f0adffd98d3072c48341843974dffd7a910bb849ba6ca04163d43bb26feb17403910160405180910390a261087c565b73ffffffffffffffffffffffffffffffffffffffff81161561087c5761087c7fc4142b4100000000000000000000000000000000000000000000000000000000610afc565b5f610885610b04565b90506509184e72a00067ffffffffffffffff821610156108c8576108c87f0e1eddda00000000000000000000000000000000000000000000000000000000610afc565b5f80547f68af751683498a9f9be59fe8b0d52a64dd155255d85cdb29fea30b1e3f891d46918a918a918a918a9187918b918b9167ffffffffffffffff16908061091083610f20565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060405161094a989796959493929190610f93565b60405180910390a15050505050505050565b5f6002848460405161096f929190610ec0565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff1690503381146109c7576109c77f7c214f0400000000000000000000000000000000000000000000000000000000610afc565b73ffffffffffffffffffffffffffffffffffffffff8216610a0b57610a0b7fd92e233d00000000000000000000000000000000000000000000000000000000610afc565b5f60038585604051610a1e929190610ec0565b908152604051908190036020018120426bffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff86166c01000000000000000000000000027fffffffffffffffffffffffffffffffffffffffff000000000000000000000000161781559150610a969086908690610ec0565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff8681168452851660208401524283830152905190917f7640ec3c8c4695deadda414dd20400acf275297a7c38715f9237657e97ddba5f919081900360600190a25050505050565b805f5260045ffd5b5f610b13633b9aca003461102b565b15610b4157610b417f40567b3800000000000000000000000000000000000000000000000000000000610afc565b5f610b50633b9aca003461103e565b905067ffffffffffffffff811115610b8b57610b8b7f2aa6673400000000000000000000000000000000000000000000000000000000610afc565b610b955f34610b9a565b919050565b5f385f3884865af1610bb35763b12d13eb5f526004601cfd5b5050565b5f60208284031215610bc7575f80fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610bf6575f80fd5b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f60208284031215610c3a575f80fd5b813567ffffffffffffffff811115610c50575f80fd5b8201601f81018413610c60575f80fd5b803567ffffffffffffffff811115610c7a57610c7a610bfd565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160116810181811067ffffffffffffffff82111715610ce657610ce6610bfd565b604052818152828201602001861015610cfd575f80fd5b816020840160208301375f91810160200191909152949350505050565b5f8083601f840112610d2a575f80fd5b50813567ffffffffffffffff811115610d41575f80fd5b602083019150836020828501011115610d58575f80fd5b9250929050565b5f8060208385031215610d70575f80fd5b823567ffffffffffffffff811115610d86575f80fd5b610d9285828601610d1a565b90969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610b95575f80fd5b5f805f805f805f6080888a031215610dd7575f80fd5b873567ffffffffffffffff811115610ded575f80fd5b610df98a828b01610d1a565b909850965050602088013567ffffffffffffffff811115610e18575f80fd5b610e248a828b01610d1a565b909650945050604088013567ffffffffffffffff811115610e43575f80fd5b610e4f8a828b01610d1a565b9094509250610e62905060608901610d9e565b905092959891949750929550565b5f805f60408486031215610e82575f80fd5b833567ffffffffffffffff811115610e98575f80fd5b610ea486828701610d1a565b9094509250610eb7905060208501610d9e565b90509250925092565b818382375f9101908152919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b6bffffffffffffffffffffffff818116838216019081111561031457610314610ecf565b5f67ffffffffffffffff821667ffffffffffffffff8103610f4357610f43610ecf565b60010192915050565b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60a081525f610fa660a083018a8c610f4c565b8281036020840152610fb981898b610f4c565b905067ffffffffffffffff871660408401528281036060840152610fde818688610f4c565b91505067ffffffffffffffff831660808301529998505050505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f8261103957611039610ffe565b500690565b5f8261104c5761104c610ffe565b50049056fea164736f6c634300081a000a\",\n      \"storage\": {\n        \"0x0000000000000000000000000000000000000000000000000000000000000000\": \"{{.GENESIS_DEPOSIT_COUNT_HEX}}\",\n        \"0x0000000000000000000000000000000000000000000000000000000000000001\": \"{{.GENESIS_DEPOSITS_ROOT}}\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "kurtosis/src/networks/networks.star",
    "content": "el_cl_genesis_data = import_module(\n    \"github.com/ethpandaops/ethereum-package/src/prelaunch_data_generator/el_cl_genesis/el_cl_genesis_data.star\",\n)\n\nNETWORKS_DIR_PATH = \"/kurtosis/src/networks/\"\n\nNETWORKS = struct(\n    kurtosis_devnet = \"kurtosis-devnet/\",\n)\n\ndef get_genesis_data(plan):\n    genesis_file = plan.upload_files(\n        NETWORKS_DIR_PATH + NETWORKS.kurtosis_devnet,\n        \"el_cl_genesis_data\",\n    )\n\n    return el_cl_genesis_data.new_el_cl_genesis_data(\n        genesis_file,\n\n        # The following fields are not relevant for our testing, but are required by the parent\n        \"\",  # genesis_validators_root\n        0,  # cancun_time\n        0,  # prague_time\n    )\n\ndef get_genesis_path(network = \"kurtosis-devnet\"):\n    return NETWORKS_DIR_PATH + network\n"
  },
  {
    "path": "kurtosis/src/networks/private-testnet-1/.gitkeep",
    "content": "We can put the testnet genesis files here, this will let people sync nodes easily once\nthe testnet is actually live"
  },
  {
    "path": "kurtosis/src/nodes/consensus/beacond/launcher.star",
    "content": "shared_utils = import_module(\"github.com/ethpandaops/ethereum-package/src/shared_utils/shared_utils.star\")\nexecution = import_module(\"../../execution/execution.star\")\nnode = import_module(\"./node.star\")\nbash = import_module(\"../../../lib/bash.star\")\n\nCOMETBFT_RPC_PORT_NUM = 26657\nCOMETBFT_P2P_PORT_NUM = 26656\n\nCOMETBFT_PPROF_PORT_NUM = 6060\nMETRICS_PORT_NUM = 26660\nENGINE_RPC_PORT_NUM = 8551\nNODE_API_PORT_NUM = 3500\n\n# Port IDs\nCOMETBFT_RPC_PORT_ID = \"cometbft-rpc\"\nCOMETBFT_P2P_PORT_ID = \"cometbft-p2p\"\nCOMETBFT_GRPC_PORT_ID = \"cometbft-grpc\"\nCOMETBFT_REST_PORT_ID = \"cometbft-rest\"\nCOMETBFT_PPROF_PORT_ID = \"cometbft-pprof\"\nENGINE_RPC_PORT_ID = \"engine-rpc\"\nMETRICS_PORT_ID = \"metrics\"\nMETRICS_PATH = \"/metrics\"\nNODE_API_PORT_ID = \"node-api\"\n\nUSED_PORTS = {\n    COMETBFT_RPC_PORT_ID: shared_utils.new_port_spec(COMETBFT_RPC_PORT_NUM, shared_utils.TCP_PROTOCOL),\n    COMETBFT_P2P_PORT_ID: shared_utils.new_port_spec(COMETBFT_P2P_PORT_NUM, shared_utils.TCP_PROTOCOL),\n    COMETBFT_PPROF_PORT_ID: shared_utils.new_port_spec(COMETBFT_PPROF_PORT_NUM, shared_utils.TCP_PROTOCOL),\n    # ENGINE_RPC_PORT_ID: shared_utils.new_port_spec(ENGINE_RPC_PORT_NUM, shared_utils.TCP_PROTOCOL),\n    METRICS_PORT_ID: shared_utils.new_port_spec(METRICS_PORT_NUM, shared_utils.TCP_PROTOCOL, wait = None),\n    NODE_API_PORT_ID: shared_utils.new_port_spec(NODE_API_PORT_NUM, shared_utils.TCP_PROTOCOL),\n}\n\ndef get_config(node_struct, engine_dial_url, chain_id, chain_spec, genesis_deposits_root, genesis_deposit_count_hex, entrypoint = [], cmd = [], persistent_peers = \"\", expose_ports = True, jwt_file = None, kzg_trusted_setup_file = None):\n    exposed_ports = {}\n    if expose_ports:\n        exposed_ports = USED_PORTS\n\n    files = {}\n    if jwt_file:\n        files[\"/root/jwt\"] = jwt_file\n    if kzg_trusted_setup_file:\n        files[\"/root/kzg\"] = kzg_trusted_setup_file\n\n    settings = node_struct.consensus_settings\n\n    node_labels = dict(settings.labels)\n    node_labels[\"node_type\"] = \"consensus\"\n\n    config = ServiceConfig(\n        image = node_struct.cl_image,\n        files = files,\n        entrypoint = entrypoint,\n        cmd = cmd,\n        min_cpu = settings.specs.min_cpu,\n        max_cpu = settings.specs.max_cpu,\n        min_memory = settings.specs.min_memory,\n        max_memory = settings.specs.max_memory,\n        env_vars = {\n            \"BEACOND_MONIKER\": node_struct.cl_service_name,\n            \"BEACOND_NET\": \"VALUE_2\",\n            \"BEACOND_HOME\": \"/root/.beacond\",\n            \"BEACOND_CHAIN_ID\": \"beacon-kurtosis-{}\".format(chain_id),\n            \"BEACOND_DEBUG\": \"false\",\n            \"BEACOND_KEYRING_BACKEND\": \"test\",\n            \"BEACOND_MINIMUM_GAS_PRICE\": \"0abgt\",\n            \"BEACOND_ENGINE_DIAL_URL\": engine_dial_url,\n            \"BEACOND_ETH_CHAIN_ID\": str(chain_id),\n            \"BEACOND_PERSISTENT_PEERS\": persistent_peers,\n            \"BEACOND_ENABLE_PROMETHEUS\": \"true\",\n            \"CHAIN_SPEC\": chain_spec,\n            \"BEACOND_CHAIN_SPEC\": chain_spec,\n            \"WITHDRAWAL_ADDRESS\": \"0x20f33ce90a13a4b5e7697e3544c3083b8f8a51d4\",\n            \"DEPOSIT_AMOUNT\": \"32000000000\",\n            \"GENESIS_DEPOSIT_COUNT_HEX\": genesis_deposit_count_hex,\n            \"GENESIS_DEPOSITS_ROOT\": genesis_deposits_root,\n        },\n        ports = exposed_ports,\n        labels = node_labels,\n        node_selectors = settings.node_selectors,\n    )\n\n    return config\n\ndef perform_genesis_deposits_ceremony(plan, validators, jwt_file, chain_id, chain_spec):\n    num_validators = len(validators)\n\n    node_peering_info = []\n    beacond_configs = []\n    stored_configs = []\n\n    for n in range(num_validators):\n        beacond_configs.append(\"node-beacond-config-{}\".format(n))\n        stored_configs.append(StoreSpec(src = \"/tmp/config{}\".format(n), name = beacond_configs[n]))\n\n    stored_configs.append(StoreSpec(src = \"/tmp/config_genesis/.beacond/config/genesis.json\", name = \"cosmos-genesis-final\"))\n\n    multiple_gentx_file = plan.upload_files(\n        src = \"./scripts/multiple-premined-deposits-cl.sh\",\n        name = \"multiple-premined-deposits\",\n        description = \"Uploading multiple-premined-deposits script\",\n    )\n\n    multiple_gentx_env_vars = node.get_genesis_env_vars(\"cl-validator-beaconkit-0\", chain_id, chain_spec)\n    multiple_gentx_env_vars[\"NUM_VALS\"] = str(num_validators)\n\n    plan.print(multiple_gentx_env_vars)\n    plan.print(stored_configs)\n\n    result = plan.run_sh(\n        run = \"chmod +x /app/scripts/multiple-premined-deposits-cl.sh && /app/scripts/multiple-premined-deposits-cl.sh\",\n        image = validators[0].cl_image,\n        files = {\n            \"/app/scripts\": \"multiple-premined-deposits\",\n        },\n        env_vars = multiple_gentx_env_vars,\n        store = stored_configs,\n        description = \"Collecting beacond genesis files\",\n    )\n\n    # Return both the StoreSpec list (for names) and the future references (for dependencies)\n    return struct(\n        configs = stored_configs,\n        artifacts = result.files_artifacts,\n    )\n\ndef modify_genesis_files_deposits(plan, validators, genesis_files, chain_id, chain_spec, stored_configs):\n    num_validators = len(validators)\n\n    modify_genesis_file = plan.upload_files(\n        src = \"./scripts/modify-genesis-with-deposits.sh\",\n        name = \"modify-genesis-with-deposits\",\n        description = \"Uploading modify-genesis-with-deposits script\",\n    )\n\n    genesis_env_vars = node.get_genesis_env_vars(\"cl-validator-beaconkit-0\", chain_id, chain_spec)\n\n    # First operation: Get deposit values and store to files\n    deposit_count_store = StoreSpec(\n        src = \"/tmp/values/deposit_count.txt\",\n        name = \"deposit-count\",\n    )\n    deposit_root_store = StoreSpec(\n        src = \"/tmp/values/deposit_root.txt\",\n        name = \"deposit-root\",\n    )\n\n    # Run the script and store the output files\n    result = plan.run_sh(\n        run = \"chmod +x /app/scripts/modify-genesis-with-deposits.sh && /app/scripts/modify-genesis-with-deposits.sh\",\n        image = validators[0].cl_image,\n        files = {\n            \"/app/scripts\": \"modify-genesis-with-deposits\",\n            \"/root/eth_genesis\": genesis_files[\"default\"],\n            \"/tmp/config_genesis/.beacond/config\": \"cosmos-genesis-final\",\n        },\n        env_vars = genesis_env_vars,\n        store = [deposit_count_store, deposit_root_store, stored_configs[num_validators]],\n        description = \"Running modify genesis with deposits\",\n    )\n\n    # Second operation: Read deposit count\n    result_one = plan.run_sh(\n        run = \"cat /tmp/values/deposit_count.txt\",\n        image = validators[0].cl_image,\n        files = {\n            \"/tmp/values\": \"deposit-count\",\n        },\n        description = \"Reading deposit count\",\n    )\n    deposit_count = result_one.output.strip().rstrip(\"\\n\")\n    plan.print(\"Deposit count:\", deposit_count)\n\n    # Third operation: Read deposit root\n    result_two = plan.run_sh(\n        run = \"cat /tmp/values/deposit_root.txt\",\n        image = validators[0].cl_image,\n        files = {\n            \"/tmp/values\": \"deposit-root\",\n        },\n        description = \"Reading deposit root\",\n    )\n    deposit_root = result_two.output.strip().rstrip(\"\\n\")\n    plan.print(\"Deposit root:\", deposit_root)\n\n    # Update env vars with parsed values\n    genesis_env_vars[\"GENESIS_DEPOSIT_COUNT_HEX\"] = deposit_count\n    genesis_env_vars[\"GENESIS_DEPOSITS_ROOT\"] = deposit_root\n    return genesis_env_vars\n\ndef get_persistent_peers(plan, peers):\n    persistent_peers = peers[:]\n    for i in range(len(persistent_peers)):\n        peer_cl_service_name = \"cl-seed-beaconkit-{}\".format(i)\n        peer_service = plan.get_service(peer_cl_service_name)\n        persistent_peers[i] = persistent_peers[i] + \"@\" + peer_service.ip_address + \":26656\"\n    return \",\".join(persistent_peers)\n\ndef init_consensus_nodes():\n    genesis_file = \"{}/config/genesis.json\".format(\"$BEACOND_HOME\")\n\n    # Check if genesis file exists, if not then initialize the beacond\n    init_node = \"if [ ! -f {} ]; then /usr/bin/beacond init --beacon-kit.chain-spec {} --chain-id {} {} --home {}; fi\".format(genesis_file, \"$BEACOND_CHAIN_SPEC\", \"$BEACOND_CHAIN_ID\", \"$BEACOND_MONIKER\", \"$BEACOND_HOME\")\n    add_validator = \"/usr/bin/beacond genesis add-premined-deposit {} {} --beacon-kit.chain-spec {} --home {}\".format(\"$DEPOSIT_AMOUNT\", \"$WITHDRAWAL_ADDRESS\", \"$BEACOND_CHAIN_SPEC\", \"$BEACOND_HOME\")\n    collect_gentx = \"/usr/bin/beacond genesis collect-premined-deposits --beacon-kit.chain-spec {} --home {}\".format(\"$BEACOND_CHAIN_SPEC\", \"$BEACOND_HOME\")\n    return \"{} && {} && {}\".format(init_node, add_validator, collect_gentx)\n\ndef create_node_config(plan, node_struct, peers, paired_el_client_name, chain_id, chain_spec, genesis_deposits_root, genesis_deposit_count_hex, jwt_file = None, kzg_trusted_setup_file = None):\n    engine_dial_url = \"http://{}:{}\".format(paired_el_client_name, execution.ENGINE_RPC_PORT_NUM)\n\n    persistent_peers = get_persistent_peers(plan, peers)\n    config_settings = node_struct.consensus_settings.config\n    app_settings = node_struct.consensus_settings.app\n    kzg_impl = node_struct.kzg_impl\n\n    cmd = \"{} && {}\".format(init_consensus_nodes(), node.start(persistent_peers, False, 0, config_settings, app_settings, kzg_impl))\n    if node_struct.node_type == \"validator\":\n        cmd = node.start(persistent_peers, False, node_struct.index, config_settings, app_settings, kzg_impl)\n    elif node_struct.node_type == \"seed\":\n        cmd = \"{} && {}\".format(init_consensus_nodes(), node.start(persistent_peers, True, 0, config_settings, app_settings, kzg_impl))\n\n    beacond_config = get_config(\n        node_struct,\n        engine_dial_url,\n        chain_id,\n        chain_spec,\n        genesis_deposits_root,\n        genesis_deposit_count_hex,\n        entrypoint = [\"bash\", \"-c\"],\n        cmd = [cmd],\n        persistent_peers = persistent_peers,\n        jwt_file = jwt_file,\n        kzg_trusted_setup_file = kzg_trusted_setup_file,\n    )\n\n    if node_struct.node_type == \"validator\":\n        # Add back in the node's config data and overwrite genesis.json with final genesis file\n        beacond_config.files[\"/root\"] = Directory(\n            artifact_names = [\"node-beacond-config-{}\".format(node_struct.index)],\n        )\n\n    beacond_config.files[\"/root/.tmp_genesis\"] = Directory(artifact_names = [\"cosmos-genesis-final\"])\n\n    plan.print(beacond_config)\n\n    return beacond_config\n\ndef get_peer_info(plan, cl_service_name):\n    peer_result = bash.exec_on_service(plan, cl_service_name, \"/usr/bin/beacond comet show-node-id --home $BEACOND_HOME | tr -d '\\n'\")\n    return peer_result[\"output\"]\n\ndef dial_unsafe_peers(plan, seed_service_name, peers):\n    peers_list = []\n    for cl_service_name, peer_info in peers.items():\n        p2p_addr = \"\\\"{}@{}:26656\\\"\".format(peer_info, plan.get_service(cl_service_name).ip_address)\n        peers_list.append(p2p_addr)\n\n    # Split peers_list into groups of 20\n    peer_groups = [peers_list[i:i + 20] for i in range(0, len(peers_list), 20)]\n    for group in peer_groups:\n        peer_string = \",\".join(group)\n        endpoint = \"/dial_peers?peers=%5B{}%5D&persistent=false\".format(peer_string)\n        curl_command = [\"curl\", \"-X\", \"GET\", \"http://localhost:{}{}\".format(COMETBFT_RPC_PORT_NUM, endpoint)]\n        exec_recipe = ExecRecipe(\n            command = curl_command,\n        )\n        plan.exec(\n            service_name = seed_service_name,\n            recipe = exec_recipe,\n            description = \"Adding peers to seed node\",\n        )\n"
  },
  {
    "path": "kurtosis/src/nodes/consensus/beacond/node.star",
    "content": "# Contains functionality for initializing and starting the nodes\n\ndef start(persistent_peers, is_seed, validator_index, config_settings, app_settings, kzg_impl):\n    mv_genesis = \"mv root/.tmp_genesis/genesis.json /root/.beacond/config/genesis.json\"\n    set_config = 'sed -i \"s/^prometheus = false$/prometheus = {}/\" {}/config/config.toml'.format(\"$BEACOND_ENABLE_PROMETHEUS\", \"$BEACOND_HOME\")\n    set_config += '\\nsed -i \"s/^pprof_laddr = \\\\\".*\\\\\"/pprof_laddr = \\\\\"0.0.0.0:6060\\\\\"/\" {}/config/config.toml'.format(\"$BEACOND_HOME\")\n    set_config += '\\nsed -i \"s/\\\\\":26660/\\\\\"0.0.0.0:26660/\" {}/config/config.toml'.format(\"$BEACOND_HOME\")\n    set_config += '\\nsed -i \"s/^flush_throttle_timeout = \\\\\".*\\\\\"$/flush_throttle_timeout = \\\\\"10ms\\\\\"/\" {}/config/config.toml'.format(\"$BEACOND_HOME\")\n    set_config += '\\nsed -i \"s/^timeout_propose = \\\\\".*\\\\\"$/timeout_propose = \\\\\"{}\\\\\"/\" {}/config/config.toml'.format(config_settings.timeout_propose, \"$BEACOND_HOME\")\n    set_config += '\\nsed -i \"s/^timeout_propose_delta = \\\\\".*\\\\\"$/timeout_propose_delta = \\\\\"500ms\\\\\"/\" {}/config/config.toml'.format(\"$BEACOND_HOME\")\n    set_config += '\\nsed -i \"s/^timeout_prevote = \\\\\".*\\\\\"$/timeout_prevote = \\\\\"{}\\\\\"/\" {}/config/config.toml'.format(config_settings.timeout_prevote, \"$BEACOND_HOME\")\n    set_config += '\\nsed -i \"s/^timeout_precommit = \\\\\".*\\\\\"$/timeout_precommit = \\\\\"{}\\\\\"/\" {}/config/config.toml'.format(config_settings.timeout_precommit, \"$BEACOND_HOME\")\n    set_config += '\\nsed -i \"s/^addr_book_strict = .*/addr_book_strict = false/\" \"{}/config/config.toml\"'.format(\"$BEACOND_HOME\")\n    set_config += '\\nsed -i \"s/^unsafe = false$/unsafe = true/\" \"{}/config/config.toml\"'.format(\"$BEACOND_HOME\")\n    set_config += '\\nsed -i \"s/^type = \\\\\".*\\\\\"$/type = \\\\\"nop\\\\\"/\" {}/config/config.toml'.format(\"$BEACOND_HOME\")\n    set_config += '\\nsed -i \"s/^discard_abci_responses = false$/discard_abci_responses = true/\" {}/config/config.toml'.format(\"$BEACOND_HOME\")\n    set_config += '\\nsed -i \"s/^# other sinks such as Prometheus.\\nenabled = false$/# other sinks such as Prometheus.\\nenabled = true/\" {}/config/app.toml'.format(\"$BEACOND_HOME\")\n    set_config += '\\nsed -i \"s/^prometheus-retention-time = 0$/prometheus-retention-time = 60/\" {}/config/app.toml'.format(\"$BEACOND_HOME\")\n    set_config += '\\nsed -i \"s/^payload-timeout = \\\\\".*\\\\\"$/payload-timeout = \\\\\"{}\\\\\"/\" {}/config/app.toml'.format(app_settings.payload_timeout, \"$BEACOND_HOME\")\n    set_config += '\\nsed -i \"s/^suggested-fee-recipient = \\\\\"0x0000000000000000000000000000000000000000\\\\\"/suggested-fee-recipient = \\\\\"0x$(printf \\\"%040d\\\" {})\\\\\"/\" {}/config/app.toml'.format(validator_index, \"$BEACOND_HOME\")\n    persistent_peers_option = \"\"\n    seed_option = \"\"\n    if persistent_peers != \"\":\n        persistent_peers_option = \"--p2p.seeds {}\".format(\"$BEACOND_PERSISTENT_PEERS\")\n\n    if is_seed:\n        set_config += '\\nsed -i \"s/^max_num_inbound_peers = 40$/max_num_inbound_peers = 200/\" {}/config/config.toml'.format(\"$BEACOND_HOME\")\n        set_config += '\\nsed -i \"s/^max_num_outbound_peers = 10$/max_num_outbound_peers = 200/\" {}/config/config.toml'.format(\"$BEACOND_HOME\")\n        seed_option = \"--p2p.seed_mode true\"\n    else:\n        set_config += '\\nsed -i \"s/^max_num_inbound_peers = 40$/max_num_inbound_peers = {}/\" {}/config/config.toml'.format(config_settings.max_num_inbound_peers, \"$BEACOND_HOME\")\n        set_config += '\\nsed -i \"s/^max_num_outbound_peers = 10$/max_num_outbound_peers = {}/\" {}/config/config.toml'.format(config_settings.max_num_outbound_peers, \"$BEACOND_HOME\")\n\n    start_node = \"/usr/bin/beacond start --rpc.laddr tcp://0.0.0.0:26657 \\\n    --beacon-kit.chain-spec={} \\\n    --beacon-kit.engine.jwt-secret-path=/root/jwt/jwt-secret.hex \\\n    --beacon-kit.kzg.trusted-setup-path=/root/kzg/kzg-trusted-setup.json \\\n    --beacon-kit.kzg.implementation={} \\\n    --beacon-kit.engine.rpc-dial-url {} \\\n    --beacon-kit.node-api.enabled --beacon-kit.node-api.logging --beacon-kit.node-api.address 0.0.0.0:3500 \\\n    --pruning=nothing \\\n    {} {}\".format(\"$BEACOND_CHAIN_SPEC\", kzg_impl, \"$BEACOND_ENGINE_DIAL_URL\", seed_option, persistent_peers_option)\n\n    return \"{} && {} && {}\".format(mv_genesis, set_config, start_node)\n\ndef get_genesis_env_vars(cl_service_name, chain_id, chain_spec):\n    return {\n        \"BEACOND_MONIKER\": cl_service_name,\n        \"BEACOND_NET\": \"VALUE_2\",\n        \"BEACOND_HOME\": \"/root/.beacond\",\n        \"BEACOND_CHAIN_ID\": \"beacon-kurtosis-{}\".format(chain_id),\n        \"BEACOND_DEBUG\": \"false\",\n        \"BEACOND_KEYRING_BACKEND\": \"test\",\n        \"BEACOND_MINIMUM_GAS_PRICE\": \"0abgt\",\n        \"BEACOND_ETH_CHAIN_ID\": str(chain_id),\n        \"BEACOND_ENABLE_PROMETHEUS\": \"true\",\n        \"ETH_GENESIS\": \"/root/eth_genesis/genesis.json\",\n        # For devnet/testing purposes, we use the same withdrawal address for all validators.\n        # In production, each validator should use an address derived from their own withdrawal credentials.\n        # This is fine for a local development network.\n        \"WITHDRAWAL_ADDRESS\": \"0x20f33ce90a13a4b5e7697e3544c3083b8f8a51d4\",\n        \"DEPOSIT_AMOUNT\": \"32000000000\",\n        \"BEACOND_CHAIN_SPEC\": chain_spec,\n        \"CHAIN_SPEC\": chain_spec,\n    }\n"
  },
  {
    "path": "kurtosis/src/nodes/consensus/beacond/scripts/modify-genesis-with-deposits.sh",
    "content": "#!/usr/bin/env bash\n# SPDX-License-Identifier: BUSL-1.1\n#\n# Copyright (C) 2025, Berachain Foundation. All rights reserved.\n# Use of this software is governed by the Business Source License included\n# in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n#\n# ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n# TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n# VERSIONS OF THE LICENSED WORK.\n#\n# THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n# LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n# LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n#\n# TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n# AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n# EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n# TITLE.\n\n\n# Sets the deposit storage in the new eth-genesis file in the home directory.\n/usr/bin/beacond genesis set-deposit-storage $ETH_GENESIS --beacon-kit.chain-spec $CHAIN_SPEC --home /tmp/config_genesis/.beacond\n\n# Get values directly from the storage fields\nDEPOSIT_COUNT=$(jq -r '.alloc[\"0x4242424242424242424242424242424242424242\"].storage[\"0x0000000000000000000000000000000000000000000000000000000000000000\"]' /tmp/config_genesis/.beacond/genesis.json)\nDEPOSIT_ROOT=$(jq -r '.alloc[\"0x4242424242424242424242424242424242424242\"].storage[\"0x0000000000000000000000000000000000000000000000000000000000000001\"]' /tmp/config_genesis/.beacond/genesis.json)\n\n/usr/bin/beacond genesis execution-payload /tmp/config_genesis/.beacond/genesis.json --beacon-kit.chain-spec $CHAIN_SPEC --home /tmp/config_genesis/.beacond\n\n# Write each value to separate files for easier parsing\nmkdir -p /tmp/values\nprintf \"%s\" \"$DEPOSIT_COUNT\" > /tmp/values/deposit_count.txt\nprintf \"%s\" \"$DEPOSIT_ROOT\" > /tmp/values/deposit_root.txt\n"
  },
  {
    "path": "kurtosis/src/nodes/consensus/beacond/scripts/multiple-premined-deposits-cl.sh",
    "content": "#!/usr/bin/env bash\n# SPDX-License-Identifier: BUSL-1.1\n#\n# Copyright (C) 2025, Berachain Foundation. All rights reserved.\n# Use of this software is governed by the Business Source License included\n# in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n#\n# ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n# TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n# VERSIONS OF THE LICENSED WORK.\n#\n# THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n# LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n# LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n#\n# TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n# AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n# EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n# TITLE.\n\n\n/usr/bin/beacond init --beacon-kit.chain-spec $CHAIN_SPEC --chain-id $BEACOND_CHAIN_ID $BEACOND_MONIKER --home /tmp/config0/.beacond\n/usr/bin/beacond genesis add-premined-deposit $DEPOSIT_AMOUNT $WITHDRAWAL_ADDRESS --beacon-kit.chain-spec $CHAIN_SPEC --home /tmp/config0/.beacond\ncp -r /tmp/config0 /tmp/config_genesis\n\nfor ((i=1; i<$NUM_VALS; i++)); do\n    BEACOND_HOME=/tmp/config${i}/.beacond\n    echo $BEACOND_HOME\n    BEACOND_MONIKER=cl-validator-beaconkit-${i}\n    /usr/bin/beacond init --beacon-kit.chain-spec $CHAIN_SPEC --chain-id $BEACOND_CHAIN_ID $BEACOND_MONIKER --home $BEACOND_HOME\n    /usr/bin/beacond genesis add-premined-deposit $DEPOSIT_AMOUNT $WITHDRAWAL_ADDRESS --beacon-kit.chain-spec $CHAIN_SPEC --home $BEACOND_HOME\n    cp -r /tmp/config${i}/.beacond/config/premined-deposits/premined-deposit* /tmp/config_genesis/.beacond/config/premined-deposits/\ndone\n\n/usr/bin/beacond genesis collect-premined-deposits --beacon-kit.chain-spec $CHAIN_SPEC --home /tmp/config_genesis/.beacond\n\n"
  },
  {
    "path": "kurtosis/src/nodes/consensus/types.star",
    "content": "CLIENTS = struct(\n    beacond = \"beacond\",\n)\n"
  },
  {
    "path": "kurtosis/src/nodes/execution/config.star",
    "content": "port_spec_lib = import_module(\"../../lib/port_spec.star\")\nshared_utils = import_module(\"github.com/ethpandaops/ethereum-package/src/shared_utils/shared_utils.star\")\n\n# ETH Execution constants\n\nRPC_PORT_NUM = 8545\nWS_PORT_NUM = 8546\nDISCOVERY_PORT_NUM = 30303\nENGINE_RPC_PORT_NUM = 8551\nMETRICS_PORT_NUM = 9001\n\n# Port IDs\nRPC_PORT_ID = \"eth-json-rpc\"\nWS_PORT_ID = \"eth-json-rpc-ws\"\nTCP_DISCOVERY_PORT_ID = \"tcp-discovery\"\nUDP_DISCOVERY_PORT_ID = \"udp-discovery\"\nENGINE_RPC_PORT_ID = \"engine-rpc\"\nENGINE_WS_PORT_ID = \"engineWs\"\nMETRICS_PORT_ID = \"metrics\"\n\nMETRICS_PATH = \"/debug/metrics/prometheus\"\n\n# The dirpath of the execution data directory on the client container\nEXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER = \"/data/execution-data\"\n\nUSED_PORTS = {\n    RPC_PORT_ID: shared_utils.new_port_spec(RPC_PORT_NUM, shared_utils.TCP_PROTOCOL),\n    WS_PORT_ID: shared_utils.new_port_spec(WS_PORT_NUM, shared_utils.TCP_PROTOCOL),\n    TCP_DISCOVERY_PORT_ID: shared_utils.new_port_spec(\n        DISCOVERY_PORT_NUM,\n        shared_utils.TCP_PROTOCOL,\n    ),\n    UDP_DISCOVERY_PORT_ID: shared_utils.new_port_spec(\n        DISCOVERY_PORT_NUM,\n        shared_utils.UDP_PROTOCOL,\n    ),\n    ENGINE_RPC_PORT_ID: shared_utils.new_port_spec(\n        ENGINE_RPC_PORT_NUM,\n        shared_utils.TCP_PROTOCOL,\n    ),\n    METRICS_PORT_ID: shared_utils.new_port_spec(\n        METRICS_PORT_NUM,\n        shared_utils.TCP_PROTOCOL,\n    ),\n}\n\nUSED_PORTS_TEMPLATE = {\n    RPC_PORT_ID: port_spec_lib.get_port_spec_template(RPC_PORT_NUM, shared_utils.TCP_PROTOCOL),\n    WS_PORT_ID: port_spec_lib.get_port_spec_template(WS_PORT_NUM, shared_utils.TCP_PROTOCOL),\n    TCP_DISCOVERY_PORT_ID: port_spec_lib.get_port_spec_template(\n        DISCOVERY_PORT_NUM,\n        shared_utils.TCP_PROTOCOL,\n    ),\n    UDP_DISCOVERY_PORT_ID: port_spec_lib.get_port_spec_template(\n        DISCOVERY_PORT_NUM,\n        shared_utils.UDP_PROTOCOL,\n    ),\n    ENGINE_RPC_PORT_ID: port_spec_lib.get_port_spec_template(\n        ENGINE_RPC_PORT_NUM,\n        shared_utils.TCP_PROTOCOL,\n    ),\n    METRICS_PORT_ID: port_spec_lib.get_port_spec_template(\n        METRICS_PORT_NUM,\n        shared_utils.TCP_PROTOCOL,\n    ),\n}\n"
  },
  {
    "path": "kurtosis/src/nodes/execution/execution.star",
    "content": "constants = import_module(\"../../constants.star\")\nservice_config_lib = import_module(\"../../lib/service_config.star\")\nbuiltins = import_module(\"../../lib/builtins.star\")\nport_spec_lib = import_module(\"../../lib/port_spec.star\")\nshared_utils = import_module(\"github.com/ethpandaops/ethereum-package/src/shared_utils/shared_utils.star\")\n\nRPC_PORT_NUM = 8545\nENGINE_RPC_PORT_NUM = 8551\nPUBLIC_RPC_PORT_NUM = 8547\n\n# Port IDs\nRPC_PORT_ID = \"eth-json-rpc\"\n\n# Because structs are immutable, we pass around a map to allow full modification up until we create the final ServiceConfig\ndef get_default_service_config(plan, node_struct, node_module, chain_id, chain_spec, genesis_files):\n    settings = node_struct.execution_settings\n\n    node_labels = dict(settings.labels)\n    node_labels[\"node_type\"] = \"execution\"\n\n    # Get the default genesis file\n    default_genesis_file = genesis_files[\"default\"]\n\n    # Create a copy of the module files\n    files_dict = dict(node_module.FILES)\n\n    # Default path for all supported clients\n    files_dict[\"/root/genesis\"] = Directory(\n        artifact_names = [default_genesis_file],\n    )\n\n    # Define common parameters\n    common_params = {\n        \"name\": node_struct.el_service_name,\n        \"image\": node_struct.el_image,\n        \"ports\": node_module.USED_PORTS_TEMPLATE,\n        \"entrypoint\": node_module.ENTRYPOINT,\n        \"cmd\": node_module.CMD,\n        \"env_vars\": {\n            \"CHAIN_ID\": str(chain_id),\n            \"CHAIN_SPEC\": chain_spec,\n        },\n        \"files\": files_dict,\n        \"min_cpu\": settings.specs.min_cpu,\n        \"max_cpu\": settings.specs.max_cpu,\n        \"min_memory\": settings.specs.min_memory,\n        \"max_memory\": settings.specs.max_memory,\n        \"labels\": node_labels,\n        \"node_selectors\": settings.node_selectors,\n    }\n\n    # Get the service config template\n    sc = service_config_lib.get_service_config_template(**common_params)\n\n    return sc\n\ndef upload_global_files(plan, node_modules, chain_id):\n    jwt_file = plan.upload_files(\n        src = constants.JWT_FILEPATH,\n        name = \"jwt_file\",\n    )\n\n    kzg_trusted_setup_file = plan.upload_files(\n        src = constants.KZG_TRUSTED_SETUP_FILEPATH,\n        name = \"kzg_trusted_setup\",\n    )\n\n    for node_module in node_modules.values():\n        for global_file in node_module.GLOBAL_FILES:\n            plan.upload_files(\n                src = global_file[0],\n                name = global_file[1],\n            )\n\n    return jwt_file, kzg_trusted_setup_file\n\ndef get_enode_addr(plan, el_service_name):\n    extract_statement = {\"enode\": \"\"\".result.enode | split(\"?\") | .[0]\"\"\"}\n\n    request_recipe = PostHttpRequestRecipe(\n        endpoint = \"\",\n        body = '{\"method\":\"admin_nodeInfo\",\"params\":[],\"id\":1,\"jsonrpc\":\"2.0\"}',\n        content_type = \"application/json\",\n        port_id = RPC_PORT_ID,\n        extract = extract_statement,\n    )\n\n    response = plan.request(\n        service_name = el_service_name,\n        recipe = request_recipe,\n    )\n\n    enode = response[\"extract.enode\"]\n    return enode\n\ndef set_max_peers(node_module, config, max_peers):\n    node_module.set_max_peers(config, max_peers)\n    return config\n\ndef add_bootnodes(node_module, config, bootnodes):\n    if type(bootnodes) == builtins.types.list:\n        if len(bootnodes) > 0:\n            cmdList = config[\"cmd\"][:]\n            cmdList.append(node_module.BOOTNODE_CMD)\n            config[\"cmd\"] = cmdList\n\n            bootnodes_str = \",\".join(bootnodes)\n            config[\"cmd\"].append(bootnodes_str)\n    elif type(bootnodes) == builtins.types.str:\n        if len(bootnodes) > 0:\n            config[\"cmd\"].append(node_module.BOOTNODE_CMD)\n            config[\"cmd\"].append(bootnodes)\n    else:\n        fail(\"Bootnodes was not a list or string, but instead a {}\", type(bootnodes))\n\n    return config\n\ndef deploy_nodes(plan, configs, is_full_node = False):\n    service_configs = {}\n    for config in configs:\n        service_configs[config[\"name\"]] = service_config_lib.create_from_config(config, is_full_node)\n\n    return plan.add_services(\n        configs = service_configs,\n    )\n\ndef generate_node_config(plan, node_modules, node_struct, chain_id, chain_spec, genesis_files, bootnode_enode_addrs = []):\n    node_module = node_modules[node_struct.el_type]\n\n    # 4a. Launch EL\n    el_service_config_dict = get_default_service_config(plan, node_struct, node_module, chain_id, chain_spec, genesis_files)\n\n    if node_struct.node_type == \"seed\":\n        el_service_config_dict = set_max_peers(node_module, el_service_config_dict, \"200\")\n    else:\n        el_service_config_dict = add_bootnodes(node_module, el_service_config_dict, bootnode_enode_addrs)\n\n    return el_service_config_dict\n\ndef add_peer(plan, el_service_name, enode_addr):\n    \"\"\"Adds a peer to the given EL node via admin_addPeer JSON-RPC.\"\"\"\n    request_recipe = PostHttpRequestRecipe(\n        endpoint = \"\",\n        body = '{{\"method\":\"admin_addPeer\",\"params\":[\"{}\"],\"id\":1,\"jsonrpc\":\"2.0\"}}'.format(enode_addr),\n        content_type = \"application/json\",\n        port_id = RPC_PORT_ID,\n    )\n\n    plan.request(\n        service_name = el_service_name,\n        recipe = request_recipe,\n    )\n\ndef add_metrics(metrics_enabled_services, node, el_service_name, el_client_service, node_modules):\n    metrics_enabled_services.append({\n        \"name\": el_service_name,\n        \"service\": el_client_service,\n        \"metrics_path\": node_modules[node.el_type].METRICS_PATH,\n    })\n    return metrics_enabled_services\n"
  },
  {
    "path": "kurtosis/src/nodes/execution/reth/config.star",
    "content": "global_constants = import_module(\"../../../constants.star\")\ndefaults = import_module(\"./../config.star\")\n\nGLOBAL_LOG_LEVEL = global_constants.GLOBAL_LOG_LEVEL\nKURTOSIS_IP_ADDRESS_PLACEHOLDER = global_constants.KURTOSIS_IP_ADDRESS_PLACEHOLDER\n\n# The dirpath of the execution data directory on the client container\nEXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER = defaults.EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER\n\nNODE_CONFIG_ARTIFACT_NAME = \"reth-config\"\nCONFIG_FILENAME = \"reth-config.toml\"\nGENESIS_FILENAME = \"genesis.json\"\n\n# The files that only need to be uploaded once to be read by every node\n# NOTE: THIS MUST REFERENCE THE FILEPATH RELATIVE TO execution.star\nGLOBAL_FILES = [\n    (\"./reth/reth-config.toml\", NODE_CONFIG_ARTIFACT_NAME),\n]\n\nWS_PORT_NUM = defaults.WS_PORT_NUM\nENGINE_RPC_PORT_NUM = defaults.ENGINE_RPC_PORT_NUM\nMETRICS_PORT_NUM = defaults.METRICS_PORT_NUM\n\nMETRICS_PATH = defaults.METRICS_PATH\n\nENTRYPOINT = [\"sh\", \"-c\"]\nFILES = {\n    \"/root/.reth\": NODE_CONFIG_ARTIFACT_NAME,\n    \"/root/genesis\": \"genesis_file\",\n    \"/jwt\": \"jwt_file\",\n}\nCMD = [\n    \"bera-reth\",\n    \"init\",\n    \"--datadir\",\n    EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER,\n    \"--chain\",\n    \"/root/genesis/{}\".format(GENESIS_FILENAME),\n    \"&&\",\n    \"bera-reth\",\n    \"node\",\n    \"--datadir\",\n    EXECUTION_DATA_DIRPATH_ON_CLIENT_CONTAINER,\n    \"--chain\",\n    \"/root/genesis/{}\".format(GENESIS_FILENAME),\n    \"--http\",\n    \"--http.addr\",\n    \"0.0.0.0\",\n    \"--http.corsdomain\",\n    \"'*'\",\n    \"--http.api\",\n    \"admin,eth,net,web3,txpool,debug,trace\",\n    \"--ws\",\n    \"--ws.addr\",\n    \"0.0.0.0\",\n    \"--ws.port\",\n    str(WS_PORT_NUM),\n    \"--ws.api\",\n    \"net,eth\",\n    \"--ws.origins\",\n    \"'*'\",\n    \"--authrpc.port\",\n    str(ENGINE_RPC_PORT_NUM),\n    \"--authrpc.jwtsecret\",\n    global_constants.JWT_MOUNT_PATH_ON_CONTAINER,\n    \"--authrpc.addr\",\n    \"0.0.0.0\",\n    \"--metrics\",\n    \"0.0.0.0:{0}\".format(METRICS_PORT_NUM),\n    # \"--config\", CONFIG_LOCATION,\n    \"--nat\",\n    \"extip:\" + KURTOSIS_IP_ADDRESS_PLACEHOLDER,\n    \"--builder.deadline\",\n    \"2\",\n    \"--builder.max-tasks\",\n    \"20\",\n    \"--txpool.pending-max-count\",\n    \"100000\",\n    \"--txpool.pending-max-size\",\n    \"100\",\n    \"--txpool.basefee-max-count\",\n    \"100000\",\n    \"--txpool.basefee-max-size\",\n    \"100\",\n    \"--txpool.queued-max-count\",\n    \"100000\",\n    \"--txpool.queued-max-size\",\n    \"100\",\n    \"--txpool.max-account-slots\",\n    \"1000\",\n    \"--txpool.max-cached-entries\",\n    \"1000\",\n    \"--rpc-cache.max-receipts\",\n    \"10000\",\n]\nBOOTNODE_CMD = \"--bootnodes\"\nMAX_PEERS_OUTBOUND_CMD = \"--max-outbound-peers\"\nMAX_PEERS_INBOUND_CMD = \"--max-inbound-peers\"\n\n# Modify command flag --verbosity to change the verbosity level\nVERBOSITY_LEVELS = {\n    GLOBAL_LOG_LEVEL.error: \"1\",\n    GLOBAL_LOG_LEVEL.warn: \"2\",\n    GLOBAL_LOG_LEVEL.info: \"3\",\n    GLOBAL_LOG_LEVEL.debug: \"4\",\n    GLOBAL_LOG_LEVEL.trace: \"5\",\n}\n\nUSED_PORTS = defaults.USED_PORTS\nUSED_PORTS_TEMPLATE = defaults.USED_PORTS_TEMPLATE\n\ndef set_max_peers(config, max_peers):\n    cmd_list = config[\"cmd\"][:]\n    cmd_list.append(MAX_PEERS_OUTBOUND_CMD)\n    cmd_list.append(max_peers)\n    cmd_list.append(MAX_PEERS_INBOUND_CMD)\n    cmd_list.append(max_peers)\n    config[\"cmd\"] = cmd_list\n    return config\n"
  },
  {
    "path": "kurtosis/src/nodes/execution/reth/reth-config.toml",
    "content": "[stages.headers]\ndownloader_max_concurrent_requests = 100\ndownloader_min_concurrent_requests = 5\ndownloader_max_buffered_responses = 100\ndownloader_request_limit = 1000\ncommit_threshold = 10000\n\n[stages.bodies]\ndownloader_request_limit = 200\ndownloader_stream_batch_size = 1000\ndownloader_max_buffered_blocks_size_bytes = 2147483648\ndownloader_min_concurrent_requests = 5\ndownloader_max_concurrent_requests = 100\n\n[stages.sender_recovery]\ncommit_threshold = 5000000\n\n[stages.execution]\nmax_blocks = 500000\nmax_changes = 5000000\nmax_cumulative_gas = 1500000000000\nmax_duration = \"10m\"\n\n[stages.account_hashing]\nclean_threshold = 500000\ncommit_threshold = 100000\n\n[stages.storage_hashing]\nclean_threshold = 500000\ncommit_threshold = 100000\n\n[stages.merkle]\nclean_threshold = 50000\n\n[stages.transaction_lookup]\nchunk_size = 5000000\n\n[stages.index_account_history]\ncommit_threshold = 100000\n\n[stages.index_storage_history]\ncommit_threshold = 100000\n\n[peers]\nrefill_slots_interval = \"5s\"\ntrusted_nodes = []\nconnect_trusted_nodes_only = false\nmax_backoff_count = 5\nban_duration = \"12h\"\n\n[peers.connection_info]\nmax_outbound = 100\nmax_inbound = 30\nmax_concurrent_outbound_dials = 10\n\n[peers.reputation_weights]\nbad_message = -16384\nbad_block = -16384\nbad_transactions = -16384\nalready_seen_transactions = 0\ntimeout = -4096\nbad_protocol = -2147483648\nfailed_to_connect = -25600\ndropped = -4096\nbad_announcement = -1024\n\n[peers.backoff_durations]\nlow = \"30s\"\nmedium = \"3m\"\nhigh = \"15m\"\nmax = \"1h\"\n\n[sessions]\nsession_command_buffer = 32\nsession_event_buffer = 260\n\n[sessions.limits]\n\n[sessions.initial_internal_request_timeout]\nsecs = 20\nnanos = 0\n\n[sessions.protocol_breach_request_timeout]\nsecs = 120\nnanos = 0\n\n"
  },
  {
    "path": "kurtosis/src/nodes/jwt-secret.hex",
    "content": "0x1b8d34037ac04570b76cb1a13d1db17729a5b6a90f10497b2bc4422fbd39615a"
  },
  {
    "path": "kurtosis/src/nodes/kzg-trusted-setup.json",
    "content": "{\n  \"g1_lagrange\": [\n    \"0xa0413c0dcafec6dbc9f47d66785cf1e8c981044f7d13cfe3e4fcbb71b5408dfde6312493cb3c1d30516cb3ca88c03654\",\n    \"0x8b997fb25730d661918371bb41f2a6e899cac23f04fc5365800b75433c0a953250e15e7a98fb5ca5cc56a8cd34c20c57\",\n    \"0x83302852db89424d5699f3f157e79e91dc1380f8d5895c5a772bb4ea3a5928e7c26c07db6775203ce33e62a114adaa99\",\n    \"0xa759c48b7e4a685e735c01e5aa6ef9c248705001f470f9ad856cd87806983e917a8742a3bd5ee27db8d76080269b7c83\",\n    \"0x967f8dc45ebc3be14c8705f43249a30ff48e96205fb02ae28daeab47b72eb3f45df0625928582aa1eb4368381c33e127\",\n    \"0xa418eb1e9fb84cb32b370610f56f3cb470706a40ac5a47c411c464299c45c91f25b63ae3fcd623172aa0f273c0526c13\",\n    \"0x8f44e3f0387293bc7931e978165abbaed08f53acd72a0a23ac85f6da0091196b886233bcee5b4a194db02f3d5a9b3f78\",\n    \"0x97173434b336be73c89412a6d70d416e170ea355bf1956c32d464090b107c090ef2d4e1a467a5632fbc332eeb679bf2d\",\n    \"0xa24052ad8d55ad04bc5d951f78e14213435681594110fd18173482609d5019105b8045182d53ffce4fc29fc8810516c1\",\n    \"0xb950768136b260277590b5bec3f56bbc2f7a8bc383d44ce8600e85bf8cf19f479898bcc999d96dfbd2001ede01d94949\",\n    \"0x92ab8077871037bd3b57b95cbb9fb10eb11efde9191690dcac655356986fd02841d8fdb25396faa0feadfe3f50baf56d\",\n    \"0xa79b096dff98038ac30f91112dd14b78f8ad428268af36d20c292e2b3b6d9ed4fb28480bb04e465071cc67d05786b6d1\",\n    \"0xb9ff71461328f370ce68bf591aa7fb13027044f42a575517f3319e2be4aa4843fa281e756d0aa5645428d6dfa857cef2\",\n    \"0x8d765808c00b3543ff182e2d159c38ae174b12d1314da88ea08e13bd9d1c37184cb515e6bf6420531b5d41767987d7ce\",\n    \"0xb8c9a837d20c3b53e6f578e4a257bb7ef8fc43178614ec2a154915b267ad2be135981d01ed2ee1b5fbd9d9bb27f0800a\",\n    \"0xa9773d92cf23f65f98ef68f6cf95c72b53d0683af2f9bf886bb9036e4a38184b1131b26fd24397910b494fbef856f3aa\",\n    \"0xb41ebe38962d112da4a01bf101cb248d808fbd50aaf749fc7c151cf332032eb3e3bdbd716db899724b734d392f26c412\",\n    \"0x90fbb030167fb47dcc13d604a726c0339418567c1d287d1d87423fa0cb92eec3455fbb46bcbe2e697144a2d3972142e4\",\n    \"0xb11d298bd167464b35fb923520d14832bd9ed50ed841bf6d7618424fd6f3699190af21759e351b89142d355952149da1\",\n    \"0x8bc36066f69dc89f7c4d1e58d67497675050c6aa002244cebd9fc957ec5e364c46bab4735ea3db02b73b3ca43c96e019\",\n    \"0xab7ab92c5d4d773068e485aa5831941ebd63db7118674ca38089635f3b4186833af2455a6fb9ed2b745df53b3ce96727\",\n    \"0xaf191ca3089892cb943cd97cf11a51f38e38bd9be50844a4e8da99f27e305e876f9ed4ab0628e8ae3939066b7d34a15f\",\n    \"0xa3204c1747feabc2c11339a542195e7cb6628fd3964f846e71e2e3f2d6bb379a5e51700682ea1844eba12756adb13216\",\n    \"0x903a29883846b7c50c15968b20e30c471aeac07b872c40a4d19eb1a42da18b649d5bbfde4b4cf6225d215a461b0deb6d\",\n    \"0x8e6e9c15ffbf1e16e5865a5fef7ed751dc81957a9757b535cb38b649e1098cda25d42381dc4f776778573cdf90c3e6e0\",\n    \"0xa8f6dd26100b512a8c96c52e00715c4b2cb9ac457f17aed8ffe1cf1ea524068fe5a1ddf218149845fc1417b789ecfc98\",\n    \"0xa5b0ffc819451ea639cfd1c18cbc9365cc79368d3b2e736c0ae54eba2f0801e6eb0ee14a5f373f4a70ca463bdb696c09\",\n    \"0x879f91ccd56a1b9736fbfd20d8747354da743fb121f0e308a0d298ff0d9344431890e41da66b5009af3f442c636b4f43\",\n    \"0x81bf3a2d9755e206b515a508ac4d1109bf933c282a46a4ae4a1b4cb4a94e1d23642fad6bd452428845afa155742ade7e\",\n    \"0x8de778d4742f945df40004964e165592f9c6b1946263adcdd5a88b00244bda46c7bb49098c8eb6b3d97a0dd46148a8ca\",\n    \"0xb7a57b21d13121907ee28c5c1f80ee2e3e83a3135a8101e933cf57171209a96173ff5037f5af606e9fd6d066de6ed693\",\n    \"0xb0877d1963fd9200414a38753dffd9f23a10eb3198912790d7eddbc9f6b477019d52ddd4ebdcb9f60818db076938a5a9\",\n    \"0x88da2d7a6611bc16adc55fc1c377480c828aba4496c645e3efe0e1a67f333c05a0307f7f1d2df8ac013602c655c6e209\",\n    \"0x95719eb02e8a9dede1a888c656a778b1c69b7716fbe3d1538fe8afd4a1bc972183c7d32aa7d6073376f7701df80116d8\",\n    \"0x8e8a1ca971f2444b35af3376e85dccda3abb8e8e11d095d0a4c37628dfe5d3e043a377c3de68289ef142e4308e9941a0\",\n    \"0xb720caaff02f6d798ac84c4f527203e823ff685869e3943c979e388e1c34c3f77f5c242c6daa7e3b30e511aab917b866\",\n    \"0x86040d55809afeec10e315d1ad950d269d37cfee8c144cd8dd4126459e3b15a53b3e68df5981df3c2346d23c7b4baaf4\",\n    \"0x82d8cabf13ab853db0377504f0aec00dba3a5cd3119787e8ad378ddf2c40b022ecfc67c642b7acc8c1e3dd03ab50993e\",\n    \"0xb8d873927936719d2484cd03a6687d65697e17dcf4f0d5aed6f5e4750f52ef2133d4645894e7ebfc4ef6ce6788d404c8\",\n    \"0xb1235594dbb15b674a419ff2b2deb644ad2a93791ca05af402823f87114483d6aa1689b7a9bea0f547ad12fe270e4344\",\n    \"0xa53fda86571b0651f5affb74312551a082fffc0385cfd24c1d779985b72a5b1cf7c78b42b4f7e51e77055f8e5e915b00\",\n    \"0xb579adcfd9c6ef916a5a999e77a0cb21d378c4ea67e13b7c58709d5da23a56c2e54218691fc4ac39a4a3d74f88cc31f7\",\n    \"0xab79e584011713e8a2f583e483a91a0c2a40771b77d91475825b5acbea82db4262132901cb3e4a108c46d7c9ee217a4e\",\n    \"0xa0fe58ea9eb982d7654c8aaf9366230578fc1362f6faae0594f8b9e659bcb405dff4aac0c7888bbe07f614ecf0d800a6\",\n    \"0x867e50e74281f28ecd4925560e2e7a6f8911b135557b688254623acce0dbc41e23ac3e706a184a45d54c586edc416eb0\",\n    \"0x89f81b61adda20ea9d0b387a36d0ab073dc7c7cbff518501962038be19867042f11fcc7ff78096e5d3b68c6d8dc04d9b\",\n    \"0xa58ee91bb556d43cf01f1398c5811f76dc0f11efdd569eed9ef178b3b0715e122060ec8f945b4dbf6eebfa2b90af6fa6\",\n    \"0xac460be540f4c840def2eef19fc754a9af34608d107cbadb53334cf194cc91138d53b9538fcd0ec970b5d4aa455b224a\",\n    \"0xb09b91f929de52c09d48ca0893be6eb44e2f5210a6c394689dc1f7729d4be4e11d0474b178e80cea8c2ac0d081f0e811\",\n    \"0x8d37a442a76b06a02a4e64c2504aea72c8b9b020ab7bcc94580fe2b9603c7c50d7b1e9d70d2a7daea19c68667e8f8c31\",\n    \"0xa9838d4c4e3f3a0075a952cf7dd623307ec633fcc81a7cf9e52e66c31780de33dbb3d74c320dc7f0a4b72f7a49949515\",\n    \"0xa44766b6251af458fe4f5f9ed1e02950f35703520b8656f09fc42d9a2d38a700c11a7c8a0436ac2e5e9f053d0bb8ff91\",\n    \"0xad78d9481c840f5202546bea0d13c776826feb8b1b7c72e83d99a947622f0bf38a4208551c4c41beb1270d7792075457\",\n    \"0xb619ffa8733b470039451e224b777845021e8dc1125f247a4ff2476cc774657d0ff9c5279da841fc1236047de9d81c60\",\n    \"0xaf760b0a30a1d6af3bc5cd6686f396bd41779aeeb6e0d70a09349bd5da17ca2e7965afc5c8ec22744198fbe3f02fb331\",\n    \"0xa0cc209abdb768b589fcb7b376b6e1cac07743288c95a1cf1a0354b47f0cf91fca78a75c1fcafa6f5926d6c379116608\",\n    \"0x864add673c89c41c754eeb3cd8dcff5cdde1d739fce65c30e474a082bb5d813cba6412e61154ce88fdb6c12c5d9be35b\",\n    \"0xb091443b0ce279327dc37cb484e9a5b69b257a714ce21895d67539172f95ffa326903747b64a3649e99aea7bb10d03f7\",\n    \"0xa8c452b8c4ca8e0a61942a8e08e28f17fb0ef4c5b018b4e6d1a64038280afa2bf1169202f05f14af24a06ca72f448ccd\",\n    \"0xa23c24721d18bc48d5dcf70effcbef89a7ae24e67158d70ae1d8169ee75d9a051d34b14e9cf06488bac324fe58549f26\",\n    \"0x92a730e30eb5f3231feb85f6720489dbb1afd42c43f05a1610c6b3c67bb949ec8fde507e924498f4ffc646f7b07d9123\",\n    \"0x8dbe5abf4031ec9ba6bb06d1a47dd1121fb9e03b652804069250967fd5e9577d0039e233441b7f837a7c9d67ba18c28e\",\n    \"0xaa456bcfef6a21bb88181482b279df260297b3778e84594ebddbdf337e85d9e3d46ca1d0b516622fb0b103df8ec519b7\",\n    \"0xa3b31ae621bd210a2b767e0e6f22eb28fe3c4943498a7e91753225426168b9a26da0e02f1dc5264da53a5ad240d9f51b\",\n    \"0xaa8d66857127e6e71874ce2202923385a7d2818b84cb73a6c42d71afe70972a70c6bdd2aad1a6e8c5e4ca728382a8ea8\",\n    \"0xac7e8e7a82f439127a5e40558d90d17990f8229852d21c13d753c2e97facf077cf59582b603984c3dd3faebd80aff4f5\",\n    \"0x93a8bcf4159f455d1baa73d2ef2450dcd4100420de84169bbe28b8b7a5d1746273f870091a87a057e834f754f34204b1\",\n    \"0x89d0ebb287c3613cdcae7f5acc43f17f09c0213fc40c074660120b755d664109ffb9902ed981ede79e018ddb0c845698\",\n    \"0xa87ccbfad431406aadbee878d9cf7d91b13649d5f7e19938b7dfd32645a43b114eef64ff3a13201398bd9b0337832e5a\",\n    \"0x833c51d0d0048f70c3eefb4e70e4ff66d0809c41838e8d2c21c288dd3ae9d9dfaf26d1742bf4976dab83a2b381677011\",\n    \"0x8bcd6b1c3b02fffead432e8b1680bad0a1ac5a712d4225e220690ee18df3e7406e2769e1f309e2e803b850bc96f0e768\",\n    \"0xb61e3dbd88aaf4ff1401521781e2eea9ef8b66d1fac5387c83b1da9e65c2aa2a56c262dea9eceeb4ad86c90211672db0\",\n    \"0x866d3090db944ecf190dd0651abf67659caafd31ae861bab9992c1e3915cb0952da7c561cc7e203560a610f48fae633b\",\n    \"0xa5e8971543c14274a8dc892b0be188c1b4fbc75c692ed29f166e0ea80874bc5520c2791342b7c1d2fb5dd454b03b8a5b\",\n    \"0x8f2f9fc50471bae9ea87487ebd1bc8576ef844cc42d606af5c4c0969670fdf2189afd643e4de3145864e7773d215f37f\",\n    \"0xb1bb0f2527db6d51f42b9224383c0f96048bbc03d469bf01fe1383173ef8b1cc9455d9dd8ba04d46057f46949bfc92b5\",\n    \"0xaa7c99d906b4d7922296cfe2520473fc50137c03d68b7865c5bfb8adbc316b1034310ec4b5670c47295f4a80fb8d61e9\",\n    \"0xa5d1da4d6aba555919df44cbaa8ff79378a1c9e2cfdfbf9d39c63a4a00f284c5a5724e28ecbc2d9dba27fe4ee5018bd5\",\n    \"0xa8db53224f70af4d991b9aae4ffe92d2aa5b618ad9137784b55843e9f16cefbfd25ada355d308e9bbf55f6d2f7976fb3\",\n    \"0xb6536c4232bb20e22af1a8bb12de76d5fec2ad9a3b48af1f38fa67e0f8504ef60f305a73d19385095bb6a9603fe29889\",\n    \"0x87f7e371a1817a63d6838a8cf4ab3a8473d19ce0d4f40fd013c03d5ddd5f4985df2956531cc9f187928ef54c68f4f9a9\",\n    \"0xae13530b1dbc5e4dced9d909ea61286ec09e25c12f37a1ed2f309b0eb99863d236c3b25ed3484acc8c076ad2fa8cd430\",\n    \"0x98928d850247c6f7606190e687d5c94a627550198dbdbea0161ef9515eacdb1a0f195cae3bb293112179082daccf8b35\",\n    \"0x918528bb8e6a055ad4db6230d3a405e9e55866da15c4721f5ddd1f1f37962d4904aad7a419218fe6d906fe191a991806\",\n    \"0xb71e31a06afe065773dd3f4a6e9ef81c3292e27a3b7fdfdd452d03e05af3b6dd654c355f7516b2a93553360c6681a73a\",\n    \"0x8870b83ab78a98820866f91ac643af9f3ff792a2b7fda34185a9456a63abdce42bfe8ad4dc67f08a6392f250d4062df4\",\n    \"0x91eea1b668e52f7a7a5087fabf1cab803b0316f78d9fff469fbfde2162f660c250e4336a9eea4cb0450bd30ac067bc8b\",\n    \"0x8b74990946de7b72a92147ceac1bd9d55999a8b576e8df68639e40ed5dc2062cfcd727903133de482b6dca19d0aaed82\",\n    \"0x8ebad537fece090ebbab662bdf2618e21ca30cf6329c50935e8346d1217dcbe3c1fe1ea28efca369c6003ce0a94703c1\",\n    \"0xa8640479556fb59ebd1c40c5f368fbd960932fdbb782665e4a0e24e2bdb598fc0164ce8c0726d7759cfc59e60a62e182\",\n    \"0xa9a52a6bf98ee4d749f6d38be2c60a6d54b64d5cbe4e67266633dc096cf28c97fe998596707d31968cbe2064b72256bf\",\n    \"0x847953c48a4ce6032780e9b39d0ed4384e0be202c2bbe2dfda3910f5d87aa5cd3c2ffbfcfae4dddce16d6ab657599b95\",\n    \"0xb6f6e1485d3ec2a06abaecd23028b200b2e4a0096c16144d07403e1720ff8f9ba9d919016b5eb8dc5103880a7a77a1d3\",\n    \"0x98dfc2065b1622f596dbe27131ea60bef7a193b12922cecb27f8c571404f483014f8014572e86ae2e341ab738e4887ef\",\n    \"0xacb0d205566bacc87bbe2e25d10793f63f7a1f27fd9e58f4f653ceae3ffeba511eaf658e068fad289eeb28f9edbeb35b\",\n    \"0xae4411ed5b263673cee894c11fe4abc72a4bf642d94022a5c0f3369380fcdfc1c21e277f2902972252503f91ada3029a\",\n    \"0xac4a7a27ba390a75d0a247d93d4a8ef1f0485f8d373a4af4e1139369ec274b91b3464d9738eeaceb19cd6f509e2f8262\",\n    \"0x87379c3bf231fdafcf6472a79e9e55a938d851d4dd662ab6e0d95fd47a478ed99e2ad1e6e39be3c0fc4f6d996a7dd833\",\n    \"0x81316904b035a8bcc2041199a789a2e6879486ba9fddcba0a82c745cc8dd8374a39e523b91792170cd30be7aa3005b85\",\n    \"0xb8206809c6cd027ed019f472581b45f7e12288f89047928ba32b4856b6560ad30395830d71e5e30c556f6f182b1fe690\",\n    \"0x88d76c028f534a62e019b4a52967bb8642ede6becfa3807be68fdd36d366fc84a4ac8dc176e80a68bc59eb62caf5dff9\",\n    \"0x8c3b8be685b0f8aad131ee7544d0e12f223f08a6f8edaf464b385ac644e0ddc9eff7cc7cb5c1b50ab5d71ea0f41d2213\",\n    \"0x8d91410e004f76c50fdc05784157b4d839cb5090022c629c7c97a5e0c3536eeafee17a527b54b1165c3cd81774bb54ce\",\n    \"0xb25c2863bc28ec5281ce800ddf91a7e1a53f4c6d5da1e6c86ef4616e93bcf55ed49e297216d01379f5c6e7b3c1e46728\",\n    \"0x865f7b09ac3ca03f20be90c48f6975dd2588838c2536c7a3532a6aa5187ed0b709cd03d91ff4048061c10d0aa72b69ce\",\n    \"0xb3f7477c90c11596eb4f8bbf34adbcb832638c4ff3cdd090d4d477ee50472ac9ddaf5be9ad7eca3f148960d362bbd098\",\n    \"0x8db35fd53fca04faecd1c76a8227160b3ab46ac1af070f2492445a19d8ff7c25bbaef6c9fa0c8c088444561e9f7e4eb2\",\n    \"0xa478b6e9d058a2e01d2fc053b739092e113c23a6a2770a16afbef044a3709a9e32f425ace9ba7981325f02667c3f9609\",\n    \"0x98caa6bd38916c08cf221722a675a4f7577f33452623de801d2b3429595f988090907a7e99960fff7c076d6d8e877b31\",\n    \"0xb79aaaacefc49c3038a14d2ac468cfec8c2161e88bdae91798d63552cdbe39e0e02f9225717436b9b8a40a022c633c6e\",\n    \"0x845a31006c680ee6a0cc41d3dc6c0c95d833fcf426f2e7c573fa15b2c4c641fbd6fe5ebb0e23720cc3467d6ee1d80dc4\",\n    \"0xa1bc287e272cf8b74dbf6405b3a5190883195806aa351f1dc8e525aa342283f0a35ff687e3b434324dedee74946dd185\",\n    \"0xa4fd2dc8db75d3783a020856e2b3aa266dc6926e84f5c491ef739a3bddd46dc8e9e0fc1177937839ef1b18d062ffbb9e\",\n    \"0xacbf0d3c697f57c202bb8c5dc4f3fc341b8fc509a455d44bd86acc67cad2a04495d5537bcd3e98680185e8aa286f2587\",\n    \"0xa5caf423a917352e1b8e844f5968a6da4fdeae467d10c6f4bbd82b5eea46a660b82d2f5440d3641c717b2c3c9ed0be52\",\n    \"0x8a39d763c08b926599ab1233219c49c825368fad14d9afc7c0c039224d37c00d8743293fd21645bf0b91eaf579a99867\",\n    \"0xb2b53a496def0ba06e80b28f36530fbe0fb5d70a601a2f10722e59abee529369c1ae8fd0f2db9184dd4a2519bb832d94\",\n    \"0xa73980fcef053f1b60ebbb5d78ba6332a475e0b96a0c724741a3abf3b59dd344772527f07203cf4c9cb5155ebed81fa0\",\n    \"0xa070d20acce42518ece322c9db096f16aed620303a39d8d5735a0df6e70fbeceb940e8d9f5cc38f3314b2240394ec47b\",\n    \"0xa50cf591f522f19ca337b73089557f75929d9f645f3e57d4f241e14cdd1ea3fb48d84bcf05e4f0377afbb789fbdb5d20\",\n    \"0x82a5ffce451096aca8eeb0cd2ae9d83db3ed76da3f531a80d9a70a346359bf05d74863ce6a7c848522b526156a5e20cd\",\n    \"0x88e0e84d358cbb93755a906f329db1537c3894845f32b9b0b691c29cbb455373d9452fadd1e77e20a623f6eaf624de6f\",\n    \"0xaa07ac7b84a6d6838826e0b9e350d8ec75e398a52e9824e6b0da6ae4010e5943fec4f00239e96433f291fef9d1d1e609\",\n    \"0xac8887bf39366034bc63f6cc5db0c26fd27307cbc3d6cce47894a8a019c22dd51322fb5096edc018227edfafc053a8f6\",\n    \"0xb7d26c26c5b33f77422191dca94977588ab1d4b9ce7d0e19c4a3b4cd1c25211b78c328dbf81e755e78cd7d1d622ad23e\",\n    \"0x99a676d5af49f0ba44047009298d8474cabf2d5bca1a76ba21eff7ee3c4691a102fdefea27bc948ccad8894a658abd02\",\n    \"0xb0d09a91909ab3620c183bdf1d53d43d39eb750dc7a722c661c3de3a1a5d383ad221f71bae374f8a71867505958a3f76\",\n    \"0x84681a883de8e4b93d68ac10e91899c2bbb815ce2de74bb48a11a6113b2a3f4df8aceabda1f5f67bc5aacac8c9da7221\",\n    \"0x9470259957780fa9b43521fab3644f555f5343281c72582b56d2efd11991d897b3b481cafa48681c5aeb80c9663b68f7\",\n    \"0xab1b29f7ece686e6fa968a4815da1d64f3579fed3bc92e1f3e51cd13a3c076b6cf695ed269d373300a62463dc98a4234\",\n    \"0x8ab415bfcd5f1061f7687597024c96dd9c7cb4942b5989379a7a3b5742f7d394337886317659cbeacaf030234a24f972\",\n    \"0xb9b524aad924f9acc63d002d617488f31b0016e0f0548f050cada285ce7491b74a125621638f19e9c96eabb091d945be\",\n    \"0x8c4c373e79415061837dd0def4f28a2d5d74d21cb13a76c9049ad678ca40228405ab0c3941df49249847ecdefc1a5b78\",\n    \"0xa8edf4710b5ab2929d3db6c1c0e3e242261bbaa8bcec56908ddadd7d2dad2dca9d6eb9de630b960b122ebeea41040421\",\n    \"0x8d66bb3b50b9df8f373163629f9221b3d4b6980a05ea81dc3741bfe9519cf3ebba7ab98e98390bae475e8ede5821bd5c\",\n    \"0x8d3c21bae7f0cfb97c56952bb22084b58e7bb718890935b73103f33adf5e4d99cd262f929c6eeab96209814f0dbae50a\",\n    \"0xa5c66cfab3d9ebf733c4af24bebc97070e7989fe3c73e79ac85fb0e4d40ae44fb571e0fad4ad72560e13ed453900d14f\",\n    \"0x9362e6b50b43dbefbc3254471372297b5dcce809cd3b60bf74a1268ab68bdb50e46e462cbd78f0d6c056330e982846af\",\n    \"0x854630d08e3f0243d570cc2e856234cb4c1a158d9c1883bf028a76525aaa34be897fe918d5f6da9764a3735fa9ebd24a\",\n    \"0x8c7d246985469ff252c3f4df6c7c9196fc79f05c1c66a609d84725c78001d0837c7a7049394ba5cf7e863e2d58af8417\",\n    \"0xae050271e01b528925302e71903f785b782f7bf4e4e7a7f537140219bc352dc7540c657ed03d3a297ad36798ecdb98cd\",\n    \"0x8d2ae9179fcf2b0c69850554580b52c1f4a5bd865af5f3028f222f4acad9c1ad69a8ef6c7dc7b03715ee5c506b74325e\",\n    \"0xb8ef8de6ce6369a8851cd36db0ccf00a85077e816c14c4e601f533330af9e3acf0743a95d28962ed8bfcfc2520ef3cfe\",\n    \"0xa6ecad6fdfb851b40356a8b1060f38235407a0f2706e7b8bb4a13465ca3f81d4f5b99466ac2565c60af15f022d26732e\",\n    \"0x819ff14cdea3ab89d98e133cd2d0379361e2e2c67ad94eeddcdb9232efd509f51d12f4f03ebd4dd953bd262a886281f7\",\n    \"0x8561cd0f7a6dbcddd83fcd7f472d7dbcba95b2d4fb98276f48fccf69f76d284e626d7e41314b633352df8e6333fd52a1\",\n    \"0xb42557ccce32d9a894d538c48712cb3e212d06ac05cd5e0527ccd2db1078ee6ae399bf6a601ffdab1f5913d35fc0b20c\",\n    \"0x89b4008d767aad3c6f93c349d3b956e28307311a5b1cec237e8d74bb0dee7e972c24f347fd56afd915a2342bd7bc32f0\",\n    \"0x877487384b207e53f5492f4e36c832c2227f92d1bb60542cfeb35e025a4a7afc2b885fae2528b33b40ab09510398f83e\",\n    \"0x8c411050b63c9053dd0cd81dacb48753c3d7f162028098e024d17cd6348482703a69df31ad6256e3d25a8bbf7783de39\",\n    \"0xa8506b54a88d17ac10fb1b0d1fe4aa40eae7553a064863d7f6b52ccc4236dd4b82d01dca6ba87da9a239e3069ba879fb\",\n    \"0xb1a24caef9df64750c1350789bb8d8a0db0f39474a1c74ea9ba064b1516db6923f00af8d57c632d58844fb8786c3d47a\",\n    \"0x959d6e255f212b0708c58a2f75cb1fe932248c9d93424612c1b8d1e640149656059737e4db2139afd5556bcdacf3eda2\",\n    \"0x84525af21a8d78748680b6535bbc9dc2f0cf9a1d1740d12f382f6ecb2e73811d6c1da2ad9956070b1a617c61fcff9fe5\",\n    \"0xb74417d84597a485d0a8e1be07bf78f17ebb2e7b3521b748f73935b9afbbd82f34b710fb7749e7d4ab55b0c7f9de127d\",\n    \"0xa4a9aecb19a6bab167af96d8b9d9aa5308eab19e6bfb78f5a580f9bf89bdf250a7b52a09b75f715d651cb73febd08e84\",\n    \"0x9777b30be2c5ffe7d29cc2803a562a32fb43b59d8c3f05a707ab60ec05b28293716230a7d264d7cd9dd358fc031cc13e\",\n    \"0x95dce7a3d4f23ac0050c510999f5fbf8042f771e8f8f94192e17bcbfa213470802ebdbe33a876cb621cf42e275cbfc8b\",\n    \"0xb0b963ebcbbee847ab8ae740478544350b3ac7e86887e4dfb2299ee5096247cd2b03c1de74c774d9bde94ae2ee2dcd59\",\n    \"0xa4ab20bafa316030264e13f7ef5891a2c3b29ab62e1668fcb5881f50a9acac6adbe3d706c07e62f2539715db768f6c43\",\n    \"0x901478a297669d608e406fe4989be75264b6c8be12169aa9e0ad5234f459ca377f78484ffd2099a2fe2db5e457826427\",\n    \"0x88c76e5c250810c057004a03408b85cd918e0c8903dc55a0dd8bb9b4fc2b25c87f9b8cf5943eb19fbbe99d36490050c5\",\n    \"0x91607322bbad4a4f03fc0012d0821eff5f8c516fda45d1ec1133bface6f858bf04b25547be24159cab931a7aa08344d4\",\n    \"0x843203e07fce3c6c81f84bc6dc5fb5e9d1c50c8811ace522dc66e8658433a0ef9784c947e6a62c11bf705307ef05212e\",\n    \"0x91dd8813a5d6dddcda7b0f87f672b83198cd0959d8311b2b26fb1fae745185c01f796fbd03aad9db9b58482483fdadd8\",\n    \"0x8d15911aacf76c8bcd7136e958febd6963104addcd751ce5c06b6c37213f9c4fb0ffd4e0d12c8e40c36d658999724bfd\",\n    \"0x8a36c5732d3f1b497ebe9250610605ee62a78eaa9e1a45f329d09aaa1061131cf1d9df00f3a7d0fe8ad614a1ff9caaae\",\n    \"0xa407d06affae03660881ce20dab5e2d2d6cddc23cd09b95502a9181c465e57597841144cb34d22889902aff23a76d049\",\n    \"0xb5fd856d0578620a7e25674d9503be7d97a2222900e1b4738c1d81ff6483b144e19e46802e91161e246271f90270e6cf\",\n    \"0x91b7708869cdb5a7317f88c0312d103f8ce90be14fb4f219c2e074045a2a83636fdc3e69e862049fc7c1ef000e832541\",\n    \"0xb64719cc5480709d1dae958f1d3082b32a43376da446c8f9f64cb02a301effc9c34d9102051733315a8179aed94d53cc\",\n    \"0x94347a9542ff9d18f7d9eaa2f4d9b832d0e535fe49d52aa2de08aa8192400eddabdb6444a2a78883e27c779eed7fdf5a\",\n    \"0x840ef44a733ff1376466698cd26f82cf56bb44811e196340467f932efa3ae1ef9958a0701b3b032f50fd9c1d2aed9ab5\",\n    \"0x90ab3f6f67688888a31ffc2a882bb37adab32d1a4b278951a21646f90d03385fc976715fc639a785d015751171016f10\",\n    \"0xb56f35d164c24b557dbcbc8a4bfa681ec916f8741ffcb27fb389c164f4e3ed2be325210ef5bdaeae7a172ca9599ab442\",\n    \"0xa7921a5a80d7cf6ae81ba9ee05e0579b18c20cd2852762c89d6496aa4c8ca9d1ca2434a67b2c16d333ea8e382cdab1e3\",\n    \"0xa506bcfbd7e7e5a92f68a1bd87d07ad5fe3b97aeee40af2bf2cae4efcd77fff03f872732c5b7883aa6584bee65d6f8cb\",\n    \"0xa8c46cff58931a1ce9cbe1501e1da90b174cddd6d50f3dfdfb759d1d4ad4673c0a8feed6c1f24c7af32865a7d6c984e5\",\n    \"0xb45686265a83bff69e312c5149db7bb70ac3ec790dc92e392b54d9c85a656e2bf58596ce269f014a906eafc97461aa5f\",\n    \"0x8d4009a75ccb2f29f54a5f16684b93202c570d7a56ec1a8b20173269c5f7115894f210c26b41e8d54d4072de2d1c75d0\",\n    \"0xaef8810af4fc676bf84a0d57b189760ddc3375c64e982539107422e3de2580b89bd27aa6da44e827b56db1b5555e4ee8\",\n    \"0x888f0e1e4a34f48eb9a18ef4de334c27564d72f2cf8073e3d46d881853ac1424d79e88d8ddb251914890588937c8f711\",\n    \"0xb64b0aa7b3a8f6e0d4b3499fe54e751b8c3e946377c0d5a6dbb677be23736b86a7e8a6be022411601dd75012012c3555\",\n    \"0x8d57776f519f0dd912ea14f79fbab53a30624e102f9575c0bad08d2dc754e6be54f39b11278c290977d9b9c7c0e1e0ad\",\n    \"0xa018fc00d532ceb2e4de908a15606db9b6e0665dd77190e2338da7c87a1713e6b9b61554e7c1462f0f6d4934b960b15c\",\n    \"0x8c932be83ace46f65c78e145b384f58e41546dc0395270c1397874d88626fdeda395c8a289d602b4c312fe98c1311856\",\n    \"0x89174838e21639d6bdd91a0621f04dc056907b88e305dd66e46a08f6d65f731dea72ae87ca5e3042d609e8de8de9aa26\",\n    \"0xb7b7f508bb74f7a827ac8189daa855598ff1d96fa3a02394891fd105d8f0816224cd50ac4bf2ed1cf469ace516c48184\",\n    \"0xb31877ad682583283baadd68dc1bebd83f5748b165aadd7fe9ef61a343773b88bcd3a022f36d6c92f339b7bfd72820a9\",\n    \"0xb79d77260b25daf9126dab7a193df2d7d30542786fa1733ffaf6261734770275d3ca8bae1d9915d1181a78510b3439db\",\n    \"0x91894fb94cd4c1dd2ceaf9c53a7020c5799ba1217cf2d251ea5bc91ed26e1159dd758e98282ebe35a0395ef9f1ed15a0\",\n    \"0xab59895cdafd33934ceedfc3f0d5d89880482cba6c99a6db93245f9e41987efd76e0640e80aef31782c9a8c7a83fccec\",\n    \"0xaa22ea63654315e033e09d4d4432331904a6fc5fb1732557987846e3c564668ca67c60a324b4af01663a23af11a9ce4b\",\n    \"0xb53ba3ef342601467e1f71aa280e100fbabbd38518fa0193e0099505036ee517c1ac78e96e9baeb549bb6879bb698fb0\",\n    \"0x943fd69fd656f37487cca3605dc7e5a215fddd811caf228595ec428751fc1de484a0cb84c667fe4d7c35599bfa0e5e34\",\n    \"0x9353128b5ebe0dddc555093cf3e5942754f938173541033e8788d7331fafc56f68d9f97b4131e37963ab7f1c8946f5f1\",\n    \"0xa76cd3c566691f65cfb86453b5b31dbaf3cab8f84fe1f795dd1e570784b9b01bdd5f0b3c1e233942b1b5838290e00598\",\n    \"0x983d84b2e53ffa4ae7f3ba29ef2345247ea2377686b74a10479a0ef105ecf90427bf53b74c96dfa346d0f842b6ffb25b\",\n    \"0x92e0fe9063306894a2c6970c001781cff416c87e87cb5fbac927a3192655c3da4063e6fa93539f6ff58efac6adcc5514\",\n    \"0xb00a81f03c2b8703acd4e2e4c21e06973aba696415d0ea1a648ace2b0ea19b242fede10e4f9d7dcd61c546ab878bc8f9\",\n    \"0xb0d08d880f3b456a10bf65cff983f754f545c840c413aea90ce7101a66eb0a0b9b1549d6c4d57725315828607963f15a\",\n    \"0x90cb64d03534f913b411375cce88a9e8b1329ce67a9f89ca5df8a22b8c1c97707fec727dbcbb9737f20c4cf751359277\",\n    \"0x8327c2d42590dfcdb78477fc18dcf71608686ad66c49bce64d7ee874668be7e1c17cc1042a754bbc77c9daf50b2dae07\",\n    \"0x8532171ea13aa7e37178e51a6c775da469d2e26ec854eb16e60f3307db4acec110d2155832c202e9ba525fc99174e3b0\",\n    \"0x83ca44b15393d021de2a511fa5511c5bd4e0ac7d67259dce5a5328f38a3cce9c3a269405959a2486016bc27bb140f9ff\",\n    \"0xb1d36e8ca812be545505c8214943b36cabee48112cf0de369957afa796d37f86bf7249d9f36e8e990f26f1076f292b13\",\n    \"0x9803abf45be5271e2f3164c328d449efc4b8fc92dfc1225d38e09630909fe92e90a5c77618daa5f592d23fc3ad667094\",\n    \"0xb268ad68c7bf432a01039cd889afae815c3e120f57930d463aece10af4fd330b5bd7d8869ef1bcf6b2e78e4229922edc\",\n    \"0xa4c91a0d6f16b1553264592b4cbbbf3ca5da32ab053ffbdd3dbb1aed1afb650fb6e0dc5274f71a51d7160856477228db\",\n    \"0xad89d043c2f0f17806277ffdf3ecf007448e93968663f8a0b674254f36170447b7527d5906035e5e56f4146b89b5af56\",\n    \"0x8b6964f757a72a22a642e4d69102951897e20c21449184e44717bd0681d75f7c5bfa5ee5397f6e53febf85a1810d6ed1\",\n    \"0xb08f5cdaabec910856920cd6e836c830b863eb578423edf0b32529488f71fe8257d90aed4a127448204df498b6815d79\",\n    \"0xaf26bb3358be9d280d39b21d831bb53145c4527a642446073fee5a86215c4c89ff49a3877a7a549486262f6f57a0f476\",\n    \"0xb4010b37ec4d7c2af20800e272539200a6b623ae4636ecbd0e619484f4ab9240d02bc5541ace3a3fb955dc0a3d774212\",\n    \"0x82752ab52bdcc3cc2fc405cb05a2e694d3df4a3a68f2179ec0652536d067b43660b96f85f573f26fbd664a9ef899f650\",\n    \"0x96d392dde067473a81faf2d1fea55b6429126b88b160e39b4210d31d0a82833ffd3a80e07d24d495aea2d96be7251547\",\n    \"0xa76d8236d6671204d440c33ac5b8deb71fa389f6563d80e73be8b043ec77d4c9b06f9a586117c7f957f4af0331cbc871\",\n    \"0xb6c90961f68b5e385d85c9830ec765d22a425f506904c4d506b87d8944c2b2c09615e740ed351df0f9321a7b93979cae\",\n    \"0xa6ec5ea80c7558403485b3b1869cdc63bde239bafdf936d9b62a37031628402a36a2cfa5cfbb8e26ac922cb0a209b3ba\",\n    \"0x8c3195bbdbf9bc0fc95fa7e3d7f739353c947f7767d1e3cb24d8c8602d8ea0a1790ac30b815be2a2ba26caa5227891e2\",\n    \"0xa7f8a63d809f1155722c57f375ea00412b00147776ae4444f342550279ef4415450d6f400000a326bf11fea6c77bf941\",\n    \"0x97fa404df48433a00c85793440e89bb1af44c7267588ae937a1f5d53e01e1c4d4fc8e4a6d517f3978bfdd6c2dfde012f\",\n    \"0xa984a0a3836de3d8d909c4629a2636aacb85393f6f214a2ef68860081e9db05ad608024762db0dc35e895dc00e2d4cdd\",\n    \"0x9526cf088ab90335add1db4d3a4ac631b58cbfbe88fa0845a877d33247d1cfeb85994522e1eb8f8874651bfb1df03e2a\",\n    \"0xac83443fd0afe99ad49de9bf8230158c118e2814c9c89db5ac951c240d6c2ce45e7677221279d9e97848ec466b99aafe\",\n    \"0xaeeefdbaba612e971697798ceaf63b247949dc823a0ad771ae5b988a5e882b338a98d3d0796230f49d533ec5ba411b39\",\n    \"0xae3f248b5a7b0f92b7820a6c5ae21e5bd8f4265d4f6e21a22512079b8ee9be06393fd3133ce8ebac0faf23f4f8517e36\",\n    \"0xa64a831b908eee784b8388b45447d2885ec0551b26b0c2b15e5f417d0a12c79e867fb7bd3d008d0af98b44336f8ec1ad\",\n    \"0xb242238cd8362b6e440ba21806905714dd55172db25ec7195f3fc4937b2aba146d5cbf3cf691a1384b4752dc3b54d627\",\n    \"0x819f97f337eea1ffb2a678cc25f556f1aab751c6b048993a1d430fe1a3ddd8bb411c152e12ca60ec6e057c190cd1db9a\",\n    \"0xb9d7d187407380df54ee9fef224c54eec1bfabf17dc8abf60765b7951f538f59aa26fffd5846cfe05546c35f59b573f4\",\n    \"0xaa6e3c14efa6a5962812e3f94f8ce673a433f4a82d07a67577285ea0eaa07f8be7115853122d12d6d4e1fdf64c504be1\",\n    \"0x82268bee9c1662d3ddb5fb785abfae6fb8b774190f30267f1d47091d2cd4b3874db4372625aa36c32f27b0eee986269b\",\n    \"0xb236459565b7b966166c4a35b2fa71030b40321821b8e96879d95f0e83a0baf33fa25721f30af4a631df209e25b96061\",\n    \"0x8708d752632d2435d2d5b1db4ad1fa2558d776a013655f88e9a3556d86b71976e7dfe5b8834fdec97682cd94560d0d0d\",\n    \"0xae1424a68ae2dbfb0f01211f11773732a50510b5585c1fb005cb892b2c6a58f4a55490b5c5b4483c6fce40e9d3236a52\",\n    \"0xb3f5f722af9dddb07293c871ce97abbccba0093ca98c8d74b1318fa21396fc1b45b69c15084f63d728f9908442024506\",\n    \"0x9606f3ce5e63886853ca476dc0949e7f1051889d529365c0cb0296fdc02abd088f0f0318ecd2cf36740a3634132d36f6\",\n    \"0xb11a833a49fa138db46b25ff8cdda665295226595bc212c0931b4931d0a55c99da972c12b4ef753f7e37c6332356e350\",\n    \"0xafede34e7dab0a9e074bc19a7daddb27df65735581ca24ad70c891c98b1349fcebbcf3ba6b32c2617fe06a5818dabc2d\",\n    \"0x97993d456e459e66322d01f8eb13918979761c3e8590910453944bdff90b24091bb018ac6499792515c9923be289f99f\",\n    \"0x977e3e967eff19290a192cd11df3667d511b398fb3ac9a5114a0f3707e25a0edcb56105648b1b85a8b7519fc529fc6f6\",\n    \"0xb873a7c88bf58731fe1bf61ff6828bf114cf5228f254083304a4570e854e83748fc98683ddba62d978fff7909f2c5c47\",\n    \"0xad4b2691f6f19da1d123aaa23cca3e876247ed9a4ab23c599afdbc0d3aa49776442a7ceaa996ac550d0313d9b9a36cee\",\n    \"0xb9210713c78e19685608c6475bfa974b57ac276808a443f8b280945c5d5f9c39da43effa294bfb1a6c6f7b6b9f85bf6c\",\n    \"0xa65152f376113e61a0e468759de38d742caa260291b4753391ee408dea55927af08a4d4a9918600a3bdf1df462dffe76\",\n    \"0x8bf8c27ad5140dde7f3d2280fd4cc6b29ab76537e8d7aa7011a9d2796ee3e56e9a60c27b5c2da6c5e14fc866301dc195\",\n    \"0x92fde8effc9f61393a2771155812b863cff2a0c5423d7d40aa04d621d396b44af94ddd376c28e7d2f53c930aea947484\",\n    \"0x97a01d1dd9ee30553ce676011aea97fa93d55038ada95f0057d2362ae9437f3ed13de8290e2ff21e3167dd7ba10b9c3f\",\n    \"0x89affffaa63cb2df3490f76f0d1e1d6ca35c221dd34057176ba739fa18d492355e6d2a5a5ad93a136d3b1fed0bb8aa19\",\n    \"0x928b8e255a77e1f0495c86d3c63b83677b4561a5fcbbe5d3210f1e0fc947496e426d6bf3b49394a5df796c9f25673fc4\",\n    \"0x842a0af91799c9b533e79ee081efe2a634cac6c584c2f054fb7d1db67dde90ae36de36cbf712ec9cd1a0c7ee79e151ea\",\n    \"0xa65b946cf637e090baf2107c9a42f354b390e7316beb8913638130dbc67c918926eb87bec3b1fe92ef72bc77a170fa3b\",\n    \"0xaafc0f19bfd71ab5ae4a8510c7861458b70ad062a44107b1b1dbacbfa44ba3217028c2824bd7058e2fa32455f624040b\",\n    \"0x95269dc787653814e0be899c95dba8cfa384f575a25e671c0806fd80816ad6797dc819d30ae06e1d0ed9cb01c3950d47\",\n    \"0xa1e760f7fa5775a1b2964b719ff961a92083c5c617f637fc46e0c9c20ab233f8686f7f38c3cb27d825c54dd95e93a59b\",\n    \"0xac3b8a7c2317ea967f229eddc3e23e279427f665c4705c7532ed33443f1243d33453c1088f57088d2ab1e3df690a9cc9\",\n    \"0xb787beeddfbfe36dd51ec4efd9cf83e59e84d354c3353cc9c447be53ae53d366ed1c59b686e52a92f002142c8652bfe0\",\n    \"0xb7a64198300cb6716aa7ac6b25621f8bdec46ad5c07a27e165b3f774cdf65bcfdbf31e9bae0c16b44de4b00ada7a4244\",\n    \"0xb8ae9f1452909e0c412c7a7fe075027691ea8df1347f65a5507bc8848f1d2c833d69748076db1129e5b4fb912f65c86c\",\n    \"0x9682e41872456b9fa67def89e71f06d362d6c8ca85c9c48536615bc401442711e1c9803f10ab7f8ab5feaec0f9df20a6\",\n    \"0x88889ff4e271dc1c7e21989cc39f73cde2f0475acd98078281591ff6c944fadeb9954e72334319050205d745d4df73df\",\n    \"0x8f79b5b8159e7fd0d93b0645f3c416464f39aec353b57d99ecf24f96272df8a068ad67a6c90c78d82c63b40bb73989bb\",\n    \"0x838c01a009a3d8558a3f0bdd5e22de21af71ca1aefc8423c91dc577d50920e9516880e87dce3e6d086e11cd45c9052d9\",\n    \"0xb97f1c6eee8a78f137c840667cc288256e39294268a3009419298a04a1d0087c9c9077b33c917c65caf76637702dda8a\",\n    \"0x972284ce72f96a61c899260203dfa06fc3268981732bef74060641c1a5068ead723e3399431c247ca034b0dae861e8df\",\n    \"0x945a8d52d6d3db6663dbd3110c6587f9e9c44132045eeffba15621576d178315cb52870fa5861669f84f0bee646183fe\",\n    \"0xa0a547b5f0967b1c3e5ec6c6a9a99f0578521489180dfdfbb5561f4d166baac43a2f06f950f645ce991664e167537eed\",\n    \"0xa0592cda5cdddf1340033a745fd13a6eff2021f2e26587116c61c60edead067e0f217bc2bef4172a3c9839b0b978ab35\",\n    \"0xb9c223b65a3281587fa44ec829e609154b32f801fd1de6950e01eafb07a8324243b960d5735288d0f89f0078b2c42b5b\",\n    \"0x99ebfc3b8f9f98249f4d37a0023149ed85edd7a5abe062c8fb30c8c84555258b998bdcdd1d400bc0fa2a4aaa8b224466\",\n    \"0x955b68526e6cb3937b26843270f4e60f9c6c8ece2fa9308fe3e23afa433309c068c66a4bc16ee2cf04220f095e9afce4\",\n    \"0xb766caeafcc00378135ae53397f8a67ed586f5e30795462c4a35853de6681b1f17401a1c40958de32b197c083b7279c1\",\n    \"0x921bf87cad947c2c33fa596d819423c10337a76fe5a63813c0a9dc78a728207ae7b339407a402fc4d0f7cba3af6da6fc\",\n    \"0xa74ba1f3bc3e6c025db411308f49b347ec91da1c916bda9da61e510ec8d71d25e0ac0f124811b7860e5204f93099af27\",\n    \"0xa29b4d144e0bf17a7e8353f2824cef0ce85621396babe8a0b873ca1e8a5f8d508b87866cf86da348470649fceefd735c\",\n    \"0xa8040e12ffc3480dd83a349d06741d1572ef91932c46f5cf03aee8454254156ee95786fd013d5654725e674c920cec32\",\n    \"0x8c4cf34ca60afd33923f219ffed054f90cd3f253ffeb2204a3b61b0183417e366c16c07fae860e362b0f2bfe3e1a1d35\",\n    \"0x8195eede4ddb1c950459df6c396b2e99d83059f282b420acc34220cadeed16ab65c856f2c52568d86d3c682818ed7b37\",\n    \"0x91fff19e54c15932260aa990c7fcb3c3c3da94845cc5aa8740ef56cf9f58d19b4c3c55596f8d6c877f9f4d22921d93aa\",\n    \"0xa3e0bf7e5d02a80b75cf75f2db7e66cb625250c45436e3c136d86297d652590ec97c2311bafe407ad357c79ab29d107b\",\n    \"0x81917ff87e5ed2ae4656b481a63ced9e6e5ff653b8aa6b7986911b8bc1ee5b8ef4f4d7882c3f250f2238e141b227e510\",\n    \"0x915fdbe5e7de09c66c0416ae14a8750db9412e11dc576cf6158755fdcaf67abdbf0fa79b554cac4fe91c4ec245be073f\",\n    \"0x8df27eafb5c3996ba4dc5773c1a45ca77e626b52e454dc1c4058aa94c2067c18332280630cc3d364821ee53bf2b8c130\",\n    \"0x934f8a17c5cbb827d7868f5c8ca00cb027728a841000a16a3428ab16aa28733f16b52f58c9c4fbf75ccc45df72d9c4df\",\n    \"0xb83f4da811f9183c25de8958bc73b504cf790e0f357cbe74ef696efa7aca97ad3b7ead1faf76e9f982c65b6a4d888fc2\",\n    \"0x87188213c8b5c268dc2b6da413f0501c95749e953791b727450af3e43714149c115b596b33b63a2f006a1a271b87efd0\",\n    \"0x83e9e888ab9c3e30761de635d9aabd31248cdd92f7675fc43e4b21fd96a03ec1dc4ad2ec94fec857ffb52683ac98e360\",\n    \"0xb4b9a1823fe2d983dc4ec4e3aaea297e581c3fc5ab4b4af5fa1370caa37af2d1cc7fc6bfc5e7da60ad8fdce27dfe4b24\",\n    \"0x856388bc78aef465dbcdd1f559252e028c9e9a2225c37d645c138e78f008f764124522705822a61326a6d1c79781e189\",\n    \"0xa6431b36db93c3b47353ba22e7c9592c9cdfb9cbdd052ecf2cc3793f5b60c1e89bc96e6bae117bfd047f2308da00dd2f\",\n    \"0xb619972d48e7e4291542dcde08f7a9cdc883c892986ded2f23ccb216e245cd8d9ad1d285347b0f9d7611d63bf4cee2bc\",\n    \"0x8845cca6ff8595955f37440232f8e61d5351500bd016dfadd182b9d39544db77a62f4e0102ff74dd4173ae2c181d24ef\",\n    \"0xb2f5f7fa26dcd3b6550879520172db2d64ee6aaa213cbef1a12befbce03f0973a22eb4e5d7b977f466ac2bf8323dcedd\",\n    \"0x858b7f7e2d44bdf5235841164aa8b4f3d33934e8cb122794d90e0c1cac726417b220529e4f896d7b77902ab0ccd35b3a\",\n    \"0x80b0408a092dae2b287a5e32ea1ad52b78b10e9c12f49282976cd738f5d834e03d1ad59b09c5ccaccc39818b87d06092\",\n    \"0xb996b0a9c6a2d14d984edcd6ab56bc941674102980d65b3ad9733455f49473d3f587c8cbf661228a7e125ddbe07e3198\",\n    \"0x90224fcebb36865293bd63af786e0c5ade6b67c4938d77eb0cbae730d514fdd0fe2d6632788e858afd29d46310cf86df\",\n    \"0xb71351fdfff7168b0a5ec48397ecc27ac36657a8033d9981e97002dcca0303e3715ce6dd3f39423bc8ef286fa2e9e669\",\n    \"0xae2a3f078b89fb753ce4ed87e0c1a58bb19b4f0cfb6586dedb9fcab99d097d659a489fb40e14651741e1375cfc4b6c5f\",\n    \"0x8ef476b118e0b868caed297c161f4231bbeb863cdfa5e2eaa0fc6b6669425ce7af50dc374abceac154c287de50c22307\",\n    \"0x92e46ab472c56cfc6458955270d3c72b7bde563bb32f7d4ab4d959db6f885764a3d864e1aa19802fefaa5e16b0cb0b54\",\n    \"0x96a3f68323d1c94e73d5938a18a377af31b782f56212de3f489d22bc289cf24793a95b37f1d6776edf88114b5c1fa695\",\n    \"0x962cc068cfce6faaa27213c4e43e44eeff0dfbb6d25b814e82c7da981fb81d7d91868fa2344f05fb552362f98cfd4a72\",\n    \"0x895d4e4c4ad670abf66d43d59675b1add7afad7438ada8f42a0360c704cee2060f9ac15b4d27e9b9d0996bb801276fe3\",\n    \"0xb3ad18d7ece71f89f2ef749b853c45dc56bf1c796250024b39a1e91ed11ca32713864049c9aaaea60cde309b47486bbf\",\n    \"0x8f05404e0c0258fdbae50e97ccb9b72ee17e0bd2400d9102c0dad981dac8c4c71585f03e9b5d50086d0a2d3334cb55d1\",\n    \"0x8bd877e9d4591d02c63c6f9fc9976c109de2d0d2df2bfa5f6a3232bab5b0b8b46e255679520480c2d7a318545efa1245\",\n    \"0x8d4c16b5d98957c9da13d3f36c46f176e64e5be879f22be3179a2c0e624fe4758a82bf8c8027410002f973a3b84cd55a\",\n    \"0x86e2a8dea86427b424fa8eada881bdff896907084a495546e66556cbdf070b78ba312bf441eb1be6a80006d25d5097a3\",\n    \"0x8608b0c117fd8652fdab0495b08fadbeba95d9c37068e570de6fddfef1ba4a1773b42ac2be212836141d1bdcdef11a17\",\n    \"0xa13d6febf5fb993ae76cae08423ca28da8b818d6ef0fde32976a4db57839cd45b085026b28ee5795f10a9a8e3098c683\",\n    \"0x8e261967fa6de96f00bc94a199d7f72896a6ad8a7bbb1d6187cca8fad824e522880e20f766620f4f7e191c53321d70f9\",\n    \"0x8b8e8972ac0218d7e3d922c734302803878ad508ca19f5f012bc047babd8a5c5a53deb5fe7c15a4c00fd6d1cb9b1dbd0\",\n    \"0xb5616b233fb3574a2717d125a434a2682ff68546dccf116dd8a3b750a096982f185614b9fb6c7678107ff40a451f56fa\",\n    \"0xaa6adf9b0c3334b0d0663f583a4914523b2ac2e7adffdb026ab9109295ff6af003ef8357026dbcf789896d2afded8d73\",\n    \"0xacb72df56a0b65496cd534448ed4f62950bb1e11e50873b6ed349c088ee364441821294ce0f7c61bd7d38105bea3b442\",\n    \"0xabae12df83e01ec947249fedd0115dc501d2b03ff7232092979eda531dbbca29ace1d46923427c7dde4c17bdf3fd7708\",\n    \"0x820b4fc2b63a9fda7964acf5caf19a2fc4965007cb6d6b511fcafcb1f71c3f673a1c0791d3f86e3a9a1eb6955b191cc0\",\n    \"0xaf277259d78c6b0f4f030a10c53577555df5e83319ddbad91afbd7c30bc58e7671c56d00d66ec3ab5ef56470cd910cee\",\n    \"0xad4a861c59f1f5ca1beedd488fb3d131dea924fffd8e038741a1a7371fad7370ca5cf80dc01f177fbb9576713bb9a5b3\",\n    \"0xb67a5162982ce6a55ccfb2f177b1ec26b110043cf18abd6a6c451cf140b5af2d634591eb4f28ad92177d8c7e5cd0a5e8\",\n    \"0x96176d0a83816330187798072d449cbfccff682561e668faf6b1220c9a6535b32a6e4f852e8abb00f79abb87493df16b\",\n    \"0xb0afe6e7cb672e18f0206e4423f51f8bd0017bf464c4b186d46332c5a5847647f89ff7fa4801a41c1b0b42f6135bcc92\",\n    \"0x8fc5e7a95ef20c1278c645892811f6fe3f15c431ebc998a32ec0da44e7213ea934ed2be65239f3f49b8ec471e9914160\",\n    \"0xb7793e41adda6c82ba1f2a31f656f6205f65bf8a3d50d836ee631bc7ce77c153345a2d0fc5c60edf8b37457c3729c4ec\",\n    \"0xa504dd7e4d6b2f4379f22cc867c65535079c75ccc575955f961677fa63ecb9f74026fa2f60c9fb6323c1699259e5e9c8\",\n    \"0xab899d00ae693649cc1afdf30fb80d728973d2177c006e428bf61c7be01e183866614e05410041bc82cb14a33330e69c\",\n    \"0x8a3bd8b0b1be570b65c4432a0f6dc42f48a2000e30ab089cf781d38f4090467b54f79c0d472fcbf18ef6a00df69cc6f3\",\n    \"0xb4d7028f7f76a96a3d7803fca7f507ae11a77c5346e9cdfccb120a833a59bda1f4264e425aa588e7a16f8e7638061d84\",\n    \"0xb9c7511a76ea5fb105de905d44b02edb17008335766ee357ed386b7b3cf19640a98b38785cb14603c1192bee5886c9b6\",\n    \"0x8563afb12e53aed71ac7103ab8602bfa8371ae095207cb0d59e8fd389b6ad1aff0641147e53cb6a7ca16c7f37c9c5e6b\",\n    \"0x8e108be614604e09974a9ed90960c28c4ea330a3d9a0cb4af6dd6f193f84ab282b243ecdf549b3131036bebc8905690c\",\n    \"0xb794d127fbedb9c5b58e31822361706ffac55ce023fbfe55716c3c48c2fd2f2c7660a67346864dfe588812d369cb50b6\",\n    \"0xb797a3442fc3b44f41baefd30346f9ac7f96e770d010d53c146ce74ce424c10fb62758b7e108b8abfdc5fafd89d745cb\",\n    \"0x993bb71e031e8096442e6205625e1bfddfe6dd6a83a81f3e2f84fafa9e5082ab4cad80a099f21eff2e81c83457c725c3\",\n    \"0x8711ab833fc03e37acf2e1e74cfd9133b101ff4144fe30260654398ae48912ab46549d552eb9d15d2ea57760d35ac62e\",\n    \"0xb21321fd2a12083863a1576c5930e1aecb330391ef83326d9d92e1f6f0d066d1394519284ddab55b2cb77417d4b0292f\",\n    \"0x877d98f731ffe3ee94b0b5b72d127630fa8a96f6ca4f913d2aa581f67732df6709493693053b3e22b0181632ac6c1e3b\",\n    \"0xae391c12e0eb8c145103c62ea64f41345973311c3bf7281fa6bf9b7faafac87bcf0998e5649b9ef81e288c369c827e07\",\n    \"0xb83a2842f36998890492ab1cd5a088d9423d192681b9a3a90ec518d4c541bce63e6c5f4df0f734f31fbfdd87785a2463\",\n    \"0xa21b6a790011396e1569ec5b2a423857b9bec16f543e63af28024e116c1ea24a3b96e8e4c75c6537c3e4611fd265e896\",\n    \"0xb4251a9c4aab3a495da7a42e684ba4860dbcf940ad1da4b6d5ec46050cbe8dab0ab9ae6b63b5879de97b905723a41576\",\n    \"0x8222f70aebfe6ac037f8543a08498f4cadb3edaac00336fc00437eb09f2cba758f6c38e887cc634b4d5b7112b6334836\",\n    \"0x86f05038e060594c46b5d94621a1d9620aa8ba59a6995baf448734e21f58e23c1ea2993d3002ad5250d6edd5ba59b34f\",\n    \"0xa7c0c749baef811ab31b973c39ceb1d94750e2bc559c90dc5eeb20d8bb6b78586a2b363c599ba2107d6be65cd435f24e\",\n    \"0x861d46a5d70b38d6c1cd72817a2813803d9f34c00320c8b62f8b9deb67f5b5687bc0b37c16d28fd017367b92e05da9ca\",\n    \"0xb3365d3dab639bffbe38e35383686a435c8c88b397b717cd4aeced2772ea1053ceb670f811f883f4e02975e5f1c4ac58\",\n    \"0xa5750285f61ab8f64cd771f6466e2c0395e01b692fd878f2ef2d5c78bdd8212a73a3b1dfa5e4c8d9e1afda7c84857d3b\",\n    \"0x835a10809ccf939bc46cf950a33b36d71be418774f51861f1cd98a016ade30f289114a88225a2c11e771b8b346cbe6ef\",\n    \"0xa4f59473a037077181a0a62f1856ec271028546ca9452b45cedfcb229d0f4d1aabfc13062b07e536cc8a0d4b113156a2\",\n    \"0x95cd14802180b224d44a73cc1ed599d6c4ca62ddcaa503513ccdc80aaa8be050cc98bd4b4f3b639549beb4587ac6caf9\",\n    \"0x973b731992a3e69996253d7f36dd7a0af1982b5ed21624b77a7965d69e9a377b010d6dabf88a8a97eec2a476259859cc\",\n    \"0xaf8a1655d6f9c78c8eb9a95051aa3baaf9c811adf0ae8c944a8d3fcba87b15f61021f3baf6996fa0aa51c81b3cb69de1\",\n    \"0x835aad5c56872d2a2d6c252507b85dd742bf9b8c211ccb6b25b52d15c07245b6d89b2a40f722aeb5083a47cca159c947\",\n    \"0xabf4e970b02bef8a102df983e22e97e2541dd3650b46e26be9ee394a3ea8b577019331857241d3d12b41d4eacd29a3ac\",\n    \"0xa13c32449dbedf158721c13db9539ae076a6ce5aeaf68491e90e6ad4e20e20d1cdcc4a89ed9fd49cb8c0dd50c17633c1\",\n    \"0x8c8f78f88b7e22dd7e9150ab1c000f10c28e696e21d85d6469a6fe315254740f32e73d81ab1f3c1cf8f544c86df506e8\",\n    \"0xb4b77f2acfe945abf81f2605f906c10b88fb4d28628487fb4feb3a09f17f28e9780445dfcee4878349d4c6387a9d17d4\",\n    \"0x8d255c235f3812c6ecc646f855fa3832be5cb4dbb9c9e544989fafdf3f69f05bfd370732eaf954012f0044aa013fc9c6\",\n    \"0xb982efd3f34b47df37c910148ac56a84e8116647bea24145a49e34e0a6c0176e3284d838dae6230cb40d0be91c078b85\",\n    \"0x983f365aa09bd85df2a6a2ad8e4318996b1e27d02090755391d4486144e40d80b1fbfe1c798d626db92f52e33aa634da\",\n    \"0x95fd1981271f3ea3a41d654cf497e6696730d9ff7369f26bc4d7d15c7adb4823dd0c42e4a005a810af12d234065e5390\",\n    \"0xa9f5219bd4b913c186ef30c02f995a08f0f6f1462614ea5f236964e02bdaa33db9d9b816c4aee5829947840a9a07ba60\",\n    \"0x9210e6ceb05c09b46fd09d036287ca33c45124ab86315e5d6911ff89054f1101faaa3e83d123b7805056d388bcec6664\",\n    \"0x8ed9cbf69c6ff3a5c62dd9fe0d7264578c0f826a29e614bc2fb4d621d90c8c9992438accdd7a614b1dca5d1bb73dc315\",\n    \"0x85cf2a8cca93e00da459e3cecd22c342d697eee13c74d5851634844fc215f60053cf84b0e03c327cb395f48d1c71a8a4\",\n    \"0x8818a18e9a2ec90a271b784400c1903089ffb0e0b40bc5abbbe12fbebe0f731f91959d98c5519ef1694543e31e2016d4\",\n    \"0x8dabc130f296fa7a82870bf9a8405aaf542b222ed9276bba9bd3c3555a0f473acb97d655ee7280baff766a827a8993f0\",\n    \"0xac7952b84b0dc60c4d858f034093b4d322c35959605a3dad2b806af9813a4680cb038c6d7f4485b4d6b2ff502aaeca25\",\n    \"0xad65cb6d57b48a2602568d2ec8010baed0eb440eec7638c5ec8f02687d764e9de5b5d42ad5582934e592b48471c22d26\",\n    \"0xa02ab8bd4c3d114ea23aebdd880952f9495912817da8c0c08eabc4e6755439899d635034413d51134c72a6320f807f1c\",\n    \"0x8319567764b8295402ec1ebef4c2930a138480b37e6d7d01c8b4c9cd1f2fc3f6e9a44ae6e380a0c469b25b06db23305f\",\n    \"0xafec53b2301dc0caa8034cd9daef78c48905e6068d692ca23d589b84a6fa9ddc2ed24a39480597e19cb3e83eec213b3f\",\n    \"0xac0b4ffdb5ae08e586a9cdb98f9fe56f4712af3a97065e89e274feacfb52b53c839565aee93c4cfaaccfe51432c4fab0\",\n    \"0x8972cbf07a738549205b1094c5987818124144bf187bc0a85287c94fdb22ce038c0f11df1aa16ec5992e91b44d1af793\",\n    \"0xb7267aa6f9e3de864179b7da30319f1d4cb2a3560f2ea980254775963f1523b44c680f917095879bebfa3dc2b603efcf\",\n    \"0x80f68f4bfc337952e29504ee5149f15093824ea7ab02507efd1317a670f6cbc3611201848560312e3e52e9d9af72eccf\",\n    \"0x8897fee93ce8fc1e1122e46b6d640bba309384dbd92e46e185e6364aa8210ebf5f9ee7e5e604b6ffba99aa80a10dd7d0\",\n    \"0xb58ea6c02f2360be60595223d692e82ee64874fda41a9f75930f7d28586f89be34b1083e03bbc1575bbfdda2d30db1ea\",\n    \"0x85a523a33d903280d70ac5938770453a58293480170c84926457ac2df45c10d5ff34322ab130ef4a38c916e70d81af53\",\n    \"0xa2cbf045e1bed38937492c1f2f93a5ba41875f1f262291914bc1fc40c60bd0740fb3fea428faf6da38b7c180fe8ac109\",\n    \"0x8c09328770ed8eb17afc6ac7ddd87bb476de18ed63cab80027234a605806895959990c47bd10d259d7f3e2ecb50074c9\",\n    \"0xb4b9e19edb4a33bde8b7289956568a5b6b6557404e0a34584b5721fe6f564821091013fbb158e2858c6d398293bb4b59\",\n    \"0x8a47377df61733a2aa5a0e945fce00267f8e950f37e109d4487d92d878fb8b573317bb382d902de515b544e9e233458d\",\n    \"0xb5804c9d97efeff5ca94f3689b8088c62422d92a1506fd1d8d3b1b30e8a866ad0d6dad4abfa051dfc4471250cac4c5d9\",\n    \"0x9084a6ee8ec22d4881e9dcc8a9eb3c2513523d8bc141942370fd191ad2601bf9537a0b1e84316f3209b3d8a54368051e\",\n    \"0x85447eea2fa26656a649f8519fa67279183044791d61cf8563d0783d46d747d96af31d0a93507bbb2242666aa87d3720\",\n    \"0x97566a84481027b60116c751aec552adfff2d9038e68d48c4db9811fb0cbfdb3f1d91fc176a0b0d988a765f8a020bce1\",\n    \"0xae87e5c1b9e86c49a23dceda4ecfd1dcf08567f1db8e5b6ec752ebd45433c11e7da4988573cdaebbb6f4135814fc059e\",\n    \"0xabee05cf9abdbc52897ac1ce9ed157f5466ed6c383d6497de28616238d60409e5e92619e528af8b62cc552bf09970dc2\",\n    \"0xae6d31cd7bf9599e5ee0828bab00ceb4856d829bba967278a73706b5f388465367aa8a6c7da24b5e5f1fdd3256ef8e63\",\n    \"0xac33e7b1ee47e1ee4af472e37ab9e9175260e506a4e5ce449788075da1b53c44cb035f3792d1eea2aa24b1f688cc6ed3\",\n    \"0x80f65b205666b0e089bb62152251c48c380a831e5f277f11f3ef4f0d52533f0851c1b612267042802f019ec900dc0e8f\",\n    \"0x858520ad7aa1c9fed738e3b583c84168f2927837ad0e1d326afe9935c26e9b473d7f8c382e82ef1fe37d2b39bb40a1ee\",\n    \"0xb842dd4af8befe00a97c2d0f0c33c93974761e2cb9e5ab8331b25170318ddd5e4bdbc02d8f90cbfdd5f348f4f371c1f7\",\n    \"0x8bf2cb79bc783cb57088aae7363320cbeaabd078ffdec9d41bc74ff49e0043d0dad0086a30e5112b689fd2f5a606365d\",\n    \"0x982eb03bbe563e8850847cd37e6a3306d298ab08c4d63ab6334e6b8c1fa13fce80cf2693b09714c7621d74261a0ff306\",\n    \"0xb143edb113dec9f1e5105d4a93fbe502b859e587640d3db2f628c09a17060e6aec9e900e2c8c411cda99bc301ff96625\",\n    \"0xaf472d9befa750dcebc5428fe1a024f18ec1c07bca0f95643ce6b5f4189892a910285afb03fd7ed7068fbe614e80d33c\",\n    \"0xa97e3bc57ede73ecd1bbf02de8f51b4e7c1a067da68a3cd719f4ba26a0156cbf1cef2169fd35a18c5a4cced50d475998\",\n    \"0xa862253c937cf3d75d7183e5f5be6a4385d526aeda5171c1c60a8381fea79f88f5f52a4fab244ecc70765d5765e6dfd5\",\n    \"0x90cb776f8e5a108f1719df4a355bebb04bf023349356382cae55991b31720f0fd03206b895fa10c56c98f52453be8778\",\n    \"0xa7614e8d0769dccd520ea4b46f7646e12489951efaef5176bc889e9eb65f6e31758df136b5bf1e9107e68472fa9b46ec\",\n    \"0xac3a9b80a3254c42e5ed3a090a0dd7aee2352f480de96ad187027a3bb6c791eddfc3074b6ffd74eea825188f107cda4d\",\n    \"0x82a01d0168238ef04180d4b6e0a0e39024c02c2d75b065017c2928039e154d093e1af4503f4d1f3d8a948917abb5d09f\",\n    \"0x8fab000a2b0eef851a483aec8d2dd85fe60504794411a2f73ed82e116960547ac58766cb73df71aea71079302630258d\",\n    \"0x872451a35c6db61c63e9b8bb9f16b217f985c20be4451c14282c814adb29d7fb13f201367c664435c7f1d4d9375d7a58\",\n    \"0x887d9ff54cc96b35d562df4a537ff972d7c4b3fd91ab06354969a4cfede0b9fc68bbffb61d0dbf1a58948dc701e54f5a\",\n    \"0x8cb5c2a6bd956875d88f41ae24574434f1308514d44057b55c9c70f13a3366ed054150eed0955a38fda3f757be73d55f\",\n    \"0x89ad0163cad93e24129d63f8e38422b7674632a8d0a9016ee8636184cab177659a676c4ee7efba3abe1a68807c656d60\",\n    \"0xb9ec01c7cab6d00359b5a0b4a1573467d09476e05ca51a9227cd16b589a9943d161eef62dcc73f0de2ec504d81f4d252\",\n    \"0x8031d17635d39dfe9705c485d2c94830b6fc9bc67b91300d9d2591b51e36a782e77ab5904662effa9382d9cca201f525\",\n    \"0x8be5a5f6bc8d680e5092d6f9a6585acbaaaa2ddc671da560dcf5cfa4472f4f184b9597b5b539438accd40dda885687cc\",\n    \"0xb1fc0f052fae038a2e3de3b3a96b0a1024b009de8457b8b3adb2d315ae68a89af905720108a30038e5ab8d0d97087785\",\n    \"0x8b8bdc77bd3a6bc7ca5492b6f8c614852c39a70d6c8a74916eaca0aeb4533b11898b8820a4c2620a97bf35e275480029\",\n    \"0xaf35f4dc538d4ad5cdf710caa38fd1eb496c3fa890a047b6a659619c5ad3054158371d1e88e0894428282eed9f47f76b\",\n    \"0x8166454a7089cc07758ad78724654f4e7a1a13e305bbf88ddb86f1a4b2904c4fc8ab872d7da364cdd6a6c0365239e2ad\",\n    \"0xab287c7d3addce74ce40491871c768abe01daaa0833481276ff2e56926b38a7c6d2681ffe837d2cc323045ad1a4414f9\",\n    \"0xb90317f4505793094d89365beb35537f55a6b5618904236258dd04ca61f21476837624a2f45fef8168acf732cab65579\",\n    \"0x98ae5ea27448e236b6657ab5ef7b1cccb5372f92ab25f5fa651fbac97d08353a1dae1b280b1cd42b17d2c6a70a63ab9d\",\n    \"0xadcf54e752d32cbaa6cb98fbca48d8cd087b1db1d131d465705a0d8042c8393c8f4d26b59006eb50129b21e6240f0c06\",\n    \"0xb591a3e4db18a7345fa935a8dd7994bbac5cc270b8ebd84c8304c44484c7a74afb45471fdbe4ab22156a30fae1149b40\",\n    \"0x806b53ac049a42f1dcc1d6335505371da0bf27c614f441b03bbf2e356be7b2fb4eed7117eabcce9e427a542eaa2bf7d8\",\n    \"0x800482e7a772d49210b81c4a907f5ce97f270b959e745621ee293cf8c71e8989363d61f66a98f2d16914439544ca84c7\",\n    \"0x99de9eafdad3617445312341644f2bb888680ff01ce95ca9276b1d2e5ef83fa02dab5e948ebf66c17df0752f1bd37b70\",\n    \"0x961ee30810aa4c93ae157fbe9009b8e443c082192bd36a73a6764ff9b2ad8b0948fe9a73344556e01399dd77badb4257\",\n    \"0xae0a361067c52efbe56c8adf982c00432cd478929459fc7f74052c8ee9531cd031fe1335418fde53f7c2ef34254eb7ac\",\n    \"0xa3503d16b6b27eb20c1b177bcf90d13706169220523a6271b85b2ce35a9a2b9c5bed088540031c0a4ebfdae3a4c6ab04\",\n    \"0x909420122c3e723289ca4e7b81c2df5aff312972a2203f4c45821b176e7c862bf9cac7f7df3adf1d59278f02694d06e7\",\n    \"0x989f42380ae904b982f85d0c6186c1aef5d6bcba29bcfbb658e811b587eb2749c65c6e4a8cc6409c229a107499a4f5d7\",\n    \"0x8037a6337195c8e26a27ea4ef218c6e7d79a9720aaab43932d343192abc2320fe72955f5e431c109093bda074103330a\",\n    \"0xb312e168663842099b88445e940249cc508f080ab0c94331f672e7760258dbd86be5267e4cf25ea25facb80bff82a7e9\",\n    \"0xaaa3ff8639496864fcdbfdda1ac97edc4f08e3c9288b768f6c8073038c9fbbf7e1c4bea169b4d45c31935cdf0680d45e\",\n    \"0x97dbd3df37f0b481a311dfc5f40e59227720f367912200d71908ef6650f32cc985cb05b981e3eea38958f7e48d10a15d\",\n    \"0xa89d49d1e267bb452d6cb621b9a90826fe55e9b489c0427b94442d02a16f390eed758e209991687f73f6b5a032321f42\",\n    \"0x9530dea4e0e19d6496f536f2e75cf7d814d65fde567055eb20db48fd8d20d501cd2a22fb506db566b94c9ee10f413d43\",\n    \"0x81a7009b9e67f1965fa7da6a57591c307de91bf0cd35ab4348dc4a98a4961e096d004d7e7ad318000011dc4342c1b809\",\n    \"0x83440a9402b766045d7aca61a58bba2aa29cac1cf718199e472ba086f5d48093d9dda4d135292ba51d049a23964eceae\",\n    \"0xa06c9ce5e802df14f6b064a3d1a0735d429b452f0e2e276042800b0a4f16df988fd94cf3945921d5dd3802ab2636f867\",\n    \"0xb1359e358b89936dee9e678a187aad3e9ab14ac40e96a0a68f70ee2583cdcf467ae03bef4215e92893f4e12f902adec8\",\n    \"0x835304f8619188b4d14674d803103d5a3fa594d48e96d9699e653115dd05fdc2dda6ba3641cf7ad53994d448da155f02\",\n    \"0x8327cba5a9ff0d3f5cd0ae55e77167448926d5fcf76550c0ad978092a14122723090c51c415e88e42a2b62eb07cc3981\",\n    \"0xb373dcdaea85f85ce9978b1426a7ef4945f65f2d3467a9f1cc551a99766aac95df4a09e2251d3f89ca8c9d1a7cfd7b0e\",\n    \"0xab1422dc41af2a227b973a6fd124dfcb2367e2a11a21faa1d381d404f51b7257e5bc82e9cf20cd7fe37d7ae761a2ab37\",\n    \"0xa93774a03519d2f20fdf2ef46547b0a5b77c137d6a3434b48d56a2cbef9e77120d1b85d0092cf8842909213826699477\",\n    \"0x8eb967a495a38130ea28711580b7e61bcd1d051cd9e4f2dbf62f1380bd86e0d60e978d72f6f31e909eb97b3b9a2b867c\",\n    \"0xae8213378da1287ba1fe4242e1acaec19b877b6fe872400013c6eac1084b8d03156792fa3020201725b08228a1e80f49\",\n    \"0xb143daf6893d674d607772b3b02d8ac48f294237e2f2c87963c0d4e26d9227d94a2a13512457c3d5883544bbc259f0ef\",\n    \"0xb343bd2aca8973888e42542218924e2dda2e938fd1150d06878af76f777546213912b7c7a34a0f94186817d80ffa185c\",\n    \"0xb188ebc6a8c3007001aa347ae72cc0b15d09bc6c19a80e386ee4b334734ec0cc2fe8b493c2422f38d1e6d133cc3db6fe\",\n    \"0xb795f6a8b9b826aaeee18ccd6baf6c5adeeec85f95eb5b6d19450085ec7217e95a2d9e221d77f583b297d0872073ba0e\",\n    \"0xb1c7dbd998ad32ae57bfa95deafa147024afd57389e98992c36b6e52df915d3d5a39db585141ec2423173e85d212fed8\",\n    \"0x812bcdeb9fe5f12d0e1df9964798056e1f1c3de3b17b6bd2919b6356c4b86d8e763c01933efbe0224c86a96d5198a4be\",\n    \"0xb19ebeda61c23d255cbf472ef0b8a441f4c55b70f0d8ed47078c248b1d3c7c62e076b43b95c00a958ec8b16d5a7cb0d7\",\n    \"0xb02adc9aaa20e0368a989c2af14ff48b67233d28ebee44ff3418bb0473592e6b681af1cc45450bd4b175df9051df63d9\",\n    \"0x8d87f0714acee522eb58cec00360e762adc411901dba46adc9227124fa70ee679f9a47e91a6306d6030dd4eb8de2f3c1\",\n    \"0x8be54cec21e74bcc71de29dc621444263737db15f16d0bb13670f64e42f818154e04b484593d19ef95f2ee17e4b3fe21\",\n    \"0xab8e20546c1db38d31493b5d5f535758afb17e459645c1b70813b1cf7d242fd5d1f4354a7c929e8f7259f6a25302e351\",\n    \"0x89f035a1ed8a1e302ac893349ba8ddf967580fcb6e73d44af09e3929cde445e97ff60c87dafe489e2c0ab9c9986cfa00\",\n    \"0x8b2b0851a795c19191a692af55f7e72ad2474efdc5401bc3733cfdd910e34c918aaebe69d5ea951bdddf3c01cabbfc67\",\n    \"0xa4edb52c2b51495ccd1ee6450fc14b7b3ede8b3d106808929d02fb31475bacb403e112ba9c818d2857651e508b3a7dd1\",\n    \"0x9569341fded45d19f00bcf3cbf3f20eb2b4d82ef92aba3c8abd95866398438a2387437e580d8b646f17cf6fde8c5af23\",\n    \"0xaa4b671c6d20f72f2f18a939a6ff21cc37e0084b44b4a717f1be859a80b39fb1be026b3205adec2a66a608ec2bcd578f\",\n    \"0x94902e980de23c4de394ad8aec91b46f888d18f045753541492bfbb92c59d3daa8de37ae755a6853744af8472ba7b72b\",\n    \"0xaf651ef1b2a0d30a7884557edfad95b6b5d445a7561caebdc46a485aedd25932c62c0798465c340a76f6feaa196dd712\",\n    \"0xb7b669b8e5a763452128846dd46b530dca4893ace5cc5881c7ddcd3d45969d7e73fbebdb0e78aa81686e5f7b22ec5759\",\n    \"0x82507fd4ebe9fa656a7f2e084d64a1fa6777a2b0bc106d686e2d9d2edafc58997e58cb6bfd0453b2bf415704aa82ae62\",\n    \"0xb40bce2b42b88678400ecd52955bbdadd15f8b9e1b3751a1a3375dc0efb5ca3ee258cf201e1140b3c09ad41217d1d49e\",\n    \"0xb0210d0cbb3fbf3b8cdb39e862f036b0ff941cd838e7aaf3a8354e24246e64778d22f3de34572e6b2a580614fb6425be\",\n    \"0x876693cba4301b251523c7d034108831df3ce133d8be5a514e7a2ca494c268ca0556fa2ad8310a1d92a16b55bcd99ea9\",\n    \"0x8660281406d22a4950f5ef050bf71dd3090edb16eff27fa29ef600cdea628315e2054211ed2cc6eaf8f2a1771ef689fd\",\n    \"0xa610e7e41e41ab66955b809ba4ade0330b8e9057d8efc9144753caed81995edeb1a42a53f93ce93540feca1fae708dac\",\n    \"0xa49e2c176a350251daef1218efaccc07a1e06203386ede59c136699d25ca5cb2ac1b800c25b28dd05678f14e78e51891\",\n    \"0x83e0915aa2b09359604566080d411874af8c993beba97d4547782fdbe1a68e59324b800ff1f07b8db30c71adcbd102a8\",\n    \"0xa19e84e3541fb6498e9bb8a099c495cbfcad113330e0262a7e4c6544495bb8a754b2208d0c2d895c93463558013a5a32\",\n    \"0x87f2bd49859a364912023aca7b19a592c60214b8d6239e2be887ae80b69ebdeb59742bdebcfa73a586ab23b2c945586c\",\n    \"0xb8e8fdddae934a14b57bc274b8dcd0d45ebb95ddbaabef4454e0f6ce7d3a5a61c86181929546b3d60c447a15134d08e1\",\n    \"0x87e0c31dcb736ea4604727e92dc1d9a3cf00adcff79df3546e02108355260f3dd171531c3c0f57be78d8b28058fcc8c0\",\n    \"0x9617d74e8f808a4165a8ac2e30878c349e1c3d40972006f0787b31ea62d248c2d9f3fc3da83181c6e57e95feedfd0e8c\",\n    \"0x8949e2cee582a2f8db86e89785a6e46bc1565c2d8627d5b6bf43ba71ffadfab7e3c5710f88dcb5fb2fc6edf6f4fae216\",\n    \"0xad3fa7b0edceb83118972a2935a09f409d09a8db3869f30be3a76f67aa9fb379cabb3a3aff805ba023a331cad7d7eb64\",\n    \"0x8c95718a4112512c4efbd496be38bf3ca6cdcaad8a0d128f32a3f9aae57f3a57bdf295a3b372a8c549fda8f4707cffed\",\n    \"0x88f3261d1e28a58b2dee3fcc799777ad1c0eb68b3560f9b4410d134672d9533532a91ea7be28a041784872632d3c9d80\",\n    \"0xb47472a41d72dd2e8b72f5c4f8ad626737dde3717f63d6bc776639ab299e564cbad0a2ad5452a07f02ff49a359c437e5\",\n    \"0x9896d21dc2e8aad87b76d6df1654f10cd7bceed4884159d50a818bea391f8e473e01e14684814c7780235f28e69dca6e\",\n    \"0x82d47c332bbd31bbe83b5eb44a23da76d4a7a06c45d7f80f395035822bc27f62f59281d5174e6f8e77cc9b5c3193d6f0\",\n    \"0x95c74cd46206e7f70c9766117c34c0ec45c2b0f927a15ea167901a160e1530d8522943c29b61e03568aa0f9c55926c53\",\n    \"0xa89d7757825ae73a6e81829ff788ea7b3d7409857b378ebccd7df73fdbe62c8d9073741cf038314971b39af6c29c9030\",\n    \"0x8c1cd212d0b010905d560688cfc036ae6535bc334fa8b812519d810b7e7dcf1bb7c5f43deaa40f097158358987324a7f\",\n    \"0xb86993c383c015ed8d847c6b795164114dd3e9efd25143f509da318bfba89389ea72a420699e339423afd68b6512fafb\",\n    \"0x8d06bd379c6d87c6ed841d8c6e9d2d0de21653a073725ff74be1934301cc3a79b81ef6dd0aad4e7a9dc6eac9b73019bc\",\n    \"0x81af4d2d87219985b9b1202d724fe39ef988f14fef07dfe3c3b11714e90ffba2a97250838e8535eb63f107abfe645e96\",\n    \"0x8c5e0af6330a8becb787e4b502f34f528ef5756e298a77dc0c7467433454347f3a2e0bd2641fbc2a45b95e231c6e1c02\",\n    \"0x8e2a8f0f04562820dc8e7da681d5cad9fe2e85dd11c785fb6fba6786c57a857e0b3bd838fb849b0376c34ce1665e4837\",\n    \"0xa39be8269449bfdfc61b1f62077033649f18dae9bef7c6163b9314ca8923691fb832f42776f0160b9e8abd4d143aa4e1\",\n    \"0x8c154e665706355e1cc98e0a4cabf294ab019545ba9c4c399d666e6ec5c869ca9e1faf8fb06cd9c0a5c2f51a7d51b70a\",\n    \"0xa046a7d4de879d3ebd4284f08f24398e9e3bf006cd4e25b5c67273ade248689c69affff92ae810c07941e4904296a563\",\n    \"0xafd94c1cb48758e5917804df03fb38a6da0e48cd9b6262413ea13b26973f9e266690a1b7d9d24bbaf7e82718e0e594b0\",\n    \"0x859e21080310c8d6a38e12e2ac9f90a156578cdeb4bb2e324700e97d9a5511cd6045dc39d1d0de3f94aeed043a24119d\",\n    \"0xa219fb0303c379d0ab50893264919f598e753aac9065e1f23ef2949abc992577ab43c636a1d2c089203ec9ddb941e27d\",\n    \"0xb0fdb639d449588a2ca730afcba59334e7c387342d56defdfb7ef79c493f7fd0e5277eff18e7203e756c7bdda5803047\",\n    \"0x87f9c3b7ed01f54368aca6dbcf2f6e06bff96e183c4b2c65f8baa23b377988863a0a125d5cdd41a072da8462ced4c070\",\n    \"0x99ef7a5d5ac2f1c567160e1f8c95f2f38d41881850f30c461a205f7b1b9fb181277311333839b13fb3ae203447e17727\",\n    \"0xaeaca9b1c2afd24e443326cc68de67b4d9cedb22ad7b501a799d30d39c85bb2ea910d4672673e39e154d699e12d9b3dc\",\n    \"0xa11675a1721a4ba24dd3d0e4c3c33a6edf4cd1b9f6b471070b4386c61f77452266eae6e3f566a40cfc885eada9a29f23\",\n    \"0xb228334445e37b9b49cb4f2cc56b454575e92173ddb01370a553bba665adadd52df353ad74470d512561c2c3473c7bb9\",\n    \"0xa18177087c996572d76f81178d18ed1ceebc8362a396348ce289f1d8bd708b9e99539be6fccd4acb1112381cfc5749b4\",\n    \"0x8e7b8bf460f0d3c99abb19803b9e43422e91507a1c0c22b29ee8b2c52d1a384da4b87c292e28eff040db5be7b1f8641f\",\n    \"0xb03d038d813e29688b6e6f444eb56fec3abba64c3d6f890a6bcf2e916507091cdb2b9d2c7484617be6b26552ed1c56cb\",\n    \"0xa1c88ccd30e934adfc5494b72655f8afe1865a84196abfb376968f22ddc07761210b6a9fb7638f1413d1b4073d430290\",\n    \"0x961b714faebf172ad2dbc11902461e286e4f24a99a939152a53406117767682a571057044decbeb3d3feef81f4488497\",\n    \"0xa03dc4059b46effdd786a0a03cc17cfee8585683faa35bb07936ded3fa3f3a097f518c0b8e2db92fd700149db1937789\",\n    \"0xadf60180c99ca574191cbcc23e8d025b2f931f98ca7dfcebfc380226239b6329347100fcb8b0fcb12db108c6ad101c07\",\n    \"0x805d4f5ef24d46911cbf942f62cb84b0346e5e712284f82b0db223db26d51aabf43204755eb19519b00e665c7719fcaa\",\n    \"0x8dea7243e9c139662a7fe3526c6c601eee72fd8847c54c8e1f2ad93ef7f9e1826b170afe58817dac212427164a88e87f\",\n    \"0xa2ba42356606d651b077983de1ad643650997bb2babb188c9a3b27245bb65d2036e46667c37d4ce02cb1be5ae8547abe\",\n    \"0xaf2ae50b392bdc013db2d12ce2544883472d72424fc767d3f5cb0ca2d973fc7d1f425880101e61970e1a988d0670c81b\",\n    \"0x98e6bec0568d3939b31d00eb1040e9b8b2a35db46ddf4369bdaee41bbb63cc84423d29ee510a170fb5b0e2df434ba589\",\n    \"0x822ff3cd12fbef4f508f3ca813c04a2e0b9b799c99848e5ad3563265979e753ee61a48f6adc2984a850f1b46c1a43d35\",\n    \"0x891e8b8b92a394f36653d55725ef514bd2e2a46840a0a2975c76c2a935577f85289026aaa74384da0afe26775cbddfb9\",\n    \"0xb2a3131a5d2fe7c8967047aa66e4524babae941d90552171cc109527f345f42aa0df06dcbb2fa01b33d0043917bbed69\",\n    \"0x80c869469900431f3eeefafdbe07b8afd8cee7739e659e6d0109b397cacff85a88247698f87dc4e2fe39a592f250ac64\",\n    \"0x9091594f488b38f9d2bb5df49fd8b4f8829d9c2f11a197dd1431ed5abbc5c954bbde3387088f9ee3a5a834beb7619bce\",\n    \"0xb472e241e6956146cca57b97a8a204668d050423b4e76f857bad5b47f43b203a04c8391ba9d9c3e95093c071f9d376a1\",\n    \"0xb7dd2de0284844392f7dfb56fe7ca3ede41e27519753ffc579a0a8d2d65ceb8108d06b6b0d4c3c1a2588951297bd1a1e\",\n    \"0x902116ce70d0a079ac190321c1f48701318c05f8e69ee09694754885d33a835a849cafe56f499a2f49f6cda413ddf9a7\",\n    \"0xb18105cc736787fafaf7c3c11c448bce9466e683159dff52723b7951dff429565e466e4841d982e3aaa9ee2066838666\",\n    \"0x97ab9911f3f659691762d568ae0b7faa1047b0aed1009c319fa79d15d0db8db9f808fc385dc9a68fa388c10224985379\",\n    \"0xb2a2cba65f5b927e64d2904ba412e2bac1cf18c9c3eda9c72fb70262497ecf505b640827e2afebecf10eebbcf48ccd3e\",\n    \"0xb36a3fd677baa0d3ef0dac4f1548ff50a1730286b8c99d276a0a45d576e17b39b3cbadd2fe55e003796d370d4be43ce3\",\n    \"0xa5dfec96ca3c272566e89dc453a458909247e3895d3e44831528130bc47cc9d0a0dac78dd3cad680a4351d399d241967\",\n    \"0x8029382113909af6340959c3e61db27392531d62d90f92370a432aec3eb1e4c36ae1d4ef2ba8ec6edb4d7320c7a453f6\",\n    \"0x971d85121ea108e6769d54f9c51299b0381ece8b51d46d49c89f65bedc123bab4d5a8bc14d6f67f4f680077529cbae4c\",\n    \"0x98ff6afc01d0bec80a278f25912e1b1ebff80117adae72e31d5b9fa4d9624db4ba2065b444df49b489b0607c45e26c4c\",\n    \"0x8fa29be10fb3ab30ce25920fec0187e6e91e458947009dabb869aade7136c8ba23602682b71e390c251f3743164cbdaa\",\n    \"0xb3345c89eb1653418fe3940cf3e56a9a9c66526389b98f45ca02dd62bfb37baa69a4baaa7132d7320695f8ea6ad1fd94\",\n    \"0xb72c7f5541c9ac6b60a7ec9f5415e7fb14da03f7164ea529952a29399f3a071576608dbbcc0d45994f21f92ddbeb1e19\",\n    \"0xaa3450bb155a5f9043d0ef95f546a2e6ade167280bfb75c9f09c6f9cdb1fffb7ce8181436161a538433afa3681c7a141\",\n    \"0x92a18fecaded7854b349f441e7102b638ababa75b1b0281dd0bded6541abe7aa37d96693595be0b01fe0a2e2133d50f9\",\n    \"0x980756ddf9d2253cfe6c94960b516c94889d09e612810935150892627d2ecee9a2517e04968eea295d0106850c04ca44\",\n    \"0xae68c6ccc454318cdd92f32b11d89116a3b8350207a36d22a0f626718cad671d960090e054c0c77ac3162ae180ecfd4b\",\n    \"0x99f31f66eaaa551749ad91d48a0d4e3ff4d82ef0e8b28f3184c54e852422ba1bdafd53b1e753f3a070f3b55f3c23b6a2\",\n    \"0xa44eaeaa6589206069e9c0a45ff9fc51c68da38d4edff1d15529b7932e6f403d12b9387019c44a1488a5d5f27782a51f\",\n    \"0xb80b5d54d4b344840e45b79e621bd77a3f83fb4ce6d8796b7d6915107b3f3c34d2e7d95bdafd120f285669e5acf2437a\",\n    \"0xb36c069ec085a612b5908314d6b84c00a83031780261d1c77a0384c406867c9847d5b0845deddfa512cc04a8df2046fb\",\n    \"0xb09dbe501583220f640d201acea7ee3e39bf9eda8b91aa07b5c50b7641d86d71acb619b38d27835ce97c3759787f08e9\",\n    \"0x87403d46a2bf63170fff0b857acacf42ee801afe9ccba8e5b4aea967b68eac73a499a65ca46906c2eb4c8f27bc739faa\",\n    \"0x82b93669f42a0a2aa5e250ffe6097269da06a9c02fcd1801abbad415a7729a64f830754bafc702e64600ba47671c2208\",\n    \"0x8e3a3029be7edb8dd3ab1f8216664c8dc50d395f603736061d802cef77627db7b859ef287ed850382c13b4d22d6a2d80\",\n    \"0x968e9ec7194ff424409d182ce0259acd950c384c163c04463bc8700a40b79beba6146d22b7fa7016875a249b7b31c602\",\n    \"0x8b42c984bbe4996e0c20862059167c6bdc5164b1ffcd928f29512664459212d263e89f0f0e30eed4e672ffa5ed0b01b5\",\n    \"0x96bac54062110dada905363211133f1f15dc7e4fd80a4c6e4a83bc9a0bcbbaba11cd2c7a13debcf0985e1a954c1da66b\",\n    \"0xa16dc8a653d67a7cd7ae90b2fffac0bf1ca587005430fe5ba9403edd70ca33e38ba5661d2ed6e9d2864400d997626a62\",\n    \"0xa68ab11a570a27853c8d67e491591dcba746bfbee08a2e75ae0790399130d027ed387f41ef1d7de8df38b472df309161\",\n    \"0x92532b74886874447c0300d07eda9bbe4b41ed25349a3da2e072a93fe32c89d280f740d8ff70d5816793d7f2b97373cc\",\n    \"0x88e35711b471e89218fd5f4d0eadea8a29405af1cd81974427bc4a5fb26ed60798daaf94f726c96e779b403a2cd82820\",\n    \"0xb5c72aa4147c19f8c4f3a0a62d32315b0f4606e0a7025edc5445571eaf4daff64f4b7a585464821574dd50dbe1b49d08\",\n    \"0x9305d9b4095258e79744338683fd93f9e657367b3ab32d78080e51d54eec331edbc224fad5093ebf8ee4bd4286757eb8\",\n    \"0xb2a17abb3f6a05bcb14dc7b98321fa8b46d299626c73d7c6eb12140bf4c3f8e1795250870947af817834f033c88a59d6\",\n    \"0xb3477004837dbd8ba594e4296f960fc91ab3f13551458445e6c232eb04b326da803c4d93e2e8dcd268b4413305ff84da\",\n    \"0x924b4b2ebaafdcfdfedb2829a8bf46cd32e1407d8d725a5bd28bdc821f1bafb3614f030ea4352c671076a63494275a3f\",\n    \"0x8b81b9ef6125c82a9bece6fdcb9888a767ac16e70527753428cc87c56a1236e437da8be4f7ecfe57b9296dc3ae7ba807\",\n    \"0x906e19ec8b8edd58bdf9ae05610a86e4ea2282b1bbc1e8b00b7021d093194e0837d74cf27ac9916bdb8ec308b00da3da\",\n    \"0xb41c5185869071760ac786078a57a2ab4e2af60a890037ac0c0c28d6826f15c2cf028fddd42a9b6de632c3d550bfbc14\",\n    \"0xa646e5dec1b713ae9dfdf7bdc6cd474d5731a320403c7dfcfd666ffc9ae0cff4b5a79530e8df3f4aa9cb80568cb138e9\",\n    \"0xb0efad22827e562bd3c3e925acbd0d9425d19057868608d78c2209a531cccd0f2c43dc5673acf9822247428ffa2bb821\",\n    \"0xa94c19468d14b6f99002fc52ac06bbe59e5c472e4a0cdb225144a62f8870b3f10593749df7a2de0bd3c9476ce682e148\",\n    \"0x803864a91162f0273d49271dafaab632d93d494d1af935aefa522768af058fce52165018512e8d6774976d52bd797e22\",\n    \"0xa08711c2f7d45c68fb340ac23597332e1bcaec9198f72967b9921204b9d48a7843561ff318f87908c05a44fc35e3cc9d\",\n    \"0x91c3cad94a11a3197ae4f9461faab91a669e0dddb0371d3cab3ed9aeb1267badc797d8375181130e461eadd05099b2a2\",\n    \"0x81bdaaf48aae4f7b480fc13f1e7f4dd3023a41439ba231760409ce9292c11128ab2b0bdbbf28b98af4f97b3551f363af\",\n    \"0x8d60f9df9fd303f625af90e8272c4ecb95bb94e6efc5da17b8ab663ee3b3f673e9f6420d890ccc94acf4d2cae7a860d8\",\n    \"0xa7b75901520c06e9495ab983f70b61483504c7ff2a0980c51115d11e0744683ce022d76e3e09f4e99e698cbd21432a0d\",\n    \"0x82956072df0586562fda7e7738226f694e1c73518dd86e0799d2e820d7f79233667192c9236dcb27637e4c65ef19d493\",\n    \"0xa586beb9b6ffd06ad200957490803a7cd8c9bf76e782734e0f55e04a3dc38949de75dc607822ec405736c576cf83bca3\",\n    \"0xa179a30d00def9b34a7e85607a447eea0401e32ab5abeee1a281f2acd1cf6ec81a178020666f641d9492b1bdf66f05a3\",\n    \"0x83e129705c538787ed8e0fdc1275e6466a3f4ee21a1e6abedd239393b1df72244723b92f9d9d9339a0cab6ebf28f5a16\",\n    \"0x811bd8d1e3722b64cd2f5b431167e7f91456e8bba2cc669d3fbbce7d553e29c3c19f629fcedd2498bc26d33a24891d17\",\n    \"0xa243c030c858f1f60cccd26b45b024698cc6d9d9e6198c1ed4964a235d9f8d0baf9cde10c8e63dfaa47f8e74e51a6e85\",\n    \"0xab839eb82e23ca52663281f863b55b0a3d6d4425c33ffb4eeb1d7979488ab068bf99e2a60e82cea4dc42c56c26cbfebe\",\n    \"0x8b896f9bb21d49343e67aec6ad175b58c0c81a3ca73d44d113ae4354a0065d98eb1a5cafedaf232a2bb9cdc62152f309\",\n    \"0xaf6230340cc0b66f5bf845540ed4fc3e7d6077f361d60762e488d57834c3e7eb7eacc1b0ed73a7d134f174a01410e50c\",\n    \"0x88975e1b1af678d1b5179f72300a30900736af580dd748fd9461ef7afccc91ccd9bed33f9da55c8711a7635b800e831f\",\n    \"0xa97486bb9047391661718a54b8dd5a5e363964e495eae6c692730264478c927cf3e66dd3602413189a3699fbeae26e15\",\n    \"0xa5973c161ab38732885d1d2785fd74bf156ba34881980cba27fe239caef06b24a533ffe6dbbbeca5e6566682cc00300a\",\n    \"0xa24776e9a840afda0003fa73b415d5bd6ecd9b5c2cc842b643ee51b8c6087f4eead4d0bfbd987eb174c489a7b952ff2a\",\n    \"0xa8a6ee06e3af053b705a12b59777267c546f33ba8a0f49493af8e6df4e15cf8dd2d4fb4daf7e84c6b5d3a7363118ff03\",\n    \"0xa28e59ce6ad02c2ce725067c0123117e12ac5a52c8f5af13eec75f4a9efc4f696777db18a374fa33bcae82e0734ebd16\",\n    \"0x86dfc3b78e841c708aff677baa8ee654c808e5d257158715097c1025d46ece94993efe12c9d188252ad98a1e0e331fec\",\n    \"0xa88d0275510f242eab11fdb0410ff6e1b9d7a3cbd3658333539815f1b450a84816e6613d15aa8a8eb15d87cdad4b27a2\",\n    \"0x8440acea2931118a5b481268ff9f180ee4ede85d14a52c026adc882410825b8275caa44aff0b50c2b88d39f21b1a0696\",\n    \"0xa7c3182eab25bd6785bacf12079d0afb0a9b165d6ed327814e2177148539f249eb9b5b2554538f54f3c882d37c0a8abe\",\n    \"0x85291fbe10538d7da38efdd55a7acebf03b1848428a2f664c3ce55367aece60039f4f320b1771c9c89a35941797f717c\",\n    \"0xa2c6414eeb1234728ab0de94aa98fc06433a58efa646ca3fcbd97dbfb8d98ae59f7ce6d528f669c8149e1e13266f69c9\",\n    \"0x840c8462785591ee93aee2538d9f1ec44ba2ca61a569ab51d335ac873f5d48099ae8d7a7efa0725d9ff8f9475bfa4f56\",\n    \"0xa7065a9d02fb3673acf7702a488fbc01aa69580964932f6f40b6c2d1c386b19e50b0e104fcac24ea26c4e723611d0238\",\n    \"0xb72db6d141267438279e032c95e6106c2ccb3164b842ba857a2018f3a35f4b040da92680881eb17cd61d0920d5b8f006\",\n    \"0xa8005d6c5960e090374747307ef0be2871a7a43fa4e76a16c35d2baab808e9777b496e9f57a4218b23390887c33a0b55\",\n    \"0x8e152cea1e00a451ca47c20a1e8875873419700af15a5f38ee2268d3fbc974d4bd5f4be38008fa6f404dbdedd6e6e710\",\n    \"0xa3391aed1fcd68761f06a7d1008ec62a09b1cb3d0203cd04e300a0c91adfed1812d8bc1e4a3fd7976dc0aae0e99f52f1\",\n    \"0x967eb57bf2aa503ee0c6e67438098149eac305089c155f1762cf5e84e31f0fbf27c34a9af05621e34645c1ec96afaec8\",\n    \"0x88af97ddc4937a95ec0dcd25e4173127260f91c8db2f6eac84afb789b363705fb3196235af631c70cafd09411d233589\",\n    \"0xa32df75b3f2c921b8767638fd289bcfc61e08597170186637a7128ffedd52c798c434485ac2c7de07014f9e895c2c3d8\",\n    \"0xb0a783832153650aa0d766a3a73ec208b6ce5caeb40b87177ffc035ab03c7705ecdd1090b6456a29f5fb7e90e2fa8930\",\n    \"0xb59c8e803b4c3486777d15fc2311b97f9ded1602fa570c7b0200bada36a49ee9ef4d4c1474265af8e1c38a93eb66b18b\",\n    \"0x982f2c85f83e852022998ff91bafbb6ff093ef22cf9d5063e083a48b29175ccbd51b9c6557151409e439096300981a6c\",\n    \"0x939e3b5989fefebb9d272a954659a4eb125b98c9da6953f5e628d26266bd0525ec38304b8d56f08d65abc4d6da4a8dbb\",\n    \"0x8898212fe05bc8de7d18503cb84a1c1337cc2c09d1eeef2b475aa79185b7322bf1f8e065f1bf871c0c927dd19faf1f6d\",\n    \"0x94b0393a41cd00f724aee2d4bc72103d626a5aecb4b5486dd1ef8ac27528398edf56df9db5c3d238d8579af368afeb09\",\n    \"0x96ac564450d998e7445dd2ea8e3fc7974d575508fa19e1c60c308d83b645864c029f2f6b7396d4ff4c1b24e92e3bac37\",\n    \"0x8adf6638e18aff3eb3b47617da696eb6c4bdfbecbbc3c45d3d0ab0b12cbad00e462fdfbe0c35780d21aa973fc150285e\",\n    \"0xb53f94612f818571b5565bbb295e74bada9b5f9794b3b91125915e44d6ddcc4da25510eab718e251a09c99534d6042d9\",\n    \"0x8b96462508d77ee083c376cd90807aebad8de96bca43983c84a4a6f196d5faf6619a2351f43bfeec101864c3bf255519\",\n    \"0xaeadf34657083fc71df33bd44af73bf5281c9ca6d906b9c745536e1819ea90b56107c55e2178ebad08f3ba75b3f81c86\",\n    \"0x9784ba29b2f0057b5af1d3ab2796d439b8753f1f749c73e791037461bdfc3f7097394283105b8ab01788ea5255a96710\",\n    \"0x8756241bda159d4a33bf74faba0d4594d963c370fb6a18431f279b4a865b070b0547a6d1613cf45b8cfb5f9236bbf831\",\n    \"0xb03ebfd6b71421dfd49a30460f9f57063eebfe31b9ceaa2a05c37c61522b35bdc09d7db3ad75c76c253c00ba282d3cd2\",\n    \"0xb34e7e6341fa9d854b2d3153bdda0c4ae2b2f442ab7af6f99a0975d45725aa48e36ae5f7011edd249862e91f499687d4\",\n    \"0xb462ee09dc3963a14354244313e3444de5cc37ea5ccfbf14cd9aca8027b59c4cb2a949bc30474497cab8123e768460e6\",\n    \"0xaea753290e51e2f6a21a9a0ee67d3a2713f95c2a5c17fe41116c87d3aa77b1683761264d704df1ac34f8b873bc88ef7b\",\n    \"0x98430592afd414394f98ddfff9f280fcb1c322dbe3510f45e1e9c4bb8ee306b3e0cf0282c0ee73ebb8ba087d4d9e0858\",\n    \"0xb95d3b5aaf54ffca11f4be8d57f76e14afdb20afc859dc7c7471e0b42031e8f3d461b726ecb979bdb2f353498dfe95ea\",\n    \"0x984d17f9b11a683132e0b5a9ee5945e3ff7054c2d5c716be73b29078db1d36f54c6e652fd2f52a19da313112e97ade07\",\n    \"0xab232f756b3fff3262be418a1af61a7e0c95ceebbc775389622a8e10610508cd6784ab7960441917a83cc191c58829ea\",\n    \"0xa28f41678d6e60de76b0e36ab10e4516e53e02e9c77d2b5af3cfeee3ce94cfa30c5797bd1daab20c98e1cad83ad0f633\",\n    \"0xb55395fca84dd3ccc05dd480cb9b430bf8631ff06e24cb51d54519703d667268c2f8afcde4ba4ed16bece8cc7bc8c6e0\",\n    \"0x8a8a5392a0e2ea3c7a8c51328fab11156004e84a9c63483b64e8f8ebf18a58b6ffa8fe8b9d95af0a2f655f601d096396\",\n    \"0xab480000fe194d23f08a7a9ec1c392334e9c687e06851f083845121ce502c06b54dda8c43092bcc1035df45cc752fe9b\",\n    \"0xb265644c29f628d1c7e8e25a5e845cabb21799371814730a41a363e1bda8a7be50fee7c3996a365b7fcba4642add10db\",\n    \"0xb8a915a3c685c2d4728f6931c4d29487cad764c5ce23c25e64b1a3259ac27235e41b23bfe7ae982921b4cb84463097df\",\n    \"0x8efa7338442a4b6318145a5440fc213b97869647eeae41b9aa3c0a27ee51285b73e3ae3b4a9423df255e6add58864aa9\",\n    \"0x9106d65444f74d217f4187dfc8fcf3810b916d1e4275f94f6a86d1c4f3565b131fd6cde1fa708bc05fe183c49f14941a\",\n    \"0x948252dac8026bbbdb0a06b3c9d66ec4cf9532163bab68076fda1bd2357b69e4b514729c15aaa83b5618b1977bbc60c4\",\n    \"0xae6596ccfdf5cbbc5782efe3bb0b101bb132dbe1d568854ca24cacc0b2e0e9fabcb2ca7ab42aecec412efd15cf8cb7a2\",\n    \"0x84a0b6c198ff64fd7958dfd1b40eac9638e8e0b2c4cd8cf5d8cdf80419baee76a05184bce6c5b635f6bf2d30055476a7\",\n    \"0x8893118be4a055c2b3da593dbca51b1ae2ea2469911acfb27ee42faf3e6c3ad0693d3914c508c0b05b36a88c8b312b76\",\n    \"0xb097479e967504deb6734785db7e60d1d8034d6ca5ba9552887e937f5e17bb413fccac2c1d1082154ed76609127860ad\",\n    \"0xa0294e6b9958f244d29943debf24b00b538b3da1116269b6e452bb12dc742226712fd1a15b9c88195afeb5d2415f505c\",\n    \"0xb3cc15f635080bc038f61b615f62b5b5c6f2870586191f59476e8368a73641d6ac2f7d0c1f54621982defdb318020230\",\n    \"0x99856f49b9fe1604d917c94d09cc0ed753d13d015d30587a94e6631ffd964b214e607deb8a69a8b5e349a7edf4309206\",\n    \"0xa8571e113ea22b4b4fce41a094da8c70de37830ae32e62c65c2fa5ad06a9bc29e884b945e73d448c72b176d6ecebfb58\",\n    \"0xa9e9c6e52beb0013273c29844956b3ce291023678107cdc785f7b44eff5003462841ad8780761b86aefc6b734adde7cf\",\n    \"0x80a784b0b27edb51ef2bad3aee80e51778dcaa0f3f5d3dcb5dc5d4f4b2cf7ae35b08de6680ea9dac53f8438b92eb09ef\",\n    \"0x827b543e609ea328e97e373f70ad72d4915a2d1daae0c60d44ac637231070e164c43a2a58db80a64df1c624a042b38f9\",\n    \"0xb449c65e8195202efdcb9bdb4e869a437313b118fef8b510cbbf8b79a4e99376adb749b37e9c20b51b31ed3310169e27\",\n    \"0x8ea3028f4548a79a94c717e1ed28ad4d8725b8d6ab18b021063ce46f665c79da3c49440c6577319dab2d036b7e08f387\",\n    \"0x897798431cfb17fe39f08f5f854005dc37b1c1ec1edba6c24bc8acb3b88838d0534a75475325a5ea98b326ad47dbad75\",\n    \"0x89cf232e6303b0751561960fd4dea5754a28c594daf930326b4541274ffb03c7dd75938e411eb9a375006a70ce38097f\",\n    \"0x9727c6ae7f0840f0b6c8bfb3a1a5582ceee705e0b5c59b97def7a7a2283edd4d3f47b7971e902a3a2079e40b53ff69b8\",\n    \"0xb76ed72b122c48679d221072efc0eeea063cb205cbf5f9ef0101fd10cb1075b8628166c83577cced654e1c001c7882f7\",\n    \"0xae908c42d208759da5ee9b405df85a6532ea35c6f0f6a1288d22870f59d98edc896841b8ac890a538e6c8d1e8b02d359\",\n    \"0x809d12fe4039a0ec80dc9be6a89acaab7797e5f7f9b163378f52f9a75a1d73b2e9ae6e3dd49e32ced439783c1cabbef5\",\n    \"0xa4149530b7f85d1098ba534d69548c6c612c416e8d35992fc1f64f4deeb41e09e49c6cf7aadbed7e846b91299358fe2d\",\n    \"0xa49342eacd1ec1148b8df1e253b1c015f603c39de11fa0a364ccb86ea32d69c34fd7aa6980a1fadcd8e785a57fa46f60\",\n    \"0x87d43eff5a006dc4dddcf76cc96c656a1f3a68f19f124181feab86c6cc9a52cb9189cdbb423414defdd9bb0ca8ff1ddc\",\n    \"0x861367e87a9aa2f0f68296ba50aa5dbc5713008d260cc2c7e62d407c2063064749324c4e8156dc21b749656cfebce26b\",\n    \"0xb5303c2f72e84e170e66ae1b0fbd51b8c7a6f27476eaf5694b64e8737d5c84b51fe90100b256465a4c4156dd873cddb0\",\n    \"0xb62849a4f891415d74f434cdc1d23c4a69074487659ca96e1762466b2b7a5d8525b056b891d0feea6fe6845cba8bc7fb\",\n    \"0x923dd9e0d6590a9307e8c4c23f13bae3306b580e297a937711a8b13e8de85e41a61462f25b7d352b682e8437bf2b4ab3\",\n    \"0x9147379860cd713cd46c94b8cdf75125d36c37517fbecf81ace9680b98ce6291cd1c3e472f84249cc3b2b445e314b1b6\",\n    \"0xa808a4f17ac21e3fb5cfef404e61fae3693ca3e688d375f99b6116779696059a146c27b06de3ac36da349b0649befd56\",\n    \"0x87787e9322e1b75e66c1f0d9ea0915722a232770930c2d2a95e9478c4b950d15ab767e30cea128f9ed65893bfc2d0743\",\n    \"0x9036a6ee2577223be105defe1081c48ea7319e112fff9110eb9f61110c319da25a6cea0464ce65e858635b079691ef1f\",\n    \"0xaf5548c7c24e1088c23b57ee14d26c12a83484c9fd9296edf1012d8dcf88243f20039b43c8c548c265ef9a1ffe9c1c88\",\n    \"0xa0fff520045e14065965fb8accd17e878d3fcaf9e0af2962c8954e50be6683d31fa0bf4816ab68f08630dbac6bfce52a\",\n    \"0xb4c1b249e079f6ae1781af1d97a60b15855f49864c50496c09c91fe1946266915b799f0406084d7783f5b1039116dd8b\",\n    \"0x8b0ffa5e7c498cb3879dddca34743b41eee8e2dea3d4317a6e961b58adb699ef0c92400c068d5228881a2b08121226bf\",\n    \"0x852ae8b19a1d80aa8ae5382e7ee5c8e7670ceb16640871c56b20b96b66b3b60e00015a3dde039446972e57b49a999ddd\",\n    \"0xa49942f04234a7d8492169da232cfff8051df86e8e1ba3db46aede02422c689c87dc1d99699c25f96cb763f5ca0983e5\",\n    \"0xb04b597b7760cf5dcf411ef896d1661e6d5b0db3257ac2cf64b20b60c6cc18fa10523bb958a48d010b55bac7b02ab3b1\",\n    \"0xa494591b51ea8285daecc194b5e5bd45ae35767d0246ac94fae204d674ee180c8e97ff15f71f28b7aeb175b8aea59710\",\n    \"0x97d2624919e78406e7460730680dea8e71c8571cf988e11441aeea54512b95bd820e78562c99372d535d96f7e200d20d\",\n    \"0xac693ddb00e48f76e667243b9b6a7008424043fb779e4f2252330285232c3fccac4da25cbd6d95fe9ad959ff305a91f6\",\n    \"0x8d20ca0a71a64a3f702a0825bb46bd810d03bebfb227683680d474a52f965716ff99e19a165ebaf6567987f4f9ee3c94\",\n    \"0xa5c516a438f916d1d68ca76996404792e0a66e97b7f18fc54c917bf10cf3211b62387932756e39e67e47b0bd6e88385a\",\n    \"0xb089614d830abc0afa435034cec7f851f2f095d479cacf1a3fb57272da826c499a52e7dcbc0eb85f4166fb94778e18e9\",\n    \"0xa8dacc943765d930848288192f4c69e2461c4b9bc6e79e30eeef9a543318cf9ae9569d6986c65c5668a89d49993f8e07\",\n    \"0xab5a9361fa339eec8c621bdad0a58078983abd8942d4282b22835d7a3a47e132d42414b7c359694986f7db39386c2e19\",\n    \"0x94230517fb57bd8eb26c6f64129b8b2abd0282323bf7b94b8bac7fab27b4ecc2c4290c294275e1a759de19f2216134f3\",\n    \"0xb8f158ea5006bc3b90b285246625faaa6ac9b5f5030dc69701b12f3b79a53ec7e92eeb5a63bbd1f9509a0a3469ff3ffc\",\n    \"0x8b6944fd8cb8540957a91a142fdcda827762aa777a31e8810ca6d026e50370ee1636fc351724767e817ca38804ebe005\",\n    \"0x82d1ee40fe1569c29644f79fa6c4033b7ed45cd2c3b343881f6eb0de2e79548fded4787fae19bed6ee76ed76ff9f2f11\",\n    \"0xa8924c7035e99eaed244ca165607e7e568b6c8085510dcdbaf6ebdbed405af2e6c14ee27d94ffef10d30aa52a60bf66d\",\n    \"0x956f82a6c2ae044635e85812581e4866c5fa2f427b01942047d81f6d79a14192f66fbbe77c9ffeaef4e6147097fdd2b5\",\n    \"0xb1100255a1bcf5e05b6aff1dfeb6e1d55b5d68d43a7457ba10cc76b61885f67f4d0d5179abda786e037ae95deb8eea45\",\n    \"0x99510799025e3e5e8fbf06dedb14c060c6548ba2bda824f687d3999dc395e794b1fb6514b9013f3892b6cf65cb0d65aa\",\n    \"0x8f9091cebf5e9c809aab415942172258f894e66e625d7388a05289183f01b8d994d52e05a8e69f784fba41db9ea357f0\",\n    \"0xa13d2eeb0776bdee9820ecb6693536720232848c51936bb4ef4fe65588d3f920d08a21907e1fdb881c1ad70b3725e726\",\n    \"0xa68b8f18922d550284c5e5dc2dda771f24c21965a6a4d5e7a71678178f46df4d8a421497aad8fcb4c7e241aba26378a0\",\n    \"0x8b7601f0a3c6ad27f03f2d23e785c81c1460d60100f91ea9d1cab978aa03b523150206c6d52ce7c7769c71d2c8228e9e\",\n    \"0xa8e02926430813caa851bb2b46de7f0420f0a64eb5f6b805401c11c9091d3b6d67d841b5674fa2b1dce0867714124cd8\",\n    \"0xb7968ecba568b8193b3058400af02c183f0a6df995a744450b3f7e0af7a772454677c3857f99c140bbdb2a09e832e8e0\",\n    \"0x8f20b1e9ba87d0a3f35309b985f3c18d2e8800f1ca7f0c52cadef773f1496b6070c936eea48c4a1cae83fd2524e9d233\",\n    \"0x88aef260042db0d641a51f40639dbeeefa9e9811df30bee695f3791f88a2f84d318f04e8926b7f47bf25956cb9e3754f\",\n    \"0x9725345893b647e9ba4e6a29e12f96751f1ae25fcaec2173e9a259921a1a7edb7a47159b3c8767e44d9e2689f5aa0f72\",\n    \"0x8c281e6f72752cb11e239e4df9341c45106eb7993c160e54423c2bffe10bc39d42624b45a1f673936ef2e1a02fc92f1a\",\n    \"0x90aba2f68bddb2fcce6c51430dacdfeec43ea8dc379660c99095df11017691ccf5faa27665cf4b9f0eea7728ae53c327\",\n    \"0xb7022695c16521c5704f49b7ddbdbec9b5f57ce0ceebe537bc0ebb0906d8196cc855a9afeb8950a1710f6a654464d93f\",\n    \"0x8fe1b9dd3c6a258116415d36e08374e094b22f0afb104385a5da48be17123e86fb8327baacc4f0d9ebae923d55d99bb5\",\n    \"0x817e85d8e3d19a4cbc1dec31597142c2daa4871bda89c2177fa719c00eda3344eb08b82eb92d4aa91a9eaacb3fc09783\",\n    \"0xb59053e1081d2603f1ca0ba553804d6fa696e1fd996631db8f62087b26a40dfef02098b0326bb75f99ec83b9267ca738\",\n    \"0x990a173d857d3ba81ff3789b931bfc9f5609cde0169b7f055fa3cb56451748d593d62d46ba33f80f9cafffe02b68dd14\",\n    \"0xb0c538dbba4954b809ab26f9f94a3cf1dcb77ce289eaec1d19f556c0ae4be1fa03af4a9b7057837541c3cc0a80538736\",\n    \"0xac3ba42f5f44f9e1fc453ce49c4ab79d0e1d5c42d3b30b1e098f3ab3f414c4c262fa12fb2be249f52d4aaf3c5224beb9\",\n    \"0xaf47467eb152e59870e21f0d4da2f43e093daf40180ab01438030684b114d025326928eaab12c41b81a066d94fce8436\",\n    \"0x98d1b58ba22e7289b1c45c79a24624f19b1d89e00f778eef327ec4856a9a897278e6f1a9a7e673844b31dde949153000\",\n    \"0x97ccb15dfadc7c59dca08cfe0d22df2e52c684cf97de1d94bc00d7ba24e020025130b0a39c0f4d46e4fc872771ee7875\",\n    \"0xb699e4ed9a000ff96ca296b2f09dce278832bc8ac96851ff3cff99ed3f6f752cfc0fea8571be28cd9b5a7ec36f1a08ee\",\n    \"0xb9f49f0edb7941cc296435ff0a912e3ad16848ee8765ab5f60a050b280d6ea585e5b34051b15f6b8934ef01ceb85f648\",\n    \"0xac3893df7b4ceab23c6b9054e48e8ba40d6e5beda8fbe90b814f992f52494186969b35d8c4cdc3c99890a222c9c09008\",\n    \"0xa41293ad22fae81dea94467bc1488c3707f3d4765059173980be93995fa4fcc3c9340796e3eed0beeb0ba0d9bb4fa3aa\",\n    \"0xa0543e77acd2aeecde13d18d258aeb2c7397b77f17c35a1992e8666ea7abcd8a38ec6c2741bd929abba2f766138618cc\",\n    \"0x92e79b22bc40e69f6527c969500ca543899105837b6b1075fa1796755c723462059b3d1b028e0b3df2559fa440e09175\",\n    \"0xa1fa1eac8f41a5197a6fb4aa1eae1a031c89f9c13ff9448338b222780cf9022e0b0925d930c37501a0ef7b2b00fdaf83\",\n    \"0xb3cb29ff73229f0637335f28a08ad8c5f166066f27c6c175164d0f26766a927f843b987ee9b309ed71cbf0a65d483831\",\n    \"0x84d4ab787f0ac00f104f4a734dc693d62d48c2aeb03913153da62c2ae2c27d11b1110dcef8980368dd84682ea2c1a308\",\n    \"0xab6a8e4bbc78d4a7b291ad3e9a8fe2d65f640524ba3181123b09d2d18a9e300e2509ccf7000fe47e75b65f3e992a2e7e\",\n    \"0xb7805ebe4f1a4df414003dc10bca805f2ab86ca75820012653e8f9b79c405196b0e2cab099f2ab953d67f0d60d31a0f9\",\n    \"0xb12c582454148338ea605d22bd00a754109063e22617f1f8ac8ddf5502c22a181c50c216c3617b9852aa5f26af56b323\",\n    \"0x86333ad9f898947e31ce747728dc8c887479e18d36ff3013f69ebef807d82c6981543b5c3788af93c4d912ba084d3cba\",\n    \"0xb514efa310dc4ad1258add138891e540d8c87142a881b5f46563cc58ecd1488e6d3a2fca54c0b72a929f3364ca8c333e\",\n    \"0xaa0a30f92843cf2f484066a783a1d75a7aa6f41f00b421d4baf20a6ac7886c468d0eea7ca8b17dd22f4f74631b62b640\",\n    \"0xb3b7dc63baec9a752e8433c0cdee4d0f9bc41f66f2b8d132faf925eef9cf89aae756fc132c45910f057122462605dc10\",\n    \"0xb9b8190dac5bfdeb59fd44f4da41a57e7f1e7d2c21faba9da91fa45cbeca06dcf299c9ae22f0c89ece11ac46352d619f\",\n    \"0x89f8cf36501ad8bdfeab863752a9090e3bfda57cf8fdeca2944864dc05925f501e252c048221bcc57136ab09a64b64b2\",\n    \"0xb0cbfaf317f05f97be47fc9d69eda2dd82500e00d42612f271a1fe24626408c28881f171e855bd5bd67409f9847502b4\",\n    \"0xa7c21a8fcede581bfd9847b6835eda62ba250bea81f1bb17372c800a19c732abe03064e64a2f865d974fb636cab4b859\",\n    \"0x95f9df524ba7a4667351696c4176b505d8ea3659f5ff2701173064acc624af69a0fad4970963736383b979830cb32260\",\n    \"0x856a74fe8b37a2e3afeac858c8632200485d438422a16ae3b29f359e470e8244995c63ad79c7e007ed063f178d0306fd\",\n    \"0xb37faa4d78fdc0bb9d403674dbea0176c2014a171c7be8527b54f7d1a32a76883d3422a3e7a5f5fcc5e9b31b57822eeb\",\n    \"0x8d37234d8594ec3fe75670b5c9cc1ec3537564d4739b2682a75b18b08401869a4264c0f264354219d8d896cded715db4\",\n    \"0xb5289ee5737f0e0bde485d32096d23387d68dab8f01f47821ab4f06cc79a967afe7355e72dc0c751d96b2747b26f6255\",\n    \"0x9085e1fdf9f813e9c3b8232d3c8863cd84ab30d45e8e0d3d6a0abd9ebc6fd70cdf749ff4d04390000e14c7d8c6655fc7\",\n    \"0x93a388c83630331eca4da37ea4a97b3b453238af474817cc0a0727fd3138dcb4a22de38c04783ec829c22cb459cb4e8e\",\n    \"0xa5377116027c5d061dbe24c240b891c08cdd8cd3f0899e848d682c873aff5b8132c1e7cfe76d2e5ed97ee0eb1d42cb68\",\n    \"0xa274c84b04338ed28d74683e2a7519c2591a3ce37c294d6f6e678f7d628be2db8eff253ede21823e2df7183e6552f622\",\n    \"0x8bc201147a842453a50bec3ac97671397bc086d6dfc9377fa38c2124cdc286abda69b7324f47d64da094ae011d98d9d9\",\n    \"0x9842d0c066c524592b76fbec5132bc628e5e1d21c424bec4555efca8619cc1fd8ea3161febcb8b9e8ab54702f4e815e2\",\n    \"0xa19191b713a07efe85c266f839d14e25660ee74452e6c691cd9997d85ae4f732052d802d3deb018bdd847caa298a894b\",\n    \"0xa24f71fc0db504da4e287dd118a4a74301cbcd16033937ba2abc8417956fcb4ae19b8e63b931795544a978137eff51cb\",\n    \"0xa90eec4a6a3a4b8f9a5b93d978b5026fcf812fe65585b008d7e08c4aaf21195a1d0699f12fc16f79b6a18a369af45771\",\n    \"0x8b551cf89737d7d06d9b3b9c4c1c73b41f2ea0af4540999c70b82dabff8580797cf0a3caf34c86c59a7069eb2e38f087\",\n    \"0xb8d312e6c635e7a216a1cda075ae77ba3e1d2fd501dc31e83496e6e81ed5d9c7799f8e578869c2e0e256fb29f5de10a7\",\n    \"0x8d144bdb8cae0b2cdb5b33d44bbc96984a5925202506a8cc65eb67ac904b466f5a7fe3e1cbf04aa785bbb7348c4bb73c\",\n    \"0xa101b3d58b7a98659244b88de0b478b3fb87dc5fc6031f6e689b99edf498abd43e151fd32bd4bbd240e0b3e59c440359\",\n    \"0x907453abca7d8e7151a05cc3d506c988007692fe7401395dc93177d0d07d114ab6cca0cc658eb94c0223fe8658295cad\",\n    \"0x825329ffbe2147ddb68f63a0a67f32d7f309657b8e5d9ab5bb34b3730bfa2c77a23eaaadb05def7d9f94a9e08fdc1e96\",\n    \"0x88ee923c95c1dac99ae7ed6067906d734d793c5dc5d26339c1bb3314abe201c5dccb33b9007351885eb2754e9a8ea06c\",\n    \"0x98bc9798543f5f1adc9f2cfcfa72331989420e9c3f6598c45269f0dc9b7c8607bbeaf03faa0aea2ddde2b8f17fdceff5\",\n    \"0x8ee87877702a79aef923ab970db6fa81561b3c07d5bf1a072af0a7bad765b4cbaec910afe1a91703feacc7822fa38a94\",\n    \"0x8060b9584aa294fe8adc2b22f67e988bc6da768eae91e429dcc43ddc53cfcc5d6753fdc1b420b268c7eb2fb50736a970\",\n    \"0xb344a5524d80a2f051870c7001f74fcf348a70fcf78dbd20c6ff9ca85d81567d2318c8b8089f2c4f195d6aec9fc15fa6\",\n    \"0x8f5a5d893e1936ed062149d20eb73d98b62b7f50ab5d93a6429c03656b36688d1c80cb5010e4977491e51fa0d7dd35d5\",\n    \"0x86fa32ebbf97328c5f5f15564e1238297e289ec3219b9a741724e9f3ae8d5c15277008f555863a478b247ba5dc601d44\",\n    \"0x9557e55377e279f4b6b5e0ffe01eca037cc13aac242d67dfcd0374a1e775c5ed5cb30c25fe21143fee54e3302d34a3ea\",\n    \"0x8cb6bcbc39372d23464a416ea7039f57ba8413cf3f00d9a7a5b356ab20dcb8ed11b3561f7bce372b8534d2870c7ee270\",\n    \"0xb5d59075cb5abde5391f64b6c3b8b50adc6e1f654e2a580b6d6d6eff3f4fbdd8fffc92e06809c393f5c8eab37f774c4b\",\n    \"0xafcfb6903ef13e493a1f7308675582f15af0403b6553e8c37afb8b2808ad21b88b347dc139464367dc260df075fea1ad\",\n    \"0x810fbbe808375735dd22d5bc7fc3828dc49fdd22cc2d7661604e7ac9c4535c1df578780affb3b895a0831640a945bcad\",\n    \"0x8056b0c678803b416f924e09a6299a33cf9ad7da6fe1ad7accefe95c179e0077da36815fde3716711c394e2c5ea7127f\",\n    \"0x8b67403702d06979be19f1d6dc3ec73cc2e81254d6b7d0cc49cd4fdda8cd51ab0835c1d2d26fc0ecab5df90585c2f351\",\n    \"0x87f97f9e6d4be07e8db250e5dd2bffdf1390665bc5709f2b631a6fa69a7fca958f19bd7cc617183da1f50ee63e9352b5\",\n    \"0xae151310985940471e6803fcf37600d7fa98830613e381e00dab943aec32c14162d51c4598e8847148148000d6e5af5c\",\n    \"0x81eb537b35b7602c45441cfc61b27fa9a30d3998fad35a064e05bc9479e9f10b62eba2b234b348219eea3cadcaac64bb\",\n    \"0x8a441434934180ab6f5bc541f86ebd06eadbee01f438836d797e930fa803a51510e005c9248cecc231a775b74d12b5e9\",\n    \"0x81f3c250a27ba14d8496a5092b145629eb2c2e6a5298438670375363f57e2798207832c8027c3e9238ad94ecdadfc4df\",\n    \"0xa6217c311f2f3db02ceaa5b6096849fe92b6f4b6f1491535ef8525f6ccee6130bed2809e625073ecbaddd4a3eb3df186\",\n    \"0x82d1c396f0388b942cf22b119d7ef1ad03d3dad49a74d9d01649ee284f377c8daddd095d596871669e16160299a210db\",\n    \"0xa40ddf7043c5d72a7246bd727b07f7fff1549f0e443d611de6f9976c37448b21664c5089c57f20105102d935ab82f27b\",\n    \"0xb6c03c1c97adf0c4bf4447ec71366c6c1bff401ba46236cd4a33d39291e7a1f0bb34bd078ba3a18d15c98993b153a279\",\n    \"0x8a94f5f632068399c359c4b3a3653cb6df2b207379b3d0cdace51afdf70d6d5cce6b89a2b0fee66744eba86c98fb21c2\",\n    \"0xb2f19e78ee85073f680c3bba1f07fd31b057c00b97040357d97855b54a0b5accb0d3b05b2a294568fcd6a4be6f266950\",\n    \"0xa74632d13bbe2d64b51d7a9c3ae0a5a971c19f51cf7596a807cea053e6a0f3719700976d4e394b356c0329a2dced9aa2\",\n    \"0xafef616d341a9bc94393b8dfba68ff0581436aa3a3adb7c26a1bbf2cf19fa877066191681f71f17f3cd6f9cf6bf70b5a\",\n    \"0x8ce96d93ae217408acf7eb0f9cbb9563363e5c7002e19bbe1e80760bc9d449daee2118f3878b955163ed664516b97294\",\n    \"0x8414f79b496176bc8b8e25f8e4cfee28f4f1c2ddab099d63d2aca1b6403d26a571152fc3edb97794767a7c4686ad557c\",\n    \"0xb6c61d01fd8ce087ef9f079bf25bf10090db483dd4f88c4a786d31c1bdf52065651c1f5523f20c21e75cea17df69ab73\",\n    \"0xa5790fd629be70545093631efadddc136661f63b65ec682609c38ef7d3d7fa4e56bdf94f06e263bc055b90cb1c6bcefe\",\n    \"0xb515a767e95704fb7597bca9e46f1753abacdc0e56e867ee3c6f4cd382643c2a28e65312c05ad040eaa3a8cbe7217a65\",\n    \"0x8135806a02ead6aa92e9adb6fefb91349837ab73105aaa7be488ef966aa8dfaafdfa64bbae30fcbfa55dd135a036a863\",\n    \"0x8f22435702716d76b1369750694540742d909d5e72b54d0878245fab7c269953b1c6f2b29c66f08d5e0263ca3a731771\",\n    \"0x8e0f8a8e8753e077dac95848212aeffd51c23d9b6d611df8b102f654089401954413ecbedc6367561ca599512ae5dda7\",\n    \"0x815a9084e3e2345f24c5fa559deec21ee1352fb60f4025c0779be65057f2d528a3d91593bd30d3a185f5ec53a9950676\",\n    \"0x967e6555ccba395b2cc1605f8484c5112c7b263f41ce8439a99fd1c71c5ed14ad02684d6f636364199ca48afbbde13be\",\n    \"0x8cd0ccf17682950b34c796a41e2ea7dd5367aba5e80a907e01f4cdc611e4a411918215e5aebf4292f8b24765d73314a6\",\n    \"0xa58bf1bbb377e4b3915df6f058a0f53b8fb8130fdec8c391f6bc82065694d0be59bb67ffb540e6c42cc8b380c6e36359\",\n    \"0x92af3151d9e6bfb3383d85433e953c0160859f759b0988431ec5893542ba40288f65db43c78a904325ef8d324988f09d\",\n    \"0x8011bbb05705167afb47d4425065630f54cb86cd462095e83b81dfebf348f846e4d8fbcf1c13208f5de1931f81da40b9\",\n    \"0x81c743c104fc3cb047885c9fa0fb9705c3a83ee24f690f539f4985509c3dafd507af3f6a2128276f45d5939ef70c167f\",\n    \"0xa2c9679b151c041aaf5efeac5a737a8f70d1631d931609fca16be1905682f35e291292874cb3b03f14994f98573c6f44\",\n    \"0xa4949b86c4e5b1d5c82a337e5ce6b2718b1f7c215148c8bfb7e7c44ec86c5c9476048fc5c01f57cb0920876478c41ad6\",\n    \"0x86c2495088bd1772152e527a1da0ef473f924ea9ab0e5b8077df859c28078f73c4e22e3a906b507fdf217c3c80808b5c\",\n    \"0x892e0a910dcf162bcea379763c3e2349349e4cda9402949255ac4a78dd5a47e0bf42f5bd0913951576b1d206dc1e536a\",\n    \"0xa7009b2c6b396138afe4754b7cc10dee557c51c7f1a357a11486b3253818531f781ea8107360c8d4c3b1cd96282353c0\",\n    \"0x911763ef439c086065cc7b4e57484ed6d693ea44acee4b18c9fd998116da55fbe7dcb8d2a0f0f9b32132fca82d73dff6\",\n    \"0xa722000b95a4a2d40bed81870793f15ba2af633f9892df507f2842e52452e02b5ea8dea6a043c2b2611d82376e33742a\",\n    \"0x9387ac49477bd719c2f92240d0bdfcf9767aad247ca93dc51e56106463206bc343a8ec855eb803471629a66fffb565d6\",\n    \"0x92819a1fa48ab4902939bb72a0a4e6143c058ea42b42f9bc6cea5df45f49724e2530daf3fc4f097cceefa2a8b9db0076\",\n    \"0x98eac7b04537653bc0f4941aae732e4b1f84bd276c992c64a219b8715eb1fb829b5cbd997d57feb15c7694c468f95f70\",\n    \"0xb275e7ba848ce21bf7996e12dbeb8dadb5d0e4f1cb5a0248a4f8f9c9fe6c74e3c93f4b61edbcb0a51af5a141e1c14bc7\",\n    \"0x97243189285aba4d49c53770c242f2faf5fd3914451da4931472e3290164f7663c726cf86020f8f181e568c72fd172d1\",\n    \"0x839b0b3c25dd412bee3dc24653b873cc65454f8f16186bb707bcd58259c0b6765fa4c195403209179192a4455c95f3b8\",\n    \"0x8689d1a870514568a074a38232e2ceb4d7df30fabeb76cff0aed5b42bf7f02baea12c5fadf69f4713464dbd52aafa55f\",\n    \"0x8958ae7b290f0b00d17c3e9fdb4dbf168432b457c7676829299dd428984aba892de1966fc106cfc58a772862ecce3976\",\n    \"0xa422bc6bd68b8870cfa5bc4ce71781fd7f4368b564d7f1e0917f6013c8bbb5b240a257f89ecfdbecb40fe0f3aa31d310\",\n    \"0xaa61f78130cebe09bc9a2c0a37f0dd57ed2d702962e37d38b1df7f17dc554b1d4b7a39a44182a452ce4c5eb31fa4cfcc\",\n    \"0xb7918bd114f37869bf1a459023386825821bfadce545201929d13ac3256d92a431e34f690a55d944f77d0b652cefeffc\",\n    \"0x819bba35fb6ace1510920d4dcff30aa682a3c9af9022e287751a6a6649b00c5402f14b6309f0aeef8fce312a0402915e\",\n    \"0x8b7c9ad446c6f63c11e1c24e24014bd570862b65d53684e107ba9ad381e81a2eaa96731b4b33536efd55e0f055071274\",\n    \"0x8fe79b53f06d33386c0ec7d6d521183c13199498594a46d44a8a716932c3ec480c60be398650bbfa044fa791c4e99b65\",\n    \"0x9558e10fb81250b9844c99648cf38fa05ec1e65d0ccbb18aa17f2d1f503144baf59d802c25be8cc0879fff82ed5034ad\",\n    \"0xb538a7b97fbd702ba84645ca0a63725be1e2891c784b1d599e54e3480e4670d0025526674ef5cf2f87dddf2290ba09f0\",\n    \"0x92eafe2e869a3dd8519bbbceb630585c6eb21712b2f31e1b63067c0acb5f9bdbbcbdb612db4ea7f9cc4e7be83d31973f\",\n    \"0xb40d21390bb813ab7b70a010dff64c57178418c62685761784e37d327ba3cb9ef62df87ecb84277c325a637fe3709732\",\n    \"0xb349e6fbf778c4af35fbed33130bd8a7216ed3ba0a79163ebb556e8eb8e1a7dad3456ddd700dad9d08d202491c51b939\",\n    \"0xa8fdaedecb251f892b66c669e34137f2650509ade5d38fbe8a05d9b9184bb3b2d416186a3640429bd1f3e4b903c159dd\",\n    \"0xac6167ebfee1dbab338eff7642f5e785fc21ef0b4ddd6660333fe398068cbd6c42585f62e81e4edbb72161ce852a1a4f\",\n    \"0x874b1fbf2ebe140c683bd7e4e0ab017afa5d4ad38055aaa83ee6bbef77dbc88a6ce8eb0dcc48f0155244af6f86f34c2d\",\n    \"0x903c58e57ddd9c446afab8256a6bb6c911121e6ccfb4f9b4ed3e2ed922a0e500a5cb7fa379d5285bc16e11dac90d1fda\",\n    \"0x8dae7a0cffa2fd166859cd1bf10ff82dd1932e488af377366b7efc0d5dec85f85fe5e8150ff86a79a39cefc29631733a\",\n    \"0xaa047857a47cc4dfc08585f28640420fcf105b881fd59a6cf7890a36516af0644d143b73f3515ab48faaa621168f8c31\",\n    \"0x864508f7077c266cc0cb3f7f001cb6e27125ebfe79ab57a123a8195f2e27d3799ff98413e8483c533b46a816a3557f1f\",\n    \"0x8bcd45ab1f9cbab36937a27e724af819838f66dfeb15923f8113654ff877bd8667c54f6307aaf0c35027ca11b6229bfd\",\n    \"0xb21aa34da9ab0a48fcfdd291df224697ce0c1ebc0e9b022fdee8750a1a4b5ba421c419541ed5c98b461eecf363047471\",\n    \"0xa9a18a2ab2fae14542dc336269fe612e9c1af6cf0c9ac933679a2f2cb77d3c304114f4d219ca66fe288adde30716775b\",\n    \"0xb5205989b92c58bdda71817f9a897e84100b5c4e708de1fced5c286f7a6f01ae96b1c8d845f3a320d77c8e2703c0e8b1\",\n    \"0xa364059412bbcc17b8907d43ac8e5df90bc87fd1724b5f99832d0d24559fae6fa76a74cff1d1eac8cbac6ec80b44af20\",\n    \"0xae709f2c339886b31450834cf29a38b26eb3b0779bd77c9ac269a8a925d1d78ea3837876c654b61a8fe834b3b6940808\",\n    \"0x8802581bba66e1952ac4dab36af371f66778958f4612901d95e5cac17f59165e6064371d02de8fb6fccf89c6dc8bd118\",\n    \"0xa313252df653e29c672cbcfd2d4f775089cb77be1077381cf4dc9533790e88af6cedc8a119158e7da5bf6806ad9b91a1\",\n    \"0x992a065b4152c7ef11515cd54ba9d191fda44032a01aed954acff3443377ee16680c7248d530b746b8c6dee2d634e68c\",\n    \"0xb627b683ee2b32c1ab4ccd27b9f6cce2fe097d96386fa0e5c182ad997c4c422ab8dfc03870cd830b8c774feb66537282\",\n    \"0xb823cf8a9aee03dadd013eb9efe40a201b4b57ef67efaae9f99683005f5d1bf55e950bf4af0774f50859d743642d3fea\",\n    \"0xb8a7449ffac0a3f206677097baf7ce00ca07a4d2bd9b5356fbcb83f3649b0fda07cfebad220c1066afba89e5a52abf4b\",\n    \"0xb2dd1a2f986395bb4e3e960fbbe823dbb154f823284ebc9068502c19a7609790ec0073d08bfa63f71e30c7161b6ef966\",\n    \"0x98e5236de4281245234f5d40a25b503505af140b503a035fc25a26159a9074ec81512b28f324c56ea2c9a5aa7ce90805\",\n    \"0x89070847dc8bbf5bc4ed073aa2e2a1f699cf0c2ca226f185a0671cecc54e7d3e14cd475c7752314a7a8e7476829da4bc\",\n    \"0xa9402dc9117fdb39c4734c0688254f23aed3dce94f5f53f5b7ef2b4bf1b71a67f85ab1a38ec224a59691f3bee050aeb3\",\n    \"0x957288f9866a4bf56a4204218ccc583f717d7ce45c01ea27142a7e245ad04a07f289cc044f8cf1f21d35e67e39299e9c\",\n    \"0xb2fb31ccb4e69113763d7247d0fc8edaae69b550c5c56aecacfd780c7217dc672f9fb7496edf4aba65dacf3361268e5b\",\n    \"0xb44a4526b2f1d6eb2aa8dba23bfa385ff7634572ab2afddd0546c3beb630fbfe85a32f42dd287a7fec069041411537f7\",\n    \"0x8db5a6660c3ac7fd7a093573940f068ee79a82bc17312af900b51c8c439336bc86ca646c6b7ab13aaaa008a24ca508ab\",\n    \"0x8f9899a6d7e8eb4367beb5c060a1f8e94d8a21099033ae582118477265155ba9e72176a67f7f25d7bad75a152b56e21a\",\n    \"0xa67de0e91ade8d69a0e00c9ff33ee2909b8a609357095fa12319e6158570c232e5b6f4647522efb7345ce0052aa9d489\",\n    \"0x82eb2414898e9c3023d57907a2b17de8e7eea5269029d05a94bfd7bf5685ac4a799110fbb375eb5e0e2bd16acf6458ae\",\n    \"0x94451fc7fea3c5a89ba701004a9693bab555cb622caf0896b678faba040409fdfd14a978979038b2a81e8f0abc4994d2\",\n    \"0xac879a5bb433998e289809a4a966bd02b4bf6a9c1cc276454e39c886efcf4fc68baebed575826bde577ab5aa71d735a9\",\n    \"0x880c0f8f49c875dfd62b4ddedde0f5c8b19f5687e693717f7e5c031bc580e58e13ab497d48b4874130a18743c59fdce3\",\n    \"0xb582af8d8ff0bf76f0a3934775e0b54c0e8fed893245d7d89cae65b03c8125b7237edc29dc45b4fe1a3fe6db45d280ee\",\n    \"0x89f337882ed3ae060aaee98efa20d79b6822bde9708c1c5fcee365d0ec9297f694cae37d38fd8e3d49717c1e86f078e7\",\n    \"0x826d2c1faea54061848b484e288a5f4de0d221258178cf87f72e14baaa4acc21322f8c9eab5dde612ef497f2d2e1d60b\",\n    \"0xa5333d4f227543e9cd741ccf3b81db79f2f03ca9e649e40d6a6e8ff9073e06da83683566d3b3c8d7b258c62970fb24d1\",\n    \"0xa28f08c473db06aaf4c043a2fae82b3c8cfaa160bce793a4c208e4e168fb1c65115ff8139dea06453c5963d95e922b94\",\n    \"0x8162546135cc5e124e9683bdfaa45833c18553ff06a0861c887dc84a5b12ae8cd4697f6794c7ef6230492c32faba7014\",\n    \"0xb23f0d05b74c08d6a7df1760792be83a761b36e3f8ae360f3c363fb196e2a9dd2de2e492e49d36561366e14daa77155c\",\n    \"0xb6f70d6c546722d3907c708d630dbe289771d2c8bf059c2e32b77f224696d750b4dda9b3a014debda38e7d02c9a77585\",\n    \"0x83bf4c4a9f3ca022c631017e7a30ea205ba97f7f5927cba8fc8489a4646eac6712cb821c5668c9ffe94d69d524374a27\",\n    \"0xb0371475425a8076d0dd5f733f55aabbe42d20a7c8ea7da352e736d4d35a327b2beb370dfcb05284e22cfd69c5f6c4cc\",\n    \"0xa0031ba7522c79211416c2cca3aa5450f96f8fee711552a30889910970ba13608646538781a2c08b834b140aadd7166f\",\n    \"0x99d273c80c7f2dc6045d4ed355d9fc6f74e93549d961f4a3b73cd38683f905934d359058cd1fc4da8083c7d75070487f\",\n    \"0xb0e4b0efa3237793e9dcce86d75aafe9879c5fa23f0d628649aef2130454dcf72578f9bf227b9d2b9e05617468e82588\",\n    \"0xa5ab076fa2e1c5c51f3ae101afdd596ad9d106bba7882b359c43d8548b64f528af19afa76cd6f40da1e6c5fca4def3fa\",\n    \"0x8ce2299e570331d60f6a6eff1b271097cd5f1c0e1113fc69b89c6a0f685dabea3e5bc2ac6bd789aa492ab189f89be494\",\n    \"0x91b829068874d911a310a5f9dee001021f97471307b5a3de9ec336870ec597413e1d92010ce320b619f38bed7c4f7910\",\n    \"0xb14fe91f4b07bf33b046e9285b66cb07927f3a8da0af548ac2569b4c4fb1309d3ced76d733051a20814e90dd5b75ffd1\",\n    \"0xabaab92ea6152d40f82940277c725aa768a631ee0b37f5961667f82fb990fc11e6d3a6a2752b0c6f94563ed9bb28265c\",\n    \"0xb7fe28543eca2a716859a76ab9092f135337e28109544f6bd2727728d0a7650428af5713171ea60bfc273d1c821d992c\",\n    \"0x8a4917b2ab749fc7343fc64bdf51b6c0698ff15d740cc7baf248c030475c097097d5a473bcc00d8c25817563fe0447b4\",\n    \"0xaa96156d1379553256350a0a3250166add75948fb9cde62aa555a0a9dc0a9cb7f2f7b8428aff66097bf6bfedaf14bbe2\",\n    \"0xae4ffeb9bdc76830d3eca2b705f30c1bdede6412fa064260a21562c8850c7fb611ec62bc68479fe48f692833e6f66d8d\",\n    \"0xb96543caaba9d051600a14997765d49e4ab10b07c7a92cccf0c90b309e6da334fdd6d18c96806cbb67a7801024fbd3c7\",\n    \"0x97b2b9ad76f19f500fcc94ca8e434176249f542ac66e5881a3dccd07354bdab6a2157018b19f8459437a68d8b86ba8e0\",\n    \"0xa8d206f6c5a14c80005849474fde44b1e7bcf0b2d52068f5f97504c3c035b09e65e56d1cf4b5322791ae2c2fdbd61859\",\n    \"0x936bad397ad577a70cf99bf9056584a61bd7f02d2d5a6cf219c05d770ae30a5cd902ba38366ce636067fc1dd10108d31\",\n    \"0xa77e30195ee402b84f3882e2286bf5380c0ed374a112dbd11e16cef6b6b61ab209d4635e6f35cdaaa72c1a1981d5dabe\",\n    \"0xa46ba4d3947188590a43c180757886a453a0503f79cc435322d92490446f37419c7b999fdf868a023601078070e03346\",\n    \"0x80d8d4c5542f223d48240b445d4d8cf6a75d120b060bc08c45e99a13028b809d910b534d2ac47fb7068930c54efd8da9\",\n    \"0x803be9c68c91b42b68e1f55e58917a477a9a6265e679ca44ee30d3eb92453f8c89c64eafc04c970d6831edd33d066902\",\n    \"0xb14b2b3d0dfe2bb57cee4cd72765b60ac33c1056580950be005790176543826c1d4fbd737f6cfeada6c735543244ab57\",\n    \"0xa9e480188bba1b8fb7105ff12215706665fd35bf1117bacfb6ab6985f4dbc181229873b82e5e18323c2b8f5de03258e0\",\n    \"0xa66a0f0779436a9a3999996d1e6d3000f22c2cac8e0b29cddef9636393c7f1457fb188a293b6c875b05d68d138a7cc4a\",\n    \"0x848397366300ab40c52d0dbbdafbafef6cd3dadf1503bb14b430f52bb9724188928ac26f6292a2412bc7d7aa620763c8\",\n    \"0x95466cc1a78c9f33a9aaa3829a4c8a690af074916b56f43ae46a67a12bb537a5ac6dbe61590344a25b44e8512355a4a7\",\n    \"0x8b5f7a959f818e3baf0887f140f4575cac093d0aece27e23b823cf421f34d6e4ff4bb8384426e33e8ec7b5eed51f6b5c\",\n    \"0x8d5e1368ec7e3c65640d216bcc5d076f3d9845924c734a34f3558ac0f16e40597c1a775a25bf38b187213fbdba17c93b\",\n    \"0xb4647c1b823516880f60d20c5cc38c7f80b363c19d191e8992226799718ee26b522a12ecb66556ed3d483aa4824f3326\",\n    \"0xac3abaea9cd283eb347efda4ed9086ea3acf495043e08d0d19945876329e8675224b685612a6badf8fd72fb6274902b1\",\n    \"0x8eae1ce292d317aaa71bcf6e77e654914edd5090e2e1ebab78b18bb41b9b1bc2e697439f54a44c0c8aa0d436ebe6e1a9\",\n    \"0x94dc7d1aec2c28eb43d93b111fa59aaa0d77d5a09501220bd411768c3e52208806abf973c6a452fd8292ff6490e0c9e2\",\n    \"0x8fd8967f8e506fef27d17b435d6b86b232ec71c1036351f12e6fb8a2e12daf01d0ee04451fb944d0f1bf7fd20e714d02\",\n    \"0x824e6865be55d43032f0fec65b3480ea89b0a2bf860872237a19a54bc186a85d2f8f9989cc837fbb325b7c72d9babe2c\",\n    \"0x8bd361f5adb27fd6f4e3f5de866e2befda6a8454efeb704aacc606f528c03f0faae888f60310e49440496abd84083ce2\",\n    \"0xb098a3c49f2aaa28b6b3e85bc40ce6a9cdd02134ee522ae73771e667ad7629c8d82c393fba9f27f5416986af4c261438\",\n    \"0xb385f5ca285ff2cfe64dcaa32dcde869c28996ed091542600a0b46f65f3f5a38428cca46029ede72b6cf43e12279e3d3\",\n    \"0x8196b03d011e5be5288196ef7d47137d6f9237a635ab913acdf9c595fa521d9e2df722090ec7eb0203544ee88178fc5f\",\n    \"0x8ed1270211ef928db18e502271b7edf24d0bbd11d97f2786aee772d70c2029e28095cf8f650b0328cc8a4c38d045316d\",\n    \"0xa52ab60e28d69b333d597a445884d44fd2a7e1923dd60f763951e1e45f83e27a4dac745f3b9eff75977b3280e132c15d\",\n    \"0x91e9fe78cdac578f4a4687f71b800b35da54b824b1886dafec073a3c977ce7a25038a2f3a5b1e35c2c8c9d1a7312417c\",\n    \"0xa42832173f9d9491c7bd93b21497fbfa4121687cd4d2ab572e80753d7edcbb42cfa49f460026fbde52f420786751a138\",\n    \"0x97b947126d84dcc70c97be3c04b3de3f239b1c4914342fa643b1a4bb8c4fe45c0fcb585700d13a7ed50784790c54bef9\",\n    \"0x860e407d353eac070e2418ef6cb80b96fc5f6661d6333e634f6f306779651588037be4c2419562c89c61f9aa2c4947f5\",\n    \"0xb2c9d93c3ba4e511b0560b55d3501bf28a510745fd666b3cb532db051e6a8617841ea2f071dda6c9f15619c7bfd2737f\",\n    \"0x8596f4d239aeeac78311207904d1bd863ef68e769629cc379db60e019aaf05a9d5cd31dc8e630b31e106a3a93e47cbc5\",\n    \"0x8b26e14e2e136b65c5e9e5c2022cee8c255834ea427552f780a6ca130a6446102f2a6f334c3f9a0308c53df09e3dba7e\",\n    \"0xb54724354eb515a3c8bed0d0677ff1db94ac0a07043459b4358cb90e3e1aa38ac23f2caa3072cf9647275d7cd61d0e80\",\n    \"0xb7ce9fe0e515e7a6b2d7ddcb92bc0196416ff04199326aea57996eef8c5b1548bd8569012210da317f7c0074691d01b7\",\n    \"0xa1a13549c82c877253ddefa36a29ea6a23695ee401fdd48e65f6f61e5ebd956d5e0edeff99484e9075cb35071fec41e2\",\n    \"0x838ba0c1e5bd1a6da05611ff1822b8622457ebd019cb065ece36a2d176bd2d889511328120b8a357e44569e7f640c1e6\",\n    \"0xb916eccff2a95519400bbf76b5f576cbe53cf200410370a19d77734dc04c05b585cfe382e8864e67142d548cd3c4c2f4\",\n    \"0xa610447cb7ca6eea53a6ff1f5fe562377dcb7f4aaa7300f755a4f5e8eba61e863c51dc2aa9a29b35525b550fbc32a0fe\",\n    \"0x9620e8f0f0ee9a4719aa9685eeb1049c5c77659ba6149ec4c158f999cfd09514794b23388879931fe26fea03fa471fd3\",\n    \"0xa9dcf8b679e276583cf5b9360702a185470d09aea463dc474ee9c8aee91ef089dacb073e334e47fbc78ec5417c90465c\",\n    \"0x8c9adee8410bdd99e5b285744cee61e2593b6300ff31a8a83b0ec28da59475a5c6fb9346fe43aadea2e6c3dad2a8e30a\",\n    \"0x97d5afe9b3897d7b8bb628b7220cf02d8ee4e9d0b78f5000d500aaf4c1df9251aaaabfd1601626519f9d66f00a821d4e\",\n    \"0x8a382418157b601ce4c3501d3b8409ca98136a4ef6abcbf62885e16e215b76b035c94d149cc41ff92e42ccd7c43b9b3d\",\n    \"0xb64b8d11fb3b01abb2646ac99fdb9c02b804ce15d98f9fe0fbf1c9df8440c71417487feb6cdf51e3e81d37104b19e012\",\n    \"0x849d7d044f9d8f0aab346a9374f0b3a5d14a9d1faa83dbacccbdc629ad1ef903a990940255564770537f8567521d17f0\",\n    \"0x829dbb0c76b996c2a91b4cbbe93ba455ca0d5729755e5f0c92aaee37dff7f36fcdc06f33aca41f1b609c784127b67d88\",\n    \"0x85a7c0069047b978422d264d831ab816435f63938015d2e977222b6b5746066c0071b7f89267027f8a975206ed25c1b0\",\n    \"0x84b9fbc1cfb302df1acdcf3dc5d66fd1edfe7839f7a3b2fb3a0d5548656249dd556104d7c32b73967bccf0f5bdcf9e3b\",\n    \"0x972220ac5b807f53eac37dccfc2ad355d8b21ea6a9c9b011c09fe440ddcdf7513e0b43d7692c09ded80d7040e26aa28f\",\n    \"0x855885ed0b21350baeca890811f344c553cf9c21024649c722453138ba29193c6b02c4b4994cd414035486f923472e28\",\n    \"0x841874783ae6d9d0e59daea03e96a01cbbe4ecaced91ae4f2c8386e0d87b3128e6d893c98d17c59e4de1098e1ad519dd\",\n    \"0x827e50fc9ce56f97a4c3f2f4cbaf0b22f1c3ce6f844ff0ef93a9c57a09b8bf91ebfbd2ba9c7f83c442920bffdaf288cc\",\n    \"0xa441f9136c7aa4c08d5b3534921b730e41ee91ab506313e1ba5f7c6f19fd2d2e1594e88c219834e92e6fb95356385aa7\",\n    \"0x97d75b144471bf580099dd6842b823ec0e6c1fb86dd0da0db195e65524129ea8b6fd4a7a9bbf37146269e938a6956596\",\n    \"0xa4b6fa87f09d5a29252efb2b3aaab6b3b6ea9fab343132a651630206254a25378e3e9d6c96c3d14c150d01817d375a8e\",\n    \"0xa31a671876d5d1e95fe2b8858dc69967231190880529d57d3cab7f9f4a2b9b458ac9ee5bdaa3289158141bf18f559efb\",\n    \"0x90bee6fff4338ba825974021b3b2a84e36d617e53857321f13d2b3d4a28954e6de3b3c0e629d61823d18a9763313b3bf\",\n    \"0x96b622a63153f393bb419bfcf88272ea8b3560dbd46b0aa07ada3a6223990d0abdd6c2adb356ef4be5641688c8d83941\",\n    \"0x84c202adeaff9293698022bc0381adba2cd959f9a35a4e8472288fd68f96f6de8be9da314c526d88e291c96b1f3d6db9\",\n    \"0x8ca01a143b8d13809e5a8024d03e6bc9492e22226073ef6e327edf1328ef4aff82d0bcccee92cb8e212831fa35fe1204\",\n    \"0xb2f970dbad15bfbefb38903c9bcc043d1367055c55dc1100a850f5eb816a4252c8c194b3132c929105511e14ea10a67d\",\n    \"0xa5e36556472a95ad57eb90c3b6623671b03eafd842238f01a081997ffc6e2401f76e781d049bb4aa94d899313577a9cf\",\n    \"0x8d1057071051772f7c8bedce53a862af6fd530dd56ae6321eaf2b9fc6a68beff5ed745e1c429ad09d5a118650bfd420a\",\n    \"0x8aadc4f70ace4fcb8d93a78610779748dcffc36182d45b932c226dc90e48238ea5daa91f137c65ed532352c4c4d57416\",\n    \"0xa2ea05ae37e673b4343232ae685ee14e6b88b867aef6dfac35db3589cbcd76f99540fed5c2641d5bb5a4a9f808e9bf0d\",\n    \"0x947f1abad982d65648ae4978e094332b4ecb90f482c9be5741d5d1cf5a28acf4680f1977bf6e49dd2174c37f11e01296\",\n    \"0xa27b144f1565e4047ba0e3f4840ef19b5095d1e281eaa463c5358f932114cbd018aa6dcf97546465cf2946d014d8e6d6\",\n    \"0x8574e1fc3acade47cd4539df578ce9205e745e161b91e59e4d088711a7ab5aa3b410d517d7304b92109924d9e2af8895\",\n    \"0xa48ee6b86b88015d6f0d282c1ae01d2a5b9e8c7aa3d0c18b35943dceb1af580d08a65f54dc6903cde82fd0d73ce94722\",\n    \"0x8875650cec543a7bf02ea4f2848a61d167a66c91ffaefe31a9e38dc8511c6a25bde431007eefe27a62af3655aca208dc\",\n    \"0x999b0a6e040372e61937bf0d68374e230346b654b5a0f591a59d33a4f95bdb2f3581db7c7ccb420cd7699ed709c50713\",\n    \"0x878c9e56c7100c5e47bbe77dc8da5c5fe706cec94d37fa729633bca63cace7c40102eee780fcdabb655f5fa47a99600e\",\n    \"0x865006fb5b475ada5e935f27b96f9425fc2d5449a3c106aa366e55ebed3b4ee42adc3c3f0ac19fd129b40bc7d6bc4f63\",\n    \"0xb7a7da847f1202e7bc1672553e68904715e84fd897d529243e3ecda59faa4e17ba99c649a802d53f6b8dfdd51f01fb74\",\n    \"0x8b2fb4432c05653303d8c8436473682933a5cb604da10c118ecfcd2c8a0e3132e125afef562bdbcc3df936164e5ce4f2\",\n    \"0x808d95762d33ddfa5d0ee3d7d9f327de21a994d681a5f372e2e3632963ea974da7f1f9e5bac8ccce24293509d1f54d27\",\n    \"0x932946532e3c397990a1df0e94c90e1e45133e347a39b6714c695be21aeb2d309504cb6b1dde7228ff6f6353f73e1ca2\",\n    \"0x9705e7c93f0cdfaa3fa96821f830fe53402ad0806036cd1b48adc2f022d8e781c1fbdab60215ce85c653203d98426da3\",\n    \"0xaa180819531c3ec1feb829d789cb2092964c069974ae4faad60e04a6afcce5c3a59aec9f11291e6d110a788d22532bc6\",\n    \"0x88f755097f7e25cb7dd3c449520c89b83ae9e119778efabb54fbd5c5714b6f37c5f9e0346c58c6ab09c1aef2483f895d\",\n    \"0x99fc03ab7810e94104c494f7e40b900f475fde65bdec853e60807ffd3f531d74de43335c3b2646b5b8c26804a7448898\",\n    \"0xaf2dea9683086bed1a179110efb227c9c00e76cd00a2015b089ccbcee46d1134aa18bda5d6cab6f82ae4c5cd2461ac21\",\n    \"0xa500f87ba9744787fdbb8e750702a3fd229de6b8817594348dec9a723b3c4240ddfa066262d002844b9e38240ce55658\",\n    \"0x924d0e45c780f5bc1c1f35d15dfc3da28036bdb59e4c5440606750ecc991b85be18bc9a240b6c983bc5430baa4c68287\",\n    \"0x865b11e0157b8bf4c5f336024b016a0162fc093069d44ac494723f56648bc4ded13dfb3896e924959ea11c96321afefc\",\n    \"0x93672d8607d4143a8f7894f1dcca83fb84906dc8d6dd7dd063bb0049cfc20c1efd933e06ca7bd03ea4cb5a5037990bfe\",\n    \"0x826891efbdff0360446825a61cd1fa04326dd90dae8c33dfb1ed97b045e165766dd070bd7105560994d0b2044bdea418\",\n    \"0x93c4a4a8bcbc8b190485cc3bc04175b7c0ed002c28c98a540919effd6ed908e540e6594f6db95cd65823017258fb3b1c\",\n    \"0xaeb2a0af2d2239fda9aa6b8234b019708e8f792834ff0dd9c487fa09d29800ddceddd6d7929faa9a3edcb9e1b3aa0d6b\",\n    \"0x87f11de7236d387863ec660d2b04db9ac08143a9a2c4dfff87727c95b4b1477e3bc473a91e5797313c58754905079643\",\n    \"0x80dc1db20067a844fe8baceca77f80db171a5ca967acb24e2d480eae9ceb91a3343c31ad1c95b721f390829084f0eae6\",\n    \"0x9825c31f1c18da0de3fa84399c8b40f8002c3cae211fb6a0623c76b097b4d39f5c50058f57a16362f7a575909d0a44a2\",\n    \"0xa99fc8de0c38dbf7b9e946de83943a6b46a762167bafe2a603fb9b86f094da30d6de7ed55d639aafc91936923ee414b3\",\n    \"0xad594678b407db5d6ea2e90528121f84f2b96a4113a252a30d359a721429857c204c1c1c4ff71d8bb5768c833f82e80e\",\n    \"0xb33d985e847b54510b9b007e31053732c8a495e43be158bd2ffcea25c6765bcbc7ca815f7c60b36ad088b955dd6e9350\",\n    \"0x815f8dfc6f90b3342ca3fbd968c67f324dae8f74245cbf8bc3bef10e9440c65d3a2151f951e8d18959ba01c1b50b0ec1\",\n    \"0x94c608a362dd732a1abc56e338637c900d59013db8668e49398b3c7a0cae3f7e2f1d1bf94c0299eeafe6af7f76c88618\",\n    \"0x8ebd8446b23e5adfcc393adc5c52fe172f030a73e63cd2d515245ca0dd02782ceed5bcdd9ccd9c1b4c5953dfac9c340c\",\n    \"0x820437f3f6f9ad0f5d7502815b221b83755eb8dc56cd92c29e9535eb0b48fb8d08c9e4fcc26945f9c8cca60d89c44710\",\n    \"0x8910e4e8a56bf4be9cc3bbf0bf6b1182a2f48837a2ed3c2aaec7099bfd7f0c83e14e608876b17893a98021ff4ab2f20d\",\n    \"0x9633918fde348573eec15ce0ad53ac7e1823aac86429710a376ad661002ae6d049ded879383faaa139435122f64047c6\",\n    \"0xa1f5e3fa558a9e89318ca87978492f0fb4f6e54a9735c1b8d2ecfb1d1c57194ded6e0dd82d077b2d54251f3bee1279e1\",\n    \"0xb208e22d04896abfd515a95c429ff318e87ff81a5d534c8ac2c33c052d6ffb73ef1dccd39c0bbe0734b596c384014766\",\n    \"0x986d5d7d2b5bde6d16336f378bd13d0e671ad23a8ec8a10b3fc09036faeeb069f60662138d7a6df3dfb8e0d36180f770\",\n    \"0xa2d4e6c5f5569e9cef1cddb569515d4b6ace38c8aed594f06da7434ba6b24477392cc67ba867c2b079545ca0c625c457\",\n    \"0xb5ac32b1d231957d91c8b7fc43115ce3c5c0d8c13ca633374402fa8000b6d9fb19499f9181844f0c10b47357f3f757ce\",\n    \"0x96b8bf2504b4d28fa34a4ec378e0e0b684890c5f44b7a6bb6e19d7b3db2ab27b1e2686389d1de9fbd981962833a313ea\",\n    \"0x953bfd7f6c3a0469ad432072b9679a25486f5f4828092401eff494cfb46656c958641a4e6d0d97d400bc59d92dba0030\",\n    \"0x876ab3cea7484bbfd0db621ec085b9ac885d94ab55c4bb671168d82b92e609754b86aaf472c55df3d81421d768fd108a\",\n    \"0x885ff4e67d9ece646d02dd425aa5a087e485c3f280c3471b77532b0db6145b69b0fbefb18aa2e3fa5b64928b43a94e57\",\n    \"0xb91931d93f806d0b0e6cc62a53c718c099526140f50f45d94b8bbb57d71e78647e06ee7b42aa5714aed9a5c05ac8533f\",\n    \"0xa0313eeadd39c720c9c27b3d671215331ab8d0a794e71e7e690f06bcd87722b531d6525060c358f35f5705dbb7109ccb\",\n    \"0x874c0944b7fedc6701e53344100612ddcb495351e29305c00ec40a7276ea5455465ffb7bded898886c1853139dfb1fc7\",\n    \"0x8dc31701a01ee8137059ca1874a015130d3024823c0576aa9243e6942ec99d377e7715ed1444cd9b750a64b85dcaa3e5\",\n    \"0x836d2a757405e922ec9a2dfdcf489a58bd48b5f9683dd46bf6047688f778c8dee9bc456de806f70464df0b25f3f3d238\",\n    \"0xb30b0a1e454a503ea3e2efdec7483eaf20b0a5c3cefc42069e891952b35d4b2c955cf615f3066285ed8fafd9fcfbb8f6\",\n    \"0x8e6d4044b55ab747e83ec8762ea86845f1785cc7be0279c075dadf08aca3ccc5a096c015bb3c3f738f647a4eadea3ba5\",\n    \"0xad7735d16ab03cbe09c029610aa625133a6daecfc990b297205b6da98eda8c136a7c50db90f426d35069708510d5ae9c\",\n    \"0x8d62d858bbb59ec3c8cc9acda002e08addab4d3ad143b3812098f3d9087a1b4a1bb255dcb1635da2402487d8d0249161\",\n    \"0x805beec33238b832e8530645a3254aeef957e8f7ea24bcfc1054f8b9c69421145ebb8f9d893237e8a001c857fedfc77e\",\n    \"0xb1005644be4b085e3f5775aa9bd3e09a283e87ddada3082c04e7a62d303dcef3b8cf8f92944c200c7ae6bb6bdf63f832\",\n    \"0xb4ba0e0790dc29063e577474ffe3b61f5ea2508169f5adc1e394934ebb473e356239413a17962bc3e5d3762d72cce8c2\",\n    \"0xa157ba9169c9e3e6748d9f1dd67fbe08b9114ade4c5d8fc475f87a764fb7e6f1d21f66d7905cd730f28a1c2d8378682a\",\n    \"0x913e52b5c93989b5d15e0d91aa0f19f78d592bc28bcfdfddc885a9980c732b1f4debb8166a7c4083c42aeda93a702898\",\n    \"0x90fbfc1567e7cd4e096a38433704d3f96a2de2f6ed3371515ccc30bc4dd0721a704487d25a97f3c3d7e4344472702d8d\",\n    \"0x89646043028ffee4b69d346907586fd12c2c0730f024acb1481abea478e61031966e72072ff1d5e65cb8c64a69ad4eb1\",\n    \"0xb125a45e86117ee11d2fb42f680ab4a7894edd67ff927ae2c808920c66c3e55f6a9d4588eee906f33a05d592e5ec3c04\",\n    \"0xaad47f5b41eae9be55fb4f67674ff1e4ae2482897676f964a4d2dcb6982252ee4ff56aac49578b23f72d1fced707525e\",\n    \"0xb9ddff8986145e33851b4de54d3e81faa3352e8385895f357734085a1616ef61c692d925fe62a5ed3be8ca49f5d66306\",\n    \"0xb3cb0963387ed28c0c0adf7fe645f02606e6e1780a24d6cecef5b7c642499109974c81a7c2a198b19862eedcea2c2d8c\",\n    \"0xac9c53c885457aaf5cb36c717a6f4077af701e0098eebd7aa600f5e4b14e6c1067255b3a0bc40e4a552025231be7de60\",\n    \"0x8e1a8d823c4603f6648ec21d064101094f2a762a4ed37dd2f0a2d9aa97b2d850ce1e76f4a4b8cae58819b058180f7031\",\n    \"0xb268b73bf7a179b6d22bd37e5e8cb514e9f5f8968c78e14e4f6d5700ca0d0ca5081d0344bb73b028970eebde3cb4124e\",\n    \"0xa7f57d71940f0edbd29ed8473d0149cae71d921dd15d1ff589774003e816b54b24de2620871108cec1ab9fa956ad6ce6\",\n    \"0x8053e6416c8b120e2b999cc2fc420a6a55094c61ac7f2a6c6f0a2c108a320890e389af96cbe378936132363c0d551277\",\n    \"0xb3823f4511125e5aa0f4269e991b435a0d6ceb523ebd91c04d7add5534e3df5fc951c504b4fd412a309fd3726b7f940b\",\n    \"0xae6eb04674d04e982ca9a6add30370ab90e303c71486f43ed3efbe431af1b0e43e9d06c11c3412651f304c473e7dbf39\",\n    \"0x96ab55e641ed2e677591f7379a3cd126449614181fce403e93e89b1645d82c4af524381ff986cae7f9cebe676878646d\",\n    \"0xb52423b4a8c37d3c3e2eca8f0ddbf7abe0938855f33a0af50f117fab26415fb0a3da5405908ec5fdc22a2c1f2ca64892\",\n    \"0x82a69ce1ee92a09cc709d0e3cd22116c9f69d28ea507fe5901f5676000b5179b9abe4c1875d052b0dd42d39925e186bb\",\n    \"0xa84c8cb84b9d5cfb69a5414f0a5283a5f2e90739e9362a1e8c784b96381b59ac6c18723a4aa45988ee8ef5c1f45cc97d\",\n    \"0xafd7efce6b36813082eb98257aae22a4c1ae97d51cac7ea9c852d4a66d05ef2732116137d8432e3f117119725a817d24\",\n    \"0xa0f5fe25af3ce021b706fcff05f3d825384a272284d04735574ce5fb256bf27100fad0b1f1ba0e54ae9dcbb9570ecad3\",\n    \"0x8751786cb80e2e1ff819fc7fa31c2833d25086534eb12b373d31f826382430acfd87023d2a688c65b5e983927e146336\",\n    \"0x8cf5c4b17fa4f3d35c78ce41e1dc86988fd1135cd5e6b2bb0c108ee13538d0d09ae7102609c6070f39f937b439b31e33\",\n    \"0xa9108967a2fedd7c322711eca8159c533dd561bedcb181b646de98bf5c3079449478eab579731bee8d215ae8852c7e21\",\n    \"0xb54c5171704f42a6f0f4e70767cdb3d96ffc4888c842eece343a01557da405961d53ffdc34d2f902ea25d3e1ed867cad\",\n    \"0xae8d4b764a7a25330ba205bf77e9f46182cd60f94a336bbd96773cf8064e3d39caf04c310680943dc89ed1fbad2c6e0d\",\n    \"0xaa5150e911a8e1346868e1b71c5a01e2a4bb8632c195861fb6c3038a0e9b85f0e09b3822e9283654a4d7bb17db2fc5f4\",\n    \"0x9685d3756ce9069bf8bb716cf7d5063ebfafe37e15b137fc8c3159633c4e006ff4887ddd0ae90360767a25c3f90cba7f\",\n    \"0x82155fd70f107ab3c8e414eadf226c797e07b65911508c76c554445422325e71af8c9a8e77fd52d94412a6fc29417cd3\",\n    \"0xabfae52f53a4b6e00760468d973a267f29321997c3dbb5aee36dc1f20619551229c0c45b9d9749f410e7f531b73378e8\",\n    \"0x81a76d921f8ef88e774fd985e786a4a330d779b93fad7def718c014685ca0247379e2e2a007ad63ee7f729cd9ed6ce1b\",\n    \"0x81947c84bc5e28e26e2e533af5ae8fe10407a7b77436dbf8f1d5b0bbe86fc659eae10f974659dc7c826c6dabd03e3a4b\",\n    \"0x92b8c07050d635b8dd4fd09df9054efe4edae6b86a63c292e73cc819a12a21dd7d104ce51fa56af6539dedf6dbe6f7b6\",\n    \"0xb44c579e3881f32b32d20c82c207307eca08e44995dd2aac3b2692d2c8eb2a325626c80ac81c26eeb38c4137ff95add5\",\n    \"0x97efab8941c90c30860926dea69a841f2dcd02980bf5413b9fd78d85904588bf0c1021798dbc16c8bbb32cce66c82621\",\n    \"0x913363012528b50698e904de0588bf55c8ec5cf6f0367cfd42095c4468fcc64954fbf784508073e542fee242d0743867\",\n    \"0x8ed203cf215148296454012bd10fddaf119203db1919a7b3d2cdc9f80e66729464fdfae42f1f2fc5af1ed53a42b40024\",\n    \"0xab84312db7b87d711e9a60824f4fe50e7a6190bf92e1628688dfcb38930fe87b2d53f9e14dd4de509b2216856d8d9188\",\n    \"0x880726def069c160278b12d2258eac8fa63f729cd351a710d28b7e601c6712903c3ac1e7bbd0d21e4a15f13ca49db5aa\",\n    \"0x980699cd51bac6283959765f5174e543ed1e5f5584b5127980cbc2ef18d984ecabba45042c6773b447b8e694db066028\",\n    \"0xaeb019cb80dc4cb4207430d0f2cd24c9888998b6f21d9bf286cc638449668d2eec0018a4cf3fe6448673cd6729335e2b\",\n    \"0xb29852f6aa6c60effdffe96ae88590c88abae732561d35cc19e82d3a51e26cb35ea00986193e07f90060756240f5346e\",\n    \"0xa0fa855adc5ba469f35800c48414b8921455950a5c0a49945d1ef6e8f2a1881f2e2dfae47de6417270a6bf49deeb091d\",\n    \"0xb6c7332e3b14813641e7272d4f69ecc7e09081df0037d6dab97ce13a9e58510f5c930d300633f208181d9205c5534001\",\n    \"0x85a6c050f42fce560b5a8d54a11c3bbb8407abbadd859647a7b0c21c4b579ec65671098b74f10a16245dc779dff7838e\",\n    \"0x8f3eb34bb68759d53c6677de4de78a6c24dd32c8962a7fb355ed362572ef8253733e6b52bc21c9f92ecd875020a9b8de\",\n    \"0xa17dd44181e5dab4dbc128e1af93ec22624b57a448ca65d2d9e246797e4af7d079e09c6e0dfb62db3a9957ce92f098d5\",\n    \"0xa56a1b854c3183082543a8685bb34cae1289f86cfa8123a579049dbd059e77982886bfeb61bf6e05b4b1fe4e620932e7\",\n    \"0xaedae3033cb2fb7628cb4803435bdd7757370a86f808ae4cecb9a268ad0e875f308c048c80cbcac523de16b609683887\",\n    \"0x9344905376aa3982b1179497fac5a1d74b14b7038fd15e3b002db4c11c8bfc7c39430db492cdaf58b9c47996c9901f28\",\n    \"0xa3bfafdae011a19f030c749c3b071f83580dee97dd6f949e790366f95618ca9f828f1daaeabad6dcd664fcef81b6556d\",\n    \"0x81c03d8429129e7e04434dee2c529194ddb01b414feda3adee2271eb680f6c85ec872a55c9fa9d2096f517e13ed5abcc\",\n    \"0x98205ef3a72dff54c5a9c82d293c3e45d908946fa74bb749c3aabe1ab994ea93c269bcce1a266d2fe67a8f02133c5985\",\n    \"0x85a70aeed09fda24412fadbafbbbf5ba1e00ac92885df329e147bfafa97b57629a3582115b780d8549d07d19b7867715\",\n    \"0xb0fbe81c719f89a57d9ea3397705f898175808c5f75f8eb81c2193a0b555869ba7bd2e6bc54ee8a60cea11735e21c68c\",\n    \"0xb03a0bd160495ee626ff3a5c7d95bc79d7da7e5a96f6d10116600c8fa20bedd1132f5170f25a22371a34a2d763f2d6d0\",\n    \"0xa90ab04091fbca9f433b885e6c1d60ab45f6f1daf4b35ec22b09909d493a6aab65ce41a6f30c98239cbca27022f61a8b\",\n    \"0xb66f92aa3bf2549f9b60b86f99a0bd19cbdd97036d4ae71ca4b83d669607f275260a497208f6476cde1931d9712c2402\",\n    \"0xb08e1fdf20e6a9b0b4942f14fa339551c3175c1ffc5d0ab5b226b6e6a322e9eb0ba96adc5c8d59ca4259e2bdd04a7eb0\",\n    \"0xa2812231e92c1ce74d4f5ac3ab6698520288db6a38398bb38a914ac9326519580af17ae3e27cde26607e698294022c81\",\n    \"0xabfcbbcf1d3b9e84c02499003e490a1d5d9a2841a9e50c7babbef0b2dd20d7483371d4dc629ba07faf46db659459d296\",\n    \"0xb0fe9f98c3da70927c23f2975a9dc4789194d81932d2ad0f3b00843dd9cbd7fb60747a1da8fe5a79f136a601becf279d\",\n    \"0xb130a6dba7645165348cb90f023713bed0eefbd90a976b313521c60a36d34f02032e69a2bdcf5361e343ed46911297ec\",\n    \"0x862f0cffe3020cea7a5fd4703353aa1eb1be335e3b712b29d079ff9f7090d1d8b12013011e1bdcbaa80c44641fd37c9f\",\n    \"0x8c6f11123b26633e1abb9ed857e0bce845b2b3df91cc7b013b2fc77b477eee445da0285fc6fc793e29d5912977f40916\",\n    \"0x91381846126ea819d40f84d3005e9fb233dc80071d1f9bb07f102bf015f813f61e5884ffffb4f5cd333c1b1e38a05a58\",\n    \"0x8add7d908de6e1775adbd39c29a391f06692b936518db1f8fde74eb4f533fc510673a59afb86e3a9b52ade96e3004c57\",\n    \"0x8780e086a244a092206edcde625cafb87c9ab1f89cc3e0d378bc9ee776313836160960a82ec397bc3800c0a0ec3da283\",\n    \"0xa6cb4cd9481e22870fdd757fae0785edf4635e7aacb18072fe8dc5876d0bab53fb99ce40964a7d3e8bcfff6f0ab1332f\",\n    \"0xaf30ff47ecc5b543efba1ba4706921066ca8bb625f40e530fb668aea0551c7647a9d126e8aba282fbcce168c3e7e0130\",\n    \"0x91b0bcf408ce3c11555dcb80c4410b5bc2386d3c05caec0b653352377efdcb6bab4827f2018671fc8e4a0e90d772acc1\",\n    \"0xa9430b975ef138b6b2944c7baded8fe102d31da4cfe3bd3d8778bda79189c99d38176a19c848a19e2d1ee0bddd9a13c1\",\n    \"0xaa5a4eef849d7c9d2f4b018bd01271c1dd83f771de860c4261f385d3bdcc130218495860a1de298f14b703ec32fa235f\",\n    \"0xb0ce79e7f9ae57abe4ff366146c3b9bfb38b0dee09c28c28f5981a5d234c6810ad4d582751948affb480d6ae1c8c31c4\",\n    \"0xb75122748560f73d15c01a8907d36d06dc068e82ce22b84b322ac1f727034493572f7907dec34ebc3ddcc976f2f89ed7\",\n    \"0xb0fc7836369a3e4411d34792d6bd5617c14f61d9bba023dda64e89dc5fb0f423244e9b48ee64869258931daa9753a56f\",\n    \"0x8956d7455ae9009d70c6e4a0bcd7610e55f37494cf9897a8f9e1b904cc8febc3fd2d642ebd09025cfff4609ad7e3bc52\",\n    \"0xad741efe9e472026aa49ae3d9914cb9c1a6f37a54f1a6fe6419bebd8c7d68dca105a751c7859f4389505ede40a0de786\",\n    \"0xb52f418797d719f0d0d0ffb0846788b5cba5d0454a69a2925de4b0b80fa4dd7e8c445e5eac40afd92897ed28ca650566\",\n    \"0xa0ab65fb9d42dd966cd93b1de01d7c822694669dd2b7a0c04d99cd0f3c3de795f387b9c92da11353412f33af5c950e9a\",\n    \"0xa0052f44a31e5741a331f7cac515a08b3325666d388880162d9a7b97598fde8b61f9ff35ff220df224eb5c4e40ef0567\",\n    \"0xa0101cfdc94e42b2b976c0d89612a720e55d145a5ef6ef6f1f78cf6de084a49973d9b5d45915349c34ce712512191e3c\",\n    \"0xa0dd99fcf3f5cead5aaf08e82212df3a8bb543c407a4d6fab88dc5130c1769df3f147e934a46f291d6c1a55d92b86917\",\n    \"0xa5939153f0d1931bbda5cf6bdf20562519ea55fbfa978d6dbc6828d298260c0da7a50c37c34f386e59431301a96c2232\",\n    \"0x9568269f3f5257200f9ca44afe1174a5d3cf92950a7f553e50e279c239e156a9faaa2a67f288e3d5100b4142efe64856\",\n    \"0xb746b0832866c23288e07f24991bbf687cad794e7b794d3d3b79367566ca617d38af586cdc8d6f4a85a34835be41d54f\",\n    \"0xa871ce28e39ab467706e32fec1669fda5a4abba2f8c209c6745df9f7a0fa36bbf1919cf14cb89ea26fa214c4c907ae03\",\n    \"0xa08dacdd758e523cb8484f6bd070642c0c20e184abdf8e2a601f61507e93952d5b8b0c723c34fcbdd70a8485eec29db2\",\n    \"0x85bdb78d501382bb95f1166b8d032941005661aefd17a5ac32df9a3a18e9df2fc5dc2c1f07075f9641af10353cecc0c9\",\n    \"0x98d730c28f6fa692a389e97e368b58f4d95382fad8f0baa58e71a3d7baaea1988ead47b13742ce587456f083636fa98e\",\n    \"0xa557198c6f3d5382be9fb363feb02e2e243b0c3c61337b3f1801c4a0943f18e38ce1a1c36b5c289c8fa2aa9d58742bab\",\n    \"0x89174f79201742220ac689c403fc7b243eed4f8e3f2f8aba0bf183e6f5d4907cb55ade3e238e3623d9885f03155c4d2b\",\n    \"0xb891d600132a86709e06f3381158db300975f73ea4c1f7c100358e14e98c5fbe792a9af666b85c4e402707c3f2db321e\",\n    \"0xb9e5b2529ef1043278c939373fc0dbafe446def52ddd0a8edecd3e4b736de87e63e187df853c54c28d865de18a358bb6\",\n    \"0x8589b2e9770340c64679062c5badb7bbef68f55476289b19511a158a9a721f197da03ece3309e059fc4468b15ac33aa3\",\n    \"0xaad8c6cd01d785a881b446f06f1e9cd71bca74ba98674c2dcddc8af01c40aa7a6d469037498b5602e76e9c91a58d3dbd\",\n    \"0xabaccb1bd918a8465f1bf8dbe2c9ad4775c620b055550b949a399f30cf0d9eb909f3851f5b55e38f9e461e762f88f499\",\n    \"0xae62339d26db46e85f157c0151bd29916d5cc619bd4b832814b3fd2f00af8f38e7f0f09932ffe5bba692005dab2d9a74\",\n    \"0x93a6ff30a5c0edf8058c89aba8c3259e0f1b1be1b80e67682de651e5346f7e1b4b4ac3d87cbaebf198cf779524aff6bf\",\n    \"0x8980a2b1d8f574af45b459193c952400b10a86122b71fca2acb75ee0dbd492e7e1ef5b959baf609a5172115e371f3177\",\n    \"0x8c2f49f3666faee6940c75e8c7f6f8edc3f704cca7a858bbb7ee5e96bba3b0cf0993996f781ba6be3b0821ef4cb75039\",\n    \"0xb14b9e348215b278696018330f63c38db100b0542cfc5be11dc33046e3bca6a13034c4ae40d9cef9ea8b34fef0910c4e\",\n    \"0xb59bc3d0a30d66c16e6a411cb641f348cb1135186d5f69fda8b0a0934a5a2e7f6199095ba319ec87d3fe8f1ec4a06368\",\n    \"0x8874aca2a3767aa198e4c3fec2d9c62d496bc41ff71ce242e9e082b7f38cdf356089295f80a301a3cf1182bde5308c97\",\n    \"0xb1820ebd61376d91232423fc20bf008b2ba37e761199f4ef0648ea2bd70282766799b4de814846d2f4d516d525c8daa7\",\n    \"0xa6b202e5dedc16a4073e04a11af3a8509b23dfe5a1952f899adeb240e75c3f5bde0c424f811a81ea48d343591faffe46\",\n    \"0xa69becee9c93734805523b92150a59a62eed4934f66056b645728740d42223f2925a1ad38359ba644da24d9414f4cdda\",\n    \"0xad72f0f1305e37c7e6b48c272323ee883320994cb2e0d850905d6655fafc9f361389bcb9c66b3ff8d2051dbb58c8aa96\",\n    \"0xb563600bd56fad7c8853af21c6a02a16ed9d8a8bbeea2c31731d63b976d83cb05b9779372d898233e8fd597a75424797\",\n    \"0xb0abb78ce465bf7051f563c62e8be9c57a2cc997f47c82819300f36e301fefd908894bb2053a9d27ce2d0f8c46d88b5b\",\n    \"0xa071a85fb8274bac2202e0cb8e0e2028a5e138a82d6e0374d39ca1884a549c7c401312f00071b91f455c3a2afcfe0cda\",\n    \"0xb931c271513a0f267b9f41444a5650b1918100b8f1a64959c552aff4e2193cc1b9927906c6fa7b8a8c68ef13d79aaa52\",\n    \"0xa6a1bb9c7d32cb0ca44d8b75af7e40479fbce67d216b48a2bb680d3f3a772003a49d3cd675fc64e9e0f8fabeb86d6d61\",\n    \"0xb98d609858671543e1c3b8564162ad828808bb50ded261a9f8690ded5b665ed8368c58f947365ed6e84e5a12e27b423d\",\n    \"0xb3dca58cd69ec855e2701a1d66cad86717ff103ef862c490399c771ad28f675680f9500cb97be48de34bcdc1e4503ffd\",\n    \"0xb34867c6735d3c49865e246ddf6c3b33baf8e6f164db3406a64ebce4768cb46b0309635e11be985fee09ab7a31d81402\",\n    \"0xacb966c554188c5b266624208f31fab250b3aa197adbdd14aee5ab27d7fb886eb4350985c553b20fdf66d5d332bfd3fe\",\n    \"0x943c36a18223d6c870d54c3b051ef08d802b85e9dd6de37a51c932f90191890656c06adfa883c87b906557ae32d09da0\",\n    \"0x81bca7954d0b9b6c3d4528aadf83e4bc2ef9ea143d6209bc45ae9e7ae9787dbcd8333c41f12c0b6deee8dcb6805e826a\",\n    \"0xaba176b92256efb68f574e543479e5cf0376889fb48e3db4ebfb7cba91e4d9bcf19dcfec444c6622d9398f06de29e2b9\",\n    \"0xb9f743691448053216f6ece7cd699871fff4217a1409ceb8ab7bdf3312d11696d62c74b0664ba0a631b1e0237a8a0361\",\n    \"0xa383c2b6276fa9af346b21609326b53fb14fdf6f61676683076e80f375b603645f2051985706d0401e6fbed7eb0666b6\",\n    \"0xa9ef2f63ec6d9beb8f3d04e36807d84bda87bdd6b351a3e4a9bf7edcb5618c46c1f58cfbf89e64b40f550915c6988447\",\n    \"0xa141b2d7a82f5005eaea7ae7d112c6788b9b95121e5b70b7168d971812f3381de8b0082ac1f0a82c7d365922ebd2d26a\",\n    \"0xb1b76ef8120e66e1535c17038b75255a07849935d3128e3e99e56567b842fb1e8d56ef932d508d2fb18b82f7868fe1a9\",\n    \"0x8e2e234684c81f21099f5c54f6bbe2dd01e3b172623836c77668a0c49ce1fe218786c3827e4d9ae2ea25c50a8924fb3c\",\n    \"0xa5caf5ff948bfd3c4ca3ffbdfcd91eec83214a6c6017235f309a0bbf7061d3b0b466307c00b44a1009cf575163898b43\",\n    \"0x986415a82ca16ebb107b4c50b0c023c28714281db0bcdab589f6cb13d80e473a3034b7081b3c358e725833f6d845cb14\",\n    \"0xb94836bf406ac2cbacb10e6df5bcdfcc9d9124ae1062767ca4e322d287fd5e353fdcebd0e52407cb3cd68571258a8900\",\n    \"0x83c6d70a640b33087454a4788dfd9ef3ed00272da084a8d36be817296f71c086b23b576f98178ab8ca6a74f04524b46b\",\n    \"0xad4115182ad784cfe11bcfc5ce21fd56229cc2ce77ac82746e91a2f0aa53ca6593a22efd2dc4ed8d00f84542643d9c58\",\n    \"0xab1434c5e5065da826d10c2a2dba0facccab0e52b506ce0ce42fbe47ced5a741797151d9ecc99dc7d6373cfa1779bbf6\",\n    \"0x8a8b591d82358d55e6938f67ea87a89097ab5f5496f7260adb9f649abb289da12b498c5b2539c2f9614fb4e21b1f66b0\",\n    \"0x964f355d603264bc1f44c64d6d64debca66f37dff39c971d9fc924f2bc68e6c187b48564a6dc82660a98b035f8addb5d\",\n    \"0xb66235eaaf47456bc1dc4bde454a028e2ce494ece6b713a94cd6bf27cf18c717fd0c57a5681caaa2ad73a473593cdd7a\",\n    \"0x9103e3bb74304186fa4e3e355a02da77da4aca9b7e702982fc2082af67127ebb23a455098313c88465bc9b7d26820dd5\",\n    \"0xb6a42ff407c9dd132670cdb83cbad4b20871716e44133b59a932cd1c3f97c7ac8ff7f61acfaf8628372508d8dc8cad7c\",\n    \"0x883a9c21c16a167a4171b0f084565c13b6f28ba7c4977a0de69f0a25911f64099e7bbb4da8858f2e93068f4155d04e18\",\n    \"0x8dbb3220abc6a43220adf0331e3903d3bfd1d5213aadfbd8dfcdf4b2864ce2e96a71f35ecfb7a07c3bbabf0372b50271\",\n    \"0xb4ad08aee48e176bda390b7d9acf2f8d5eb008f30d20994707b757dc6a3974b2902d29cd9b4d85e032810ad25ac49e97\",\n    \"0x865bb0f33f7636ec501bb634e5b65751c8a230ae1fa807a961a8289bbf9c7fe8c59e01fbc4c04f8d59b7f539cf79ddd5\",\n    \"0x86a54d4c12ad1e3605b9f93d4a37082fd26e888d2329847d89afa7802e815f33f38185c5b7292293d788ad7d7da1df97\",\n    \"0xb26c8615c5e47691c9ff3deca3021714662d236c4d8401c5d27b50152ce7e566266b9d512d14eb63e65bc1d38a16f914\",\n    \"0x827639d5ce7db43ba40152c8a0eaad443af21dc92636cc8cc2b35f10647da7d475a1e408901cd220552fddad79db74df\",\n    \"0xa2b79a582191a85dbe22dc384c9ca3de345e69f6aa370aa6d3ff1e1c3de513e30b72df9555b15a46586bd27ea2854d9d\",\n    \"0xae0d74644aba9a49521d3e9553813bcb9e18f0b43515e4c74366e503c52f47236be92dfbd99c7285b3248c267b1de5a0\",\n    \"0x80fb0c116e0fd6822a04b9c25f456bdca704e2be7bdc5d141dbf5d1c5eeb0a2c4f5d80db583b03ef3e47517e4f9a1b10\",\n    \"0xac3a1fa3b4a2f30ea7e0a114cdc479eb51773573804c2a158d603ad9902ae8e39ffe95df09c0d871725a5d7f9ba71a57\",\n    \"0xb56b2b0d601cba7f817fa76102c68c2e518c6f20ff693aad3ff2e07d6c4c76203753f7f91686b1801e8c4659e4d45c48\",\n    \"0x89d50c1fc56e656fb9d3915964ebce703cb723fe411ab3c9eaa88ccc5d2b155a9b2e515363d9c600d3c0cee782c43f41\",\n    \"0xb24207e61462f6230f3cd8ccf6828357d03e725769f7d1de35099ef9ee4dca57dbce699bb49ed994462bee17059d25ce\",\n    \"0xb886f17fcbcbfcd08ac07f04bb9543ef58510189decaccea4b4158c9174a067cb67d14b6be3c934e6e2a18c77efa9c9c\",\n    \"0xb9c050ad9cafd41c6e2e192b70d080076eed59ed38ea19a12bd92fa17b5d8947d58d5546aaf5e8e27e1d3b5481a6ce51\",\n    \"0xaaf7a34d3267e3b1ddbc54c641e3922e89303f7c86ebebc7347ebca4cffad5b76117dac0cbae1a133053492799cd936f\",\n    \"0xa9ee604ada50adef82e29e893070649d2d4b7136cc24fa20e281ce1a07bd736bf0de7c420369676bcbcecff26fb6e900\",\n    \"0x9855315a12a4b4cf80ab90b8bd13003223ba25206e52fd4fe6a409232fbed938f30120a3db23eab9c53f308bd8b9db81\",\n    \"0x8cd488dd7a24f548a3cf03c54dec7ff61d0685cb0f6e5c46c2d728e3500d8c7bd6bba0156f4bf600466fda53e5b20444\",\n    \"0x890ad4942ebac8f5b16c777701ab80c68f56fa542002b0786f8fea0fb073154369920ac3dbfc07ea598b82f4985b8ced\",\n    \"0x8de0cf9ddc84c9b92c59b9b044387597799246b30b9f4d7626fc12c51f6e423e08ee4cbfe9289984983c1f9521c3e19d\",\n    \"0xb474dfb5b5f4231d7775b3c3a8744956b3f0c7a871d835d7e4fd9cc895222c7b868d6c6ce250de568a65851151fac860\",\n    \"0x86433b6135d9ed9b5ee8cb7a6c40e5c9d30a68774cec04988117302b8a02a11a71a1e03fd8e0264ef6611d219f103007\",\n    \"0x80b9ed4adbe9538fb1ef69dd44ec0ec5b57cbfea820054d8d445b4261962624b4c70ac330480594bc5168184378379c3\",\n    \"0x8b2e83562ccd23b7ad2d17f55b1ab7ef5fbef64b3a284e6725b800f3222b8bdf49937f4a873917ada9c4ddfb090938c2\",\n    \"0xabe78cebc0f5a45d754140d1f685e387489acbfa46d297a8592aaa0d676a470654f417a4f7d666fc0b2508fab37d908e\",\n    \"0xa9c5f8ff1f8568e252b06d10e1558326db9901840e6b3c26bbd0cd5e850cb5fb3af3f117dbb0f282740276f6fd84126f\",\n    \"0x975f8dc4fb55032a5df3b42b96c8c0ffecb75456f01d4aef66f973cb7270d4eff32c71520ceefc1adcf38d77b6b80c67\",\n    \"0xb043306ed2c3d8a5b9a056565afd8b5e354c8c4569fda66b0d797a50a3ce2c08cffbae9bbe292da69f39e89d5dc7911e\",\n    \"0x8d2afc36b1e44386ba350c14a6c1bb31ff6ea77128a0c5287584ac3584282d18516901ce402b4644a53db1ed8e7fa581\",\n    \"0x8c294058bed53d7290325c363fe243f6ec4f4ea2343692f4bac8f0cb86f115c069ccb8334b53d2e42c067691ad110dba\",\n    \"0xb92157b926751aaf7ef82c1aa8c654907dccab6376187ee8b3e8c0c82811eae01242832de953faa13ebaff7da8698b3e\",\n    \"0xa780c4bdd9e4ba57254b09d745075cecab87feda78c88ffee489625c5a3cf96aa6b3c9503a374a37927d9b78de9bd22b\",\n    \"0x811f548ef3a2e6a654f7dcb28ac9378de9515ed61e5a428515d9594a83e80b35c60f96a5cf743e6fab0d3cb526149f49\",\n    \"0x85a4dccf6d90ee8e094731eec53bd00b3887aec6bd81a0740efddf812fd35e3e4fe4f983afb49a8588691c202dabf942\",\n    \"0xb152c2da6f2e01c8913079ae2b40a09b1f361a80f5408a0237a8131b429677c3157295e11b365b1b1841924b9efb922e\",\n    \"0x849b9efee8742502ffd981c4517c88ed33e4dd518a330802caff168abae3cd09956a5ee5eda15900243bc2e829016b74\",\n    \"0x955a933f3c18ec0f1c0e38fa931e4427a5372c46a3906ebe95082bcf878c35246523c23f0266644ace1fa590ffa6d119\",\n    \"0x911989e9f43e580c886656377c6f856cdd4ff1bd001b6db3bbd86e590a821d34a5c6688a29b8d90f28680e9fdf03ba69\",\n    \"0xb73b8b4f1fd6049fb68d47cd96a18fcba3f716e0a1061aa5a2596302795354e0c39dea04d91d232aec86b0bf2ba10522\",\n    \"0x90f87456d9156e6a1f029a833bf3c7dbed98ca2f2f147a8564922c25ae197a55f7ea9b2ee1f81bf7383197c4bad2e20c\",\n    \"0x903cba8b1e088574cb04a05ca1899ab00d8960580c884bd3c8a4c98d680c2ad11410f2b75739d6050f91d7208cac33a5\",\n    \"0x9329987d42529c261bd15ecedd360be0ea8966e7838f32896522c965adfc4febf187db392bd441fb43bbd10c38fdf68b\",\n    \"0x8178ee93acf5353baa349285067b20e9bb41aa32d77b5aeb7384fe5220c1fe64a2461bd7a83142694fe673e8bbf61b7c\",\n    \"0xa06a8e53abcff271b1394bcc647440f81fb1c1a5f29c27a226e08f961c3353f4891620f2d59b9d1902bf2f5cc07a4553\",\n    \"0xaaf5fe493b337810889e777980e6bbea6cac39ac66bc0875c680c4208807ac866e9fda9b5952aa1d04539b9f4a4bec57\",\n    \"0xaa058abb1953eceac14ccfa7c0cc482a146e1232905dcecc86dd27f75575285f06bbae16a8c9fe8e35d8713717f5f19f\",\n    \"0x8f15dd732799c879ca46d2763453b359ff483ca33adb1d0e0a57262352e0476c235987dc3a8a243c74bc768f93d3014c\",\n    \"0xa61cc8263e9bc03cce985f1663b8a72928a607121005a301b28a278e9654727fd1b22bc8a949af73929c56d9d3d4a273\",\n    \"0x98d6dc78502d19eb9f921225475a6ebcc7b44f01a2df6f55ccf6908d65b27af1891be2a37735f0315b6e0f1576c1f8d8\",\n    \"0x8bd258b883f3b3793ec5be9472ad1ff3dc4b51bc5a58e9f944acfb927349ead8231a523cc2175c1f98e7e1e2b9f363b8\",\n    \"0xaeacc2ecb6e807ad09bedd99654b097a6f39840e932873ace02eabd64ccfbb475abdcb62939a698abf17572d2034c51e\",\n    \"0xb8ccf78c08ccd8df59fd6eda2e01de328bc6d8a65824d6f1fc0537654e9bc6bf6f89c422dd3a295cce628749da85c864\",\n    \"0x8f91fd8cb253ba2e71cc6f13da5e05f62c2c3b485c24f5d68397d04665673167fce1fc1aec6085c69e87e66ec555d3fd\",\n    \"0xa254baa10cb26d04136886073bb4c159af8a8532e3fd36b1e9c3a2e41b5b2b6a86c4ebc14dbe624ee07b7ccdaf59f9ab\",\n    \"0x94e3286fe5cd68c4c7b9a7d33ae3d714a7f265cf77cd0e9bc19fc51015b1d1c34ad7e3a5221c459e89f5a043ee84e3a9\",\n    \"0xa279da8878af8d449a9539bec4b17cea94f0242911f66fab275b5143ab040825f78c89cb32a793930609415cfa3a1078\",\n    \"0xac846ceb89c9e5d43a2991c8443079dc32298cd63e370e64149cec98cf48a6351c09c856f2632fd2f2b3d685a18bbf8b\",\n    \"0xa847b27995c8a2e2454aaeb983879fb5d3a23105c33175839f7300b7e1e8ec3efd6450e9fa3f10323609dee7b98c6fd5\",\n    \"0xa2f432d147d904d185ff4b2de8c6b82fbea278a2956bc406855b44c18041854c4f0ecccd472d1d0dff1d8aa8e281cb1d\",\n    \"0x94a48ad40326f95bd63dff4755f863a1b79e1df771a1173b17937f9baba57b39e651e7695be9f66a472f098b339364fc\",\n    \"0xa12a0ccd8f96e96e1bc6494341f7ebce959899341b3a084aa1aa87d1c0d489ac908552b7770b887bb47e7b8cbc3d8e66\",\n    \"0x81a1f1681bda923bd274bfe0fbb9181d6d164fe738e54e25e8d4849193d311e2c4253614ed673c98af2c798f19a93468\",\n    \"0xabf71106a05d501e84cc54610d349d7d5eae21a70bd0250f1bebbf412a130414d1c8dbe673ffdb80208fd72f1defa4d4\",\n    \"0x96266dc2e0df18d8136d79f5b59e489978eee0e6b04926687fe389d4293c14f36f055c550657a8e27be4118b64254901\",\n    \"0x8df5dcbefbfb4810ae3a413ca6b4bf08619ca53cd50eb1dde2a1c035efffc7b7ac7dff18d403253fd80104bd83dc029e\",\n    \"0x9610b87ff02e391a43324a7122736876d5b3af2a137d749c52f75d07b17f19900b151b7f439d564f4529e77aa057ad12\",\n    \"0xa90a5572198b40fe2fcf47c422274ff36c9624df7db7a89c0eb47eb48a73a03c985f4ac5016161c76ca317f64339bce1\",\n    \"0x98e5e61a6ab6462ba692124dba7794b6c6bde4249ab4fcc98c9edd631592d5bc2fb5e38466691a0970a38e48d87c2e43\",\n    \"0x918cefb8f292f78d4db81462c633daf73b395e772f47b3a7d2cea598025b1d8c3ec0cbff46cdb23597e74929981cde40\",\n    \"0xa98918a5dc7cf610fe55f725e4fd24ce581d594cb957bb9b4e888672e9c0137003e1041f83e3f1d7b9caab06462c87d4\",\n    \"0xb92b74ac015262ca66c33f2d950221e19d940ba3bf4cf17845f961dc1729ae227aa9e1f2017829f2135b489064565c29\",\n    \"0xa053ee339f359665feb178b4e7ee30a85df37debd17cacc5a27d6b3369d170b0114e67ad1712ed26d828f1df641bcd99\",\n    \"0x8c3c8bad510b35da5ce5bd84b35c958797fbea024ad1c97091d2ff71d9b962e9222f65a9b776e5b3cc29c36e1063d2ee\",\n    \"0xaf99dc7330fe7c37e850283eb47cc3257888e7c197cb0d102edf94439e1e02267b6a56306d246c326c4c79f9dc8c6986\",\n    \"0xafecb2dc34d57a725efbd7eb93d61eb29dbe8409b668ab9ea040791f5b796d9be6d4fc10d7f627bf693452f330cf0435\",\n    \"0x93334fedf19a3727a81a6b6f2459db859186227b96fe7a391263f69f1a0884e4235de64d29edebc7b99c44d19e7c7d7a\",\n    \"0x89579c51ac405ad7e9df13c904061670ce4b38372492764170e4d3d667ed52e5d15c7cd5c5991bbfa3a5e4e3fa16363e\",\n    \"0x9778f3e8639030f7ef1c344014f124e375acb8045bd13d8e97a92c5265c52de9d1ffebaa5bc3e1ad2719da0083222991\",\n    \"0x88f77f34ee92b3d36791bdf3326532524a67d544297dcf1a47ff00b47c1b8219ff11e34034eab7d23b507caa2fd3c6b9\",\n    \"0xa699c1e654e7c484431d81d90657892efeb4adcf72c43618e71ca7bd7c7a7ebbb1db7e06e75b75dc4c74efd306b5df3f\",\n    \"0x81d13153baebb2ef672b5bdb069d3cd669ce0be96b742c94e04038f689ff92a61376341366b286eee6bf3ae85156f694\",\n    \"0x81efb17de94400fdacc1deec2550cbe3eecb27c7af99d8207e2f9be397e26be24a40446d2a09536bb5172c28959318d9\",\n    \"0x989b21ebe9ceab02488992673dc071d4d5edec24bff0e17a4306c8cb4b3c83df53a2063d1827edd8ed16d6e837f0d222\",\n    \"0x8d6005d6536825661b13c5fdce177cb37c04e8b109b7eb2b6d82ea1cb70efecf6a0022b64f84d753d165edc2bba784a3\",\n    \"0xa32607360a71d5e34af2271211652d73d7756d393161f4cf0da000c2d66a84c6826e09e759bd787d4fd0305e2439d342\",\n    \"0xaaad8d6f6e260db45d51b2da723be6fa832e76f5fbcb77a9a31e7f090dd38446d3b631b96230d78208cae408c288ac4e\",\n    \"0xabcfe425255fd3c5cffd3a818af7650190c957b6b07b632443f9e33e970a8a4c3bf79ac9b71f4d45f238a04d1c049857\",\n    \"0xaeabf026d4c783adc4414b5923dbd0be4b039cc7201219f7260d321f55e9a5b166d7b5875af6129c034d0108fdc5d666\",\n    \"0xaf49e740c752d7b6f17048014851f437ffd17413c59797e5078eaaa36f73f0017c3e7da020310cfe7d3c85f94a99f203\",\n    \"0x8854ca600d842566e3090040cd66bb0b3c46dae6962a13946f0024c4a8aca447e2ccf6f240045f1ceee799a88cb9210c\",\n    \"0xb6c03b93b1ab1b88ded8edfa1b487a1ed8bdce8535244dddb558ffb78f89b1c74058f80f4db2320ad060d0c2a9c351cc\",\n    \"0xb5bd7d17372faff4898a7517009b61a7c8f6f0e7ed4192c555db264618e3f6e57fb30a472d169fea01bf2bf0362a19a8\",\n    \"0x96eb1d38319dc74afe7e7eb076fcd230d19983f645abd14a71e6103545c01301b31c47ae931e025f3ecc01fb3d2f31fa\",\n    \"0xb55a8d30d4403067def9b65e16f867299f8f64c9b391d0846d4780bc196569622e7e5b64ce799b5aefac8f965b2a7a7b\",\n    \"0x8356d199a991e5cbbff608752b6291731b6b6771aed292f8948b1f41c6543e4ab1bedc82dd26d10206c907c03508df06\",\n    \"0x97f4137445c2d98b0d1d478049de952610ad698c91c9d0f0e7227d2aae690e9935e914ec4a2ea1fbf3fc1dddfeeacebb\",\n    \"0xaf5621707e0938320b15ddfc87584ab325fbdfd85c30efea36f8f9bd0707d7ec12c344eff3ec21761189518d192df035\",\n    \"0x8ac7817e71ea0825b292687928e349da7140285d035e1e1abff0c3704fa8453faaae343a441b7143a74ec56539687cc4\",\n    \"0x8a5e0a9e4758449489df10f3386029ada828d1762e4fb0a8ffe6b79e5b6d5d713cb64ed95960e126398b0cdb89002bc9\",\n    \"0x81324be4a71208bbb9bca74b77177f8f1abb9d3d5d9db195d1854651f2cf333cd618d35400da0f060f3e1b025124e4b2\",\n    \"0x849971d9d095ae067525b3cbc4a7dfae81f739537ade6d6cec1b42fb692d923176197a8770907c58069754b8882822d6\",\n    \"0x89f830825416802477cc81fdf11084885865ee6607aa15aa4eb28e351c569c49b8a1b9b5e95ddc04fa0ebafe20071313\",\n    \"0x9240aeeaff37a91af55f860b9badd466e8243af9e8c96a7aa8cf348cd270685ab6301bc135b246dca9eda696f8b0e350\",\n    \"0xacf74db78cc33138273127599eba35b0fb4e7b9a69fe02dae18fc6692d748ca332bd00b22afa8e654ed587aab11833f3\",\n    \"0xb091e6d37b157b50d76bd297ad752220cd5c9390fac16dc838f8557aed6d9833fc920b61519df21265406216315e883f\",\n    \"0xa6446c429ebf1c7793c622250e23594c836b2fbcaf6c5b3d0995e1595a37f50ea643f3e549b0be8bbdadd69044d72ab9\",\n    \"0x93e675353bd60e996bf1c914d5267eeaa8a52fc3077987ccc796710ef9becc6b7a00e3d82671a6bdfb8145ee3c80245a\",\n    \"0xa2f731e43251d04ed3364aa2f072d05355f299626f2d71a8a38b6f76cf08c544133f7d72dd0ab4162814b674b9fc7fa6\",\n    \"0x97a8b791a5a8f6e1d0de192d78615d73d0c38f1e557e4e15d15adc663d649e655bc8da3bcc499ef70112eafe7fb45c7a\",\n    \"0x98cd624cbbd6c53a94469be4643c13130916b91143425bcb7d7028adbbfede38eff7a21092af43b12d4fab703c116359\",\n    \"0x995783ce38fd5f6f9433027f122d4cf1e1ff3caf2d196ce591877f4a544ce9113ead60de2de1827eaff4dd31a20d79a8\",\n    \"0x8cf251d6f5229183b7f3fe2f607a90b4e4b6f020fb4ba2459d28eb8872426e7be8761a93d5413640a661d73e34a5b81f\",\n    \"0xb9232d99620652a3aa7880cad0876f153ff881c4ed4c0c2e7b4ea81d5d42b70daf1a56b869d752c3743c6d4c947e6641\",\n    \"0x849716f938f9d37250cccb1bf77f5f9fde53096cdfc6f2a25536a6187029a8f1331cdbed08909184b201f8d9f04b792f\",\n    \"0x80c7c4de098cbf9c6d17b14eba1805e433b5bc905f6096f8f63d34b94734f2e4ebf4bce8a177efd1186842a61204a062\",\n    \"0xb790f410cf06b9b8daadceeb4fd5ff40a2deda820c8df2537e0a7554613ae3948e149504e3e79aa84889df50c8678eeb\",\n    \"0x813aab8bd000299cd37485b73cd7cba06e205f8efb87f1efc0bae8b70f6db2bc7702eb39510ad734854fb65515fe9d0f\",\n    \"0x94f0ab7388ac71cdb67f6b85dfd5945748afb2e5abb622f0b5ad104be1d4d0062b651f134ba22385c9e32c2dfdcccce1\",\n    \"0xab6223dca8bd6a4f969e21ccd9f8106fc5251d321f9e90cc42cea2424b3a9c4e5060a47eeef6b23c7976109b548498e8\",\n    \"0x859c56b71343fce4d5c5b87814c47bf55d581c50fd1871a17e77b5e1742f5af639d0e94d19d909ec7dfe27919e954e0c\",\n    \"0xaae0d632b6191b8ad71b027791735f1578e1b89890b6c22e37de0e4a6074886126988fe8319ae228ac9ef3b3bcccb730\",\n    \"0x8ca9f32a27a024c3d595ecfaf96b0461de57befa3b331ab71dc110ec3be5824fed783d9516597537683e77a11d334338\",\n    \"0xa061df379fb3f4b24816c9f6cd8a94ecb89b4c6dc6cd81e4b8096fa9784b7f97ab3540259d1de9c02eb91d9945af4823\",\n    \"0x998603102ac63001d63eb7347a4bb2bf4cf33b28079bb48a169076a65c20d511ccd3ef696d159e54cc8e772fb5d65d50\",\n    \"0x94444d96d39450872ac69e44088c252c71f46be8333a608a475147752dbb99db0e36acfc5198f158509401959c12b709\",\n    \"0xac1b51b6c09fe055c1d7c9176eea9adc33f710818c83a1fbfa073c8dc3a7eb3513cbdd3f5960b7845e31e3e83181e6ba\",\n    \"0x803d530523fc9e1e0f11040d2412d02baef3f07eeb9b177fa9bfa396af42eea898a4276d56e1db998dc96ae47b644cb2\",\n    \"0x85a3c9fc7638f5bf2c3e15ba8c2fa1ae87eb1ceb44c6598c67a2948667a9dfa41e61f66d535b4e7fda62f013a5a8b885\",\n    \"0xa961cf5654c46a1a22c29baf7a4e77837a26b7f138f410e9d1883480ed5fa42411d522aba32040b577046c11f007388e\",\n    \"0xad1154142344f494e3061ef45a34fab1aaacf5fdf7d1b26adbb5fbc3d795655fa743444e39d9a4119b4a4f82a6f30441\",\n    \"0xb1d6c30771130c77806e7ab893b73d4deb590b2ff8f2f8b5e54c2040c1f3e060e2bd99afc668cf706a2df666a508bbf6\",\n    \"0xa00361fd440f9decabd98d96c575cd251dc94c60611025095d1201ef2dedde51cb4de7c2ece47732e5ed9b3526c2012c\",\n    \"0xa85c5ab4d17d328bda5e6d839a9a6adcc92ff844ec25f84981e4f44a0e8419247c081530f8d9aa629c7eb4ca21affba6\",\n    \"0xa4ddd3eab4527a2672cf9463db38bc29f61460e2a162f426b7852b7a7645fbd62084fd39a8e4d60e1958cce436dd8f57\",\n    \"0x811648140080fe55b8618f4cf17f3c5a250adb0cd53d885f2ddba835d2b4433188e41fc0661faac88e4ff910b16278c0\",\n    \"0xb85c7f1cfb0ed29addccf7546023a79249e8f15ac2d14a20accbfef4dd9dc11355d599815fa09d2b6b4e966e6ea8cff1\",\n    \"0xa10b5d8c260b159043b020d5dd62b3467df2671afea6d480ca9087b7e60ed170c82b121819d088315902842d66c8fb45\",\n    \"0x917e191df1bcf3f5715419c1e2191da6b8680543b1ba41fe84ed07ef570376e072c081beb67b375fca3565a2565bcabb\",\n    \"0x881fd967407390bfd7badc9ab494e8a287559a01eb07861f527207c127eadea626e9bcc5aa9cca2c5112fbac3b3f0e9c\",\n    \"0x959fd71149af82cc733619e0e5bf71760ca2650448c82984b3db74030d0e10f8ab1ce1609a6de6f470fe8b5bd90df5b3\",\n    \"0xa3370898a1c5f33d15adb4238df9a6c945f18b9ada4ce2624fc32a844f9ece4c916a64e9442225b6592afa06d2e015f2\",\n    \"0x817efb8a791435e4236f7d7b278181a5fa34587578c629dbc14fbf9a5c26772290611395eecd20222a4c58649fc256d8\",\n    \"0xa04c9876acf2cfdc8ef96de4879742709270fa1d03fe4c8511fbef2d59eb0aaf0336fa2c7dfe41a651157377fa217813\",\n    \"0x81e15875d7ea7f123e418edf14099f2e109d4f3a6ce0eb65f67fe9fb10d2f809a864a29f60ad3fc949f89e2596b21783\",\n    \"0xb49f529975c09e436e6bc202fdc16e3fdcbe056db45178016ad6fdece9faad4446343e83aed096209690b21a6910724f\",\n    \"0x879e8eda589e1a279f7f49f6dd0580788c040d973748ec4942dbe51ea8fbd05983cc919b78f0c6b92ef3292ae29db875\",\n    \"0x81a2b74b2118923f34139a102f3d95e7eee11c4c2929c2576dee200a5abfd364606158535a6c9e4178a6a83dbb65f3c4\",\n    \"0x8913f281d8927f2b45fc815d0f7104631cb7f5f7278a316f1327d670d15868daadd2a64e3eb98e1f53fe7e300338cc80\",\n    \"0xa6f815fba7ef9af7fbf45f93bc952e8b351f5de6568a27c7c47a00cb39a254c6b31753794f67940fc7d2e9cc581529f4\",\n    \"0xb3722a15c66a0014ce4d082de118def8d39190c15678a472b846225585f3a83756ae1b255b2e3f86a26168878e4773b2\",\n    \"0x817ae61ab3d0dd5b6e24846b5a5364b1a7dc2e77432d9fed587727520ae2f307264ea0948c91ad29f0aea3a11ff38624\",\n    \"0xb3db467464415fcad36dc1de2d6ba7686772a577cc2619242ac040d6734881a45d3b40ed4588db124e4289cfeec4bbf6\",\n    \"0xad66a14f5a54ac69603b16e5f1529851183da77d3cc60867f10aea41339dd5e06a5257982e9e90a352cdd32750f42ee4\",\n    \"0xadafa3681ef45d685555601a25a55cf23358319a17f61e2179e704f63df83a73bdd298d12cf6cef86db89bd17119e11d\",\n    \"0xa379dc44cb6dd3b9d378c07b2ec654fec7ca2f272de6ba895e3d00d20c9e4c5550498a843c8ac67e4221db2115bedc1c\",\n    \"0xb7bf81c267a78efc6b9e5a904574445a6487678d7ef70054e3e93ea6a23f966c2b68787f9164918e3b16d2175459ed92\",\n    \"0xb41d66a13a4afafd5760062b77f79de7e6ab8ccacde9c6c5116a6d886912fb491dc027af435b1b44aacc6af7b3c887f2\",\n    \"0x9904d23a7c1c1d2e4bab85d69f283eb0a8e26d46e8b7b30224438015c936729b2f0af7c7c54c03509bb0500acb42d8a4\",\n    \"0xae30d65e9e20c3bfd603994ae2b175ff691d51f3e24b2d058b3b8556d12ca4c75087809062dddd4aaac81c94d15d8a17\",\n    \"0x9245162fab42ac01527424f6013310c3eb462982518debef6c127f46ba8a06c705d7dc9f0a41e796ba8d35d60ae6cc64\",\n    \"0x87fab853638d7a29a20f3ba2b1a7919d023e9415bfa78ebb27973d8cbc7626f584dc5665d2e7ad71f1d760eba9700d88\",\n    \"0x85aac46ecd330608e5272430970e6081ff02a571e8ea444f1e11785ea798769634a22a142d0237f67b75369d3c484a8a\",\n    \"0x938c85ab14894cc5dfce3d80456f189a2e98eddbc8828f4ff6b1df1dcb7b42b17ca2ff40226a8a1390a95d63dca698dd\",\n    \"0xa18ce1f846e3e3c4d846822f60271eecf0f5d7d9f986385ac53c5ace9589dc7c0188910448c19b91341a1ef556652fa9\",\n    \"0x8611608a9d844f0e9d7584ad6ccf62a5087a64f764caf108db648a776b5390feb51e5120f0ef0e9e11301af3987dd7dc\",\n    \"0x8106333ba4b4de8d1ae43bc9735d3fea047392e88efd6a2fa6f7b924a18a7a265ca6123c3edc0f36307dd7fb7fe89257\",\n    \"0xa91426fa500951ff1b051a248c050b7139ca30dde8768690432d597d2b3c4357b11a577be6b455a1c5d145264dcf81fc\",\n    \"0xb7f9f90e0e450f37b081297f7f651bad0496a8b9afd2a4cf4120a2671aaaa8536dce1af301258bfbfdb122afa44c5048\",\n    \"0x84126da6435699b0c09fa4032dec73d1fca21d2d19f5214e8b0bea43267e9a8dd1fc44f8132d8315e734c8e2e04d7291\",\n    \"0xaff064708103884cb4f1a3c1718b3fc40a238d35cf0a7dc24bdf9823693b407c70da50df585bf5bc4e9c07d1c2d203e8\",\n    \"0xa8b40fc6533752983a5329c31d376c7a5c13ce6879cc7faee648200075d9cd273537001fb4c86e8576350eaac6ba60c2\",\n    \"0xa02db682bdc117a84dcb9312eb28fcbde12d49f4ce915cc92c610bb6965ec3cc38290f8c5b5ec70afe153956692cda95\",\n    \"0x86decd22b25d300508472c9ce75d3e465b737e7ce13bc0fcce32835e54646fe12322ba5bc457be18bfd926a1a6ca4a38\",\n    \"0xa18666ef65b8c2904fd598791f5627207165315a85ee01d5fb0e6b2e10bdd9b00babc447da5bd63445e3337de33b9b89\",\n    \"0x89bb0c06effadefdaf34ffe4b123e1678a90d4451ee856c863df1e752eef41fd984689ded8f0f878bf8916d5dd8e8024\",\n    \"0x97cfcba08ebec05d0073992a66b1d7d6fb9d95871f2cdc36db301f78bf8069294d1c259efef5c93d20dc937eedae3a1a\",\n    \"0xac2643b14ece79dcb2e289c96776a47e2bebd40dd6dc74fd035df5bb727b5596f40e3dd2d2202141e69b0993717ede09\",\n    \"0xa5e6fd88a2f9174d9bd4c6a55d9c30974be414992f22aa852f552c7648f722ed8077acf5aba030abd47939bb451b2c60\",\n    \"0x8ad40a612824a7994487731a40b311b7349038c841145865539c6ada75c56de6ac547a1c23df190e0caaafecddd80ccc\",\n    \"0x953a7cea1d857e09202c438c6108060961f195f88c32f0e012236d7a4b39d840c61b162ec86436e8c38567328bea0246\",\n    \"0x80d8b47a46dae1868a7b8ccfe7029445bbe1009dad4a6c31f9ef081be32e8e1ac1178c3c8fb68d3e536c84990cc035b1\",\n    \"0x81ecd99f22b3766ce0aca08a0a9191793f68c754fdec78b82a4c3bdc2db122bbb9ebfd02fc2dcc6e1567a7d42d0cc16a\",\n    \"0xb1dd0446bccc25846fb95d08c1c9cc52fb51c72c4c5d169ffde56ecfe800f108dc1106d65d5c5bd1087c656de3940b63\",\n    \"0xb87547f0931e164e96de5c550ca5aa81273648fe34f6e193cd9d69cf729cb432e17aa02e25b1c27a8a0d20a3b795e94e\",\n    \"0x820a94e69a927e077082aae66f6b292cfbe4589d932edf9e68e268c9bd3d71ef76cf7d169dd445b93967c25db11f58f1\",\n    \"0xb0d07ddf2595270c39adfa0c8cf2ab1322979b0546aa4d918f641be53cd97f36c879bb75d205e457c011aca3bbd9f731\",\n    \"0x8700b876b35b4b10a8a9372c5230acecd39539c1bb87515640293ad4464a9e02929d7d6a6a11112e8a29564815ac0de4\",\n    \"0xa61a601c5bb27dcb97e37c8e2b9ce479c6b192a5e04d9ed5e065833c5a1017ee5f237b77d1a17be5d48f8e7cc0bcacf6\",\n    \"0x92fb88fe774c1ba1d4a08cae3c0e05467ad610e7a3f1d2423fd47751759235fe0a3036db4095bd6404716aa03820f484\",\n    \"0xb274f140d77a3ce0796f5e09094b516537ccaf27ae1907099bff172e6368ba85e7c3ef8ea2a07457cac48ae334da95b3\",\n    \"0xb2292d9181f16581a9a9142490b2bdcdfb218ca6315d1effc8592100d792eb89d5356996c890441f04f2b4a95763503e\",\n    \"0x8897e73f576d86bc354baa3bd96e553107c48cf5889dcc23c5ba68ab8bcd4e81f27767be2233fdfa13d39f885087e668\",\n    \"0xa29eac6f0829791c728d71abc49569df95a4446ecbfc534b39f24f56c88fe70301838dfc1c19751e7f3c5c1b8c6af6a0\",\n    \"0x9346dc3720adc5df500a8df27fd9c75ef38dc5c8f4e8ed66983304750e66d502c3c59b8e955be781b670a0afc70a2167\",\n    \"0x9566d534e0e30a5c5f1428665590617e95fd05d45f573715f58157854ad596ece3a3cfec61356aee342308d623e029d5\",\n    \"0xa464fb8bffe6bd65f71938c1715c6e296cc6d0311a83858e4e7eb5873b7f2cf0c584d2101e3407b85b64ca78b2ac93ce\",\n    \"0xb54088f7217987c87e9498a747569ac5b2f8afd5348f9c45bf3fd9fbf713a20f495f49c8572d087efe778ac7313ad6d3\",\n    \"0x91fa9f5f8000fe050f5b224d90b59fcce13c77e903cbf98ded752e5b3db16adb2bc1f8c94be48b69f65f1f1ad81d6264\",\n    \"0x92d04a5b0ac5d8c8e313709b432c9434ecd3e73231f01e9b4e7952b87df60cbfa97b5dedd2200bd033b4b9ea8ba45cc1\",\n    \"0xa94b90ad3c3d6c4bbe169f8661a790c40645b40f0a9d1c7220f01cf7fc176e04d80bab0ced9323fcafb93643f12b2760\",\n    \"0x94d86149b9c8443b46196f7e5a3738206dd6f3be7762df488bcbb9f9ee285a64c997ed875b7b16b26604fa59020a8199\",\n    \"0x82efe4ae2c50a2d7645240c173a047f238536598c04a2c0b69c96e96bd18e075a99110f1206bc213f39edca42ba00cc1\",\n    \"0xab8667685f831bc14d4610f84a5da27b4ea5b133b4d991741a9e64dceb22cb64a3ce8f1b6e101d52af6296df7127c9ad\",\n    \"0x83ba433661c05dcc5d562f4a9a261c8110dac44b8d833ae1514b1fc60d8b4ee395b18804baea04cb10adb428faf713c3\",\n    \"0xb5748f6f660cc5277f1211d2b8649493ed8a11085b871cd33a5aea630abd960a740f08c08be5f9c21574600ac9bf5737\",\n    \"0xa5c8dd12af48fb710642ad65ebb97ca489e8206741807f7acfc334f8035d3c80593b1ff2090c9bb7bd138f0c48714ca8\",\n    \"0xa2b382fd5744e3babf454b1d806cc8783efeb4761bc42b6914ea48a46a2eae835efbe0a18262b6bc034379e03cf1262b\",\n    \"0xb3145ffaf603f69f15a64936d32e3219eea5ed49fdfd2f5bf40ea0dfd974b36fb6ff12164d4c2282d892db4cf3ff3ce1\",\n    \"0x87a316fb213f4c5e30c5e3face049db66be4f28821bd96034714ec23d3e97849d7b301930f90a4323c7ccf53de23050c\",\n    \"0xb9de09a919455070fed6220fc179c8b7a4c753062bcd27acf28f5b9947a659c0b364298daf7c85c4ca6fca7f945add1f\",\n    \"0x806fbd98d411b76979464c40ad88bc07a151628a27fcc1012ba1dfbaf5b5cc9d962fb9b3386008978a12515edce934bc\",\n    \"0xa15268877fae0d21610ae6a31061ed7c20814723385955fac09fdc9693a94c33dea11db98bb89fdfe68f933490f5c381\",\n    \"0x8d633fb0c4da86b2e0b37d8fad5972d62bff2ac663c5ec815d095cd4b7e1fe66ebef2a2590995b57eaf941983c7ad7a4\",\n    \"0x8139e5dd9cf405e8ef65f11164f0440827d98389ce1b418b0c9628be983a9ddd6cf4863036ccb1483b40b8a527acd9ed\",\n    \"0x88b15fa94a08eac291d2b94a2b30eb851ff24addf2cc30b678e72e32cfcb3424cf4b33aa395d741803f3e578ddf524de\",\n    \"0xb5eaf0c8506e101f1646bcf049ee38d99ea1c60169730da893fd6020fd00a289eb2f415947e44677af49e43454a7b1be\",\n    \"0x8489822ad0647a7e06aa2aa5595960811858ddd4542acca419dd2308a8c5477648f4dd969a6740bb78aa26db9bfcc555\",\n    \"0xb1e9a7b9f3423c220330d45f69e45fa03d7671897cf077f913c252e3e99c7b1b1cf6d30caad65e4228d5d7b80eb86e5e\",\n    \"0xb28fe9629592b9e6a55a1406903be76250b1c50c65296c10c5e48c64b539fb08fe11f68cf462a6edcbba71b0cee3feb2\",\n    \"0xa41acf96a02c96cd8744ff6577c244fc923810d17ade133587e4c223beb7b4d99fa56eae311a500d7151979267d0895c\",\n    \"0x880798938fe4ba70721be90e666dfb62fcab4f3556fdb7b0dc8ec5bc34f6b4513df965eae78527136eb391889fe2caf9\",\n    \"0x98d4d89d358e0fb7e212498c73447d94a83c1b66e98fc81427ab13acddb17a20f52308983f3a5a8e0aaacec432359604\",\n    \"0x81430b6d2998fc78ba937a1639c6020199c52da499f68109da227882dc26d005b73d54c5bdcac1a04e8356a8ca0f7017\",\n    \"0xa8d906a4786455eb74613aba4ce1c963c60095ffb8658d368df9266fdd01e30269ce10bf984e7465f34b4fd83beba26a\",\n    \"0xaf54167ac1f954d10131d44a8e0045df00d581dd9e93596a28d157543fbe5fb25d213806ed7fb3cba6b8f5b5423562db\",\n    \"0x8511e373a978a12d81266b9afbd55035d7bc736835cfa921903a92969eeba3624437d1346b55382e61415726ab84a448\",\n    \"0x8cf43eea93508ae586fa9a0f1354a1e16af659782479c2040874a46317f9e8d572a23238efa318fdfb87cc63932602b7\",\n    \"0xb0bdd3bacff077173d302e3a9678d1d37936188c7ecc34950185af6b462b7c679815176f3cce5db19aac8b282f2d60ad\",\n    \"0xa355e9b87f2f2672052f5d4d65b8c1c827d24d89b0d8594641fccfb69aef1b94009105f3242058bb31c8bf51caae5a41\",\n    \"0xb8baa9e4b950b72ff6b88a6509e8ed1304bc6fd955748b2e59a523a1e0c5e99f52aec3da7fa9ff407a7adf259652466c\",\n    \"0x840bc3dbb300ea6f27d1d6dd861f15680bd098be5174f45d6b75b094d0635aced539fa03ddbccb453879de77fb5d1fe9\",\n    \"0xb4bc7e7e30686303856472bae07e581a0c0bfc815657c479f9f5931cff208d5c12930d2fd1ff413ebd8424bcd7a9b571\",\n    \"0x89b5d514155d7999408334a50822508b9d689add55d44a240ff2bdde2eee419d117031f85e924e2a2c1ca77db9b91eea\",\n    \"0xa8604b6196f87a04e1350302e8aa745bba8dc162115d22657b37a1d1a98cb14876ddf7f65840b5dbd77e80cd22b4256c\",\n    \"0x83cb7acdb9e03247515bb2ce0227486ccf803426717a14510f0d59d45e998b245797d356f10abca94f7a14e1a2f0d552\",\n    \"0xaeb3266a9f16649210ab2df0e1908ac259f34ce1f01162c22b56cf1019096ee4ea5854c36e30bb2feb06c21a71e8a45c\",\n    \"0x89e72e86edf2aa032a0fc9acf4d876a40865fbb2c8f87cb7e4d88856295c4ac14583e874142fd0c314a49aba68c0aa3c\",\n    \"0x8c3576eba0583c2a7884976b4ed11fe1fda4f6c32f6385d96c47b0e776afa287503b397fa516a455b4b8c3afeedc76db\",\n    \"0xa31e5b633bda9ffa174654fee98b5d5930a691c3c42fcf55673d927dbc8d91c58c4e42e615353145431baa646e8bbb30\",\n    \"0x89f2f3f7a8da1544f24682f41c68114a8f78c86bd36b066e27da13acb70f18d9f548773a16bd8e24789420e17183f137\",\n    \"0xada27fa4e90a086240c9164544d2528621a415a5497badb79f8019dc3dce4d12eb6b599597e47ec6ac39c81efda43520\",\n    \"0x90dc1eb21bf21c0187f359566fc4bf5386abea52799306a0e5a1151c0817c5f5bc60c86e76b1929c092c0f3ff48cedd2\",\n    \"0xb702a53ebcc17ae35d2e735a347d2c700e9cbef8eadbece33cac83df483b2054c126593e1f462cfc00a3ce9d737e2af5\",\n    \"0x9891b06455ec925a6f8eafffba05af6a38cc5e193acaaf74ffbf199df912c5197106c5e06d72942bbb032ce277b6417f\",\n    \"0x8c0ee71eb01197b019275bcf96cae94e81d2cdc3115dbf2d8e3080074260318bc9303597e8f72b18f965ad601d31ec43\",\n    \"0x8aaf580aaf75c1b7a5f99ccf60503506e62058ef43b28b02f79b8536a96be3f019c9f71caf327b4e6730134730d1bef5\",\n    \"0xae6f9fc21dd7dfa672b25a87eb0a41644f7609fab5026d5cedb6e43a06dbbfd6d6e30322a2598c8dedde88c52eaed626\",\n    \"0x8159b953ffece5693edadb2e906ebf76ff080ee1ad22698950d2d3bfc36ac5ea78f58284b2ca180664452d55bd54716c\",\n    \"0xab7647c32ca5e9856ac283a2f86768d68de75ceeba9e58b74c5324f8298319e52183739aba4340be901699d66ac9eb3f\",\n    \"0xa4d85a5701d89bcfaf1572db83258d86a1a0717603d6f24ac2963ffcf80f1265e5ab376a4529ca504f4396498791253c\",\n    \"0x816080c0cdbfe61b4d726c305747a9eb58ac26d9a35f501dd32ba43c098082d20faf3ccd41aad24600aa73bfa453dfac\",\n    \"0x84f3afac024f576b0fd9acc6f2349c2fcefc3f77dbe5a2d4964d14b861b88e9b1810334b908cf3427d9b67a8aee74b18\",\n    \"0x94b390655557b1a09110018e9b5a14490681ade275bdc83510b6465a1218465260d9a7e2a6e4ec700f58c31dc3659962\",\n    \"0xa8c66826b1c04a2dd4c682543242e7a57acae37278bd09888a3d17747c5b5fec43548101e6f46d703638337e2fd3277b\",\n    \"0x86e6f4608a00007fa533c36a5b054c5768ccafe41ad52521d772dcae4c8a4bcaff8f7609be30d8fab62c5988cbbb6830\",\n    \"0x837da4cf09ae8aa0bceb16f8b3bfcc3b3367aecac9eed6b4b56d7b65f55981ef066490764fb4c108792623ecf8cad383\",\n    \"0x941ff3011462f9b5bf97d8cbdb0b6f5d37a1b1295b622f5485b7d69f2cb2bcabc83630dae427f0259d0d9539a77d8424\",\n    \"0xb99e5d6d82aa9cf7d5970e7f710f4039ac32c2077530e4c2779250c6b9b373bc380adb0a03b892b652f649720672fc8c\",\n    \"0xa791c78464b2d65a15440b699e1e30ebd08501d6f2720adbc8255d989a82fcded2f79819b5f8f201bed84a255211b141\",\n    \"0x84af7ad4a0e31fcbb3276ab1ad6171429cf39adcf78dc03750dc5deaa46536d15591e26d53e953dfb31e1622bc0743ab\",\n    \"0xa833e62fe97e1086fae1d4917fbaf09c345feb6bf1975b5cb863d8b66e8d621c7989ab3dbecda36bc9eaffc5eaa6fa66\",\n    \"0xb4ef79a46a2126f53e2ebe62770feb57fd94600be29459d70a77c5e9cc260fa892be06cd60f886bf48459e48eb50d063\",\n    \"0xb43b8f61919ea380bf151c294e54d3a3ff98e20d1ee5efbfe38aa2b66fafbc6a49739793bd5cb1c809f8b30466277c3a\",\n    \"0xab37735af2412d2550e62df9d8b3b5e6f467f20de3890bf56faf1abf2bf3bd1d98dc3fa0ad5e7ab3fce0fa20409eb392\",\n    \"0x82416b74b1551d484250d85bb151fabb67e29cce93d516125533df585bc80779ab057ea6992801a3d7d5c6dcff87a018\",\n    \"0x8145d0787f0e3b5325190ae10c1d6bee713e6765fb6a0e9214132c6f78f4582bb2771aaeae40d3dad4bafb56bf7e36d8\",\n    \"0xb6935886349ecbdd5774e12196f4275c97ec8279fdf28ccf940f6a022ebb6de8e97d6d2173c3fe402cbe9643bed3883b\",\n    \"0x87ef9b4d3dc71ac86369f8ed17e0dd3b91d16d14ae694bc21a35b5ae37211b043d0e36d8ff07dcc513fb9e6481a1f37f\",\n    \"0xae1d0ded32f7e6f1dc8fef495879c1d9e01826f449f903c1e5034aeeabc5479a9e323b162b688317d46d35a42d570d86\",\n    \"0xa40d16497004db4104c6794e2f4428d75bdf70352685944f3fbe17526df333e46a4ca6de55a4a48c02ecf0bde8ba03c0\",\n    \"0x8d45121efba8cc308a498e8ee39ea6fa5cae9fb2e4aab1c2ff9d448aa8494ccbec9a078f978a86fcd97b5d5e7be7522a\",\n    \"0xa8173865c64634ba4ac2fa432740f5c05056a9deaf6427cb9b4b8da94ca5ddbc8c0c5d3185a89b8b28878194de9cdfcd\",\n    \"0xb6ec06a74d690f6545f0f0efba236e63d1fdfba54639ca2617408e185177ece28901c457d02b849fd00f1a53ae319d0a\",\n    \"0xb69a12df293c014a40070e3e760169b6f3c627caf9e50b35a93f11ecf8df98b2bc481b410eecb7ab210bf213bbe944de\",\n    \"0x97e7dc121795a533d4224803e591eef3e9008bab16f12472210b73aaf77890cf6e3877e0139403a0d3003c12c8f45636\",\n    \"0xacdfa6fdd4a5acb7738cc8768f7cba84dbb95c639399b291ae8e4e63df37d2d4096900a84d2f0606bf534a9ccaa4993f\",\n    \"0x86ee253f3a9446a33e4d1169719b7d513c6b50730988415382faaf751988c10a421020609f7bcdef91be136704b906e2\",\n    \"0xaac9438382a856caf84c5a8a234282f71b5fc5f65219103b147e7e6cf565522285fbfd7417b513bdad8277a00f652ca1\",\n    \"0x83f3799d8e5772527930f5dc071a2e0a65471618993ec8990a96ccdeee65270e490bda9d26bb877612475268711ffd80\",\n    \"0x93f28a81ac8c0ec9450b9d762fae9c7f8feaace87a6ee6bd141ef1d2d0697ef1bbd159fe6e1de640dbdab2b0361fca8a\",\n    \"0xa0825c95ba69999b90eac3a31a3fd830ea4f4b2b7409bde5f202b61d741d6326852ce790f41de5cb0eccec7af4db30c1\",\n    \"0x83924b0e66233edd603c3b813d698daa05751fc34367120e3cf384ea7432e256ccee4d4daf13858950549d75a377107d\",\n    \"0x956fd9fa58345277e06ba2ec72f49ed230b8d3d4ff658555c52d6cddeb84dd4e36f1a614f5242d5ca0192e8daf0543c2\",\n    \"0x944869912476baae0b114cced4ff65c0e4c90136f73ece5656460626599051b78802df67d7201c55d52725a97f5f29fe\",\n    \"0x865cb25b64b4531fb6fe4814d7c8cd26b017a6c6b72232ff53defc18a80fe3b39511b23f9e4c6c7249d06e03b2282ed2\",\n    \"0x81e09ff55214960775e1e7f2758b9a6c4e4cd39edf7ec1adfaad51c52141182b79fe2176b23ddc7df9fd153e5f82d668\",\n    \"0xb31006896f02bc90641121083f43c3172b1039334501fbaf1672f7bf5d174ddd185f945adf1a9c6cf77be34c5501483d\",\n    \"0x88b92f6f42ae45e9f05b16e52852826e933efd0c68b0f2418ac90957fd018df661bc47c8d43c2a7d7bfcf669dab98c3c\",\n    \"0x92fc68f595853ee8683930751789b799f397135d002eda244fe63ecef2754e15849edde3ba2f0cc8b865c9777230b712\",\n    \"0x99ca06a49c5cd0bb097c447793fcdd809869b216a34c66c78c7e41e8c22f05d09168d46b8b1f3390db9452d91bc96dea\",\n    \"0xb48b9490a5d65296802431852d548d81047bbefc74fa7dc1d4e2a2878faacdfcb365ae59209cb0ade01901a283cbd15d\",\n    \"0xaff0fdbef7c188b120a02bc9085d7b808e88f73973773fef54707bf2cd772cd066740b1b6f4127b5c349f657bd97e738\",\n    \"0x966fd4463b4f43dd8ccba7ad50baa42292f9f8b2e70da23bb6780e14155d9346e275ef03ddaf79e47020dcf43f3738bd\",\n    \"0x9330c3e1fadd9e08ac85f4839121ae20bbeb0a5103d84fa5aadbd1213805bdcda67bf2fb75fc301349cbc851b5559d20\",\n    \"0x993bb99867bd9041a71a55ad5d397755cfa7ab6a4618fc526179bfc10b7dc8b26e4372fe9a9b4a15d64f2b63c1052dda\",\n    \"0xa29b59bcfab51f9b3c490a3b96f0bf1934265c315349b236012adbd64a56d7f6941b2c8cc272b412044bc7731f71e1dc\",\n    \"0xa65c9cefe1fc35d089fe8580c2e7671ebefdb43014ac291528ff4deefd4883fd4df274af83711dad610dad0d615f9d65\",\n    \"0x944c78c56fb227ae632805d448ca3884cd3d2a89181cead3d2b7835e63297e6d740aa79a112edb1d4727824991636df5\",\n    \"0xa73d782da1db7e4e65d7b26717a76e16dd9fab4df65063310b8e917dc0bc24e0d6755df5546c58504d04d9e68c3b474a\",\n    \"0xaf80f0b87811ae3124f68108b4ca1937009403f87928bbc53480e7c5408d072053ace5eeaf5a5aba814dab8a45502085\",\n    \"0x88aaf1acfc6e2e19b8387c97da707cb171c69812fefdd4650468e9b2c627bd5ccfb459f4d8e56bdfd84b09ddf87e128f\",\n    \"0x92c97276ff6f72bab6e9423d02ad6dc127962dbce15a0dd1e4a393b4510c555df6aa27be0f697c0d847033a9ca8b8dfd\",\n    \"0xa0e07d43d96e2d85b6276b3c60aadb48f0aedf2de8c415756dc597249ea64d2093731d8735231dadc961e5682ac59479\",\n    \"0xadc9e6718a8f9298957d1da3842a7751c5399bbdf56f8de6c1c4bc39428f4aee6f1ba6613d37bf46b9403345e9d6fc81\",\n    \"0x951da434da4b20d949b509ceeba02e24da7ed2da964c2fcdf426ec787779c696b385822c7dbea4df3e4a35921f1e912c\",\n    \"0xa04cbce0d2b2e87bbf038c798a12ec828423ca6aca08dc8d481cf6466e3c9c73d4d4a7fa47df9a7e2e15aae9e9f67208\",\n    \"0x8f855cca2e440d248121c0469de1f94c2a71b8ee2682bbad3a78243a9e03da31d1925e6760dbc48a1957e040fae9abe8\",\n    \"0xb642e5b17c1df4a4e101772d73851180b3a92e9e8b26c918050f51e6dd3592f102d20b0a1e96f0e25752c292f4c903ff\",\n    \"0xa92454c300781f8ae1766dbbb50a96192da7d48ef4cbdd72dd8cbb44c6eb5913c112cc38e9144615fdc03684deb99420\",\n    \"0x8b74f7e6c2304f8e780df4649ef8221795dfe85fdbdaa477a1542d135b75c8be45bf89adbbb6f3ddf54ca40f02e733e9\",\n    \"0x85cf66292cbb30cec5fd835ab10c9fcb3aea95e093aebf123e9a83c26f322d76ebc89c4e914524f6c5f6ee7d74fc917d\",\n    \"0xae0bfe0cdc97c09542a7431820015f2d16067b30dca56288013876025e81daa8c519e5e347268e19aa1a85fa1dc28793\",\n    \"0x921322fc6a47dc091afa0ad6df18ed14cde38e48c6e71550aa513918b056044983aee402de21051235eecf4ce8040fbe\",\n    \"0x96c030381e97050a45a318d307dcb3c8377b79b4dd5daf6337cded114de26eb725c14171b9b8e1b3c08fe1f5ea6b49e0\",\n    \"0x90c23b86b6111818c8baaf53a13eaee1c89203b50e7f9a994bf0edf851919b48edbac7ceef14ac9414cf70c486174a77\",\n    \"0x8bf6c301240d2d1c8d84c71d33a6dfc6d9e8f1cfae66d4d0f7a256d98ae12b0bcebfa94a667735ee89f810bcd7170cff\",\n    \"0xa41a4ffbbea0e36874d65c009ee4c3feffff322f6fc0e30d26ee4dbc1f46040d05e25d9d0ecb378cef0d24a7c2c4b850\",\n    \"0xa8d4cdd423986bb392a0a92c12a8bd4da3437eec6ef6af34cf5310944899287452a2eb92eb5386086d5063381189d10e\",\n    \"0xa81dd26ec057c4032a4ed7ad54d926165273ed51d09a1267b2e477535cf6966835a257c209e4e92d165d74fa75695fa3\",\n    \"0x8d7f708c3ee8449515d94fc26b547303b53d8dd55f177bc3b25d3da2768accd9bc8e9f09546090ebb7f15c66e6c9c723\",\n    \"0x839ba65cffcd24cfffa7ab3b21faabe3c66d4c06324f07b2729c92f15cad34e474b0f0ddb16cd652870b26a756b731d3\",\n    \"0x87f1a3968afec354d92d77e2726b702847c6afcabb8438634f9c6f7766de4c1504317dc4fa9a4a735acdbf985e119564\",\n    \"0x91a8a7fd6542f3e0673f07f510d850864b34ac087eb7eef8845a1d14b2b1b651cbdc27fa4049bdbf3fea54221c5c8549\",\n    \"0xaef3cf5f5e3a2385ead115728d7059e622146c3457d266c612e778324b6e06fbfb8f98e076624d2f3ce1035d65389a07\",\n    \"0x819915d6232e95ccd7693fdd78d00492299b1983bc8f96a08dcb50f9c0a813ed93ae53c0238345d5bea0beda2855a913\",\n    \"0x8e9ba68ded0e94935131b392b28218315a185f63bf5e3c1a9a9dd470944509ca0ba8f6122265f8da851b5cc2abce68f1\",\n    \"0xb28468e9b04ee9d69003399a3cf4457c9bf9d59f36ab6ceeb8e964672433d06b58beeea198fedc7edbaa1948577e9fa2\",\n    \"0xa633005e2c9f2fd94c8bce2dd5bb708fe946b25f1ec561ae65e54e15cdd88dc339f1a083e01f0d39610c8fe24151aaf0\",\n    \"0x841d0031e22723f9328dd993805abd13e0c99b0f59435d2426246996b08d00ce73ab906f66c4eab423473b409e972ce0\",\n    \"0x85758d1b084263992070ec8943f33073a2d9b86a8606672550c17545507a5b3c88d87382b41916a87ee96ff55a7aa535\",\n    \"0x8581b06b0fc41466ef94a76a1d9fb8ae0edca6d018063acf6a8ca5f4b02d76021902feba58972415691b4bdbc33ae3b4\",\n    \"0x83539597ff5e327357ee62bc6bf8c0bcaec2f227c55c7c385a4806f0d37fb461f1690bad5066b8a5370950af32fafbef\",\n    \"0xaee3557290d2dc10827e4791d00e0259006911f3f3fce4179ed3c514b779160613eca70f720bff7804752715a1266ffa\",\n    \"0xb48d2f0c4e90fc307d5995464e3f611a9b0ef5fe426a289071f4168ed5cc4f8770c9332960c2ca5c8c427f40e6bb389f\",\n    \"0x847af8973b4e300bb06be69b71b96183fd1a0b9d51b91701bef6fcfde465068f1eb2b1503b07afda380f18d69de5c9e1\",\n    \"0xa70a6a80ce407f07804c0051ac21dc24d794b387be94eb24e1db94b58a78e1bcfb48cd0006db8fc1f9bedaece7a44fbe\",\n    \"0xb40e942b8fa5336910ff0098347df716bff9d1fa236a1950c16eeb966b3bc1a50b8f7b0980469d42e75ae13ced53cead\",\n    \"0xb208fabaa742d7db3148515330eb7a3577487845abdb7bd9ed169d0e081db0a5816595c33d375e56aeac5b51e60e49d3\",\n    \"0xb7c8194b30d3d6ef5ab66ec88ad7ebbc732a3b8a41731b153e6f63759a93f3f4a537eab9ad369705bd730184bdbbdc34\",\n    \"0x9280096445fe7394d04aa1bc4620c8f9296e991cc4d6c131bd703cb1cc317510e6e5855ac763f4d958c5edfe7eebeed7\",\n    \"0xabc2aa4616a521400af1a12440dc544e3c821313d0ab936c86af28468ef8bbe534837e364598396a81cf8d06274ed5a6\",\n    \"0xb18ca8a3325adb0c8c18a666d4859535397a1c3fe08f95eebfac916a7a99bbd40b3c37b919e8a8ae91da38bc00fa56c0\",\n    \"0x8a40c33109ecea2a8b3558565877082f79121a432c45ec2c5a5e0ec4d1c203a6788e6b69cb37f1fd5b8c9a661bc5476d\",\n    \"0x88c47301dd30998e903c84e0b0f2c9af2e1ce6b9f187dab03528d44f834dc991e4c86d0c474a2c63468cf4020a1e24a0\",\n    \"0x920c832853e6ab4c851eecfa9c11d3acc7da37c823be7aa1ab15e14dfd8beb5d0b91d62a30cec94763bd8e4594b66600\",\n    \"0x98e1addbe2a6b8edc7f12ecb9be81c3250aeeca54a1c6a7225772ca66549827c15f3950d01b8eb44aecb56fe0fff901a\",\n    \"0x8cfb0fa1068be0ec088402f5950c4679a2eb9218c729da67050b0d1b2d7079f3ddf4bf0f57d95fe2a8db04bc6bcdb20c\",\n    \"0xb70f381aafe336b024120453813aeab70baac85b9c4c0f86918797b6aee206e6ed93244a49950f3d8ec9f81f4ac15808\",\n    \"0xa4c8edf4aa33b709a91e1062939512419711c1757084e46f8f4b7ed64f8e682f4e78b7135920c12f0eb0422fe9f87a6a\",\n    \"0xb4817e85fd0752d7ebb662d3a51a03367a84bac74ebddfba0e5af5e636a979500f72b148052d333b3dedf9edd2b4031b\",\n    \"0xa87430169c6195f5d3e314ff2d1c2f050e766fd5d2de88f5207d72dba4a7745bb86d0baca6e9ae156582d0d89e5838c7\",\n    \"0x991b00f8b104566b63a12af4826b61ce7aa40f4e5b8fff3085e7a99815bdb4471b6214da1e480214fac83f86a0b93cc5\",\n    \"0xb39966e3076482079de0678477df98578377a094054960ee518ef99504d6851f8bcd3203e8da5e1d4f6f96776e1fe6eb\",\n    \"0xa448846d9dc2ab7a0995fa44b8527e27f6b3b74c6e03e95edb64e6baa4f1b866103f0addb97c84bef1d72487b2e21796\",\n    \"0x894bec21a453ae84b592286e696c35bc30e820e9c2fd3e63dd4fbe629e07df16439c891056070faa490155f255bf7187\",\n    \"0xa9ec652a491b11f6a692064e955f3f3287e7d2764527e58938571469a1e29b5225b9415bd602a45074dfbfe9c131d6ca\",\n    \"0xb39d37822e6cbe28244b5f42ce467c65a23765bd16eb6447c5b3e942278069793763483dafd8c4dd864f8917aad357fe\",\n    \"0x88dba51133f2019cb266641c56101e3e5987d3b77647a2e608b5ff9113dfc5f85e2b7c365118723131fbc0c9ca833c9c\",\n    \"0xb566579d904b54ecf798018efcb824dccbebfc6753a0fd2128ac3b4bd3b038c2284a7c782b5ca6f310eb7ea4d26a3f0a\",\n    \"0xa97a55c0a492e53c047e7d6f9d5f3e86fb96f3dddc68389c0561515343b66b4bc02a9c0d5722dff1e3445308240b27f7\",\n    \"0xa044028ab4bcb9e1a2b9b4ca4efbf04c5da9e4bf2fff0e8bd57aa1fc12a71e897999c25d9117413faf2f45395dee0f13\",\n    \"0xa78dc461decbeaeed8ebd0909369b491a5e764d6a5645a7dac61d3140d7dc0062526f777b0eb866bff27608429ebbdde\",\n    \"0xb2c2a8991f94c39ca35fea59f01a92cb3393e0eccb2476dfbf57261d406a68bd34a6cff33ed80209991688c183609ef4\",\n    \"0x84189eefb521aff730a4fd3fd5b10ddfd29f0d365664caef63bb015d07e689989e54c33c2141dd64427805d37a7e546e\",\n    \"0x85ac80bd734a52235da288ff042dea9a62e085928954e8eacd2c751013f61904ed110e5b3afe1ab770a7e6485efb7b5e\",\n    \"0x9183a560393dcb22d0d5063e71182020d0fbabb39e32493eeffeb808df084aa243eb397027f150b55a247d1ed0c8513e\",\n    \"0x81c940944df7ecc58d3c43c34996852c3c7915ed185d7654627f7af62abae7e0048dd444a6c09961756455000bd96d09\",\n    \"0xaa8c34e164019743fd8284b84f06c3b449aae7996e892f419ee55d82ad548cb300fd651de329da0384243954c0ef6a60\",\n    \"0x89a7b7bdfc7e300d06a14d463e573d6296d8e66197491900cc9ae49504c4809ff6e61b758579e9091c61085ba1237b83\",\n    \"0x878d21809ba540f50bd11f4c4d9590fb6f3ab9de5692606e6e2ef4ed9d18520119e385be5e1f4b3f2e2b09c319f0e8fc\",\n    \"0x8eb248390193189cf0355365e630b782cd15751e672dc478b39d75dc681234dcd9309df0d11f4610dbb249c1e6be7ef9\",\n    \"0xa1d7fb3aecb896df3a52d6bd0943838b13f1bd039c936d76d03de2044c371d48865694b6f532393b27fd10a4cf642061\",\n    \"0xa34bca58a24979be442238cbb5ece5bee51ae8c0794dd3efb3983d4db713bc6f28a96e976ac3bd9a551d3ed9ba6b3e22\",\n    \"0x817c608fc8cacdd178665320b5a7587ca21df8bdd761833c3018b967575d25e3951cf3d498a63619a3cd2ad4406f5f28\",\n    \"0x86c95707db0495689afd0c2e39e97f445f7ca0edffad5c8b4cacd1421f2f3cc55049dfd504f728f91534e20383955582\",\n    \"0x99c3b0bb15942c301137765d4e19502f65806f3b126dc01a5b7820c87e8979bce6a37289a8f6a4c1e4637227ad5bf3bf\",\n    \"0x8aa1518a80ea8b074505a9b3f96829f5d4afa55a30efe7b4de4e5dbf666897fdd2cf31728ca45921e21a78a80f0e0f10\",\n    \"0x8d74f46361c79e15128ac399e958a91067ef4cec8983408775a87eca1eed5b7dcbf0ddf30e66f51780457413496c7f07\",\n    \"0xa41cde4a786b55387458a1db95171aca4fd146507b81c4da1e6d6e495527c3ec83fc42fad1dfe3d92744084a664fd431\",\n    \"0x8c352852c906fae99413a84ad11701f93f292fbf7bd14738814f4c4ceab32db02feb5eb70bc73898b0bc724a39d5d017\",\n    \"0xa5993046e8f23b71ba87b7caa7ace2d9023fb48ce4c51838813174880d918e9b4d2b0dc21a2b9c6f612338c31a289df8\",\n    \"0x83576d3324bf2d8afbfb6eaecdc5d767c8e22e7d25160414924f0645491df60541948a05e1f4202e612368e78675de8a\",\n    \"0xb43749b8df4b15bc9a3697e0f1c518e6b04114171739ef1a0c9c65185d8ec18e40e6954d125cbc14ebc652cf41ad3109\",\n    \"0xb4eebd5d80a7327a040cafb9ccdb12b2dfe1aa86e6bc6d3ac8a57fadfb95a5b1a7332c66318ff72ba459f525668af056\",\n    \"0x9198be7f1d413c5029b0e1c617bcbc082d21abe2c60ec8ce9b54ca1a85d3dba637b72fda39dae0c0ae40d047eab9f55a\",\n    \"0x8d96a0232832e24d45092653e781e7a9c9520766c3989e67bbe86b3a820c4bf621ea911e7cd5270a4bfea78b618411f6\",\n    \"0x8d7160d0ea98161a2d14d46ef01dff72d566c330cd4fabd27654d300e1bc7644c68dc8eabf2a20a59bfe7ba276545f9b\",\n    \"0xabb60fce29dec7ba37e3056e412e0ec3e05538a1fc0e2c68877378c867605966108bc5742585ab6a405ce0c962b285b6\",\n    \"0x8fabffa3ed792f05e414f5839386f6449fd9f7b41a47595c5d71074bd1bb3784cc7a1a7e1ad6b041b455035957e5b2dc\",\n    \"0x90ff017b4804c2d0533b72461436b10603ab13a55f86fd4ec11b06a70ef8166f958c110519ca1b4cc7beba440729fe2d\",\n    \"0xb340cfd120f6a4623e3a74cf8c32bfd7cd61a280b59dfd17b15ca8fae4d82f64a6f15fbde4c02f424debc72b7db5fe67\",\n    \"0x871311c9c7220c932e738d59f0ecc67a34356d1429fe570ca503d340c9996cb5ee2cd188fad0e3bd16e4c468ec1dbebd\",\n    \"0xa772470262186e7b94239ba921b29f2412c148d6f97c4412e96d21e55f3be73f992f1ad53c71008f0558ec3f84e2b5a7\",\n    \"0xb2a897dcb7ffd6257f3f2947ec966f2077d57d5191a88840b1d4f67effebe8c436641be85524d0a21be734c63ab5965d\",\n    \"0xa044f6eacc48a4a061fa149500d96b48cbf14853469aa4d045faf3dca973be1bd4b4ce01646d83e2f24f7c486d03205d\",\n    \"0x981af5dc2daa73f7fa9eae35a93d81eb6edba4a7f673b55d41f6ecd87a37685d31bb40ef4f1c469b3d72f2f18b925a17\",\n    \"0x912d2597a07864de9020ac77083eff2f15ceb07600f15755aba61251e8ce3c905a758453b417f04d9c38db040954eb65\",\n    \"0x9642b7f6f09394ba5e0805734ef6702c3eddf9eea187ba98c676d5bbaec0e360e3e51dc58433aaa1e2da6060c8659cb7\",\n    \"0x8ab3836e0a8ac492d5e707d056310c4c8e0489ca85eb771bff35ba1d658360084e836a6f51bb990f9e3d2d9aeb18fbb5\",\n    \"0x879e058e72b73bb1f4642c21ffdb90544b846868139c6511f299aafe59c2d0f0b944dffc7990491b7c4edcd6a9889250\",\n    \"0xb9e60b737023f61479a4a8fd253ed0d2a944ea6ba0439bbc0a0d3abf09b0ad1f18d75555e4a50405470ae4990626f390\",\n    \"0xb9c2535d362796dcd673640a9fa2ebdaec274e6f8b850b023153b0a7a30fffc87f96e0b72696f647ebe7ab63099a6963\",\n    \"0x94aeff145386a087b0e91e68a84a5ede01f978f9dd9fe7bebca78941938469495dc30a96bba9508c0d017873aeea9610\",\n    \"0x98b179f8a3d9f0d0a983c30682dd425a2ddc7803be59bd626c623c8951a5179117d1d2a68254c95c9952989877d0ee55\",\n    \"0x889ecf5f0ee56938273f74eb3e9ecfb5617f04fb58e83fe4c0e4aef51615cf345bc56f3f61b17f6eed3249d4afd54451\",\n    \"0xa0f2b2c39bcea4b50883e2587d16559e246248a66ecb4a4b7d9ab3b51fb39fe98d83765e087eee37a0f86b0ba4144c02\",\n    \"0xb2a61e247ed595e8a3830f7973b07079cbda510f28ad8c78c220b26cb6acde4fbb5ee90c14a665f329168ee951b08cf0\",\n    \"0x95bd0fcfb42f0d6d8a8e73d7458498a85bcddd2fb132fd7989265648d82ac2707d6d203fac045504977af4f0a2aca4b7\",\n    \"0x843e5a537c298666e6cf50fcc044f13506499ef83c802e719ff2c90e85003c132024e04711be7234c04d4b0125512d5d\",\n    \"0xa46d1797c5959dcd3a5cfc857488f4d96f74277c3d13b98b133620192f79944abcb3a361d939a100187f1b0856eae875\",\n    \"0xa1c7786736d6707a48515c38660615fcec67eb8a2598f46657855215f804fd72ab122d17f94fcffad8893f3be658dca7\",\n    \"0xb23dc9e610abc7d8bd21d147e22509a0fa49db5be6ea7057b51aae38e31654b3aa044df05b94b718153361371ba2f622\",\n    \"0xb00cc8f257d659c22d30e6d641f79166b1e752ea8606f558e4cad6fc01532e8319ea4ee12265ba4140ac45aa4613c004\",\n    \"0xac7019af65221b0cc736287b32d7f1a3561405715ba9a6a122342e04e51637ba911c41573de53e4781f2230fdcb2475f\",\n    \"0x81a630bc41b3da8b3eb4bf56cba10cd9f93153c3667f009dc332287baeb707d505fb537e6233c8e53d299ec0f013290c\",\n    \"0xa6b7aea5c545bb76df0f230548539db92bc26642572cb7dd3d5a30edca2b4c386f44fc8466f056b42de2a452b81aff5b\",\n    \"0x8271624ff736b7b238e43943c81de80a1612207d32036d820c11fc830c737972ccc9c60d3c2359922b06652311e3c994\",\n    \"0x8a684106458cb6f4db478170b9ad595d4b54c18bf63b9058f095a2fa1b928c15101472c70c648873d5887880059ed402\",\n    \"0xa5cc3c35228122f410184e4326cf61a37637206e589fcd245cb5d0cec91031f8f7586b80503070840fdfd8ce75d3c88b\",\n    \"0x9443fc631aed8866a7ed220890911057a1f56b0afe0ba15f0a0e295ab97f604b134b1ed9a4245e46ee5f9a93aa74f731\",\n    \"0x984b6f7d79835dffde9558c6bb912d992ca1180a2361757bdba4a7b69dc74b056e303adc69fe67414495dd9c2dd91e64\",\n    \"0xb15a5c8cba5de080224c274d31c68ed72d2a7126d347796569aef0c4e97ed084afe3da4d4b590b9dda1a07f0c2ff3dfb\",\n    \"0x991708fe9650a1f9a4e43938b91d45dc68c230e05ee999c95dbff3bf79b1c1b2bb0e7977de454237c355a73b8438b1d9\",\n    \"0xb4f7edc7468b176a4a7c0273700c444fa95c726af6697028bed4f77eee887e3400f9c42ee15b782c0ca861c4c3b8c98a\",\n    \"0x8c60dcc16c51087eb477c13e837031d6c6a3dc2b8bf8cb43c23f48006bc7173151807e866ead2234b460c2de93b31956\",\n    \"0x83ad63e9c910d1fc44bc114accfb0d4d333b7ebe032f73f62d25d3e172c029d5e34a1c9d547273bf6c0fead5c8801007\",\n    \"0x85de73213cc236f00777560756bdbf2b16841ba4b55902cf2cad9742ecaf5d28209b012ceb41f337456dfeca93010cd7\",\n    \"0xa7561f8827ccd75b6686ba5398bb8fc3083351c55a589b18984e186820af7e275af04bcd4c28e1dc11be1e8617a0610b\",\n    \"0x88c0a4febd4068850557f497ea888035c7fc9f404f6cc7794e7cc8722f048ad2f249e7dc62743e7a339eb7473ad3b0cd\",\n    \"0x932b22b1d3e6d5a6409c34980d176feb85ada1bf94332ef5c9fc4d42b907dabea608ceef9b5595ef3feee195151f18d8\",\n    \"0xa2867bb3f5ab88fbdae3a16c9143ab8a8f4f476a2643c505bb9f37e5b1fd34d216cab2204c9a017a5a67b7ad2dda10e8\",\n    \"0xb573d5f38e4e9e8a3a6fd82f0880dc049efa492a946d00283019bf1d5e5516464cf87039e80aef667cb86fdea5075904\",\n    \"0xb948f1b5ab755f3f5f36af27d94f503b070696d793b1240c1bdfd2e8e56890d69e6904688b5f8ff5a4bdf5a6abfe195f\",\n    \"0x917eae95ebc4109a2e99ddd8fec7881d2f7aaa0e25fda44dec7ce37458c2ee832f1829db7d2dcfa4ca0f06381c7fe91d\",\n    \"0x95751d17ed00a3030bce909333799bb7f4ab641acf585807f355b51d6976dceee410798026a1a004ef4dcdff7ec0f5b8\",\n    \"0xb9b7bd266f449a79bbfe075e429613e76c5a42ac61f01c8f0bbbd34669650682efe01ff9dbbc400a1e995616af6aa278\",\n    \"0xac1722d097ce9cd7617161f8ec8c23d68f1fb1c9ca533e2a8b4f78516c2fd8fb38f23f834e2b9a03bb06a9d655693ca9\",\n    \"0xa7ad9e96ffd98db2ecdb6340c5d592614f3c159abfd832fe27ee9293519d213a578e6246aae51672ee353e3296858873\",\n    \"0x989b8814d5de7937c4acafd000eec2b4cd58ba395d7b25f98cafd021e8efa37029b29ad8303a1f6867923f5852a220eb\",\n    \"0xa5bfe6282c771bc9e453e964042d44eff4098decacb89aecd3be662ea5b74506e1357ab26f3527110ba377711f3c9f41\",\n    \"0x8900a7470b656639721d2abbb7b06af0ac4222ab85a1976386e2a62eb4b88bfb5b72cf7921ddb3cf3a395d7eeb192a2e\",\n    \"0x95a71b55cd1f35a438cf5e75f8ff11c5ec6a2ebf2e4dba172f50bfad7d6d5dca5de1b1afc541662c81c858f7604c1163\",\n    \"0x82b5d62fea8db8d85c5bc3a76d68dedd25794cf14d4a7bc368938ffca9e09f7e598fdad2a5aac614e0e52f8112ae62b9\",\n    \"0x997173f07c729202afcde3028fa7f52cefc90fda2d0c8ac2b58154a5073140683e54c49ed1f254481070d119ce0ce02a\",\n    \"0xaeffb91ccc7a72bbd6ffe0f9b99c9e66e67d59cec2e02440465e9636a613ab3017278cfa72ea8bc4aba9a8dc728cb367\",\n    \"0x952743b06e8645894aeb6440fc7a5f62dd3acf96dab70a51e20176762c9751ea5f2ba0b9497ccf0114dc4892dc606031\",\n    \"0x874c63baeddc56fbbca2ff6031f8634b745f6e34ea6791d7c439201aee8f08ef5ee75f7778700a647f3b21068513fce6\",\n    \"0x85128fec9c750c1071edfb15586435cc2f317e3e9a175bb8a9697bcda1eb9375478cf25d01e7fed113483b28f625122d\",\n    \"0x85522c9576fd9763e32af8495ae3928ed7116fb70d4378448926bc9790e8a8d08f98cf47648d7da1b6e40d6a210c7924\",\n    \"0x97d0f37a13cfb723b848099ca1c14d83e9aaf2f7aeb71829180e664b7968632a08f6a85f557d74b55afe6242f2a36e7c\",\n    \"0xabaa472d6ad61a5fccd1a57c01aa1bc081253f95abbcba7f73923f1f11c4e79b904263890eeb66926de3e2652f5d1c70\",\n    \"0xb3c04945ba727a141e5e8aec2bf9aa3772b64d8fd0e2a2b07f3a91106a95cbcb249adcd074cbe498caf76fffac20d4ef\",\n    \"0x82c46781a3d730d9931bcabd7434a9171372dde57171b6180e5516d4e68db8b23495c8ac3ab96994c17ddb1cf249b9fb\",\n    \"0xa202d8b65613c42d01738ccd68ed8c2dbc021631f602d53f751966e04182743ebc8e0747d600b8a8676b1da9ae7f11ab\",\n    \"0xae73e7256e9459db04667a899e0d3ea5255211fb486d084e6550b6dd64ca44af6c6b2d59d7aa152de9f96ce9b58d940d\",\n    \"0xb67d87b176a9722945ec7593777ee461809861c6cfd1b945dde9ee4ff009ca4f19cf88f4bbb5c80c9cbab2fe25b23ac8\",\n    \"0x8f0b7a317a076758b0dac79959ee4a06c08b07d0f10538a4b53d3da2eda16e2af26922feb32c090330dc4d969cf69bd3\",\n    \"0x90b36bf56adbd8c4b6cb32febc3a8d5f714370c2ac3305c10fa6d168dffb2a026804517215f9a2d4ec8310cdb6bb459b\",\n    \"0xaa80c19b0682ead69934bf18cf476291a0beddd8ef4ed75975d0a472e2ab5c70f119722a8574ae4973aceb733d312e57\",\n    \"0xa3fc9abb12574e5c28dcb51750b4339b794b8e558675eef7d26126edf1de920c35e992333bcbffcbf6a5f5c0d383ce62\",\n    \"0xa1573ff23ab972acdcd08818853b111fc757fdd35aa070186d3e11e56b172fb49d840bf297ac0dd222e072fc09f26a81\",\n    \"0x98306f2be4caa92c2b4392212d0cbf430b409b19ff7d5b899986613bd0e762c909fc01999aa94be3bd529d67f0113d7f\",\n    \"0x8c1fc42482a0819074241746d17dc89c0304a2acdae8ed91b5009e9e3e70ff725ba063b4a3e68fdce05b74f5180c545e\",\n    \"0xa6c6113ebf72d8cf3163b2b8d7f3fa24303b13f55752522c660a98cd834d85d8c79214d900fa649499365e2e7641f77a\",\n    \"0xab95eea424f8a2cfd9fb1c78bb724e5b1d71a0d0d1e4217c5d0f98b0d8bbd3f8400a2002abc0a0e4576d1f93f46fefad\",\n    \"0x823c5a4fd8cf4a75fdc71d5f2dd511b6c0f189b82affeacd2b7cfcad8ad1a5551227dcc9bfdb2e34b2097eaa00efbb51\",\n    \"0xb97314dfff36d80c46b53d87a61b0e124dc94018a0bb680c32765b9a2d457f833a7c42bbc90b3b1520c33a182580398d\",\n    \"0xb17566ee3dcc6bb3b004afe4c0136dfe7dd27df9045ae896dca49fb36987501ae069eb745af81ba3fc19ff037e7b1406\",\n    \"0xb0bdc0f55cfd98d331e3a0c4fbb776a131936c3c47c6bffdc3aaf7d8c9fa6803fbc122c2fefbb532e634228687d52174\",\n    \"0xaa5d9e60cc9f0598559c28bb9bdd52aa46605ab4ffe3d192ba982398e72cec9a2a44c0d0d938ce69935693cabc0887ea\",\n    \"0x802b6459d2354fa1d56c592ac1346c428dadea6b6c0a87bf7d309bab55c94e1cf31dd98a7a86bd92a840dd51f218b91b\",\n    \"0xa526914efdc190381bf1a73dd33f392ecf01350b9d3f4ae96b1b1c3d1d064721c7d6eec5788162c933245a3943f5ee51\",\n    \"0xb3b8fcf637d8d6628620a1a99dbe619eabb3e5c7ce930d6efd2197e261bf394b74d4e5c26b96c4b8009c7e523ccfd082\",\n    \"0x8f7510c732502a93e095aba744535f3928f893f188adc5b16008385fb9e80f695d0435bfc5b91cdad4537e87e9d2551c\",\n    \"0x97b90beaa56aa936c3ca45698f79273a68dd3ccd0076eab48d2a4db01782665e63f33c25751c1f2e070f4d1a8525bf96\",\n    \"0xb9fb798324b1d1283fdc3e48288e3861a5449b2ab5e884b34ebb8f740225324af86e4711da6b5cc8361c1db15466602f\",\n    \"0xb6d52b53cea98f1d1d4c9a759c25bf9d8a50b604b144e4912acbdbdc32aab8b9dbb10d64a29aa33a4f502121a6fb481c\",\n    \"0x9174ffff0f2930fc228f0e539f5cfd82c9368d26b074467f39c07a774367ff6cccb5039ac63f107677d77706cd431680\",\n    \"0xa33b6250d4ac9e66ec51c063d1a6a31f253eb29bbaed12a0d67e2eccfffb0f3a52750fbf52a1c2aaba8c7692346426e7\",\n    \"0xa97025fd5cbcebe8ef865afc39cd3ea707b89d4e765ec817fd021d6438e02fa51e3544b1fd45470c58007a08efac6edd\",\n    \"0xb32a78480edd9ff6ba2f1eec4088db5d6ceb2d62d7e59e904ecaef7bb4a2e983a4588e51692b3be76e6ffbc0b5f911a5\",\n    \"0xb5ab590ef0bb77191f00495b33d11c53c65a819f7d0c1f9dc4a2caa147a69c77a4fff7366a602d743ee1f395ce934c1e\",\n    \"0xb3fb0842f9441fb1d0ee0293b6efbc70a8f58d12d6f769b12872db726b19e16f0f65efbc891cf27a28a248b0ef9c7e75\",\n    \"0x9372ad12856fefb928ccb0d34e198df99e2f8973b07e9d417a3134d5f69e12e79ff572c4e03ccd65415d70639bc7c73e\",\n    \"0xaa8d6e83d09ce216bfe2009a6b07d0110d98cf305364d5529c170a23e693aabb768b2016befb5ada8dabdd92b4d012bb\",\n    \"0xa954a75791eeb0ce41c85200c3763a508ed8214b5945a42c79bfdcfb1ec4f86ad1dd7b2862474a368d4ac31911a2b718\",\n    \"0x8e2081cfd1d062fe3ab4dab01f68062bac802795545fede9a188f6c9f802cb5f884e60dbe866710baadbf55dc77c11a4\",\n    \"0xa2f06003b9713e7dd5929501ed485436b49d43de80ea5b15170763fd6346badf8da6de8261828913ee0dacd8ff23c0e1\",\n    \"0x98eecc34b838e6ffd1931ca65eec27bcdb2fdcb61f33e7e5673a93028c5865e0d1bf6d3bec040c5e96f9bd08089a53a4\",\n    \"0x88cc16019741b341060b95498747db4377100d2a5bf0a5f516f7dec71b62bcb6e779de2c269c946d39040e03b3ae12b7\",\n    \"0xad1135ccbc3019d5b2faf59a688eef2500697642be8cfbdf211a1ab59abcc1f24483e50d653b55ff1834675ac7b4978f\",\n    \"0xa946f05ed9972f71dfde0020bbb086020fa35b482cce8a4cc36dd94355b2d10497d7f2580541bb3e81b71ac8bba3c49f\",\n    \"0xa83aeed488f9a19d8cfd743aa9aa1982ab3723560b1cd337fc2f91ad82f07afa412b3993afb845f68d47e91ba4869840\",\n    \"0x95eebe006bfc316810cb71da919e5d62c2cebb4ac99d8e8ef67be420302320465f8b69873470982de13a7c2e23516be9\",\n    \"0xa55f8961295a11e91d1e5deadc0c06c15dacbfc67f04ccba1d069cba89d72aa3b3d64045579c3ea8991b150ac29366ae\",\n    \"0xb321991d12f6ac07a5de3c492841d1a27b0d3446082fbce93e7e1f9e8d8fe3b45d41253556261c21b70f5e189e1a7a6f\",\n    \"0xa0b0822f15f652ce7962a4f130104b97bf9529797c13d6bd8e24701c213cc37f18157bd07f3d0f3eae6b7cd1cb40401f\",\n    \"0x96e2fa4da378aa782cc2d5e6e465fc9e49b5c805ed01d560e9b98abb5c0de8b74a2e7bec3aa5e2887d25cccb12c66f0c\",\n    \"0x97e4ab610d414f9210ed6f35300285eb3ccff5b0b6a95ed33425100d7725e159708ea78704497624ca0a2dcabce3a2f9\",\n    \"0x960a375b17bdb325761e01e88a3ea57026b2393e1d887b34b8fa5d2532928079ce88dc9fd06a728b26d2bb41b12b9032\",\n    \"0x8328a1647398e832aadc05bd717487a2b6fcdaa0d4850d2c4da230c6a2ed44c3e78ec4837b6094f3813f1ee99414713f\",\n    \"0xaa283834ebd18e6c99229ce4b401eda83f01d904f250fedd4e24f1006f8fa0712a6a89a7296a9bf2ce8de30e28d1408e\",\n    \"0xb29e097f2caadae3e0f0ae3473c072b0cd0206cf6d2e9b22c1a5ad3e07d433e32bd09ed1f4e4276a2da4268633357b7f\",\n    \"0x9539c5cbba14538b2fe077ecf67694ef240da5249950baaabea0340718b882a966f66d97f08556b08a4320ceb2cc2629\",\n    \"0xb4529f25e9b42ae8cf8338d2eface6ba5cd4b4d8da73af502d081388135c654c0b3afb3aa779ffc80b8c4c8f4425dd2b\",\n    \"0x95be0739c4330619fbe7ee2249c133c91d6c07eab846c18c5d6c85fc21ac5528c5d56dcb0145af68ed0c6a79f68f2ccd\",\n    \"0xac0c83ea802227bfc23814a24655c9ff13f729619bcffdb487ccbbf029b8eaee709f8bddb98232ef33cd70e30e45ca47\",\n    \"0xb503becb90acc93b1901e939059f93e671900ca52c6f64ae701d11ac891d3a050b505d89324ce267bc43ab8275da6ffe\",\n    \"0x98e3811b55b1bacb70aa409100abb1b870f67e6d059475d9f278c751b6e1e2e2d6f2e586c81a9fb6597fda06e7923274\",\n    \"0xb0b0f61a44053fa6c715dbb0731e35d48dba257d134f851ee1b81fd49a5c51a90ebf5459ec6e489fce25da4f184fbdb1\",\n    \"0xb1d2117fe811720bb997c7c93fe9e4260dc50fca8881b245b5e34f724aaf37ed970cdad4e8fcb68e05ac8cf55a274a53\",\n    \"0xa10f502051968f14b02895393271776dee7a06db9de14effa0b3471825ba94c3f805302bdddac4d397d08456f620999d\",\n    \"0xa3dbad2ef060ae0bb7b02eaa4a13594f3f900450faa1854fc09620b01ac94ab896321dfb1157cf2374c27e5718e8026a\",\n    \"0xb550fdec503195ecb9e079dcdf0cad559d64d3c30818ef369b4907e813e689da316a74ad2422e391b4a8c2a2bef25fc0\",\n    \"0xa25ba865e2ac8f28186cea497294c8649a201732ecb4620c4e77b8e887403119910423df061117e5f03fc5ba39042db1\",\n    \"0xb3f88174e03fdb443dd6addd01303cf88a4369352520187c739fc5ae6b22fa99629c63c985b4383219dab6acc5f6f532\",\n    \"0x97a7503248e31e81b10eb621ba8f5210c537ad11b539c96dfb7cf72b846c7fe81bd7532c5136095652a9618000b7f8d3\",\n    \"0xa8bcdc1ce5aa8bfa683a2fc65c1e79de8ff5446695dcb8620f7350c26d2972a23da22889f9e2b1cacb3f688c6a2953dc\",\n    \"0x8458c111df2a37f5dd91a9bee6c6f4b79f4f161c93fe78075b24a35f9817da8dde71763218d627917a9f1f0c4709c1ed\",\n    \"0xac5f061a0541152b876cbc10640f26f1cc923c9d4ae1b6621e4bb3bf2cec59bbf87363a4eb72fb0e5b6d4e1c269b52d5\",\n    \"0xa9a25ca87006e8a9203cbb78a93f50a36694aa4aad468b8d80d3feff9194455ca559fcc63838128a0ab75ad78c07c13a\",\n    \"0xa450b85f5dfffa8b34dfd8bc985f921318efacf8857cf7948f93884ba09fb831482ee90a44224b1a41e859e19b74962f\",\n    \"0x8ed91e7f92f5c6d7a71708b6132f157ac226ecaf8662af7d7468a4fa25627302efe31e4620ad28719318923e3a59bf82\",\n    \"0xab524165fd4c71b1fd395467a14272bd2b568592deafa039d8492e9ef36c6d3f96927c95c72d410a768dc0b6d1fbbc9b\",\n    \"0xb662144505aa8432c75ffb8d10318526b6d5777ac7af9ebfad87d9b0866c364f7905a6352743bd8fd79ffd9d5dd4f3e6\",\n    \"0xa48f1677550a5cd40663bb3ba8f84caaf8454f332d0ceb1d94dbea52d0412fe69c94997f7749929712fd3995298572f7\",\n    \"0x8391cd6e2f6b0c242de1117a612be99776c3dc95cb800b187685ea5bf7e2722275eddb79fd7dfc8be8e389c4524cdf70\",\n    \"0x875d3acb9af47833b72900bc0a2448999d638f153c5e97e8a14ec02d0c76f6264353a7e275e1f1a5855daced523d243b\",\n    \"0x91f1823657d30b59b2f627880a9a9cb530f5aca28a9fd217fe6f2f5133690dfe7ad5a897872e400512db2e788b3f7628\",\n    \"0xad3564332aa56cea84123fc7ca79ea70bb4fef2009fa131cb44e4b15e8613bd11ca1d83b9d9bf456e4b7fee9f2e8b017\",\n    \"0x8c530b84001936d5ab366c84c0b105241a26d1fb163669f17c8f2e94776895c2870edf3e1bc8ccd04d5e65531471f695\",\n    \"0x932d01fa174fdb0c366f1230cffde2571cc47485f37f23ba5a1825532190cc3b722aeb1f15aed62cf83ccae9403ba713\",\n    \"0x88b28c20585aca50d10752e84b901b5c2d58efef5131479fbbe53de7bce2029e1423a494c0298e1497669bd55be97a5d\",\n    \"0xb914148ca717721144ebb3d3bf3fcea2cd44c30c5f7051b89d8001502f3856fef30ec167174d5b76265b55d70f8716b5\",\n    \"0x81d0173821c6ddd2a068d70766d9103d1ee961c475156e0cbd67d54e668a796310474ef698c7ab55abe6f2cf76c14679\",\n    \"0x8f28e8d78e2fe7fa66340c53718e0db4b84823c8cfb159c76eac032a62fb53da0a5d7e24ca656cf9d2a890cb2a216542\",\n    \"0x8a26360335c73d1ab51cec3166c3cf23b9ea51e44a0ad631b0b0329ef55aaae555420348a544e18d5760969281759b61\",\n    \"0x94f326a32ed287545b0515be9e08149eb0a565025074796d72387cc3a237e87979776410d78339e23ef3172ca43b2544\",\n    \"0xa785d2961a2fa5e70bffa137858a92c48fe749fee91b02599a252b0cd50d311991a08efd7fa5e96b78d07e6e66ffe746\",\n    \"0x94af9030b5ac792dd1ce517eaadcec1482206848bea4e09e55cc7f40fd64d4c2b3e9197027c5636b70d6122c51d2235d\",\n    \"0x9722869f7d1a3992850fe7be405ec93aa17dc4d35e9e257d2e469f46d2c5a59dbd504056c85ab83d541ad8c13e8bcd54\",\n    \"0xb13c4088b61a06e2c03ac9813a75ff1f68ffdfee9df6a8f65095179a475e29cc49119cad2ce05862c3b1ac217f3aace9\",\n    \"0x8c64d51774753623666b10ca1b0fe63ae42f82ed6aa26b81dc1d48c86937c5772eb1402624c52a154b86031854e1fb9f\",\n    \"0xb47e4df18002b7dac3fee945bf9c0503159e1b8aafcce2138818e140753011b6d09ef1b20894e08ba3006b093559061b\",\n    \"0x93cb5970076522c5a0483693f6a35ffd4ea2aa7aaf3730c4eccd6af6d1bebfc1122fc4c67d53898ae13eb6db647be7e2\",\n    \"0xa68873ef80986795ea5ed1a597d1cd99ed978ec25e0abb57fdcc96e89ef0f50aeb779ff46e3dce21dc83ada3157a8498\",\n    \"0x8cab67f50949cc8eee6710e27358aea373aae3c92849f8f0b5531c080a6300cdf2c2094fe6fecfef6148de0d28446919\",\n    \"0x993e932bcb616dbaa7ad18a4439e0565211d31071ef1b85a0627db74a05d978c60d507695eaeea5c7bd9868a21d06923\",\n    \"0xacdadff26e3132d9478a818ef770e9fa0d2b56c6f5f48bd3bd674436ccce9bdfc34db884a73a30c04c5f5e9764cb2218\",\n    \"0xa0d3e64c9c71f84c0eef9d7a9cb4fa184224b969db5514d678e93e00f98b41595588ca802643ea225512a4a272f5f534\",\n    \"0x91c9140c9e1ba6e330cb08f6b2ce4809cd0d5a0f0516f70032bf30e912b0ed684d07b413b326ab531ee7e5b4668c799b\",\n    \"0x87bc2ee7a0c21ba8334cd098e35cb703f9af57f35e091b8151b9b63c3a5b0f89bd7701dbd44f644ea475901fa6d9ef08\",\n    \"0x9325ccbf64bf5d71b303e31ee85d486298f9802c5e55b2c3d75427097bf8f60fa2ab4fcaffa9b60bf922c3e24fbd4b19\",\n    \"0x95d0506e898318f3dc8d28d16dfd9f0038b54798838b3c9be2a2ae3c2bf204eb496166353fc042220b0bd4f6673b9285\",\n    \"0x811de529416331fe9c416726d45df9434c29dcd7e949045eb15740f47e97dde8f31489242200e19922cac2a8b7c6fd1f\",\n    \"0xade632d04a4c8bbab6ca7df370b2213cb9225023e7973f0e29f4f5e52e8aeaabc65171306bbdd12a67b195dfbb96d48f\",\n    \"0x88b7f029e079b6ae956042c0ea75d53088c5d0efd750dd018adaeacf46be21bf990897c58578c491f41afd3978d08073\",\n    \"0x91f477802de507ffd2be3f4319903119225b277ad24f74eb50f28b66c14d32fae53c7edb8c7590704741af7f7f3e3654\",\n    \"0x809838b32bb4f4d0237e98108320d4b079ee16ed80c567e7548bd37e4d7915b1192880f4812ac0e00476d246aec1dbc8\",\n    \"0x84183b5fc4a7997a8ae5afedb4d21dce69c480d5966b5cbdafd6dd10d29a9a6377f3b90ce44da0eb8b176ac3af0253bb\",\n    \"0x8508abbf6d3739a16b9165caf0f95afb3b3ac1b8c38d6d374cf0c91296e2c1809a99772492b539cda184510bce8a0271\",\n    \"0x8722054e59bab2062e6419a6e45fc803af77fde912ef2cd23055ad0484963de65a816a2debe1693d93c18218d2b8e81a\",\n    \"0x8e895f80e485a7c4f56827bf53d34b956281cdc74856c21eb3b51f6288c01cc3d08565a11cc6f3e2604775885490e8c5\",\n    \"0xafc92714771b7aa6e60f3aee12efd9c2595e9659797452f0c1e99519f67c8bc3ac567119c1ddfe82a3e961ee9defea9a\",\n    \"0x818ff0fd9cefd32db87b259e5fa32967201016fc02ef44116cdca3c63ce5e637756f60477a408709928444a8ad69c471\",\n    \"0x8251e29af4c61ae806fc5d032347fb332a94d472038149225298389495139ce5678fae739d02dfe53a231598a992e728\",\n    \"0xa0ea39574b26643f6f1f48f99f276a8a64b5481989cfb2936f9432a3f8ef5075abfe5c067dc5512143ce8bf933984097\",\n    \"0xaf67a73911b372bf04e57e21f289fc6c3dfac366c6a01409b6e76fea4769bdb07a6940e52e8d7d3078f235c6d2f632c6\",\n    \"0xb5291484ef336024dd2b9b4cf4d3a6b751133a40656d0a0825bcc6d41c21b1c79cb50b0e8f4693f90c29c8f4358641f9\",\n    \"0x8bc0d9754d70f2cb9c63f991902165a87c6535a763d5eece43143b5064ae0bcdce7c7a8f398f2c1c29167b2d5a3e6867\",\n    \"0x8d7faff53579ec8f6c92f661c399614cc35276971752ce0623270f88be937c414eddcb0997e14724a783905a026c8883\",\n    \"0x9310b5f6e675fdf60796f814dbaa5a6e7e9029a61c395761e330d9348a7efab992e4e115c8be3a43d08e90d21290c892\",\n    \"0xb5eb4f3eb646038ad2a020f0a42202532d4932e766da82b2c1002bf9c9c2e5336b54c8c0ffcc0e02d19dde2e6a35b6cc\",\n    \"0x91dabfd30a66710f1f37a891136c9be1e23af4abf8cb751f512a40c022a35f8e0a4fb05b17ec36d4208de02d56f0d53a\",\n    \"0xb3ded14e82d62ac7a5a036122a62f00ff8308498f3feae57d861babaff5a6628d43f0a0c5fc903f10936bcf4e2758ceb\",\n    \"0xa88e8348fed2b26acca6784d19ef27c75963450d99651d11a950ea81d4b93acd2c43e0ecce100eaf7e78508263d5baf3\",\n    \"0xb1f5bbf7c4756877b87bb42163ac570e08c6667c4528bf68b5976680e19beeff7c5effd17009b0718797077e2955457a\",\n    \"0xad2e7b516243f915d4d1415326e98b1a7390ae88897d0b03b66c2d9bd8c3fba283d7e8fe44ed3333296a736454cef6d8\",\n    \"0x8f82eae096d5b11f995de6724a9af895f5e1c58d593845ad16ce8fcae8507e0d8e2b2348a0f50a1f66a17fd6fac51a5c\",\n    \"0x890e4404d0657c6c1ee14e1aac132ecf7a568bb3e04137b85ac0f84f1d333bd94993e8750f88eee033a33fb00f85dcc7\",\n    \"0x82ac7d3385e035115f1d39a99fc73e5919de44f5e6424579776d118d711c8120b8e5916372c6f27bed4cc64cac170b6c\",\n    \"0x85ee16d8901c272cfbbe966e724b7a891c1bd5e68efd5d863043ad8520fc409080af61fd726adc680b3f1186fe0ac8b8\",\n    \"0x86dc564c9b545567483b43a38f24c41c6551a49cabeebb58ce86404662a12dbfafd0778d30d26e1c93ce222e547e3898\",\n    \"0xa29f5b4522db26d88f5f95f18d459f8feefab02e380c2edb65aa0617a82a3c1a89474727a951cef5f15050bcf7b380fb\",\n    \"0xa1ce039c8f6cac53352899edb0e3a72c76da143564ad1a44858bd7ee88552e2fe6858d1593bbd74aeee5a6f8034b9b9d\",\n    \"0x97f10d77983f088286bd7ef3e7fdd8fa275a56bec19919adf33cf939a90c8f2967d2b1b6fc51195cb45ad561202a3ed7\",\n    \"0xa25e2772e8c911aaf8712bdac1dd40ee061c84d3d224c466cfaae8e5c99604053f940cde259bd1c3b8b69595781dbfec\",\n    \"0xb31bb95a0388595149409c48781174c340960d59032ab2b47689911d03c68f77a2273576fbe0c2bf4553e330656058c7\",\n    \"0xb8b2e9287ad803fb185a13f0d7456b397d4e3c8ad5078f57f49e8beb2e85f661356a3392dbd7bcf6a900baa5582b86a1\",\n    \"0xa3d0893923455eb6e96cc414341cac33d2dbc88fba821ac672708cce131761d85a0e08286663a32828244febfcae6451\",\n    \"0x82310cb42f647d99a136014a9f881eb0b9791efd2e01fc1841907ad3fc8a9654d3d1dab6689c3607214b4dc2aca01cee\",\n    \"0x874022d99c16f60c22de1b094532a0bc6d4de700ad01a31798fac1d5088b9a42ad02bef8a7339af7ed9c0d4f16b186ee\",\n    \"0x94981369e120265aed40910eebc37eded481e90f4596b8d57c3bec790ab7f929784bd33ddd05b7870aad6c02e869603b\",\n    \"0xa4f1f50e1e2a73f07095e0dd31cb45154f24968dae967e38962341c1241bcd473102fff1ff668b20c6547e9732d11701\",\n    \"0xae2328f3b0ad79fcda807e69a1b5278145225083f150f67511dafc97e079f860c3392675f1752ae7e864c056e592205b\",\n    \"0x875d8c971e593ca79552c43d55c8c73b17cd20c81ff2c2fed1eb19b1b91e4a3a83d32df150dbfd5db1092d0aebde1e1f\",\n    \"0xadd2e80aa46aae95da73a11f130f4bda339db028e24c9b11e5316e75ba5e63bc991d2a1da172c7c8e8fee038baae3433\",\n    \"0xb46dbe1cb3424002aa7de51e82f600852248e251465c440695d52538d3f36828ff46c90ed77fc1d11534fe3c487df8ef\",\n    \"0xa5e5045d28b4e83d0055863c30c056628c58d4657e6176fd0536f5933f723d60e851bb726d5bf3c546b8ce4ac4a57ef8\",\n    \"0x91fec01e86dd1537e498fff7536ea3ca012058b145f29d9ada49370cd7b7193ac380e116989515df1b94b74a55c45df3\",\n    \"0xa7428176d6918cd916a310bdc75483c72de660df48cac4e6e7478eef03205f1827ea55afc0df5d5fa7567d14bbea7fc9\",\n    \"0x851d89bef45d9761fe5fdb62972209335193610015e16a675149519f9911373bac0919add226ef118d9f3669cfdf4734\",\n    \"0xb74acf5c149d0042021cb2422ea022be4c4f72a77855f42393e71ffd12ebb3eec16bdf16f812159b67b79a9706e7156d\",\n    \"0x99f35dce64ec99aa595e7894b55ce7b5a435851b396e79036ffb249c28206087db4c85379df666c4d95857db02e21ff9\",\n    \"0xb6b9a384f70db9e298415b8ab394ee625dafff04be2886476e59df8d052ca832d11ac68a9b93fba7ab055b7bc36948a4\",\n    \"0x898ee4aefa923ffec9e79f2219c7389663eb11eb5b49014e04ed4a336399f6ea1691051d86991f4c46ca65bcd4fdf359\",\n    \"0xb0f948217b0d65df7599a0ba4654a5e43c84db477936276e6f11c8981efc6eaf14c90d3650107ed4c09af4cc8ec11137\",\n    \"0xaa6286e27ac54f73e63dbf6f41865dd94d24bc0cf732262fcaff67319d162bb43af909f6f8ee27b1971939cfbba08141\",\n    \"0x8bca7cdf730cf56c7b2c8a2c4879d61361a6e1dba5a3681a1a16c17a56e168ace0e99cf0d15826a1f5e67e6b8a8a049a\",\n    \"0xa746d876e8b1ce225fcafca603b099b36504846961526589af977a88c60d31ba2cc56e66a3dec8a77b3f3531bf7524c9\",\n    \"0xa11e2e1927e6704cdb8874c75e4f1842cef84d7d43d7a38e339e61dc8ba90e61bbb20dd3c12e0b11d2471d58eed245be\",\n    \"0xa36395e22bc1d1ba8b0459a235203177737397da5643ce54ded3459d0869ff6d8d89f50c73cb62394bf66a959cde9b90\",\n    \"0x8b49f12ba2fdf9aca7e5f81d45c07d47f9302a2655610e7634d1e4bd16048381a45ef2c95a8dd5b0715e4b7cf42273af\",\n    \"0x91cffa2a17e64eb7f76bccbe4e87280ee1dd244e04a3c9eac12e15d2d04845d876eb24fe2ec6d6d266cce9efb281077f\",\n    \"0xa6b8afabf65f2dee01788114e33a2f3ce25376fb47a50b74da7c3c25ff1fdc8aa9f41307534abbf48acb6f7466068f69\",\n    \"0x8d13db896ccfea403bd6441191995c1a65365cab7d0b97fbe9526da3f45a877bd1f4ef2edef160e8a56838cd1586330e\",\n    \"0x98c717de9e01bef8842c162a5e757fe8552d53269c84862f4d451e7c656ae6f2ae473767b04290b134773f63be6fdb9d\",\n    \"0x8c2036ace1920bd13cf018e82848c49eb511fad65fd0ff51f4e4b50cf3bfc294afb63cba682c16f52fb595a98fa84970\",\n    \"0xa3520fdff05dbad9e12551b0896922e375f9e5589368bcb2cc303bde252743b74460cb5caf99629325d3620f13adc796\",\n    \"0x8d4f83a5bfec05caf5910e0ce538ee9816ee18d0bd44c1d0da2a87715a23cd2733ad4d47552c6dc0eb397687d611dd19\",\n    \"0xa7b39a0a6a02823452d376533f39d35029867b3c9a6ad6bca181f18c54132d675613a700f9db2440fb1b4fa13c8bf18a\",\n    \"0x80bcb114b2544b80f404a200fc36860ed5e1ad31fe551acd4661d09730c452831751baa9b19d7d311600d267086a70bc\",\n    \"0x90dcce03c6f88fc2b08f2b42771eedde90cc5330fe0336e46c1a7d1b5a6c1641e5fcc4e7b3d5db00bd8afca9ec66ed81\",\n    \"0xaec15f40805065c98e2965b1ae12a6c9020cfdb094c2d0549acfc7ea2401a5fb48d3ea7d41133cf37c4e096e7ff53eb9\",\n    \"0x80e129b735dba49fa627a615d6c273119acec8e219b2f2c4373a332b5f98d66cbbdd688dfbe72a8f8bfefaccc02c50c1\",\n    \"0xa9b596da3bdfe23e6799ece5f7975bf7a1979a75f4f546deeaf8b34dfe3e0d623217cb4cf4ccd504cfa3625b88cd53f1\",\n    \"0xabcbbb70b16f6e517c0ab4363ab76b46e4ff58576b5f8340e5c0e8cc0e02621b6e23d742d73b015822a238b17cfd7665\",\n    \"0xa046937cc6ea6a2e1adae543353a9fe929c1ae4ad655be1cc051378482cf88b041e28b1e9a577e6ccff2d3570f55e200\",\n    \"0x831279437282f315e65a60184ef158f0a3dddc15a648dc552bdc88b3e6fe8288d3cfe9f0031846d81350f5e7874b4b33\",\n    \"0x993d7916fa213c6d66e7c4cafafc1eaec9a2a86981f91c31eb8a69c5df076c789cbf498a24c84e0ee77af95b42145026\",\n    \"0x823907a3b6719f8d49b3a4b7c181bd9bb29fcf842d7c70660c4f351852a1e197ca46cf5e879b47fa55f616fa2b87ce5e\",\n    \"0x8d228244e26132b234930ee14c75d88df0943cdb9c276a8faf167d259b7efc1beec2a87c112a6c608ad1600a239e9aae\",\n    \"0xab6e55766e5bfb0cf0764ed909a8473ab5047d3388b4f46faeba2d1425c4754c55c6daf6ad4751e634c618b53e549529\",\n    \"0xab0cab6860e55a84c5ad2948a7e0989e2b4b1fd637605634b118361497332df32d9549cb854b2327ca54f2bcb85eed8f\",\n    \"0xb086b349ae03ef34f4b25a57bcaa5d1b29bd94f9ebf87e22be475adfe475c51a1230c1ebe13506cb72c4186192451658\",\n    \"0x8a0b49d8a254ca6d91500f449cbbfbb69bb516c6948ac06808c65595e46773e346f97a5ce0ef7e5a5e0de278af22709c\",\n    \"0xac49de11edaaf04302c73c578cc0824bdd165c0d6321be1c421c1950e68e4f3589aa3995448c9699e93c6ebae8803e27\",\n    \"0x884f02d841cb5d8f4c60d1402469216b114ab4e93550b5bc1431756e365c4f870a9853449285384a6fa49e12ce6dc654\",\n    \"0xb75f3a28fa2cc8d36b49130cb7448a23d73a7311d0185ba803ad55c8219741d451c110f48b786e96c728bc525903a54f\",\n    \"0x80ae04dbd41f4a35e33f9de413b6ad518af0919e5a30cb0fa1b061b260420780bb674f828d37fd3b52b5a31673cbd803\",\n    \"0xb9a8011eb5fcea766907029bf743b45262db3e49d24f84503687e838651ed11cb64c66281e20a0ae9f6aa51acc552263\",\n    \"0x90bfdd75e2dc9cf013e22a5d55d2d2b8a754c96103a17524488e01206e67f8b6d52b1be8c4e3d5307d4fe06d0e51f54c\",\n    \"0xb4af353a19b06203a815ec43e79a88578cc678c46f5a954b85bc5c53b84059dddba731f3d463c23bfd5273885c7c56a4\",\n    \"0xaa125e96d4553b64f7140e5453ff5d2330318b69d74d37d283e84c26ad672fa00e3f71e530eb7e28be1e94afb9c4612e\",\n    \"0xa18e060aee3d49cde2389b10888696436bb7949a79ca7d728be6456a356ea5541b55492b2138da90108bd1ce0e6f5524\",\n    \"0x93e55f92bdbccc2de655d14b1526836ea2e52dba65eb3f87823dd458a4cb5079bf22ce6ef625cb6d6bfdd0995ab9a874\",\n    \"0x89f5a683526b90c1c3ceebbb8dc824b21cff851ce3531b164f6626e326d98b27d3e1d50982e507d84a99b1e04e86a915\",\n    \"0x83d1c38800361633a3f742b1cb2bfc528129496e80232611682ddbe403e92c2ac5373aea0bca93ecb5128b0b2b7a719e\",\n    \"0x8ecba560ac94905e19ce8d9c7af217bf0a145d8c8bd38e2db82f5e94cc3f2f26f55819176376b51f154b4aab22056059\",\n    \"0xa7e2a4a002b60291924850642e703232994acb4cfb90f07c94d1e0ecd2257bb583443283c20fc6017c37e6bfe85b7366\",\n    \"0x93ed7316fa50b528f1636fc6507683a672f4f4403e55e94663f91221cc198199595bd02eef43d609f451acc9d9b36a24\",\n    \"0xa1220a8ebc5c50ceed76a74bc3b7e0aa77f6884c71b64b67c4310ac29ce5526cb8992d6abc13ef6c8413ce62486a6795\",\n    \"0xb2f6eac5c869ad7f4a25161d3347093e2f70e66cd925032747e901189355022fab3038bca4d610d2f68feb7e719c110b\",\n    \"0xb703fa11a4d511ca01c7462979a94acb40b5d933759199af42670eb48f83df202fa0c943f6ab3b4e1cc54673ea3aab1e\",\n    \"0xb5422912afbfcb901f84791b04f1ddb3c3fbdc76d961ee2a00c5c320e06d3cc5b5909c3bb805df66c5f10c47a292b13d\",\n    \"0xad0934368da823302e1ac08e3ede74b05dfdbfffca203e97ffb0282c226814b65c142e6e15ec1e754518f221f01b30f7\",\n    \"0xa1dd302a02e37df15bf2f1147efe0e3c06933a5a767d2d030e1132f5c3ce6b98e216b6145eb39e1e2f74e76a83165b8d\",\n    \"0xa346aab07564432f802ae44738049a36f7ca4056df2d8f110dbe7fef4a3e047684dea609b2d03dc6bf917c9c2a47608f\",\n    \"0xb96c5f682a5f5d02123568e50f5d0d186e4b2c4c9b956ec7aabac1b3e4a766d78d19bd111adb5176b898e916e49be2aa\",\n    \"0x8a96676d56876fc85538db2e806e1cba20fd01aeb9fa3cb43ca6ca94a2c102639f65660db330e5d74a029bb72d6a0b39\",\n    \"0xab0048336bd5c3def1a4064eadd49e66480c1f2abb4df46e03afbd8a3342c2c9d74ee35d79f08f4768c1646681440984\",\n    \"0x888427bdf76caec90814c57ee1c3210a97d107dd88f7256f14f883ad0f392334b82be11e36dd8bfec2b37935177c7831\",\n    \"0xb622b282becf0094a1916fa658429a5292ba30fb48a4c8066ce1ddcefb71037948262a01c95bab6929ed3a76ba5db9fe\",\n    \"0xb5b9e005c1f456b6a368a3097634fb455723abe95433a186e8278dceb79d4ca2fbe21f8002e80027b3c531e5bf494629\",\n    \"0xa3c6707117a1e48697ed41062897f55d8119403eea6c2ee88f60180f6526f45172664bfee96bf61d6ec0b7fbae6aa058\",\n    \"0xb02a9567386a4fbbdb772d8a27057b0be210447348efe6feb935ceec81f361ed2c0c211e54787dc617cdffed6b4a6652\",\n    \"0xa9b8364e40ef15c3b5902e5534998997b8493064fa2bea99600def58279bb0f64574c09ba11e9f6f669a8354dd79dc85\",\n    \"0x9998a2e553a9aa9a206518fae2bc8b90329ee59ab23005b10972712389f2ec0ee746033c733092ffe43d73d33abbb8ef\",\n    \"0x843a4b34d9039bf79df96d79f2d15e8d755affb4d83d61872daf540b68c0a3888cf8fc00d5b8b247b38524bcb3b5a856\",\n    \"0x84f7128920c1b0bb40eee95701d30e6fc3a83b7bb3709f16d97e72acbb6057004ee7ac8e8f575936ca9dcb7866ab45f7\",\n    \"0x918d3e2222e10e05edb34728162a899ad5ada0aaa491aeb7c81572a9c0d506e31d5390e1803a91ff3bd8e2bb15d47f31\",\n    \"0x9442d18e2489613a7d47bb1cb803c8d6f3259d088cd079460976d87f7905ee07dea8f371b2537f6e1d792d36d7e42723\",\n    \"0xb491976970fe091995b2ed86d629126523ccf3e9daf8145302faca71b5a71a5da92e0e05b62d7139d3efac5c4e367584\",\n    \"0xaa628006235dc77c14cef4c04a308d66b07ac92d377df3de1a2e6ecfe3144f2219ad6d7795e671e1cb37a3641910b940\",\n    \"0x99d386adaea5d4981d7306feecac9a555b74ffdc218c907c5aa7ac04abaead0ec2a8237300d42a3fbc464673e417ceed\",\n    \"0x8f78e8b1556f9d739648ea3cab9606f8328b52877fe72f9305545a73b74d49884044ba9c1f1c6db7d9b7c7b7c661caba\",\n    \"0x8fb357ae49932d0babdf74fc7aa7464a65d3b6a2b3acf4f550b99601d3c0215900cfd67f2b6651ef94cfc323bac79fae\",\n    \"0x9906f2fa25c0290775aa001fb6198113d53804262454ae8b83ef371b5271bde189c0460a645829cb6c59f9ee3a55ce4d\",\n    \"0x8f4379b3ebb50e052325b27655ca6a82e6f00b87bf0d2b680d205dd2c7afdc9ff32a9047ae71a1cdf0d0ce6b9474d878\",\n    \"0xa85534e88c2bd43c043792eaa75e50914b21741a566635e0e107ae857aed0412035f7576cf04488ade16fd3f35fdbb87\",\n    \"0xb4ce93199966d3c23251ca7f28ec5af7efea1763d376b0385352ffb2e0a462ef95c69940950278cf0e3dafd638b7bd36\",\n    \"0xb10cb3d0317dd570aa73129f4acf63c256816f007607c19b423fb42f65133ce21f2f517e0afb41a5378cccf893ae14d0\",\n    \"0xa9b231c9f739f7f914e5d943ed9bff7eba9e2c333fbd7c34eb1648a362ee01a01af6e2f7c35c9fe962b11152cddf35de\",\n    \"0x99ff6a899e156732937fb81c0cced80ae13d2d44c40ba99ac183aa246103b31ec084594b1b7feb96da58f4be2dd5c0ed\",\n    \"0x8748d15d18b75ff2596f50d6a9c4ce82f61ecbcee123a6ceae0e43cab3012a29b6f83cf67b48c22f6f9d757c6caf76b2\",\n    \"0xb88ab05e4248b7fb634cf640a4e6a945d13e331237410f7217d3d17e3e384ddd48897e7a91e4516f1b9cbd30f35f238b\",\n    \"0x8d826deaeeb84a3b2d2c04c2300ca592501f992810582d6ae993e0d52f6283a839dba66c6c72278cff5871802b71173b\",\n    \"0xb36fed027c2f05a5ef625ca00b0364b930901e9e4420975b111858d0941f60e205546474bb25d6bfa6928d37305ae95f\",\n    \"0xaf2fcfc6b87967567e8b8a13a4ed914478185705724e56ce68fb2df6d1576a0cf34a61e880997a0d35dc2c3276ff7501\",\n    \"0xac351b919cd1fbf106feb8af2c67692bfcddc84762d18cea681cfa7470a5644839caace27efee5f38c87d3df306f4211\",\n    \"0x8d6665fb1d4d8d1fa23bd9b8a86e043b8555663519caac214d1e3e3effbc6bee7f2bcf21e645f77de0ced279d69a8a8b\",\n    \"0xa9fc1c2061756b2a1a169c1b149f212ff7f0d2488acd1c5a0197eba793cffa593fc6d1d1b40718aa75ca3ec77eff10e1\",\n    \"0xaff64f0fa009c7a6cf0b8d7a22ddb2c8170c3cb3eec082e60d5aadb00b0040443be8936d728d99581e33c22178c41c87\",\n    \"0x82e0b181adc5e3b1c87ff8598447260e839d53debfae941ebea38265575546c3a74a14b4325a030833a62ff6c52d9365\",\n    \"0xb7ad43cbb22f6f892c2a1548a41dc120ab1f4e1b8dea0cb6272dd9cb02054c542ecabc582f7e16de709d48f5166cae86\",\n    \"0x985e0c61094281532c4afb788ecb2dfcba998e974b5d4257a22040a161883908cdd068fe80f8eb49b8953cfd11acf43a\",\n    \"0xae46895c6d67ea6d469b6c9c07b9e5d295d9ae73b22e30da4ba2c973ba83a130d7eef39717ec9d0f36e81d56bf742671\",\n    \"0x8600177ea1f7e7ef90514b38b219a37dedfc39cb83297e4c7a5b479817ef56479d48cf6314820960c751183f6edf8b0e\",\n    \"0xb9208ec1c1d7a1e99b59c62d3e4e61dfb706b0e940d09d3abfc3454c19749083260614d89cfd7e822596c3cdbcc6bb95\",\n    \"0xa1e94042c796c2b48bc724352d2e9f3a22291d9a34705993357ddb6adabd76da6fc25dac200a8cb0b5bbd99ecddb7af6\",\n    \"0xb29c3adedd0bcad8a930625bc4dfdc3552a9afd5ca6dd9c0d758f978068c7982b50b711aa0eb5b97f2b84ee784637835\",\n    \"0xaf0632a238bb1f413c7ea8e9b4c3d68f2827bd2e38cd56024391fba6446ac5d19a780d0cfd4a78fe497d537b766a591a\",\n    \"0xaaf6e7f7d54f8ef5e2e45dd59774ecbeecf8683aa70483b2a75be6a6071b5981bbaf1627512a65d212817acdfab2e428\",\n    \"0x8c751496065da2e927cf492aa5ca9013b24f861d5e6c24b30bbf52ec5aaf1905f40f9a28175faef283dd4ed4f2182a09\",\n    \"0x8952377d8e80a85cf67d6b45499f3bad5fd452ea7bcd99efc1b066c4720d8e5bff1214cea90fd1f972a7f0baac3d29be\",\n    \"0xa1946ee543d1a6e21f380453be4d446e4130950c5fc3d075794eb8260f6f52d0a795c1ff91d028a648dc1ce7d9ab6b47\",\n    \"0x89f3fefe37af31e0c17533d2ca1ce0884cc1dc97c15cbfab9c331b8debd94781c9396abef4bb2f163d09277a08d6adf0\",\n    \"0xa2753f1e6e1a154fb117100a5bd9052137add85961f8158830ac20541ab12227d83887d10acf7fd36dcaf7c2596d8d23\",\n    \"0x814955b4198933ee11c3883863b06ff98c7eceb21fc3e09df5f916107827ccf3323141983e74b025f46ae00284c9513b\",\n    \"0x8cc5c6bb429073bfef47cae7b3bfccb0ffa076514d91a1862c6bda4d581e0df87db53cc6c130bf8a7826304960f5a34e\",\n    \"0x909f22c1f1cdc87f7be7439c831a73484a49acbf8f23d47087d7cf867c64ef61da3bde85dc57d705682b4c3fc710d36e\",\n    \"0x8048fee7f276fcd504aed91284f28e73693615e0eb3858fa44bcf79d7285a9001c373b3ef71d9a3054817ba293ebe28c\",\n    \"0x94400e5cf5d2700ca608c5fe35ce14623f71cc24959f2bc27ca3684092850f76b67fb1f07ca9e5b2ca3062cf8ad17bd4\",\n    \"0x81c2ae7d4d1b17f8b6de6a0430acc0d58260993980fe48dc2129c4948269cdc74f9dbfbf9c26b19360823fd913083d48\",\n    \"0x8c41fe765128e63f6889d6a979f6a4342300327c8b245a8cfe3ecfbcac1e09c3da30e2a1045b24b78efc6d6d50c8c6ac\",\n    \"0xa5dd4ae51ae48c8be4b218c312ade226cffce671cf121cb77810f6c0990768d6dd767badecb5c69921d5574d5e8433d3\",\n    \"0xb7642e325f4ba97ae2a39c1c9d97b35aafd49d53dba36aed3f3cb0ca816480b3394079f46a48252d46596559c90f4d58\",\n    \"0xae87375b40f35519e7bd4b1b2f73cd0b329b0c2cb9d616629342a71c6c304338445eda069b78ea0fbe44087f3de91e09\",\n    \"0xb08918cb6f736855e11d3daca1ddfbdd61c9589b203b5493143227bf48e2c77c2e8c94b0d1aa2fab2226e0eae83f2681\",\n    \"0xac36b84a4ac2ebd4d6591923a449c564e3be8a664c46092c09e875c2998eba16b5d32bfd0882fd3851762868e669f0b1\",\n    \"0xa44800a3bb192066fa17a3f29029a23697240467053b5aa49b9839fb9b9b8b12bcdcbfc557f024b61f4f51a9aacdefcb\",\n    \"0x9064c688fec23441a274cdf2075e5a449caf5c7363cc5e8a5dc9747183d2e00a0c69f2e6b3f6a7057079c46014c93b3b\",\n    \"0xaa367b021469af9f5b764a79bb3afbe2d87fe1e51862221672d1a66f954b165778b7c27a705e0f93841fab4c8468344d\",\n    \"0xa1a8bfc593d4ab71f91640bc824de5c1380ab2591cfdafcbc78a14b32de3c0e15f9d1b461d85c504baa3d4232c16bb53\",\n    \"0x97df48da1799430f528184d30b6baa90c2a2f88f34cdfb342d715339c5ebd6d019aa693cea7c4993daafc9849063a3aa\",\n    \"0xabd923831fbb427e06e0dd335253178a9e5791395c84d0ab1433c07c53c1209161097e9582fb8736f8a60bde62d8693e\",\n    \"0x84cd1a43f1a438b43dc60ffc775f646937c4f6871438163905a3cebf1115f814ccd38a6ccb134130bff226306e412f32\",\n    \"0x91426065996b0743c5f689eb3ca68a9f7b9e4d01f6c5a2652b57fa9a03d8dc7cd4bdbdab0ca5a891fee1e97a7f00cf02\",\n    \"0xa4bee50249db3df7fd75162b28f04e57c678ba142ce4d3def2bc17bcb29e4670284a45f218dad3969af466c62a903757\",\n    \"0x83141ebcc94d4681404e8b67a12a46374fded6df92b506aff3490d875919631408b369823a08b271d006d5b93136f317\",\n    \"0xa0ea1c8883d58d5a784da3d8c8a880061adea796d7505c1f903d07c287c5467f71e4563fc0faafbc15b5a5538b0a7559\",\n    \"0x89d9d480574f201a87269d26fb114278ed2c446328df431dc3556e3500e80e4cd01fcac196a2459d8646361ebda840df\",\n    \"0x8bf302978973632dd464bec819bdb91304712a3ec859be071e662040620422c6e75eba6f864f764cffa2799272efec39\",\n    \"0x922f666bc0fd58b6d7d815c0ae4f66d193d32fc8382c631037f59eeaeae9a8ca6c72d08e72944cf9e800b8d639094e77\",\n    \"0x81ad8714f491cdff7fe4399f2eb20e32650cff2999dd45b9b3d996d54a4aba24cc6c451212e78c9e5550368a1a38fb3f\",\n    \"0xb58fcf4659d73edb73175bd9139d18254e94c3e32031b5d4b026f2ed37aa19dca17ec2eb54c14340231615277a9d347e\",\n    \"0xb365ac9c2bfe409b710928c646ea2fb15b28557e0f089d39878e365589b9d1c34baf5566d20bb28b33bb60fa133f6eff\",\n    \"0x8fcae1d75b53ab470be805f39630d204853ca1629a14158bac2f52632277d77458dec204ff84b7b2d77e641c2045be65\",\n    \"0xa03efa6bebe84f4f958a56e2d76b5ba4f95dd9ed7eb479edc7cc5e646c8d4792e5b0dfc66cc86aa4b4afe2f7a4850760\",\n    \"0xaf1c823930a3638975fb0cc5c59651771b2719119c3cd08404fbd4ce77a74d708cefbe3c56ea08c48f5f10e6907f338f\",\n    \"0x8260c8299b17898032c761c325ac9cabb4c5b7e735de81eacf244f647a45fb385012f4f8df743128888c29aefcaaad16\",\n    \"0xab2f37a573c82e96a8d46198691cd694dfa860615625f477e41f91b879bc58a745784fccd8ffa13065834ffd150d881d\",\n    \"0x986c746c9b4249352d8e5c629e8d7d05e716b3c7aab5e529ca969dd1e984a14b5be41528baef4c85d2369a42d7209216\",\n    \"0xb25e32da1a8adddf2a6080725818b75bc67240728ad1853d90738485d8924ea1e202df0a3034a60ffae6f965ec55cf63\",\n    \"0xa266e627afcebcefea6b6b44cbc50f5c508f7187e87d047b0450871c2a030042c9e376f3ede0afcf9d1952f089582f71\",\n    \"0x86c3bbca4c0300606071c0a80dbdec21ce1dd4d8d4309648151c420854032dff1241a1677d1cd5de4e4de4385efda986\",\n    \"0xb9a21a1fe2d1f3273a8e4a9185abf2ff86448cc98bfa435e3d68306a2b8b4a6a3ea33a155be3cb62a2170a86f77679a5\",\n    \"0xb117b1ea381adce87d8b342cba3a15d492ff2d644afa28f22424cb9cbc820d4f7693dfc1a4d1b3697046c300e1c9b4c8\",\n    \"0x9004c425a2e68870d6c69b658c344e3aa3a86a8914ee08d72b2f95c2e2d8a4c7bb0c6e7e271460c0e637cec11117bf8e\",\n    \"0x86a18aa4783b9ebd9131580c8b17994825f27f4ac427b0929a1e0236907732a1c8139e98112c605488ee95f48bbefbfc\",\n    \"0x84042243b955286482ab6f0b5df4c2d73571ada00716d2f737ca05a0d2e88c6349e8ee9e67934cfee4a1775dbf7f4800\",\n    \"0x92c2153a4733a62e4e1d5b60369f3c26777c7d01cd3c8679212660d572bd3bac9b8a8a64e1f10f7dbf5eaa7579c4e423\",\n    \"0x918454b6bb8e44a2afa144695ba8d48ae08d0cdfef4ad078f67709eddf3bb31191e8b006f04e82ea45a54715ef4d5817\",\n    \"0xacf0b54f6bf34cf6ed6c2b39cf43194a40d68de6bcf1e4b82c34c15a1343e9ac3737885e1a30b78d01fa3a5125463db8\",\n    \"0xa7d60dbe4b6a7b054f7afe9ee5cbbfeca0d05dc619e6041fa2296b549322529faddb8a11e949562309aecefb842ac380\",\n    \"0x91ffb53e6d7e5f11159eaf13e783d6dbdfdb1698ed1e6dbf3413c6ea23492bbb9e0932230a9e2caac8fe899a17682795\",\n    \"0xb6e8d7be5076ee3565d5765a710c5ecf17921dd3cf555c375d01e958a365ae087d4a88da492a5fb81838b7b92bf01143\",\n    \"0xa8c6b763de2d4b2ed42102ef64eccfef31e2fb2a8a2776241c82912fa50fc9f77f175b6d109a97ede331307c016a4b1a\",\n    \"0x99839f86cb700c297c58bc33e28d46b92931961548deac29ba8df91d3e11721b10ea956c8e16984f9e4acf1298a79b37\",\n    \"0x8c2e2c338f25ea5c25756b7131cde0d9a2b35abf5d90781180a00fe4b8e64e62590dc63fe10a57fba3a31c76d784eb01\",\n    \"0x9687d7df2f41319ca5469d91978fed0565a5f11f829ebadaa83db92b221755f76c6eacd7700735e75c91e257087512e3\",\n    \"0x8795fdfb7ff8439c58b9bf58ed53873d2780d3939b902b9ddaaa4c99447224ced9206c3039a23c2c44bcc461e2bb637f\",\n    \"0xa803697b744d2d087f4e2307218d48fa88620cf25529db9ce71e2e3bbcc65bac5e8bb9be04777ef7bfb5ed1a5b8e6170\",\n    \"0x80f3d3efbbb9346ddd413f0a8e36b269eb5d7ff6809d5525ff9a47c4bcab2c01b70018b117f6fe05253775612ff70c6b\",\n    \"0x9050e0e45bcc83930d4c505af35e5e4d7ca01cd8681cba92eb55821aececcebe32bb692ebe1a4daac4e7472975671067\",\n    \"0x8d206812aac42742dbaf233e0c080b3d1b30943b54b60283515da005de05ea5caa90f91fedcfcba72e922f64d7040189\",\n    \"0xa2d44faaeb2eff7915c83f32b13ca6f31a6847b1c1ce114ea240bac3595eded89f09b2313b7915ad882292e2b586d5b4\",\n    \"0x961776c8576030c39f214ea6e0a3e8b3d32f023d2600958c098c95c8a4e374deeb2b9dc522adfbd6bda5949bdc09e2a2\",\n    \"0x993fa7d8447407af0fbcd9e6d77f815fa5233ab00674efbcf74a1f51c37481445ae291cc7b76db7c178f9cb0e570e0fc\",\n    \"0xabd5b1c78e05f9d7c8cc99bdaef8b0b6a57f2daf0f02bf492bec48ea4a27a8f1e38b5854da96efff11973326ff980f92\",\n    \"0x8f15af4764bc275e6ccb892b3a4362cacb4e175b1526a9a99944e692fe6ccb1b4fc19abf312bb2a089cb1f344d91a779\",\n    \"0xa09b27ccd71855512aba1d0c30a79ffbe7f6707a55978f3ced50e674b511a79a446dbc6d7946add421ce111135a460af\",\n    \"0x94b2f98ce86a9271fbd4153e1fc37de48421fe3490fb3840c00f2d5a4d0ba8810c6a32880b002f6374b59e0a7952518b\",\n    \"0x8650ac644f93bbcb88a6a0f49fee2663297fd4bc6fd47b6a89b9d8038d32370438ab3a4775ec9b58cb10aea8a95ef7b6\",\n    \"0x95e5c2f2e84eed88c6980bbba5a1c0bb375d5a628bff006f7516d45bb7d723da676add4fdd45956f312e7bab0f052644\",\n    \"0xb3278a3fa377ac93af7cfc9453f8cb594aae04269bbc99d2e0e45472ff4b6a2f97a26c4c57bf675b9d86f5e77a5d55d1\",\n    \"0xb4bcbe6eb666a206e2ea2f877912c1d3b5bdbd08a989fc4490eb06013e1a69ad1ba08bcdac048bf29192312be399077b\",\n    \"0xa76d70b78c99fffcbf9bb9886eab40f1ea4f99a309710b660b64cbf86057cbcb644d243f6e341711bb7ef0fedf0435a7\",\n    \"0xb2093c1ee945dca7ac76ad5aed08eae23af31dd5a77c903fd7b6f051f4ab84425d33a03c3d45bf2907bc93c02d1f3ad8\",\n    \"0x904b1f7534e053a265b22d20be859912b9c9ccb303af9a8d6f1d8f6ccdc5c53eb4a45a1762b880d8444d9be0cd55e7f9\",\n    \"0x8f664a965d65bc730c9ef1ec7467be984d4b8eb46bd9b0d64e38e48f94e6e55dda19aeac82cbcf4e1473440e64c4ca18\",\n    \"0x8bcee65c4cc7a7799353d07b114c718a2aae0cd10a3f22b7eead5185d159dafd64852cb63924bf87627d176228878bce\",\n    \"0x8c78f2e3675096fef7ebaa898d2615cd50d39ca3d8f02b9bdfb07e67da648ae4be3da64838dffc5935fd72962c4b96c7\",\n    \"0x8c40afd3701629421fec1df1aac4e849384ef2e80472c0e28d36cb1327acdf2826f99b357f3d7afdbc58a6347fc40b3c\",\n    \"0xa197813b1c65a8ea5754ef782522a57d63433ef752215ecda1e7da76b0412ee619f58d904abd2e07e0c097048b6ae1dd\",\n    \"0xa670542629e4333884ad7410f9ea3bd6f988df4a8f8a424ca74b9add2312586900cf9ae8bd50411f9146e82626b4af56\",\n    \"0xa19875cc07ab84e569d98b8b67fb1dbbdfb59093c7b748fae008c8904a6fd931a63ca8d03ab5fea9bc8d263568125a9b\",\n    \"0xb57e7f68e4eb1bd04aafa917b1db1bdab759a02aa8a9cdb1cba34ba8852b5890f655645c9b4e15d5f19bf37e9f2ffe9f\",\n    \"0x8abe4e2a4f6462b6c64b3f10e45db2a53c2b0d3c5d5443d3f00a453e193df771eda635b098b6c8604ace3557514027af\",\n    \"0x8459e4fb378189b22b870a6ef20183deb816cefbf66eca1dc7e86d36a2e011537db893729f500dc154f14ce24633ba47\",\n    \"0x930851df4bc7913c0d8c0f7bd3b071a83668987ed7c397d3d042fdc0d9765945a39a3bae83da9c88cb6b686ed8aeeb26\",\n    \"0x8078c9e5cd05e1a8c932f8a1d835f61a248b6e7133fcbb3de406bf4ffc0e584f6f9f95062740ba6008d98348886cf76b\",\n    \"0xaddff62bb29430983fe578e3709b0949cdc0d47a13a29bc3f50371a2cb5c822ce53e2448cfaa01bcb6e0aa850d5a380e\",\n    \"0x9433add687b5a1e12066721789b1db2edf9b6558c3bdc0f452ba33b1da67426abe326e9a34d207bfb1c491c18811bde1\",\n    \"0x822beda3389963428cccc4a2918fa9a8a51cf0919640350293af70821967108cded5997adae86b33cb917780b097f1ca\",\n    \"0xa7a9f52bda45e4148ed56dd176df7bd672e9b5ed18888ccdb405f47920fdb0844355f8565cefb17010b38324edd8315f\",\n    \"0xb35c3a872e18e607b2555c51f9696a17fa18da1f924d503b163b4ec9fe22ed0c110925275cb6c93ce2d013e88f173d6a\",\n    \"0xadf34b002b2b26ab84fc1bf94e05bd8616a1d06664799ab149363c56a6e0c807fdc473327d25632416e952ea327fcd95\",\n    \"0xae4a6b9d22a4a3183fac29e2551e1124a8ce4a561a9a2afa9b23032b58d444e6155bb2b48f85c7b6d70393274e230db7\",\n    \"0xa2ea3be4fc17e9b7ce3110284038d46a09e88a247b6971167a7878d9dcf36925d613c382b400cfa4f37a3ebea3699897\",\n    \"0x8e5863786b641ce3140fbfe37124d7ad3925472e924f814ebfc45959aaf3f61dc554a597610b5defaecc85b59a99b50f\",\n    \"0xaefde3193d0f700d0f515ab2aaa43e2ef1d7831c4f7859f48e52693d57f97fa9e520090f3ed700e1c966f4b76048e57f\",\n    \"0x841a50f772956622798e5cd208dc7534d4e39eddee30d8ce133383d66e5f267e389254a0cdae01b770ecd0a9ca421929\",\n    \"0x8fbc2bfd28238c7d47d4c03b1b910946c0d94274a199575e5b23242619b1de3497784e646a92aa03e3e24123ae4fcaba\",\n    \"0x926999579c8eec1cc47d7330112586bdca20b4149c8b2d066f527c8b9f609e61ce27feb69db67eea382649c6905efcf9\",\n    \"0xb09f31f305efcc65589adf5d3690a76cf339efd67cd43a4e3ced7b839507466e4be72dd91f04e89e4bbef629d46e68c0\",\n    \"0xb917361f6b95f759642638e0b1d2b3a29c3bdef0b94faa30de562e6078c7e2d25976159df3edbacbf43614635c2640b4\",\n    \"0x8e7e8a1253bbda0e134d62bfe003a2669d471b47bd2b5cde0ff60d385d8e62279d54022f5ac12053b1e2d3aaa6910b4c\",\n    \"0xb69671a3c64e0a99d90b0ed108ce1912ff8ed983e4bddd75a370e9babde25ee1f5efb59ec707edddd46793207a8b1fe7\",\n    \"0x910b2f4ebd37b7ae94108922b233d0920b4aba0bd94202c70f1314418b548d11d8e9caa91f2cd95aff51b9432d122b7f\",\n    \"0x82f645c90dfb52d195c1020346287c43a80233d3538954548604d09fbab7421241cde8593dbc4acc4986e0ea39a27dd9\",\n    \"0x8fee895f0a140d88104ce442fed3966f58ff9d275e7373483f6b4249d64a25fb5374bbdc6bce6b5ab0270c2847066f83\",\n    \"0x84f5bd7aab27b2509397aeb86510dd5ac0a53f2c8f73799bf720f2f87a52277f8d6b0f77f17bc80739c6a7119b7eb062\",\n    \"0x9903ceced81099d7e146e661bcf01cbaccab5ba54366b85e2177f07e2d8621e19d9c9c3eee14b9266de6b3f9b6ea75ae\",\n    \"0xb9c16ea2a07afa32dd6c7c06df0dec39bca2067a9339e45475c98917f47e2320f6f235da353fd5e15b477de97ddc68dd\",\n    \"0x9820a9bbf8b826bec61ebf886de2c4f404c1ebdc8bab82ee1fea816d9de29127ce1852448ff717a3fe8bbfe9e92012e5\",\n    \"0x817224d9359f5da6f2158c2c7bf9165501424f063e67ba9859a07ab72ee2ee62eb00ca6da821cfa19065c3282ca72c74\",\n    \"0x94b95c465e6cb00da400558a3c60cfec4b79b27e602ca67cbc91aead08de4b6872d8ea096b0dc06dca4525c8992b8547\",\n    \"0xa2b539a5bccd43fa347ba9c15f249b417997c6a38c63517ca38394976baa08e20be384a360969ff54e7e721db536b3e5\",\n    \"0x96caf707e34f62811ee8d32ccf28d8d6ec579bc33e424d0473529af5315c456fd026aa910c1fed70c91982d51df7d3ca\",\n    \"0x8a77b73e890b644c6a142bdbac59b22d6a676f3b63ddafb52d914bb9d395b8bf5aedcbcc90429337df431ebd758a07a6\",\n    \"0x8857830a7351025617a08bc44caec28d2fae07ebf5ffc9f01d979ce2a53839a670e61ae2783e138313929129790a51a1\",\n    \"0xaa3e420321ed6f0aa326d28d1a10f13facec6f605b6218a6eb9cbc074801f3467bf013a456d1415a5536f12599efa3d3\",\n    \"0x824aed0951957b00ea2f3d423e30328a3527bf6714cf9abbae84cf27e58e5c35452ba89ccc011de7c68c75d6e021d8f1\",\n    \"0xa2e87cc06bf202e953fb1081933d8b4445527dde20e38ed1a4f440144fd8fa464a2b73e068b140562e9045e0f4bd3144\",\n    \"0xae3b8f06ad97d7ae3a5e5ca839efff3e4824dc238c0c03fc1a8d2fc8aa546cdfd165b784a31bb4dec7c77e9305b99a4b\",\n    \"0xb30c3e12395b1fb8b776f3ec9f87c70e35763a7b2ddc68f0f60a4982a84017f27c891a98561c830038deb033698ed7fc\",\n    \"0x874e507757cd1177d0dff0b0c62ce90130324442a33da3b2c8ee09dbca5d543e3ecfe707e9f1361e7c7db641c72794bb\",\n    \"0xb53012dd10b5e7460b57c092eaa06d6502720df9edbbe3e3f61a9998a272bf5baaac4a5a732ad4efe35d6fac6feca744\",\n    \"0x85e6509d711515534d394e6cacbed6c81da710074d16ef3f4950bf2f578d662a494d835674f79c4d6315bced4defc5f0\",\n    \"0xb6132b2a34b0905dcadc6119fd215419a7971fe545e52f48b768006944b4a9d7db1a74b149e2951ea48c083b752d0804\",\n    \"0x989867da6415036d19b4bacc926ce6f4df7a556f50a1ba5f3c48eea9cefbb1c09da81481c8009331ee83f0859185e164\",\n    \"0x960a6c36542876174d3fbc1505413e29f053ed87b8d38fef3af180491c7eff25200b45dd5fe5d4d8e63c7e8c9c00f4c8\",\n    \"0x9040b59bd739d9cc2e8f6e894683429e4e876a8106238689ff4c22770ae5fdae1f32d962b30301fa0634ee163b524f35\",\n    \"0xaf3fcd0a45fe9e8fe256dc7eab242ef7f582dd832d147444483c62787ac820fafc6ca55d639a73f76bfa5e7f5462ab8f\",\n    \"0xb934c799d0736953a73d91e761767fdb78454355c4b15c680ce08accb57ccf941b13a1236980001f9e6195801cffd692\",\n    \"0x8871e8e741157c2c326b22cf09551e78da3c1ec0fc0543136f581f1550f8bab03b0a7b80525c1e99812cdbf3a9698f96\",\n    \"0xa8a977f51473a91d178ee8cfa45ffef8d6fd93ab1d6e428f96a3c79816d9c6a93cd70f94d4deda0125fd6816e30f3bea\",\n    \"0xa7688b3b0a4fc1dd16e8ba6dc758d3cfe1b7cf401c31739484c7fa253cce0967df1b290769bcefc9d23d3e0cb19e6218\",\n    \"0x8ae84322662a57c6d729e6ff9d2737698cc2da2daeb1f39e506618750ed23442a6740955f299e4a15dda6db3e534d2c6\",\n    \"0xa04a961cdccfa4b7ef83ced17ab221d6a043b2c718a0d6cc8e6f798507a31f10bf70361f70a049bc8058303fa7f96864\",\n    \"0xb463e39732a7d9daec8a456fb58e54b30a6e160aa522a18b9a9e836488cce3342bcbb2e1deab0f5e6ec0a8796d77197d\",\n    \"0xb1434a11c6750f14018a2d3bcf94390e2948f4f187e93bb22070ca3e5393d339dc328cbfc3e48815f51929465ffe7d81\",\n    \"0x84ff81d73f3828340623d7e3345553610aa22a5432217ef0ebd193cbf4a24234b190c65ca0873c22d10ea7b63bd1fbed\",\n    \"0xb6fe2723f0c47757932c2ddde7a4f8434f665612f7b87b4009c2635d56b6e16b200859a8ade49276de0ef27a2b6c970a\",\n    \"0x9742884ed7cd52b4a4a068a43d3faa02551a424136c85a9313f7cb58ea54c04aa83b0728fd741d1fe39621e931e88f8f\",\n    \"0xb7d2d65ea4d1ad07a5dee39e40d6c03a61264a56b1585b4d76fc5b2a68d80a93a42a0181d432528582bf08d144c2d6a9\",\n    \"0x88c0f66bada89f8a43e5a6ead2915088173d106c76f724f4a97b0f6758aed6ae5c37c373c6b92cdd4aea8f6261f3a374\",\n    \"0x81f9c43582cb42db3900747eb49ec94edb2284999a499d1527f03315fd330e5a509afa3bff659853570e9886aab5b28b\",\n    \"0x821f9d27d6beb416abf9aa5c79afb65a50ed276dbda6060103bc808bcd34426b82da5f23e38e88a55e172f5c294b4d40\",\n    \"0x8ba307b9e7cb63a6c4f3851b321aebfdb6af34a5a4c3bd949ff7d96603e59b27ff4dc4970715d35f7758260ff942c9e9\",\n    \"0xb142eb6c5f846de33227d0bda61d445a7c33c98f0a8365fe6ab4c1fabdc130849be597ef734305894a424ea715372d08\",\n    \"0xa732730ae4512e86a741c8e4c87fee8a05ee840fec0e23b2e037d58dba8dde8d10a9bc5191d34d00598941becbbe467f\",\n    \"0xadce6f7c30fd221f6b10a0413cc76435c4bb36c2d60bca821e5c67409fe9dbb2f4c36ef85eb3d734695e4be4827e9fd3\",\n    \"0xa74f00e0f9b23aff7b2527ce69852f8906dab9d6abe62ecd497498ab21e57542e12af9918d4fd610bb09e10b0929c510\",\n    \"0xa593b6b0ef26448ce4eb3ab07e84238fc020b3cb10d542ff4b16d4e2be1bcde3797e45c9cf753b8dc3b0ffdb63984232\",\n    \"0xaed3913afccf1aa1ac0eb4980eb8426d0baccebd836d44651fd72af00d09fac488a870223c42aca3ceb39752070405ae\",\n    \"0xb2c44c66a5ea7fde626548ba4cef8c8710191343d3dadfd3bb653ce715c0e03056a5303a581d47dde66e70ea5a2d2779\",\n    \"0x8e5029b2ccf5128a12327b5103f7532db599846e422531869560ceaff392236434d87159f597937dbf4054f810c114f4\",\n    \"0x82beed1a2c4477e5eb39fc5b0e773b30cfec77ef2b1bf17eadaf60eb35b6d0dd9d8cf06315c48d3546badb3f21cd0cca\",\n    \"0x90077bd6cc0e4be5fff08e5d07a5a158d36cebd1d1363125bc4fae0866ffe825b26f933d4ee5427ba5cd0c33c19a7b06\",\n    \"0xa7ec0d8f079970e8e34f0ef3a53d3e0e45428ddcef9cc776ead5e542ef06f3c86981644f61c5a637e4faf001fb8c6b3e\",\n    \"0xae6d4add6d1a6f90b22792bc9d40723ee6850c27d0b97eefafd5b7fd98e424aa97868b5287cc41b4fbd7023bca6a322c\",\n    \"0x831aa917533d077da07c01417feaa1408846363ba2b8d22c6116bb858a95801547dd88b7d7fa1d2e3f0a02bdeb2e103d\",\n    \"0x96511b860b07c8a5ed773f36d4aa9d02fb5e7882753bf56303595bcb57e37ccc60288887eb83bef08c657ec261a021a2\",\n    \"0x921d2a3e7e9790f74068623de327443666b634c8443aba80120a45bba450df920b2374d96df1ce3fb1b06dd06f8cf6e3\",\n    \"0xaa74451d51fe82b4581ead8e506ec6cd881010f7e7dd51fc388eb9a557db5d3c6721f81c151d08ebd9c2591689fbc13e\",\n    \"0xa972bfbcf4033d5742d08716c927c442119bdae336bf5dff914523b285ccf31953da2733759aacaa246a9af9f698342c\",\n    \"0xad1fcd0cae0e76840194ce4150cb8a56ebed728ec9272035f52a799d480dfc85840a4d52d994a18b6edb31e79be6e8ad\",\n    \"0xa2c69fe1d36f235215432dad48d75887a44c99dfa0d78149acc74087da215a44bdb5f04e6eef88ff7eff80a5a7decc77\",\n    \"0xa94ab2af2b6ee1bc6e0d4e689ca45380d9fbd3c5a65b9bd249d266a4d4c07bf5d5f7ef2ae6000623aee64027892bf8fe\",\n    \"0x881ec1fc514e926cdc66480ac59e139148ff8a2a7895a49f0dff45910c90cdda97b66441a25f357d6dd2471cddd99bb3\",\n    \"0x884e6d3b894a914c8cef946a76d5a0c8351843b2bffa2d1e56c6b5b99c84104381dd1320c451d551c0b966f4086e60f9\",\n    \"0x817c6c10ce2677b9fc5223500322e2b880583254d0bb0d247d728f8716f5e05c9ff39f135854342a1afecd9fbdcf7c46\",\n    \"0xaaf4a9cb686a14619aa1fc1ac285dd3843ac3dd99f2b2331c711ec87b03491c02f49101046f3c5c538dc9f8dba2a0ac2\",\n    \"0x97ecea5ce53ca720b5d845227ae61d70269a2f53540089305c86af35f0898bfd57356e74a8a5e083fa6e1ea70080bd31\",\n    \"0xa22d811e1a20a75feac0157c418a4bfe745ccb5d29466ffa854dca03e395b6c3504a734341746b2846d76583a780b32e\",\n    \"0x940cbaa0d2b2db94ae96b6b9cf2deefbfd059e3e5745de9aec4a25f0991b9721e5cd37ef71c631575d1a0c280b01cd5b\",\n    \"0xae33cb4951191258a11044682de861bf8d92d90ce751b354932dd9f3913f542b6a0f8a4dc228b3cd9244ac32c4582832\",\n    \"0xa580df5e58c4274fe0f52ac2da1837e32f5c9db92be16c170187db4c358f43e5cfdda7c5911dcc79d77a5764e32325f5\",\n    \"0x81798178cb9d8affa424f8d3be67576ba94d108a28ccc01d330c51d5a63ca45bb8ca63a2f569b5c5fe1303cecd2d777f\",\n    \"0x89975b91b94c25c9c3660e4af4047a8bacf964783010820dbc91ff8281509379cb3b24c25080d5a01174dd9a049118d5\",\n    \"0xa7327fcb3710ed3273b048650bde40a32732ef40a7e58cf7f2f400979c177944c8bc54117ba6c80d5d4260801dddab79\",\n    \"0x92b475dc8cb5be4b90c482f122a51bcb3b6c70593817e7e2459c28ea54a7845c50272af38119406eaadb9bcb993368d0\",\n    \"0x9645173e9ecefc4f2eae8363504f7c0b81d85f8949a9f8a6c01f2d49e0a0764f4eacecf3e94016dd407fc14494fce9f9\",\n    \"0x9215fd8983d7de6ae94d35e6698226fc1454977ae58d42d294be9aad13ac821562ad37d5e7ee5cdfe6e87031d45cd197\",\n    \"0x810360a1c9b88a9e36f520ab5a1eb8bed93f52deefbe1312a69225c0a08edb10f87cc43b794aced9c74220cefcc57e7d\",\n    \"0xad7e810efd61ed4684aeda9ed8bb02fb9ae4b4b63fda8217d37012b94ff1b91c0087043bfa4e376f961fff030c729f3b\",\n    \"0x8b07c95c6a06db8738d10bb03ec11b89375c08e77f0cab7e672ce70b2685667ca19c7e1c8b092821d31108ea18dfd4c7\",\n    \"0x968825d025ded899ff7c57245250535c732836f7565eab1ae23ee7e513201d413c16e1ba3f5166e7ac6cf74de8ceef4f\",\n    \"0x908243370c5788200703ade8164943ad5f8c458219186432e74dbc9904a701ea307fd9b94976c866e6c58595fd891c4b\",\n    \"0x959969d16680bc535cdc6339e6186355d0d6c0d53d7bbfb411641b9bf4b770fd5f575beef5deec5c4fa4d192d455c350\",\n    \"0xad177f4f826a961adeac76da40e2d930748effff731756c797eddc4e5aa23c91f070fb69b19221748130b0961e68a6bb\",\n    \"0x82f8462bcc25448ef7e0739425378e9bb8a05e283ce54aae9dbebaf7a3469f57833c9171672ad43a79778366c72a5e37\",\n    \"0xa28fb275b1845706c2814d9638573e9bc32ff552ebaed761fe96fdbce70395891ca41c400ae438369264e31a2713b15f\",\n    \"0x8a9c613996b5e51dadb587a787253d6081ea446bf5c71096980bf6bd3c4b69905062a8e8a3792de2d2ece3b177a71089\",\n    \"0x8d5aefef9f60cb27c1db2c649221204dda48bb9bf8bf48f965741da051340e8e4cab88b9d15c69f3f84f4c854709f48a\",\n    \"0x93ebf2ca6ad85ab6deace6de1a458706285b31877b1b4d7dcb9d126b63047efaf8c06d580115ec9acee30c8a7212fa55\",\n    \"0xb3ee46ce189956ca298057fa8223b7fd1128cf52f39159a58bca03c71dd25161ac13f1472301f72aef3e1993fe1ab269\",\n    \"0xa24d7a8d066504fc3f5027ccb13120e2f22896860e02c45b5eba1dbd512d6a17c28f39155ea581619f9d33db43a96f92\",\n    \"0xae9ceacbfe12137db2c1a271e1b34b8f92e4816bad1b3b9b6feecc34df0f8b3b0f7ed0133acdf59c537d43d33fc8d429\",\n    \"0x83967e69bf2b361f86361bd705dce0e1ad26df06da6c52b48176fe8dfcbeb03c462c1a4c9e649eff8c654b18c876fdef\",\n    \"0x9148e6b814a7d779c19c31e33a068e97b597de1f8100513db3c581190513edc4d544801ce3dd2cf6b19e0cd6daedd28a\",\n    \"0x94ccdafc84920d320ed22de1e754adea072935d3c5f8c2d1378ebe53d140ea29853f056fb3fb1e375846061a038cc9bc\",\n    \"0xafb43348498c38b0fa5f971b8cdd3a62c844f0eb52bc33daf2f67850af0880fce84ecfb96201b308d9e6168a0d443ae3\",\n    \"0x86d5736520a83538d4cd058cc4b4e84213ed00ebd6e7af79ae787adc17a92ba5359e28ba6c91936d967b4b28d24c3070\",\n    \"0xb5210c1ff212c5b1e9ef9126e08fe120a41e386bb12c22266f7538c6d69c7fd8774f11c02b81fd4e88f9137b020801fe\",\n    \"0xb78cfd19f94d24e529d0f52e18ce6185cb238edc6bd43086270fd51dd99f664f43dd4c7d2fe506762fbd859028e13fcf\",\n    \"0xa6e7220598c554abdcc3fdc587b988617b32c7bb0f82c06205467dbedb58276cc07cae317a190f19d19078773f4c2bbb\",\n    \"0xb88862809487ee430368dccd85a5d72fa4d163ca4aad15c78800e19c1a95be2192719801e315d86cff7795e0544a77e4\",\n    \"0x87ecb13a03921296f8c42ceb252d04716f10e09c93962239fcaa0a7fef93f19ab3f2680bc406170108bc583e9ff2e721\",\n    \"0xa810cd473832b6581c36ec4cb403f2849357ba2d0b54df98ef3004b8a530c078032922a81d40158f5fb0043d56477f6e\",\n    \"0xa247b45dd85ca7fbb718b328f30a03f03c84aef2c583fbdc9fcc9eb8b52b34529e8c8f535505c10598b1b4dac3d7c647\",\n    \"0x96ee0b91313c68bac4aa9e065ce9e1d77e51ca4cff31d6a438718c58264dee87674bd97fc5c6b8008be709521e4fd008\",\n    \"0x837567ad073e42266951a9a54750919280a2ac835a73c158407c3a2b1904cf0d17b7195a393c71a18ad029cbd9cf79ee\",\n    \"0xa6a469c44b67ebf02196213e7a63ad0423aab9a6e54acc6fcbdbb915bc043586993454dc3cd9e4be8f27d67c1050879b\",\n    \"0x8712d380a843b08b7b294f1f06e2f11f4ad6bcc655fdde86a4d8bc739c23916f6fad2b902fe47d6212f03607907e9f0e\",\n    \"0x920adfb644b534789943cdae1bdd6e42828dda1696a440af2f54e6b97f4f97470a1c6ea9fa6a2705d8f04911d055acd1\",\n    \"0xa161c73adf584a0061e963b062f59d90faac65c9b3a936b837a10d817f02fcabfa748824607be45a183dd40f991fe83f\",\n    \"0x874f4ecd408c76e625ea50bc59c53c2d930ee25baf4b4eca2440bfbffb3b8bc294db579caa7c68629f4d9ec24187c1ba\",\n    \"0x8bff18087f112be7f4aa654e85c71fef70eee8ae480f61d0383ff6f5ab1a0508f966183bb3fc4d6f29cb7ca234aa50d3\",\n    \"0xb03b46a3ca3bc743a173cbc008f92ab1aedd7466b35a6d1ca11e894b9482ea9dc75f8d6db2ddd1add99bfbe7657518b7\",\n    \"0x8b4f3691403c3a8ad9e097f02d130769628feddfa8c2b3dfe8cff64e2bed7d6e5d192c1e2ba0ac348b8585e94acd5fa1\",\n    \"0xa0d9ca4a212301f97591bf65d5ef2b2664766b427c9dd342e23cb468426e6a56be66b1cb41fea1889ac5d11a8e3c50a5\",\n    \"0x8c93ed74188ca23b3df29e5396974b9cc135c91fdefdea6c0df694c8116410e93509559af55533a3776ac11b228d69b1\",\n    \"0x82dd331fb3f9e344ebdeeb557769b86a2cc8cc38f6c298d7572a33aea87c261afa9dbd898989139b9fc16bc1e880a099\",\n    \"0xa65faedf326bcfd8ef98a51410c78b021d39206704e8291cd1f09e096a66b9b0486be65ff185ca224c45918ac337ddeb\",\n    \"0xa188b37d363ac072a766fd5d6fa27df07363feff1342217b19e3c37385e42ffde55e4be8355aceaa2f267b6d66b4ac41\",\n    \"0x810fa3ba3e96d843e3bafd3f2995727f223d3567c8ba77d684c993ba1773c66551eb5009897c51b3fe9b37196984f5ec\",\n    \"0x87631537541852da323b4353af45a164f68b304d24c01183bf271782e11687f3fcf528394e1566c2a26cb527b3148e64\",\n    \"0xb721cb2b37b3c477a48e3cc0044167d51ff568a5fd2fb606e5aec7a267000f1ddc07d3db919926ae12761a8e017c767c\",\n    \"0x904dfad4ba2cc1f6e60d1b708438a70b1743b400164cd981f13c064b8328d5973987d4fb9cf894068f29d3deaf624dfb\",\n    \"0xa70491538893552c20939fae6be2f07bfa84d97e2534a6bbcc0f1729246b831103505e9f60e97a8fa7d2e6c1c2384579\",\n    \"0x8726cf1b26b41f443ff7485adcfddc39ace2e62f4d65dd0bb927d933e262b66f1a9b367ded5fbdd6f3b0932553ac1735\",\n    \"0xae8a11cfdf7aa54c08f80cb645e3339187ab3886babe9fae5239ba507bb3dd1c0d161ca474a2df081dcd3d63e8fe445e\",\n    \"0x92328719e97ce60e56110f30a00ac5d9c7a2baaf5f8d22355d53c1c77941e3a1fec7d1405e6fbf8959665fe2ba7a8cad\",\n    \"0x8d9d6255b65798d0018a8cccb0b6343efd41dc14ff2058d3eed9451ceaad681e4a0fa6af67b0a04318aa628024e5553d\",\n    \"0xb70209090055459296006742d946a513f0cba6d83a05249ee8e7a51052b29c0ca9722dc4af5f9816a1b7938a5dac7f79\",\n    \"0xaab7b766b9bf91786dfa801fcef6d575dc6f12b77ecc662eb4498f0312e54d0de9ea820e61508fc8aeee5ab5db529349\",\n    \"0xa8104b462337748b7f086a135d0c3f87f8e51b7165ca6611264b8fb639d9a2f519926cb311fa2055b5fadf03da70c678\",\n    \"0xb0d2460747d5d8b30fc6c6bd0a87cb343ddb05d90a51b465e8f67d499cfc5e3a9e365da05ae233bbee792cdf90ec67d5\",\n    \"0xaa55f5bf3815266b4a149f85ed18e451c93de9163575e3ec75dd610381cc0805bb0a4d7c4af5b1f94d10231255436d2c\",\n    \"0x8d4c6a1944ff94426151909eb5b99cfd92167b967dabe2bf3aa66bb3c26c449c13097de881b2cfc1bf052862c1ef7b03\",\n    \"0x8862296162451b9b6b77f03bf32e6df71325e8d7485cf3335d66fd48b74c2a8334c241db8263033724f26269ad95b395\",\n    \"0x901aa96deb26cda5d9321190ae6624d357a41729d72ef1abfd71bebf6139af6d690798daba53b7bc5923462115ff748a\",\n    \"0x96c195ec4992728a1eb38cdde42d89a7bce150db43adbc9e61e279ea839e538deec71326b618dd39c50d589f78fc0614\",\n    \"0xb6ff8b8aa0837b99a1a8b46fb37f20ad4aecc6a98381b1308697829a59b8442ffc748637a88cb30c9b1f0f28a926c4f6\",\n    \"0x8d807e3dca9e7bef277db1d2cfb372408dd587364e8048b304eff00eacde2c723bfc84be9b98553f83cba5c7b3cba248\",\n    \"0x8800c96adb0195c4fc5b24511450dee503c32bf47044f5e2e25bd6651f514d79a2dd9b01cd8c09f3c9d3859338490f57\",\n    \"0x89fe366096097e38ec28dd1148887112efa5306cc0c3da09562aafa56f4eb000bf46ff79bf0bdd270cbde6bf0e1c8957\",\n    \"0xaf409a90c2776e1e7e3760b2042507b8709e943424606e31e791d42f17873a2710797f5baaab4cc4a19998ef648556b0\",\n    \"0x8d761863c9b6edbd232d35ab853d944f5c950c2b643f84a1a1327ebb947290800710ff01dcfa26dc8e9828481240e8b1\",\n    \"0x90b95e9be1e55c463ed857c4e0617d6dc3674e99b6aa62ed33c8e79d6dfcf7d122f4f4cc2ee3e7c5a49170cb617d2e2e\",\n    \"0xb3ff381efefabc4db38cc4727432e0301949ae4f16f8d1dea9b4f4de611cf5a36d84290a0bef160dac4e1955e516b3b0\",\n    \"0xa8a84564b56a9003adcadb3565dc512239fc79572762cda7b5901a255bc82656bb9c01212ad33d6bef4fbbce18dacc87\",\n    \"0x90a081890364b222eef54bf0075417f85e340d2fec8b7375995f598aeb33f26b44143ebf56fca7d8b4ebb36b5747b0eb\",\n    \"0xade6ee49e1293224ddf2d8ab7f14bb5be6bc6284f60fd5b3a1e0cf147b73cff57cf19763b8a36c5083badc79c606b103\",\n    \"0xb2fa99806dd2fa3de09320b615a2570c416c9bcdb052e592b0aead748bbe407ec9475a3d932ae48b71c2627eb81986a6\",\n    \"0x91f3b7b73c8ccc9392542711c45fe6f236057e6efad587d661ad5cb4d6e88265f86b807bb1151736b1009ab74fd7acb4\",\n    \"0x8800e2a46af96696dfbdcbf2ca2918b3dcf28ad970170d2d1783b52b8d945a9167d052beeb55f56c126da7ffa7059baa\",\n    \"0x9862267a1311c385956b977c9aa08548c28d758d7ba82d43dbc3d0a0fd1b7a221d39e8399997fea9014ac509ff510ac4\",\n    \"0xb7d24f78886fd3e2d283e18d9ad5a25c1a904e7d9b9104bf47da469d74f34162e27e531380dbbe0a9d051e6ffd51d6e7\",\n    \"0xb0f445f9d143e28b9df36b0f2c052da87ee2ca374d9d0fbe2eff66ca6fe5fe0d2c1951b428d58f7314b7e74e45d445ea\",\n    \"0xb63fc4083eabb8437dafeb6a904120691dcb53ce2938b820bb553da0e1eecd476f72495aacb72600cf9cad18698fd3db\",\n    \"0xb9ffd8108eaebd582d665f8690fe8bb207fd85185e6dd9f0b355a09bac1bbff26e0fdb172bc0498df025414e88fe2eda\",\n    \"0x967ed453e1f1a4c5b7b6834cc9f75c13f6889edc0cc91dc445727e9f408487bbf05c337103f61397a10011dfbe25d61d\",\n    \"0x98ceb673aff36e1987d5521a3984a07079c3c6155974bb8b413e8ae1ce84095fe4f7862fba7aefa14753eb26f2a5805f\",\n    \"0x85f01d28603a8fdf6ce6a50cb5c44f8a36b95b91302e3f4cd95c108ce8f4d212e73aec1b8d936520d9226802a2bd9136\",\n    \"0x88118e9703200ca07910345fbb789e7a8f92bd80bbc79f0a9e040e8767d33df39f6eded403a9b636eabf9101e588482a\",\n    \"0x90833a51eef1b10ed74e8f9bbd6197e29c5292e469c854eed10b0da663e2bceb92539710b1858bbb21887bd538d28d89\",\n    \"0xb513b905ec19191167c6193067b5cfdf5a3d3828375360df1c7e2ced5815437dfd37f0c4c8f009d7fb29ff3c8793f560\",\n    \"0xb1b6d405d2d18f9554b8a358cc7e2d78a3b34269737d561992c8de83392ac9a2857be4bf15de5a6c74e0c9d0f31f393c\",\n    \"0xb828bd3e452b797323b798186607849f85d1fb20c616833c0619360dfd6b3e3aa000fd09dafe4b62d74abc41072ff1a9\",\n    \"0x8efde67d0cca56bb2c464731879c9ac46a52e75bac702a63200a5e192b4f81c641f855ca6747752b84fe469cb7113b6c\",\n    \"0xb2762ba1c89ac3c9a983c242e4d1c2610ff0528585ed5c0dfc8a2c0253551142af9b59f43158e8915a1da7cc26b9df67\",\n    \"0x8a3f1157fb820d1497ef6b25cd70b7e16bb8b961b0063ad340d82a79ee76eb2359ca9e15e6d42987ed7f154f5eeaa2da\",\n    \"0xa75e29f29d38f09c879f971c11beb5368affa084313474a5ecafa2896180b9e47ea1995c2733ec46f421e395a1d9cffe\",\n    \"0x8e8c3dd3e7196ef0b4996b531ec79e4a1f211db5d5635e48ceb80ff7568b2ff587e845f97ee703bb23a60945ad64314a\",\n    \"0x8e7f32f4a3e3c584af5e3d406924a0aa34024c42eca74ef6cc2a358fd3c9efaf25f1c03aa1e66bb94b023a2ee2a1cace\",\n    \"0xab7dce05d59c10a84feb524fcb62478906b3fa045135b23afbede3bb32e0c678d8ebe59feabccb5c8f3550ea76cae44b\",\n    \"0xb38bb4b44d827f6fd3bd34e31f9186c59e312dbfadd4a7a88e588da10146a78b1f8716c91ad8b806beb8da65cab80c4c\",\n    \"0x9490ce9442bbbd05438c7f5c4dea789f74a7e92b1886a730544b55ba377840740a3ae4f2f146ee73f47c9278b0e233bc\",\n    \"0x83c003fab22a7178eed1a668e0f65d4fe38ef3900044e9ec63070c23f2827d36a1e73e5c2b883ec6a2afe2450171b3b3\",\n    \"0x9982f02405978ddc4fca9063ebbdb152f524c84e79398955e66fe51bc7c1660ec1afc3a86ec49f58d7b7dde03505731c\",\n    \"0xab337bd83ccdd2322088ffa8d005f450ced6b35790f37ab4534313315ee84312adc25e99cce052863a8bedee991729ed\",\n    \"0x8312ce4bec94366d88f16127a17419ef64285cd5bf9e5eda010319b48085966ed1252ed2f5a9fd3e0259b91bb65f1827\",\n    \"0xa60d5a6327c4041b0c00a1aa2f0af056520f83c9ce9d9ccd03a0bd4d9e6a1511f26a422ea86bd858a1f77438adf07e6c\",\n    \"0xb84a0a0b030bdad83cf5202aa9afe58c9820e52483ab41f835f8c582c129ee3f34aa096d11c1cd922eda02ea1196a882\",\n    \"0x8077d105317f4a8a8f1aadeb05e0722bb55f11abcb490c36c0904401107eb3372875b0ac233144829e734f0c538d8c1d\",\n    \"0x9202503bd29a6ec198823a1e4e098f9cfe359ed51eb5174d1ca41368821bfeebcbd49debfd02952c41359d1c7c06d2b1\",\n    \"0xabc28c155e09365cb77ffead8dc8f602335ef93b2f44e4ef767ce8fc8ef9dd707400f3a722e92776c2e0b40192c06354\",\n    \"0xb0f6d1442533ca45c9399e0a63a11f85ff288d242cea6cb3b68c02e77bd7d158047cae2d25b3bcd9606f8f66d9b32855\",\n    \"0xb01c3d56a0db84dc94575f4b6ee2de4beca3230e86bed63e2066beb22768b0a8efb08ebaf8ac3dedb5fe46708b084807\",\n    \"0x8c8634b0432159f66feaabb165842d1c8ac378f79565b1b90c381aa8450eb4231c3dad11ec9317b9fc2b155c3a771e32\",\n    \"0x8e67f623d69ecd430c9ee0888520b6038f13a2b6140525b056dc0951f0cfed2822e62cf11d952a483107c5c5acac4826\",\n    \"0x9590bb1cba816dd6acd5ac5fba5142c0a19d53573e422c74005e0bcf34993a8138c83124cad35a3df65879dba6134edd\",\n    \"0x801cd96cde0749021a253027118d3ea135f3fcdbe895db08a6c145641f95ebd368dd6a1568d995e1d0084146aebe224a\",\n    \"0x848b5d196427f6fc1f762ee3d36e832b64a76ec1033cfedc8b985dea93932a7892b8ef1035c653fb9dcd9ab2d9a44ac8\",\n    \"0xa1017eb83d5c4e2477e7bd2241b2b98c4951a3b391081cae7d75965cadc1acaec755cf350f1f3d29741b0828e36fedea\",\n    \"0x8d6d2785e30f3c29aad17bd677914a752f831e96d46caf54446d967cb2432be2c849e26f0d193a60bee161ea5c6fe90a\",\n    \"0x935c0ba4290d4595428e034b5c8001cbd400040d89ab00861108e8f8f4af4258e41f34a7e6b93b04bc253d3b9ffc13bf\",\n    \"0xaac02257146246998477921cef2e9892228590d323b839f3e64ea893b991b463bc2f47e1e5092ddb47e70b2f5bce7622\",\n    \"0xb921fde9412970a5d4c9a908ae8ce65861d06c7679af577cf0ad0d5344c421166986bee471fd6a6cecb7d591f06ec985\",\n    \"0x8ef4c37487b139d6756003060600bb6ebac7ea810b9c4364fc978e842f13ac196d1264fbe5af60d76ff6d9203d8e7d3f\",\n    \"0x94b65e14022b5cf6a9b95f94be5ace2711957c96f4211c3f7bb36206bd39cfbd0ea82186cab5ad0577a23214a5c86e9e\",\n    \"0xa31c166d2a2ca1d5a75a5920fef7532681f62191a50d8555fdaa63ba4581c3391cc94a536fc09aac89f64eafceec3f90\",\n    \"0x919a8cc128de01e9e10f5d83b08b52293fdd41bde2b5ae070f3d95842d4a16e5331cf2f3d61c765570c8022403610fa4\",\n    \"0xb23d6f8331eef100152d60483cfa14232a85ee712c8538c9b6417a5a7c5b353c2ac401390c6c215cb101f5cee6b5f43e\",\n    \"0xab357160c08a18319510a571eafff154298ce1020de8e1dc6138a09fcb0fcbcdd8359f7e9386bda00b7b9cdea745ffdc\",\n    \"0xab55079aea34afa5c0bd1124b9cdfe01f325b402fdfa017301bf87812eaa811ea5798c3aaf818074d420d1c782b10ada\",\n    \"0xade616010dc5009e7fc4f8d8b00dc716686a5fa0a7816ad9e503e15839d3b909b69d9dd929b7575376434ffec0d2bea8\",\n    \"0x863997b97ed46898a8a014599508fa3079f414b1f4a0c4fdc6d74ae8b444afa350f327f8bfc2a85d27f9e2d049c50135\",\n    \"0x8d602ff596334efd4925549ed95f2aa762b0629189f0df6dbb162581657cf3ea6863cd2287b4d9c8ad52813d87fcd235\",\n    \"0xb70f68c596dcdeed92ad5c6c348578b26862a51eb5364237b1221e840c47a8702f0fbc56eb520a22c0eed99795d3903e\",\n    \"0x9628088f8e0853cefadee305a8bf47fa990c50fa96a82511bbe6e5dc81ef4b794e7918a109070f92fc8384d77ace226f\",\n    \"0x97e26a46e068b605ce96007197ecd943c9a23881862f4797a12a3e96ba2b8d07806ad9e2a0646796b1889c6b7d75188c\",\n    \"0xb1edf467c068cc163e2d6413cc22b16751e78b3312fe47b7ea82b08a1206d64415b2c8f2a677fa89171e82cc49797150\",\n    \"0xa44d15ef18745b251429703e3cab188420e2d974de07251501799b016617f9630643fcd06f895634d8ecdd579e1bf000\",\n    \"0xabd126df3917ba48c618ee4dbdf87df506193462f792874439043fa1b844466f6f4e0ff2e42516e63b5b23c0892b2695\",\n    \"0xa2a67f57c4aa3c2aa1eeddbfd5009a89c26c2ce8fa3c96a64626aba19514beb125f27df8559506f737de3eae0f1fc18f\",\n    \"0xa633e0132197e6038197304b296ab171f1d8e0d0f34dcf66fe9146ac385b0239232a8470b9205a4802ab432389f4836d\",\n    \"0xa914b3a28509a906c3821463b936455d58ff45dcbe158922f9efb2037f2eb0ce8e92532d29b5d5a3fcd0d23fa773f272\",\n    \"0xa0e1412ce4505daf1a2e59ce4f0fc0e0023e335b50d2b204422f57cd65744cc7a8ed35d5ef131a42c70b27111d3115b7\",\n    \"0xa2339e2f2b6072e88816224fdd612c04d64e7967a492b9f8829db15367f565745325d361fd0607b0def1be384d010d9e\",\n    \"0xa7309fc41203cb99382e8193a1dcf03ac190a7ce04835304eb7e341d78634e83ea47cb15b885601956736d04cdfcaa01\",\n    \"0x81f3ccd6c7f5b39e4e873365f8c37b214e8ab122d04a606fbb7339dc3298c427e922ec7418002561d4106505b5c399ee\",\n    \"0x92c121cf914ca549130e352eb297872a63200e99b148d88fbc9506ad882bec9d0203d65f280fb5b0ba92e336b7f932e8\",\n    \"0xa4b330cf3f064f5b131578626ad7043ce2a433b6f175feb0b52d36134a454ca219373fd30d5e5796410e005b69082e47\",\n    \"0x86fe5774112403ad83f9c55d58317eeb17ad8e1176d9f2f69c2afb7ed83bc718ed4e0245ceab4b377f5f062dcd4c00e7\",\n    \"0x809d152a7e2654c7fd175b57f7928365a521be92e1ed06c05188a95864ddb25f7cab4c71db7d61bbf4cae46f3a1d96ce\",\n    \"0xb82d663e55c2a5ada7e169e9b1a87bc1c0177baf1ec1c96559b4cb1c5214ce1ddf2ab8d345014cab6402f3774235cf5a\",\n    \"0x86580af86df1bd2c385adb8f9a079e925981b7184db66fc5fe5b14cddb82e7d836b06eaeef14924ac529487b23dae111\",\n    \"0xb5f5f4c5c94944ecc804df6ab8687d64e27d988cbfeae1ba7394e0f6adbf778c5881ead7cd8082dd7d68542b9bb4ecd5\",\n    \"0xa6016916146c2685c46e8fdd24186394e2d5496e77e08c0c6a709d4cd7dfa97f1efcef94922b89196819076a91ad37b5\",\n    \"0xb778e7367ded3b6eab53d5fc257f7a87e8faf74a593900f2f517220add2125be3f6142022660d8181df8d164ad9441ce\",\n    \"0x8581b2d36abe6f553add4d24be761bec1b8efaa2929519114346615380b3c55b59e6ad86990e312f7e234d0203bdf59b\",\n    \"0x9917e74fd45c3f71a829ff5498a7f6b5599b48c098dda2339bf04352bfc7f368ccf1a407f5835901240e76452ae807d7\",\n    \"0xafd196ce6f9335069138fd2e3d133134da253978b4ce373152c0f26affe77a336505787594022e610f8feb722f7cc1fb\",\n    \"0xa477491a1562e329764645e8f24d8e228e5ef28c9f74c6b5b3abc4b6a562c15ffb0f680d372aed04d9e1bf944dece7be\",\n    \"0x9767440d58c57d3077319d3a330e5322b9ba16981ec74a5a14d53462eab59ae7fd2b14025bfc63b268862094acb444e6\",\n    \"0x80986d921be3513ef69264423f351a61cb48390c1be8673aee0f089076086aaebea7ebe268fd0aa7182695606116f679\",\n    \"0xa9554c5c921c07b450ee04e34ec58e054ac1541b26ce2ce5a393367a97348ba0089f53db6660ad76b60278b66fd12e3e\",\n    \"0x95097e7d2999b3e84bf052c775581cf361325325f4a50192521d8f4693c830bed667d88f482dc1e3f833aa2bd22d2cbf\",\n    \"0x9014c91d0f85aefd28436b5228c12f6353c055a9326c7efbf5e071e089e2ee7c070fcbc84c5fafc336cbb8fa6fec1ca1\",\n    \"0x90f57ba36ee1066b55d37384942d8b57ae00f3cf9a3c1d6a3dfee1d1af42d4b5fa9baeb0cd7e46687d1d6d090ddb931d\",\n    \"0x8e4b1db12fd760a17214c9e47f1fce6e43c0dbb4589a827a13ac61aaae93759345697bb438a00edab92e0b7b62414683\",\n    \"0x8022a959a513cdc0e9c705e0fc04eafd05ff37c867ae0f31f6d01cddd5df86138a426cab2ff0ac8ff03a62e20f7e8f51\",\n    \"0x914e9a38829834c7360443b8ed86137e6f936389488eccf05b4b4db7c9425611705076ecb3f27105d24b85c852be7511\",\n    \"0x957fb10783e2bd0db1ba66b18e794df710bc3b2b05776be146fa5863c15b1ebdd39747b1a95d9564e1772cdfc4f37b8a\",\n    \"0xb6307028444daed8ed785ac9d0de76bc3fe23ff2cc7e48102553613bbfb5afe0ebe45e4212a27021c8eb870721e62a1f\",\n    \"0x8f76143597777d940b15a01b39c5e1b045464d146d9a30a6abe8b5d3907250e6c7f858ff2308f8591e8b0a7b3f3c568a\",\n    \"0x96163138ac0ce5fd00ae9a289648fd9300a0ca0f63a88481d703ecd281c06a52a3b5178e849e331f9c85ca4ba398f4cc\",\n    \"0xa63ef47c3e18245b0482596a09f488a716df3cbd0f9e5cfabed0d742843e65db8961c556f45f49762f3a6ac8b627b3ef\",\n    \"0x8cb595466552e7c4d42909f232d4063e0a663a8ef6f6c9b7ce3a0542b2459cde04e0e54c7623d404acb5b82775ac04f6\",\n    \"0xb47fe69960eb45f399368807cff16d941a5a4ebad1f5ec46e3dc8a2e4d598a7e6114d8f0ca791e9720fd786070524e2b\",\n    \"0x89eb5ff83eea9df490e5beca1a1fbbbbcf7184a37e2c8c91ede7a1e654c81e8cd41eceece4042ea7918a4f4646b67fd6\",\n    \"0xa84f5d155ed08b9054eecb15f689ba81e44589e6e7207a99790c598962837ca99ec12344105b16641ca91165672f7153\",\n    \"0xa6cc8f25c2d5b2d2f220ec359e6a37a52b95fa6af6e173c65e7cd55299eff4aa9e6d9e6f2769e6459313f1f2aecb0fab\",\n    \"0xafcde944411f017a9f7979755294981e941cc41f03df5e10522ef7c7505e5f1babdd67b3bf5258e8623150062eb41d9b\",\n    \"0x8fab39f39c0f40182fcd996ade2012643fe7731808afbc53f9b26900b4d4d1f0f5312d9d40b3df8baa4739970a49c732\",\n    \"0xae193af9726da0ebe7df1f9ee1c4846a5b2a7621403baf8e66c66b60f523e719c30c6b4f897bb14b27d3ff3da8392eeb\",\n    \"0x8ac5adb82d852eba255764029f42e6da92dcdd0e224d387d1ef94174038db9709ac558d90d7e7c57ad4ce7f89bbfc38c\",\n    \"0xa2066b3458fdf678ee487a55dd5bfb74fde03b54620cb0e25412a89ee28ad0d685e309a51e3e4694be2fa6f1593a344c\",\n    \"0x88d031745dd0ae07d61a15b594be5d4b2e2a29e715d081649ad63605e3404b0c3a5353f0fd9fad9c05c18e93ce674fa1\",\n    \"0x8283cfb0ef743a043f2b77ecaeba3005e2ca50435585b5dd24777ee6bce12332f85e21b446b536da38508807f0f07563\",\n    \"0xb376de22d5f6b0af0b59f7d9764561f4244cf8ffe22890ecd3dcf2ff1832130c9b821e068c9d8773136f4796721e5963\",\n    \"0xae3afc50c764f406353965363840bf28ee85e7064eb9d5f0bb3c31c64ab10f48c853e942ee2c9b51bae59651eaa08c2f\",\n    \"0x948b204d103917461a01a6c57a88f2d66b476eae5b00be20ec8c747650e864bc8a83aee0aff59cb7584b7a3387e0ee48\",\n    \"0x81ab098a082b07f896c5ffd1e4446cb7fb44804cbbf38d125208b233fc82f8ec9a6a8d8dd1c9a1162dc28ffeec0dde50\",\n    \"0xa149c6f1312821ced2969268789a3151bdda213451760b397139a028da609c4134ac083169feb0ee423a0acafd10eceb\",\n    \"0xb0ac9e27a5dadaf523010f730b28f0ebac01f460d3bbbe277dc9d44218abb5686f4fac89ae462682fef9edbba663520a\",\n    \"0x8d0e0073cca273daaaa61b6fc54bfe5a009bc3e20ae820f6c93ba77b19eca517d457e948a2de5e77678e4241807157cb\",\n    \"0xad61d3a2edf7c7533a04964b97499503fd8374ca64286dba80465e68fe932e96749b476f458c6fc57cb1a7ca85764d11\",\n    \"0x90eb5e121ae46bc01a30881eaa556f46bd8457a4e80787cf634aab355082de34ac57d7f497446468225f7721e68e2a47\",\n    \"0x8cdac557de7c42d1f3780e33dec1b81889f6352279be81c65566cdd4952d4c15d79e656cbd46035ab090b385e90245ef\",\n    \"0x82b67e61b88b84f4f4d4f65df37b3e3dcf8ec91ea1b5c008fdccd52da643adbe6468a1cfdb999e87d195afe2883a3b46\",\n    \"0x8503b467e8f5d6048a4a9b78496c58493a462852cab54a70594ae3fd064cfd0deb4b8f336a262155d9fedcaa67d2f6fd\",\n    \"0x8db56c5ac763a57b6ce6832930c57117058e3e5a81532b7d19346346205e2ec614eb1a2ee836ef621de50a7bc9b7f040\",\n    \"0xad344699198f3c6e8c0a3470f92aaffc805b76266734414c298e10b5b3797ca53578de7ccb2f458f5e0448203f55282b\",\n    \"0x80602032c43c9e2a09154cc88b83238343b7a139f566d64cb482d87436b288a98f1ea244fd3bff8da3c398686a900c14\",\n    \"0xa6385bd50ecd548cfb37174cdbb89e10025b5cadaf3cff164c95d7aef5a33e3d6a9bf0c681b9e11db9ef54ebeee2a0c1\",\n    \"0xabf2d95f4aa34b0581eb9257a0cc8462b2213941a5deb8ba014283293e8b36613951b61261cc67bbd09526a54cbbff76\",\n    \"0xa3d5de52f48df72c289ff713e445991f142390798cd42bd9d9dbefaee4af4f5faf09042d126b975cf6b98711c3072553\",\n    \"0x8e627302ff3d686cff8872a1b7c2a57b35f45bf2fc9aa42b049d8b4d6996a662b8e7cbac6597f0cb79b0cc4e29fbf133\",\n    \"0x8510702e101b39a1efbf4e504e6123540c34b5689645e70d0bac1ecc1baf47d86c05cef6c4317a4e99b4edaeb53f2d00\",\n    \"0xaa173f0ecbcc6088f878f8726d317748c81ebf501bba461f163b55d66099b191ec7c55f7702f351a9c8eb42cfa3280e2\",\n    \"0xb560a697eafab695bcef1416648a0a664a71e311ecbe5823ae903bd0ed2057b9d7574b9a86d3fe22aa3e6ddce38ea513\",\n    \"0x8df6304a3d9cf40100f3f687575419c998cd77e5cc27d579cf4f8e98642de3609af384a0337d145dd7c5635172d26a71\",\n    \"0x8105c7f3e4d30a29151849673853b457c1885c186c132d0a98e63096c3774bc9deb956cf957367e633d0913680bda307\",\n    \"0x95373fc22c0917c3c2044ac688c4f29a63ed858a45c0d6d2d0fe97afd6f532dcb648670594290c1c89010ecc69259bef\",\n    \"0x8c2fae9bcadab341f49b55230310df93cac46be42d4caa0d42e45104148a91e527af1b4209c0d972448162aed28fab64\",\n    \"0xb05a77baab70683f76209626eaefdda2d36a0b66c780a20142d23c55bd479ddd4ad95b24579384b6cf62c8eb4c92d021\",\n    \"0x8e6bc6a7ea2755b4aaa19c1c1dee93811fcde514f03485fdc3252f0ab7f032c315614f6336e57cea25dcfb8fb6084eeb\",\n    \"0xb656a27d06aade55eadae2ad2a1059198918ea6cc3fd22c0ed881294d34d5ac7b5e4700cc24350e27d76646263b223aa\",\n    \"0xa296469f24f6f56da92d713afcd4dd606e7da1f79dc4e434593c53695847eefc81c7c446486c4b3b8c8d00c90c166f14\",\n    \"0x87a326f57713ac2c9dffeb3af44b9f3c613a8f952676fc46343299122b47ee0f8d792abaa4b5db6451ced5dd153aabd0\",\n    \"0xb689e554ba9293b9c1f6344a3c8fcb6951d9f9eac4a2e2df13de021aade7c186be27500e81388e5b8bcab4c80f220a31\",\n    \"0x87ae0aa0aa48eac53d1ca5a7b93917de12db9e40ceabf8fdb40884ae771cfdf095411deef7c9f821af0b7070454a2608\",\n    \"0xa71ffa7eae8ace94e6c3581d4cb2ad25d48cbd27edc9ec45baa2c8eb932a4773c3272b2ffaf077b40f76942a1f3af7f2\",\n    \"0x94c218c91a9b73da6b7a495b3728f3028df8ad9133312fc0c03e8c5253b7ccb83ed14688fd4602e2fd41f29a0bc698bd\",\n    \"0xae1e77b90ca33728af07a4c03fb2ef71cd92e2618e7bf8ed4d785ce90097fc4866c29999eb84a6cf1819d75285a03af2\",\n    \"0xb7a5945b277dab9993cf761e838b0ac6eaa903d7111fca79f9fde3d4285af7a89bf6634a71909d095d7619d913972c9c\",\n    \"0x8c43b37be02f39b22029b20aca31bff661abce4471dca88aa3bddefd9c92304a088b2dfc8c4795acc301ca3160656af2\",\n    \"0xb32e5d0fba024554bd5fe8a793ebe8003335ddd7f585876df2048dcf759a01285fecb53daae4950ba57f3a282a4d8495\",\n    \"0x85ea7fd5e10c7b659df5289b2978b2c89e244f269e061b9a15fcab7983fc1962b63546e82d5731c97ec74b6804be63ef\",\n    \"0x96b89f39181141a7e32986ac02d7586088c5a9662cec39843f397f3178714d02f929af70630c12cbaba0268f8ba2d4fa\",\n    \"0x929ab1a2a009b1eb37a2817c89696a06426529ebe3f306c586ab717bd34c35a53eca2d7ddcdef36117872db660024af9\",\n    \"0xa696dccf439e9ca41511e16bf3042d7ec0e2f86c099e4fc8879d778a5ea79e33aa7ce96b23dc4332b7ba26859d8e674d\",\n    \"0xa8fe69a678f9a194b8670a41e941f0460f6e2dbc60470ab4d6ae2679cc9c6ce2c3a39df2303bee486dbfde6844e6b31a\",\n    \"0x95f58f5c82de2f2a927ca99bf63c9fc02e9030c7e46d0bf6b67fe83a448d0ae1c99541b59caf0e1ccab8326231af09a5\",\n    \"0xa57badb2c56ca2c45953bd569caf22968f76ed46b9bac389163d6fe22a715c83d5e94ae8759b0e6e8c2f27bff7748f3f\",\n    \"0x868726fd49963b24acb5333364dffea147e98f33aa19c7919dc9aca0fd26661cfaded74ede7418a5fadbe7f5ae67b67b\",\n    \"0xa8d8550dcc64d9f1dd7bcdab236c4122f2b65ea404bb483256d712c7518f08bb028ff8801f1da6aed6cbfc5c7062e33b\",\n    \"0x97e25a87dae23155809476232178538d4bc05d4ff0882916eb29ae515f2a62bfce73083466cc0010ca956aca200aeacc\",\n    \"0xb4ea26be3f4bd04aa82d7c4b0913b97bcdf5e88b76c57eb1a336cbd0a3eb29de751e1bc47c0e8258adec3f17426d0c71\",\n    \"0x99ee555a4d9b3cf2eb420b2af8e3bc99046880536116d0ce7193464ac40685ef14e0e3c442f604e32f8338cb0ef92558\",\n    \"0x8c64efa1da63cd08f319103c5c7a761221080e74227bbc58b8fb35d08aa42078810d7af3e60446cbaff160c319535648\",\n    \"0x8d9fd88040076c28420e3395cbdfea402e4077a3808a97b7939d49ecbcf1418fe50a0460e1c1b22ac3f6e7771d65169a\",\n    \"0xae3c19882d7a9875d439265a0c7003c8d410367627d21575a864b9cb4918de7dbdb58a364af40c5e045f3df40f95d337\",\n    \"0xb4f7bfacab7b2cafe393f1322d6dcc6f21ffe69cd31edc8db18c06f1a2b512c27bd0618091fd207ba8df1808e9d45914\",\n    \"0x94f134acd0007c623fb7934bcb65ef853313eb283a889a3ffa79a37a5c8f3665f3d5b4876bc66223610c21dc9b919d37\",\n    \"0xaa15f74051171daacdc1f1093d3f8e2d13da2833624b80a934afec86fc02208b8f55d24b7d66076444e7633f46375c6a\",\n    \"0xa32d6bb47ef9c836d9d2371807bafbbbbb1ae719530c19d6013f1d1f813c49a60e4fa51d83693586cba3a840b23c0404\",\n    \"0xb61b3599145ea8680011aa2366dc511a358b7d67672d5b0c5be6db03b0efb8ca5a8294cf220ea7409621f1664e00e631\",\n    \"0x859cafc3ee90b7ececa1ed8ef2b2fc17567126ff10ca712d5ffdd16aa411a5a7d8d32c9cab1fbf63e87dce1c6e2f5f53\",\n    \"0xa2fef1b0b2874387010e9ae425f3a9676d01a095d017493648bcdf3b31304b087ccddb5cf76abc4e1548b88919663b6b\",\n    \"0x939e18c73befc1ba2932a65ede34c70e4b91e74cc2129d57ace43ed2b3af2a9cc22a40fbf50d79a63681b6d98852866d\",\n    \"0xb3b4259d37b1b14aee5b676c9a0dd2d7f679ab95c120cb5f09f9fbf10b0a920cb613655ddb7b9e2ba5af4a221f31303c\",\n    \"0x997255fe51aaca6e5a9cb3359bcbf25b2bb9e30649bbd53a8a7c556df07e441c4e27328b38934f09c09d9500b5fabf66\",\n    \"0xabb91be2a2d860fd662ed4f1c6edeefd4da8dc10e79251cf87f06029906e7f0be9b486462718f0525d5e049472692cb7\",\n    \"0xb2398e593bf340a15f7801e1d1fbda69d93f2a32a889ec7c6ae5e8a37567ac3e5227213c1392ee86cfb3b56ec2787839\",\n    \"0x8ddf10ccdd72922bed36829a36073a460c2118fc7a56ff9c1ac72581c799b15c762cb56cb78e3d118bb9f6a7e56cb25e\",\n    \"0x93e6bc0a4708d16387cacd44cf59363b994dc67d7ada7b6d6dbd831c606d975247541b42b2a309f814c1bfe205681fc6\",\n    \"0xb93fc35c05998cffda2978e12e75812122831523041f10d52f810d34ff71944979054b04de0117e81ddf5b0b4b3e13c0\",\n    \"0x92221631c44d60d68c6bc7b287509f37ee44cbe5fdb6935cee36b58b17c7325098f98f7910d2c3ca5dc885ad1d6dabc7\",\n    \"0xa230124424a57fad3b1671f404a94d7c05f4c67b7a8fbacfccea28887b78d7c1ed40b92a58348e4d61328891cd2f6cee\",\n    \"0xa6a230edb8518a0f49d7231bc3e0bceb5c2ac427f045819f8584ba6f3ae3d63ed107a9a62aad543d7e1fcf1f20605706\",\n    \"0x845be1fe94223c7f1f97d74c49d682472585d8f772762baad8a9d341d9c3015534cc83d102113c51a9dea2ab10d8d27b\",\n    \"0xb44262515e34f2db597c8128c7614d33858740310a49cdbdf9c8677c5343884b42c1292759f55b8b4abc4c86e4728033\",\n    \"0x805592e4a3cd07c1844bc23783408310accfdb769cca882ad4d07d608e590a288b7370c2cb327f5336e72b7083a0e30f\",\n    \"0x95153e8b1140df34ee864f4ca601cb873cdd3efa634af0c4093fbaede36f51b55571ab271e6a133020cd34db8411241f\",\n    \"0x82878c1285cfa5ea1d32175c9401f3cc99f6bb224d622d3fd98cc7b0a27372f13f7ab463ce3a33ec96f9be38dbe2dfe3\",\n    \"0xb7588748f55783077c27fc47d33e20c5c0f5a53fc0ac10194c003aa09b9f055d08ec971effa4b7f760553997a56967b3\",\n    \"0xb36b4de6d1883b6951f59cfae381581f9c6352fcfcf1524fccdab1571a20f80441d9152dc6b48bcbbf00371337ca0bd5\",\n    \"0x89c5523f2574e1c340a955cbed9c2f7b5fbceb260cb1133160dabb7d41c2f613ec3f6e74bbfab3c4a0a6f0626dbe068f\",\n    \"0xa52f58cc39f968a9813b1a8ddc4e83f4219e4dd82c7aa1dd083bea7edf967151d635aa9597457f879771759b876774e4\",\n    \"0x8300a67c2e2e123f89704abfde095463045dbd97e20d4c1157bab35e9e1d3d18f1f4aaba9cbe6aa2d544e92578eaa1b6\",\n    \"0xac6a7f2918768eb6a43df9d3a8a04f8f72ee52f2e91c064c1c7d75cad1a3e83e5aba9fe55bb94f818099ac91ccf2e961\",\n    \"0x8d64a2b0991cf164e29835c8ddef6069993a71ec2a7de8157bbfa2e00f6367be646ed74cbaf524f0e9fe13fb09fa15fd\",\n    \"0x8b2ffe5a545f9f680b49d0a9797a4a11700a2e2e348c34a7a985fc278f0f12def6e06710f40f9d48e4b7fbb71e072229\",\n    \"0x8ab8f71cd337fa19178924e961958653abf7a598e3f022138b55c228440a2bac4176cea3aea393549c03cd38a13eb3fc\",\n    \"0x8419d28318c19ea4a179b7abb43669fe96347426ef3ac06b158d79c0acf777a09e8e770c2fb10e14b3a0421705990b23\",\n    \"0x8bacdac310e1e49660359d0a7a17fe3d334eb820e61ae25e84cb52f863a2f74cbe89c2e9fc3283745d93a99b79132354\",\n    \"0xb57ace3fa2b9f6b2db60c0d861ace7d7e657c5d35d992588aeed588c6ce3a80b6f0d49f8a26607f0b17167ab21b675e4\",\n    \"0x83e265cde477f2ecc164f49ddc7fb255bb05ff6adc347408353b7336dc3a14fdedc86d5a7fb23f36b8423248a7a67ed1\",\n    \"0xa60ada971f9f2d79d436de5d3d045f5ab05308cae3098acaf5521115134b2a40d664828bb89895840db7f7fb499edbc5\",\n    \"0xa63eea12efd89b62d3952bf0542a73890b104dd1d7ff360d4755ebfa148fd62de668edac9eeb20507967ea37fb220202\",\n    \"0xa0275767a270289adc991cc4571eff205b58ad6d3e93778ddbf95b75146d82517e8921bd0d0564e5b75fa0ccdab8e624\",\n    \"0xb9b03fd3bf07201ba3a039176a965d736b4ef7912dd9e9bf69fe1b57c330a6aa170e5521fe8be62505f3af81b41d7806\",\n    \"0xa95f640e26fb1106ced1729d6053e41a16e4896acac54992279ff873e5a969aad1dcfa10311e28b8f409ac1dab7f03bb\",\n    \"0xb144778921742418053cb3c70516c63162c187f00db2062193bb2c14031075dbe055d020cde761b26e8c58d0ea6df2c1\",\n    \"0x8432fbb799e0435ef428d4fefc309a05dd589bce74d7a87faf659823e8c9ed51d3e42603d878e80f439a38be4321c2fa\",\n    \"0xb08ddef14e42d4fd5d8bf39feb7485848f0060d43b51ed5bdda39c05fe154fb111d29719ee61a23c392141358c0cfcff\",\n    \"0x8ae3c5329a5e025b86b5370e06f5e61177df4bda075856fade20a17bfef79c92f54ed495f310130021ba94fb7c33632b\",\n    \"0x92b6d3c9444100b4d7391febfc1dddaa224651677c3695c47a289a40d7a96d200b83b64e6d9df51f534564f272a2c6c6\",\n    \"0xb432bc2a3f93d28b5e506d68527f1efeb2e2570f6be0794576e2a6ef9138926fdad8dd2eabfa979b79ab7266370e86bc\",\n    \"0x8bc315eacedbcfc462ece66a29662ca3dcd451f83de5c7626ef8712c196208fb3d8a0faf80b2e80384f0dd9772f61a23\",\n    \"0xa72375b797283f0f4266dec188678e2b2c060dfed5880fc6bb0c996b06e91a5343ea2b695adaab0a6fd183b040b46b56\",\n    \"0xa43445036fbaa414621918d6a897d3692fdae7b2961d87e2a03741360e45ebb19fcb1703d23f1e15bb1e2babcafc56ac\",\n    \"0xb9636b2ffe305e63a1a84bd44fb402442b1799bd5272638287aa87ca548649b23ce8ce7f67be077caed6aa2dbc454b78\",\n    \"0x99a30bf0921d854c282b83d438a79f615424f28c2f99d26a05201c93d10378ab2cd94a792b571ddae5d4e0c0013f4006\",\n    \"0x8648e3c2f93d70b392443be116b48a863e4b75991bab5db656a4ef3c1e7f645e8d536771dfe4e8d1ceda3be8d32978b0\",\n    \"0xab50dc9e6924c1d2e9d2e335b2d679fc7d1a7632e84964d3bac0c9fe57e85aa5906ec2e7b0399d98ddd022e9b19b5904\",\n    \"0xab729328d98d295f8f3272afaf5d8345ff54d58ff9884da14f17ecbdb7371857fdf2f3ef58080054e9874cc919b46224\",\n    \"0x83fa5da7592bd451cad3ad7702b4006332b3aae23beab4c4cb887fa6348317d234bf62a359e665b28818e5410c278a09\",\n    \"0x8bdbff566ae9d368f114858ef1f009439b3e9f4649f73efa946e678d6c781d52c69af195df0a68170f5f191b2eac286b\",\n    \"0x91245e59b4425fd4edb2a61d0d47c1ccc83d3ced8180de34887b9655b5dcda033d48cde0bdc3b7de846d246c053a02e8\",\n    \"0xa2cb00721e68f1cad8933947456f07144dc69653f96ceed845bd577d599521ba99cdc02421118971d56d7603ed118cbf\",\n    \"0xaf8cd66d303e808b22ec57860dd909ca64c27ec2c60e26ffecfdc1179d8762ffd2739d87b43959496e9fee4108df71df\",\n    \"0x9954136812dffcd5d3f167a500e7ab339c15cfc9b3398d83f64b0daa3dd5b9a851204f424a3493b4e326d3de81e50a62\",\n    \"0x93252254d12511955f1aa464883ad0da793f84d900fea83e1df8bca0f2f4cf5b5f9acbaec06a24160d33f908ab5fea38\",\n    \"0x997cb55c26996586ba436a95566bd535e9c22452ca5d2a0ded2bd175376557fa895f9f4def4519241ff386a063f2e526\",\n    \"0xa12c78ad451e0ac911260ade2927a768b50cb4125343025d43474e7f465cdc446e9f52a84609c5e7e87ae6c9b3f56cda\",\n    \"0xa789d4ca55cbba327086563831b34487d63d0980ba8cf55197c016702ed6da9b102b1f0709ce3da3c53ff925793a3d73\",\n    \"0xa5d76acbb76741ce85be0e655b99baa04f7f587347947c0a30d27f8a49ae78cce06e1cde770a8b618d3db402be1c0c4b\",\n    \"0x873c0366668c8faddb0eb7c86f485718d65f8c4734020f1a18efd5fa123d3ea8a990977fe13592cd01d17e60809cb5ff\",\n    \"0xb659b71fe70f37573ff7c5970cc095a1dc0da3973979778f80a71a347ef25ad5746b2b9608bad4ab9a4a53a4d7df42d7\",\n    \"0xa34cbe05888e5e5f024a2db14cb6dcdc401a9cbd13d73d3c37b348f68688f87c24ca790030b8f84fef9e74b4eab5e412\",\n    \"0x94ce8010f85875c045b0f014db93ef5ab9f1f6842e9a5743dce9e4cb872c94affd9e77c1f1d1ab8b8660b52345d9acb9\",\n    \"0xadefa9b27a62edc0c5b019ddd3ebf45e4de846165256cf6329331def2e088c5232456d3de470fdce3fa758bfdd387512\",\n    \"0xa6b83821ba7c1f83cc9e4529cf4903adb93b26108e3d1f20a753070db072ad5a3689643144bdd9c5ea06bb9a7a515cd0\",\n    \"0xa3a9ddedc2a1b183eb1d52de26718151744db6050f86f3580790c51d09226bf05f15111691926151ecdbef683baa992c\",\n    \"0xa64bac89e7686932cdc5670d07f0b50830e69bfb8c93791c87c7ffa4913f8da881a9d8a8ce8c1a9ce5b6079358c54136\",\n    \"0xa77b5a63452cb1320b61ab6c7c2ef9cfbcade5fd4727583751fb2bf3ea330b5ca67757ec1f517bf4d503ec924fe32fbd\",\n    \"0x8746fd8d8eb99639d8cd0ca34c0d9c3230ed5a312aab1d3d925953a17973ee5aeb66e68667e93caf9cb817c868ea8f3d\",\n    \"0x88a2462a26558fc1fbd6e31aa8abdc706190a17c27fdc4217ffd2297d1b1f3321016e5c4b2384c5454d5717dc732ed03\",\n    \"0xb78893a97e93d730c8201af2e0d3b31cb923d38dc594ffa98a714e627c473d42ea82e0c4d2eeb06862ee22a9b2c54588\",\n    \"0x920cc8b5f1297cf215a43f6fc843e379146b4229411c44c0231f6749793d40f07b9af7699fd5d21fd69400b97febe027\",\n    \"0xa0f0eafce1e098a6b58c7ad8945e297cd93aaf10bc55e32e2e32503f02e59fc1d5776936577d77c0b1162cb93b88518b\",\n    \"0x98480ba0064e97a2e7a6c4769b4d8c2a322cfc9a3b2ca2e67e9317e2ce04c6e1108169a20bd97692e1cb1f1423b14908\",\n    \"0x83dbbb2fda7e287288011764a00b8357753a6a44794cc8245a2275237f11affdc38977214e463ad67aec032f3dfa37e9\",\n    \"0x86442fff37598ce2b12015ff19b01bb8a780b40ad353d143a0f30a06f6d23afd5c2b0a1253716c855dbf445cc5dd6865\",\n    \"0xb8a4c60c5171189414887847b9ed9501bff4e4c107240f063e2d254820d2906b69ef70406c585918c4d24f1dd052142b\",\n    \"0x919f33a98e84015b2034b57b5ffe9340220926b2c6e45f86fd79ec879dbe06a148ae68b77b73bf7d01bd638a81165617\",\n    \"0x95c13e78d89474a47fbc0664f6f806744b75dede95a479bbf844db4a7f4c3ae410ec721cb6ffcd9fa9c323da5740d5ae\",\n    \"0xab7151acc41fffd8ec6e90387700bcd7e1cde291ea669567295bea1b9dd3f1df2e0f31f3588cd1a1c08af8120aca4921\",\n    \"0x80e74c5c47414bd6eeef24b6793fb1fa2d8fb397467045fcff887c52476741d5bc4ff8b6d3387cb53ad285485630537f\",\n    \"0xa296ad23995268276aa351a7764d36df3a5a3cffd7dbeddbcea6b1f77adc112629fdeffa0918b3242b3ccd5e7587e946\",\n    \"0x813d2506a28a2b01cb60f49d6bd5e63c9b056aa56946faf2f33bd4f28a8d947569cfead3ae53166fc65285740b210f86\",\n    \"0x924b265385e1646287d8c09f6c855b094daaee74b9e64a0dddcf9ad88c6979f8280ba30c8597b911ef58ddb6c67e9fe3\",\n    \"0x8d531513c70c2d3566039f7ca47cd2352fd2d55b25675a65250bdb8b06c3843db7b2d29c626eed6391c238fc651cf350\",\n    \"0x82b338181b62fdc81ceb558a6843df767b6a6e3ceedc5485664b4ea2f555904b1a45fbb35f6cf5d96f27da10df82a325\",\n    \"0x92e62faaedea83a37f314e1d3cb4faaa200178371d917938e59ac35090be1db4b4f4e0edb78b9c991de202efe4f313d8\",\n    \"0x99d645e1b642c2dc065bac9aaa0621bc648c9a8351efb6891559c3a41ba737bd155fb32d7731950514e3ecf4d75980e4\",\n    \"0xb34a13968b9e414172fb5d5ece9a39cf2eb656128c3f2f6cc7a9f0c69c6bae34f555ecc8f8837dc34b5e470e29055c78\",\n    \"0xa2a0bb7f3a0b23a2cbc6585d59f87cd7e56b2bbcb0ae48f828685edd9f7af0f5edb4c8e9718a0aaf6ef04553ba71f3b7\",\n    \"0x8e1a94bec053ed378e524b6685152d2b52d428266f2b6eadd4bcb7c4e162ed21ab3e1364879673442ee2162635b7a4d8\",\n    \"0x9944adaff14a85eab81c73f38f386701713b52513c4d4b838d58d4ffa1d17260a6d056b02334850ea9a31677c4b078bd\",\n    \"0xa450067c7eceb0854b3eca3db6cf38669d72cb7143c3a68787833cbca44f02c0be9bfbe082896f8a57debb13deb2afb1\",\n    \"0x8be4ad3ac9ef02f7df09254d569939757101ee2eda8586fefcd8c847adc1efe5bdcb963a0cafa17651befaafb376a531\",\n    \"0x90f6de91ea50255f148ac435e08cf2ac00c772a466e38155bd7e8acf9197af55662c7b5227f88589b71abe9dcf7ba343\",\n    \"0x86e5a24f0748b106dee2d4d54e14a3b0af45a96cbee69cac811a4196403ebbee17fd24946d7e7e1b962ac7f66dbaf610\",\n    \"0xafdd96fbcda7aa73bf9eeb2292e036c25753d249caee3b9c013009cc22e10d3ec29e2aa6ddbb21c4e949b0c0bccaa7f4\",\n    \"0xb5a4e7436d5473647c002120a2cb436b9b28e27ad4ebdd7c5f122b91597c507d256d0cbd889d65b3a908531936e53053\",\n    \"0xb632414c3da704d80ac2f3e5e0e9f18a3637cdc2ebeb613c29300745582427138819c4e7b0bec3099c1b8739dac1807b\",\n    \"0xa28df1464d3372ce9f37ef1db33cc010f752156afae6f76949d98cd799c0cf225c20228ae86a4da592d65f0cffe3951b\",\n    \"0x898b93d0a31f7d3f11f253cb7a102db54b669fd150da302d8354d8e02b1739a47cb9bd88015f3baf12b00b879442464e\",\n    \"0x96fb88d89a12049091070cb0048a381902965e67a8493e3991eaabe5d3b7ff7eecd5c94493a93b174df3d9b2c9511755\",\n    \"0xb899cb2176f59a5cfba3e3d346813da7a82b03417cad6342f19cc8f12f28985b03bf031e856a4743fd7ebe16324805b0\",\n    \"0xa60e2d31bc48e0c0579db15516718a03b73f5138f15037491f4dae336c904e312eda82d50862f4debd1622bb0e56d866\",\n    \"0x979fc8b987b5cef7d4f4b58b53a2c278bd25a5c0ea6f41c715142ea5ff224c707de38451b0ad3aa5e749aa219256650a\",\n    \"0xb2a75bff18e1a6b9cf2a4079572e41205741979f57e7631654a3c0fcec57c876c6df44733c9da3d863db8dff392b44a3\",\n    \"0xb7a0f0e811222c91e3df98ff7f286b750bc3b20d2083966d713a84a2281744199e664879401e77470d44e5a90f3e5181\",\n    \"0x82b74ba21c9d147fbc338730e8f1f8a6e7fc847c3110944eb17a48bea5e06eecded84595d485506d15a3e675fd0e5e62\",\n    \"0xa7f44eef817d5556f0d1abcf420301217d23c69dd2988f44d91ea1f1a16c322263cbacd0f190b9ba22b0f141b9267b4f\",\n    \"0xaadb68164ede84fc1cb3334b3194d84ba868d5a88e4c9a27519eef4923bc4abf81aab8114449496c073c2a6a0eb24114\",\n    \"0xb5378605fabe9a8c12a5dc55ef2b1de7f51aedb61960735c08767a565793cea1922a603a6983dc25f7cea738d0f7c40d\",\n    \"0xa97a4a5cd8d51302e5e670aee78fe6b5723f6cc892902bbb4f131e82ca1dfd5de820731e7e3367fb0c4c1922a02196e3\",\n    \"0x8bdfeb15c29244d4a28896f2b2cb211243cd6a1984a3f5e3b0ebe5341c419beeab3304b390a009ffb47588018034b0ea\",\n    \"0xa9af3022727f2aa2fca3b096968e97edad3f08edcbd0dbca107b892ae8f746a9c0485e0d6eb5f267999b23a845923ed0\",\n    \"0x8e7594034feef412f055590fbb15b6322dc4c6ab7a4baef4685bd13d71a83f7d682b5781bdfa0d1c659489ce9c2b8000\",\n    \"0x84977ca6c865ebee021c58106c1a4ad0c745949ecc5332948002fd09bd9b890524878d0c29da96fd11207621136421fe\",\n    \"0x8687551a79158e56b2375a271136756313122132a6670fa51f99a1b5c229ed8eea1655a734abae13228b3ebfd2a825dd\",\n    \"0xa0227d6708979d99edfc10f7d9d3719fd3fc68b0d815a7185b60307e4c9146ad2f9be2b8b4f242e320d4288ceeb9504c\",\n    \"0x89f75583a16735f9dd8b7782a130437805b34280ccea8dac6ecaee4b83fe96947e7b53598b06fecfffdf57ffc12cc445\",\n    \"0xa0056c3353227f6dd9cfc8e3399aa5a8f1d71edf25d3d64c982910f50786b1e395c508d3e3727ac360e3e040c64b5298\",\n    \"0xb070e61a6d813626144b312ded1788a6d0c7cec650a762b2f8df6e4743941dd82a2511cd956a3f141fc81e15f4e092da\",\n    \"0xb4e6db232e028a1f989bb5fc13416711f42d389f63564d60851f009dcffac01acfd54efa307aa6d4c0f932892d4e62b0\",\n    \"0x89b5991a67db90024ddd844e5e1a03ef9b943ad54194ae0a97df775dde1addf31561874f4e40fbc37a896630f3bbda58\",\n    \"0xad0e8442cb8c77d891df49cdb9efcf2b0d15ac93ec9be1ad5c3b3cca1f4647b675e79c075335c1f681d56f14dc250d76\",\n    \"0xb5d55a6ae65bb34dd8306806cb49b5ccb1c83a282ee47085cf26c4e648e19a52d9c422f65c1cd7e03ca63e926c5e92ea\",\n    \"0xb749501347e5ec07e13a79f0cb112f1b6534393458b3678a77f02ca89dca973fa7b30e55f0b25d8b92b97f6cb0120056\",\n    \"0x94144b4a3ffc5eec6ba35ce9c245c148b39372d19a928e236a60e27d7bc227d18a8cac9983851071935d8ffb64b3a34f\",\n    \"0x92bb4f9f85bc8c028a3391306603151c6896673135f8a7aefedd27acb322c04ef5dac982fc47b455d6740023e0dd3ea3\",\n    \"0xb9633a4a101461a782fc2aa092e9dbe4e2ad00987578f18cd7cf0021a909951d60fe79654eb7897806795f93c8ff4d1c\",\n    \"0x809f0196753024821b48a016eca5dbb449a7c55750f25981bb7a4b4c0e0846c09b8f6128137905055fc43a3f0deb4a74\",\n    \"0xa27dc9cdd1e78737a443570194a03d89285576d3d7f3a3cf15cc55b3013e42635d4723e2e8fe1d0b274428604b630db9\",\n    \"0x861f60f0462e04cd84924c36a28163def63e777318d00884ab8cb64c8df1df0bce5900342163edb60449296484a6c5bf\",\n    \"0xb7bc23fb4e14af4c4704a944253e760adefeca8caee0882b6bbd572c84434042236f39ae07a8f21a560f486b15d82819\",\n    \"0xb9a6eb492d6dd448654214bd01d6dc5ff12067a11537ab82023fc16167507ee25eed2c91693912f4155d1c07ed9650b3\",\n    \"0x97678af29c68f9a5e213bf0fb85c265303714482cfc4c2c00b4a1e8a76ed08834ee6af52357b143a1ca590fb0265ea5a\",\n    \"0x8a15b499e9eca5b6cac3070b5409e8296778222018ad8b53a5d1f6b70ad9bb10c68a015d105c941ed657bf3499299e33\",\n    \"0xb487fefede2e8091f2c7bfe85770db2edff1db83d4effe7f7d87bff5ab1ace35e9b823a71adfec6737fede8d67b3c467\",\n    \"0x8b51b916402aa2c437fce3bcad6dad3be8301a1a7eab9d163085b322ffb6c62abf28637636fe6114573950117fc92898\",\n    \"0xb06a2106d031a45a494adec0881cb2f82275dff9dcdd2bc16807e76f3bec28a6734edd3d54f0be8199799a78cd6228ad\",\n    \"0xaf0a185391bbe2315eb97feac98ad6dd2e5d931d012c621abd6e404a31cc188b286fef14871762190acf086482b2b5e2\",\n    \"0x8e78ee8206506dd06eb7729e32fceda3bebd8924a64e4d8621c72e36758fda3d0001af42443851d6c0aea58562870b43\",\n    \"0xa1ba52a569f0461aaf90b49b92be976c0e73ec4a2c884752ee52ffb62dd137770c985123d405dfb5de70692db454b54a\",\n    \"0x8d51b692fa1543c51f6b62b9acb8625ed94b746ef96c944ca02859a4133a5629da2e2ce84e111a7af8d9a5b836401c64\",\n    \"0xa7a20d45044cf6492e0531d0b8b26ffbae6232fa05a96ed7f06bdb64c2b0f5ca7ec59d5477038096a02579e633c7a3ff\",\n    \"0x84df867b98c53c1fcd4620fef133ee18849c78d3809d6aca0fb6f50ff993a053a455993f216c42ab6090fa5356b8d564\",\n    \"0xa7227c439f14c48e2577d5713c97a5205feb69acb0b449152842e278fa71e8046adfab468089c8b2288af1fc51fa945b\",\n    \"0x855189b3a105670779997690876dfaa512b4a25a24931a912c2f0f1936971d2882fb4d9f0b3d9daba77eaf660e9d05d5\",\n    \"0xb5696bd6706de51c502f40385f87f43040a5abf99df705d6aac74d88c913b8ecf7a99a63d7a37d9bdf3a941b9e432ff5\",\n    \"0xab997beb0d6df9c98d5b49864ef0b41a2a2f407e1687dfd6089959757ba30ed02228940b0e841afe6911990c74d536c4\",\n    \"0xb36b65f85546ebfdbe98823d5555144f96b4ab39279facd19c0de3b8919f105ba0315a0784dce4344b1bc62d8bb4a5a3\",\n    \"0xb8371f0e4450788720ac5e0f6cd3ecc5413d33895083b2c168d961ec2b5c3de411a4cc0712481cbe8df8c2fa1a7af006\",\n    \"0x98325d8026b810a8b7a114171ae59a57e8bbc9848e7c3df992efc523621729fd8c9f52114ce01d7730541a1ada6f1df1\",\n    \"0x8d0e76dbd37806259486cd9a31bc8b2306c2b95452dc395546a1042d1d17863ef7a74c636b782e214d3aa0e8d717f94a\",\n    \"0xa4e15ead76da0214d702c859fb4a8accdcdad75ed08b865842bd203391ec4cba2dcc916455e685f662923b96ee0c023f\",\n    \"0x8618190972086ebb0c4c1b4a6c94421a13f378bc961cc8267a301de7390c5e73c3333864b3b7696d81148f9d4843fd02\",\n    \"0x85369d6cc7342e1aa15b59141517d8db8baaaeb7ab9670f3ba3905353948d575923d283b7e5a05b13a30e7baf1208a86\",\n    \"0x87c51ef42233c24a6da901f28c9a075d9ba3c625687c387ad6757b72ca6b5a8885e6902a3082da7281611728b1e45f26\",\n    \"0xaa6348a4f71927a3106ad0ea8b02fc8d8c65531e4ab0bd0a17243e66f35afe252e40ab8eef9f13ae55a72566ffdaff5c\",\n    \"0x96a3bc976e9d03765cc3fee275fa05b4a84c94fed6b767e23ca689394501e96f56f7a97cffddc579a6abff632bf153be\",\n    \"0x97dbf96c6176379fdb2b888be4e757b2bca54e74124bd068d3fa1dbd82a011bbeb75079da38e0cd22a761fe208ecad9b\",\n    \"0xb70cf0a1d14089a4129ec4e295313863a59da8c7e26bf74cc0e704ed7f0ee4d7760090d0ddf7728180f1bf2c5ac64955\",\n    \"0x882d664714cc0ffe53cbc9bef21f23f3649824f423c4dbad1f893d22c4687ab29583688699efc4d5101aa08b0c3e267a\",\n    \"0x80ecb7cc963e677ccaddbe3320831dd6ee41209acf4ed41b16dc4817121a3d86a1aac9c4db3d8c08a55d28257088af32\",\n    \"0xa25ba667d832b145f9ce18c3f9b1bd00737aa36db020e1b99752c8ef7d27c6c448982bd8d352e1b6df266b8d8358a8d5\",\n    \"0x83734841c13dee12759d40bdd209b277e743b0d08cc0dd1e0b7afd2d65bfa640400eefcf6be4a52e463e5b3d885eeac6\",\n    \"0x848d16505b04804afc773aebabb51b36fd8aacfbb0e09b36c0d5d57df3c0a3b92f33e7d5ad0a7006ec46ebb91df42b8c\",\n    \"0x909a8d793f599e33bb9f1dc4792a507a97169c87cd5c087310bc05f30afcd247470b4b56dec59894c0fb1d48d39bb54e\",\n    \"0x8e558a8559df84a1ba8b244ece667f858095c50bb33a5381e60fcc6ba586b69693566d8819b4246a27287f16846c1dfa\",\n    \"0x84d6b69729f5aaa000cd710c2352087592cfbdf20d5e1166977e195818e593fa1a50d1e04566be23163a2523dc1612f1\",\n    \"0x9536d262b7a42125d89f4f32b407d737ba8d9242acfc99d965913ab3e043dcac9f7072a43708553562cac4cba841df30\",\n    \"0x9598548923ca119d6a15fd10861596601dd1dedbcccca97bb208cdc1153cf82991ea8cc17686fbaa867921065265970c\",\n    \"0xb87f2d4af6d026e4d2836bc3d390a4a18e98a6e386282ce96744603bab74974272e97ac2da281afa21885e2cbb3a8001\",\n    \"0x991ece62bf07d1a348dd22191868372904b9f8cf065ae7aa4e44fd24a53faf6d851842e35fb472895963aa1992894918\",\n    \"0xa8c53dea4c665b30e51d22ca6bc1bc78aaf172b0a48e64a1d4b93439b053877ec26cb5221c55efd64fa841bbf7d5aff4\",\n    \"0x93487ec939ed8e740f15335b58617c3f917f72d07b7a369befd479ae2554d04deb240d4a14394b26192efae4d2f4f35d\",\n    \"0xa44793ab4035443f8f2968a40e043b4555960193ffa3358d22112093aadfe2c136587e4139ffd46d91ed4107f61ea5e0\",\n    \"0xb13fe033da5f0d227c75927d3dacb06dbaf3e1322f9d5c7c009de75cdcba5e308232838785ab69a70f0bedea755e003f\",\n    \"0x970a29b075faccd0700fe60d1f726bdebf82d2cc8252f4a84543ebd3b16f91be42a75c9719a39c4096139f0f31393d58\",\n    \"0xa4c3eb1f7160f8216fc176fb244df53008ff32f2892363d85254002e66e2de21ccfe1f3b1047589abee50f29b9d507e3\",\n    \"0x8c552885eab04ba40922a8f0c3c38c96089c95ff1405258d3f1efe8d179e39e1295cbf67677894c607ae986e4e6b1fb0\",\n    \"0xb3671746fa7f848c4e2ae6946894defadd815230b906b419143523cc0597bc1d6c0a4c1e09d49b66b4a2c11cde3a4de3\",\n    \"0x937a249a95813a5e2ef428e355efd202e15a37d73e56cfb7e57ea9f943f2ce5ca8026f2f1fd25bf164ba89d07077d858\",\n    \"0x83646bdf6053a04aa9e2f112499769e5bd5d0d10f2e13db3ca89bd45c0b3b7a2d752b7d137fb3909f9c62b78166c9339\",\n    \"0xb4eac4b91e763666696811b7ed45e97fd78310377ebea1674b58a2250973f80492ac35110ed1240cd9bb2d17493d708c\",\n    \"0x82db43a99bc6573e9d92a3fd6635dbbb249ac66ba53099c3c0c8c8080b121dd8243cd5c6e36ba0a4d2525bae57f5c89c\",\n    \"0xa64d6a264a681b49d134c655d5fc7756127f1ee7c93d328820f32bca68869f53115c0d27fef35fe71f7bc4fdaed97348\",\n    \"0x8739b7a9e2b4bc1831e7f04517771bc7cde683a5e74e052542517f8375a2f64e53e0d5ac925ef722327e7bb195b4d1d9\",\n    \"0x8f337cdd29918a2493515ebb5cf702bbe8ecb23b53c6d18920cc22f519e276ca9b991d3313e2d38ae17ae8bdfa4f8b7e\",\n    \"0xb0edeab9850e193a61f138ef2739fc42ceec98f25e7e8403bfd5fa34a7bc956b9d0898250d18a69fa4625a9b3d6129da\",\n    \"0xa9920f26fe0a6d51044e623665d998745c9eca5bce12051198b88a77d728c8238f97d4196f26e43b24f8841500b998d0\",\n    \"0x86e655d61502b979eeeeb6f9a7e1d0074f936451d0a1b0d2fa4fb3225b439a3770767b649256fe481361f481a8dbc276\",\n    \"0x84d3b32fa62096831cc3bf013488a9f3f481dfe293ae209ed19585a03f7db8d961a7a9dd0db82bd7f62d612707575d9c\",\n    \"0x81c827826ec9346995ffccf62a241e3b2d32f7357acd1b1f8f7a7dbc97022d3eb51b8a1230e23ce0b401d2e535e8cd78\",\n    \"0x94a1e40c151191c5b055b21e86f32e69cbc751dcbdf759a48580951834b96a1eed75914c0d19a38aefd21fb6c8d43d0c\",\n    \"0xab890222b44bc21b71f7c75e15b6c6e16bb03371acce4f8d4353ff3b8fcd42a14026589c5ed19555a3e15e4d18bfc3a3\",\n    \"0xaccb0be851e93c6c8cc64724cdb86887eea284194b10e7a43c90528ed97e9ec71ca69c6fac13899530593756dd49eab2\",\n    \"0xb630220aa9e1829c233331413ee28c5efe94ea8ea08d0c6bfd781955078b43a4f92915257187d8526873e6c919c6a1de\",\n    \"0xadd389a4d358c585f1274b73f6c3c45b58ef8df11f9d11221f620e241bf3579fba07427b288c0c682885a700cc1fa28d\",\n    \"0xa9fe6ca8bf2961a3386e8b8dcecc29c0567b5c0b3bcf3b0f9169f88e372b80151af883871fc5229815f94f43a6f5b2b0\",\n    \"0xad839ae003b92b37ea431fa35998b46a0afc3f9c0dd54c3b3bf7a262467b13ff3c323ada1c1ae02ac7716528bdf39e3e\",\n    \"0x9356d3fd0edcbbb65713c0f2a214394f831b26f792124b08c5f26e7f734b8711a87b7c4623408da6a091c9aef1f6af3c\",\n    \"0x896b25b083c35ac67f0af3784a6a82435b0e27433d4d74cd6d1eafe11e6827827799490fb1c77c11de25f0d75f14e047\",\n    \"0x8bfa019391c9627e8e5f05c213db625f0f1e51ec68816455f876c7e55b8f17a4f13e5aae9e3fb9e1cf920b1402ee2b40\",\n    \"0x8ba3a6faa6a860a8f3ce1e884aa8769ceded86380a86520ab177ab83043d380a4f535fe13884346c5e51bee68da6ab41\",\n    \"0xa8292d0844084e4e3bb7af92b1989f841a46640288c5b220fecfad063ee94e86e13d3d08038ec2ac82f41c96a3bfe14d\",\n    \"0x8229bb030b2fc566e11fd33c7eab7a1bb7b49fed872ea1f815004f7398cb03b85ea14e310ec19e1f23e0bdaf60f8f76c\",\n    \"0x8cfbf869ade3ec551562ff7f63c2745cc3a1f4d4dc853a0cd42dd5f6fe54228f86195ea8fe217643b32e9f513f34a545\",\n    \"0xac52a3c8d3270ddfe1b5630159da9290a5ccf9ccbdef43b58fc0a191a6c03b8a5974cf6e2bbc7bd98d4a40a3581482d7\",\n    \"0xab13decb9e2669e33a7049b8eca3ca327c40dea15ad6e0e7fa63ed506db1d258bc36ac88b35f65cae0984e937eb6575d\",\n    \"0xb5e748eb1a7a1e274ff0cc56311c198f2c076fe4b7e73e5f80396fe85358549df906584e6bb2c8195b3e2be7736850a5\",\n    \"0xb5cb911325d8f963c41f691a60c37831c7d3bbd92736efa33d1f77a22b3fde7f283127256c2f47e197571e6fe0b46149\",\n    \"0x8a01dc6ed1b55f26427a014faa347130738b191a06b800e32042a46c13f60b49534520214359d68eb2e170c31e2b8672\",\n    \"0xa72fa874866e19b2efb8e069328362bf7921ec375e3bcd6b1619384c3f7ee980f6cf686f3544e9374ff54b4d17a1629c\",\n    \"0x8db21092f7c5f110fba63650b119e82f4b42a997095d65f08f8237b02dd66fdf959f788df2c35124db1dbd330a235671\",\n    \"0x8c65d50433d9954fe28a09fa7ba91a70a590fe7ba6b3060f5e4be0f6cef860b9897fa935fb4ebc42133524eb071dd169\",\n    \"0xb4614058e8fa21138fc5e4592623e78b8982ed72aa35ee4391b164f00c68d277fa9f9eba2eeefc890b4e86eba5124591\",\n    \"0xab2ad3a1bce2fbd55ca6b7c23786171fe1440a97d99d6df4d80d07dd56ac2d7203c294b32fc9e10a6c259381a73f24a1\",\n    \"0x812ae3315fdc18774a8da3713a4679e8ed10b9405edc548c00cacbe25a587d32040566676f135e4723c5dc25df5a22e9\",\n    \"0xa464b75f95d01e5655b54730334f443c8ff27c3cb79ec7af4b2f9da3c2039c609908cd128572e1fd0552eb597e8cef8d\",\n    \"0xa0db3172e93ca5138fe419e1c49a1925140999f6eff7c593e5681951ee0ec1c7e454c851782cbd2b8c9bc90d466e90e0\",\n    \"0x806db23ba7d00b87d544eed926b3443f5f9c60da6b41b1c489fba8f73593b6e3b46ebfcab671ee009396cd77d5e68aa1\",\n    \"0x8bfdf2c0044cc80260994e1c0374588b6653947b178e8b312be5c2a05e05767e98ea15077278506aee7df4fee1aaf89e\",\n    \"0x827f6558c16841b5592ff089c9c31e31eb03097623524394813a2e4093ad2d3f8f845504e2af92195aaa8a1679d8d692\",\n    \"0x925c4f8eab2531135cd71a4ec88e7035b5eea34ba9d799c5898856080256b4a15ed1a746e002552e2a86c9c157e22e83\",\n    \"0xa9f9a368f0e0b24d00a35b325964c85b69533013f9c2cfad9708be5fb87ff455210f8cb8d2ce3ba58ca3f27495552899\",\n    \"0x8ac0d3bebc1cae534024187e7c71f8927ba8fcc6a1926cb61c2b6c8f26bb7831019e635a376146c29872a506784a4aaa\",\n    \"0x97c577be2cbbfdb37ad754fae9df2ada5fc5889869efc7e18a13f8e502fbf3f4067a509efbd46fd990ab47ce9a70f5a8\",\n    \"0x935e7d82bca19f16614aa43b4a3474e4d20d064e4bfdf1cea2909e5c9ab72cfe3e54dc50030e41ee84f3588cebc524e9\",\n    \"0x941aafc08f7c0d94cebfbb1f0aad5202c02e6e37f2c12614f57e727efa275f3926348f567107ee6d8914dd71e6060271\",\n    \"0xaf0fbc1ba05b4b5b63399686df3619968be5d40073de0313cbf5f913d3d4b518d4c249cdd2176468ccaa36040a484f58\",\n    \"0xa0c414f23f46ca6d69ce74c6f8a00c036cb0edd098af0c1a7d39c802b52cfb2d5dbdf93fb0295453d4646e2af7954d45\",\n    \"0x909cf39e11b3875bb63b39687ae1b5d1f5a15445e39bf164a0b14691b4ddb39a8e4363f584ef42213616abc4785b5d66\",\n    \"0xa92bac085d1194fbd1c88299f07a061d0bdd3f980b663e81e6254dbb288bf11478c0ee880e28e01560f12c5ccb3c0103\",\n    \"0x841705cd5cd76b943e2b7c5e845b9dd3c8defe8ef67e93078d6d5e67ade33ad4b0fd413bc196f93b0a4073c855cd97d4\",\n    \"0x8e7eb8364f384a9161e81d3f1d52ceca9b65536ae49cc35b48c3e2236322ba4ae9973e0840802d9fa4f4d82ea833544f\",\n    \"0xaed3ab927548bc8bec31467ba80689c71a168e34f50dcb6892f19a33a099f5aa6b3f9cb79f5c0699e837b9a8c7f27efe\",\n    \"0xb8fbf7696210a36e20edabd77839f4dfdf50d6d015cdf81d587f90284a9bcef7d2a1ff520728d7cc69a4843d6c20dedd\",\n    \"0xa9d533769ce6830211c884ae50a82a7bf259b44ac71f9fb11f0296fdb3981e6b4c1753fe744647b247ebc433a5a61436\",\n    \"0x8b4bdf90d33360b7f428c71cde0a49fb733badba8c726876945f58c620ce7768ae0e98fc8c31fa59d8955a4823336bb1\",\n    \"0x808d42238e440e6571c59e52a35ae32547d502dc24fd1759d8ea70a7231a95859baf30b490a4ba55fa2f3aaa11204597\",\n    \"0x85594701f1d2fee6dc1956bc44c7b31db93bdeec2f3a7d622c1a08b26994760773e3d57521a44cfd7e407ac3fd430429\",\n    \"0xa66de045ce7173043a6825e9dc440ac957e2efb6df0a337f4f8003eb0c719d873a52e6eba3cb0d69d977ca37d9187674\",\n    \"0x87a1c6a1fdff993fa51efa5c3ba034c079c0928a7d599b906336af7c2dcab9721ceaf3108c646490af9dff9a754f54b3\",\n    \"0x926424223e462ceb75aed7c22ade8a7911a903b7e5dd4bc49746ddce8657f4616325cd12667d4393ac52cdd866396d0e\",\n    \"0xb5dc96106593b42b30f06f0b0a1e0c1aafc70432e31807252d3674f0b1ea5e58eac8424879d655c9488d85a879a3e572\",\n    \"0x997ca0987735cc716507cb0124b1d266d218b40c9d8e0ecbf26a1d65719c82a637ce7e8be4b4815d307df717bde7c72a\",\n    \"0x92994d3f57a569b7760324bb5ae4e8e14e1633d175dab06aa57b8e391540e05f662fdc08b8830f489a063f59b689a688\",\n    \"0xa8087fcc6aa4642cb998bea11facfe87eb33b90a9aa428ab86a4124ad032fc7d2e57795311a54ec9f55cc120ebe42df1\",\n    \"0xa9bd7d1de6c0706052ca0b362e2e70e8c8f70f1f026ea189b4f87a08ce810297ebfe781cc8004430776c54c1a05ae90c\",\n    \"0x856d33282e8a8e33a3d237fb0a0cbabaf77ba9edf2fa35a831fdafcadf620561846aa6cbb6bdc5e681118e1245834165\",\n    \"0x9524a7aa8e97a31a6958439c5f3339b19370f03e86b89b1d02d87e4887309dbbe9a3a8d2befd3b7ed5143c8da7e0a8ad\",\n    \"0x824fdf433e090f8acbd258ac7429b21f36f9f3b337c6d0b71d1416a5c88a767883e255b2888b7c906dd2e9560c4af24c\",\n    \"0x88c7fee662ca7844f42ed5527996b35723abffd0d22d4ca203b9452c639a5066031207a5ae763dbc0865b3299d19b1ec\",\n    \"0x919dca5c5595082c221d5ab3a5bc230f45da7f6dec4eb389371e142c1b9c6a2c919074842479c2844b72c0d806170c0c\",\n    \"0xb939be8175715e55a684578d8be3ceff3087f60fa875fff48e52a6e6e9979c955efef8ff67cfa2b79499ea23778e33b0\",\n    \"0x873b6db725e7397d11bc9bed9ac4468e36619135be686790a79bc6ed4249058f1387c9a802ea86499f692cf635851066\",\n    \"0xaeae06db3ec47e9e5647323fa02fac44e06e59b885ad8506bf71b184ab3895510c82f78b6b22a5d978e8218e7f761e9f\",\n    \"0xb99c0a8359c72ab88448bae45d4bf98797a26bca48b0d4460cd6cf65a4e8c3dd823970ac3eb774ae5d0cea4e7fadf33e\",\n    \"0x8f10c8ec41cdfb986a1647463076a533e6b0eec08520c1562401b36bb063ac972aa6b28a0b6ce717254e35940b900e3c\",\n    \"0xa106d9be199636d7add43b942290269351578500d8245d4aae4c083954e4f27f64740a3138a66230391f2d0e6043a8de\",\n    \"0xa469997908244578e8909ff57cffc070f1dbd86f0098df3cfeb46b7a085cfecc93dc69ee7cad90ff1dc5a34d50fe580c\",\n    \"0xa4ef087bea9c20eb0afc0ee4caba7a9d29dfa872137828c721391273e402fb6714afc80c40e98bbd8276d3836bffa080\",\n    \"0xb07a013f73cd5b98dae0d0f9c1c0f35bff8a9f019975c4e1499e9bee736ca6fcd504f9bc32df1655ff333062382cff04\",\n    \"0xb0a77188673e87cc83348c4cc5db1eecf6b5184e236220c8eeed7585e4b928db849944a76ec60ef7708ef6dac02d5592\",\n    \"0xb1284b37e59b529f0084c0dacf0af6c0b91fc0f387bf649a8c74819debf606f7b07fc3e572500016fb145ec2b24e9f17\",\n    \"0x97b20b5b4d6b9129da185adfbf0d3d0b0faeba5b9715f10299e48ea0521709a8296a9264ce77c275a59c012b50b6519a\",\n    \"0xb9d37e946fae5e4d65c1fbfacc8a62e445a1c9d0f882e60cca649125af303b3b23af53c81d7bac544fb7fcfc7a314665\",\n    \"0x8e5acaac379f4bb0127efbef26180f91ff60e4c525bc9b798fc50dfaf4fe8a5aa84f18f3d3cfb8baead7d1e0499af753\",\n    \"0xb0c0b8ab1235bf1cda43d4152e71efc1a06c548edb964eb4afceb201c8af24240bf8ab5cae30a08604e77432b0a5faf0\",\n    \"0x8cc28d75d5c8d062d649cbc218e31c4d327e067e6dbd737ec0a35c91db44fbbd0d40ec424f5ed79814add16947417572\",\n    \"0x95ae6219e9fd47efaa9cb088753df06bc101405ba50a179d7c9f7c85679e182d3033f35b00dbba71fdcd186cd775c52e\",\n    \"0xb5d28fa09f186ebc5aa37453c9b4d9474a7997b8ae92748ecb940c14868792292ac7d10ade01e2f8069242b308cf97e5\",\n    \"0x8c922a0faa14cc6b7221f302df3342f38fc8521ec6c653f2587890192732c6da289777a6cd310747ea7b7d104af95995\",\n    \"0xb9ad5f660b65230de54de535d4c0fcae5bc6b59db21dea5500fdc12eea4470fb8ea003690fdd16d052523418d5e01e8c\",\n    \"0xa39a9dd41a0ff78c82979483731f1cd68d3921c3e9965869662c22e02dde3877802e180ba93f06e7346f96d9fa9261d2\",\n    \"0x8b32875977ec372c583b24234c27ed73aef00cdff61eb3c3776e073afbdeade548de9497c32ec6d703ff8ad0a5cb7fe4\",\n    \"0x9644cbe755a5642fe9d26cfecf170d3164f1848c2c2e271d5b6574a01755f3980b3fc870b98cf8528fef6ecef4210c16\",\n    \"0x81ea9d1fdd9dd66d60f40ce0712764b99da9448ae0b300f8324e1c52f154e472a086dda840cb2e0b9813dc8ce8afd4b5\",\n    \"0x906aaa4a7a7cdf01909c5cfbc7ded2abc4b869213cbf7c922d4171a4f2e637e56f17020b852ad339d83b8ac92f111666\",\n    \"0x939b5f11acbdeff998f2a080393033c9b9d8d5c70912ea651c53815c572d36ee822a98d6dfffb2e339f29201264f2cf4\",\n    \"0xaba4898bf1ccea9b9e2df1ff19001e05891581659c1cbbde7ee76c349c7fc7857261d9785823c9463a8aea3f40e86b38\",\n    \"0x83ca1a56b8a0be4820bdb5a9346357c68f9772e43f0b887729a50d2eb2a326bbcede676c8bf2e51d7c89bbd8fdb778a6\",\n    \"0x94e86e9fe6addfe2c3ee3a547267ed921f4230d877a85bb4442c2d9350c2fa9a9c54e6fe662de82d1a2407e4ab1691c2\",\n    \"0xa0cc3bdef671a59d77c6984338b023fa2b431b32e9ed2abe80484d73edc6540979d6f10812ecc06d4d0c5d4eaca7183c\",\n    \"0xb5343413c1b5776b55ea3c7cdd1f3af1f6bd802ea95effe3f2b91a523817719d2ecc3f8d5f3cc2623ace7e35f99ca967\",\n    \"0x92085d1ed0ed28d8cabe3e7ff1905ed52c7ceb1eac5503760c52fb5ee3a726aba7c90b483c032acc3f166b083d7ec370\",\n    \"0x8ec679520455275cd957fca8122724d287db5df7d29f1702a322879b127bff215e5b71d9c191901465d19c86c8d8d404\",\n    \"0xb65eb2c63d8a30332eb24ee8a0c70156fc89325ebbb38bacac7cf3f8636ad8a472d81ccca80423772abc00192d886d8a\",\n    \"0xa9fe1c060b974bee4d590f2873b28635b61bfcf614e61ff88b1be3eee4320f4874e21e8d666d8ac8c9aba672efc6ecae\",\n    \"0xb3fe2a9a389c006a831dea7e777062df84b5c2803f9574d7fbe10b7e1c125817986af8b6454d6be9d931a5ac94cfe963\",\n    \"0x95418ad13b734b6f0d33822d9912c4c49b558f68d08c1b34a0127fcfa666bcae8e6fda8832d2c75bb9170794a20e4d7c\",\n    \"0xa9a7df761e7f18b79494bf429572140c8c6e9d456c4d4e336184f3f51525a65eb9582bea1e601bdb6ef8150b7ca736a5\",\n    \"0xa0de03b1e75edf7998c8c1ac69b4a1544a6fa675a1941950297917366682e5644a4bda9cdeedfaf9473d7fccd9080b0c\",\n    \"0xa61838af8d95c95edf32663a68f007d95167bf6e41b0c784a30b22d8300cfdd5703bd6d16e86396638f6db6ae7e42a85\",\n    \"0x8866d62084d905c145ff2d41025299d8b702ac1814a7dec4e277412c161bc9a62fed735536789cb43c88693c6b423882\",\n    \"0x91da22c378c81497fe363e7f695c0268443abee50f8a6625b8a41e865638a643f07b157ee566de09ba09846934b4e2d7\",\n    \"0x941d21dd57c9496aa68f0c0c05507405fdd413acb59bc668ce7e92e1936c68ec4b065c3c30123319884149e88228f0b2\",\n    \"0xa77af9b094bc26966ddf2bf9e1520c898194a5ccb694915950dadc204facbe3066d3d89f50972642d76b14884cfbaa21\",\n    \"0x8e76162932346869f4618bde744647f7ab52ab498ad654bdf2a4feeb986ac6e51370841e5acbb589e38b6e7142bb3049\",\n    \"0xb60979ace17d6937ece72e4f015da4657a443dd01cebc7143ef11c09e42d4aa8855999a65a79e2ea0067f31c9fc2ab0f\",\n    \"0xb3e2ffdd5ee6fd110b982fd4fad4b93d0fca65478f986d086eeccb0804960bfaa1919afa743c2239973ea65091fe57d2\",\n    \"0x8ce0ce05e7d7160d44574011da687454dbd3c8b8290aa671731b066e2c82f8cf2d63cb8e932d78c6122ec610e44660e6\",\n    \"0xab005dd8d297045c39e2f72fb1c48edb501ccf3575d3d04b9817b3afee3f0bb0f3f53f64bda37d1d9cde545aae999bae\",\n    \"0x95bd7edb4c4cd60e3cb8a72558845a3cce6bb7032ccdf33d5a49ebb6ddf203bc3c79e7b7e550735d2d75b04c8b2441e8\",\n    \"0x889953ee256206284094e4735dbbb17975bafc7c3cb94c9fbfee4c3e653857bfd49e818f64a47567f721b98411a3b454\",\n    \"0xb188423e707640ab0e75a061e0b62830cde8afab8e1ad3dae30db69ffae4e2fc005bababbdcbd7213b918ed4f70e0c14\",\n    \"0xa97e0fafe011abd70d4f99a0b36638b3d6e7354284588f17a88970ed48f348f88392779e9a038c6cbc9208d998485072\",\n    \"0x87db11014a91cb9b63e8dfaa82cdebca98272d89eb445ee1e3ff9dbaf2b3fad1a03b888cffc128e4fe208ed0dddece0f\",\n    \"0xaad2e40364edd905d66ea4ac9d51f9640d6fda9a54957d26ba233809851529b32c85660fa401dbee3679ec54fa6dd966\",\n    \"0x863e99336ca6edf03a5a259e59a2d0f308206e8a2fb320cfc0be06057366df8e0f94b33a28f574092736b3c5ada84270\",\n    \"0xb34bcc56a057589f34939a1adc51de4ff6a9f4fee9c7fa9aa131e28d0cf0759a0c871b640162acdfbf91f3f1b59a3703\",\n    \"0x935dd28f2896092995c5eff1618e5b6efe7a40178888d7826da9b0503c2d6e68a28e7fac1a334e166d0205f0695ef614\",\n    \"0xb842cd5f8f5de5ca6c68cb4a5c1d7b451984930eb4cc18fd0934d52fdc9c3d2d451b1c395594d73bc3451432bfba653f\",\n    \"0x9014537885ce2debad736bc1926b25fdab9f69b216bf024f589c49dc7e6478c71d595c3647c9f65ff980b14f4bb2283b\",\n    \"0x8e827ccca1dd4cd21707140d10703177d722be0bbe5cac578db26f1ef8ad2909103af3c601a53795435b27bf95d0c9ed\",\n    \"0x8a0b8ad4d466c09d4f1e9167410dbe2edc6e0e6229d4b3036d30f85eb6a333a18b1c968f6ca6d6889bb08fecde017ef4\",\n    \"0x9241ee66c0191b06266332dc9161dede384c4bb4e116dbd0890f3c3790ec5566da4568243665c4725b718ac0f6b5c179\",\n    \"0xaeb4d5fad81d2b505d47958a08262b6f1b1de9373c2c9ba6362594194dea3e002ab03b8cbb43f867be83065d3d370f19\",\n    \"0x8781bc83bb73f7760628629fe19e4714b494dbed444c4e4e4729b7f6a8d12ee347841a199888794c2234f51fa26fc2b9\",\n    \"0xb58864f0acd1c2afa29367e637cbde1968d18589245d9936c9a489c6c495f54f0113ecdcbe4680ac085dd3c397c4d0c3\",\n    \"0x94a24284afaeead61e70f3e30f87248d76e9726759445ca18cdb9360586c60cc9f0ec1c397f9675083e0b56459784e2e\",\n    \"0xaed358853f2b54dcbddf865e1816c2e89be12e940e1abfa661e2ee63ffc24a8c8096be2072fa83556482c0d89e975124\",\n    \"0xb95374e6b4fc0765708e370bc881e271abf2e35c08b056a03b847e089831ef4fe3124b9c5849d9c276eb2e35b3daf264\",\n    \"0xb834cdbcfb24c8f84bfa4c552e7fadc0028a140952fd69ed13a516e1314a4cd35d4b954a77d51a1b93e1f5d657d0315d\",\n    \"0x8fb6d09d23bfa90e7443753d45a918d91d75d8e12ec7d016c0dfe94e5c592ba6aaf483d2f16108d190822d955ad9cdc3\",\n    \"0xaa315cd3c60247a6ad4b04f26c5404c2713b95972843e4b87b5a36a89f201667d70f0adf20757ebe1de1b29ae27dda50\",\n    \"0xa116862dca409db8beff5b1ccd6301cdd0c92ca29a3d6d20eb8b87f25965f42699ca66974dd1a355200157476b998f3b\",\n    \"0xb4c2f5fe173c4dc8311b60d04a65ce1be87f070ac42e13cd19c6559a2931c6ee104859cc2520edebbc66a13dc7d30693\",\n    \"0x8d4a02bf99b2260c334e7d81775c5cf582b00b0c982ce7745e5a90624919028278f5e9b098573bad5515ce7fa92a80c8\",\n    \"0x8543493bf564ce6d97bd23be9bff1aba08bd5821ca834f311a26c9139c92a48f0c2d9dfe645afa95fec07d675d1fd53b\",\n    \"0x9344239d13fde08f98cb48f1f87d34cf6abe8faecd0b682955382a975e6eed64e863fa19043290c0736261622e00045c\",\n    \"0xaa49d0518f343005ca72b9e6c7dcaa97225ce6bb8b908ebbe7b1a22884ff8bfb090890364e325a0d414ad180b8f161d1\",\n    \"0x907d7fd3e009355ab326847c4a2431f688627faa698c13c03ffdd476ecf988678407f029b8543a475dcb3dafdf2e7a9c\",\n    \"0x845f1f10c6c5dad2adc7935f5cd2e2b32f169a99091d4f1b05babe7317b9b1cdce29b5e62f947dc621b9acbfe517a258\",\n    \"0x8f3be8e3b380ea6cdf9e9c237f5e88fd5a357e5ded80ea1fc2019810814de82501273b4da38916881125b6fa0cfd4459\",\n    \"0xb9c7f487c089bf1d20c822e579628db91ed9c82d6ca652983aa16d98b4270c4da19757f216a71b9c13ddee3e6e43705f\",\n    \"0x8ba2d8c88ad2b872db104ea8ddbb006ec2f3749fd0e19298a804bb3a5d94de19285cc7fb19fee58a66f7851d1a66c39f\",\n    \"0x9375ecd3ed16786fe161af5d5c908f56eeb467a144d3bbddfc767e90065b7c94fc53431adebecba2b6c9b5821184d36e\",\n    \"0xa49e069bfadb1e2e8bff6a4286872e2a9765d62f0eaa4fcb0e5af4bbbed8be3510fb19849125a40a8a81d1e33e81c3eb\",\n    \"0x9522cc66757b386aa6b88619525c8ce47a5c346d590bb3647d12f991e6c65c3ab3c0cfc28f0726b6756c892eae1672be\",\n    \"0xa9a0f1f51ff877406fa83a807aeb17b92a283879f447b8a2159653db577848cc451cbadd01f70441e351e9ed433c18bc\",\n    \"0x8ff7533dcff6be8714df573e33f82cf8e9f2bcaaa43e939c4759d52b754e502717950de4b4252fb904560fc31dce94a4\",\n    \"0x959724671e265a28d67c29d95210e97b894b360da55e4cf16e6682e7912491ed8ca14bfaa4dce9c25a25b16af580494f\",\n    \"0x92566730c3002f4046c737032487d0833c971e775de59fe02d9835c9858e2e3bc37f157424a69764596c625c482a2219\",\n    \"0xa84b47ceff13ed9c3e5e9cdf6739a66d3e7c2bd8a6ba318fefb1a9aecf653bb2981da6733ddb33c4b0a4523acc429d23\",\n    \"0xb4ddf571317e44f859386d6140828a42cf94994e2f1dcbcc9777f4eebbfc64fc1e160b49379acc27c4672b8e41835c5d\",\n    \"0x8ab95c94072b853d1603fdd0a43b30db617d13c1d1255b99075198e1947bfa5f59aed2b1147548a1b5e986cd9173d15c\",\n    \"0x89511f2eab33894fd4b3753d24249f410ff7263052c1fef6166fc63a79816656b0d24c529e45ccce6be28de6e375d916\",\n    \"0xa0866160ca63d4f2be1b4ea050dac6b59db554e2ebb4e5b592859d8df339b46fd7cb89aaed0951c3ee540aee982c238a\",\n    \"0x8fcc5cbba1b94970f5ff2eb1922322f5b0aa7d918d4b380c9e7abfd57afd8b247c346bff7b87af82efbce3052511cd1b\",\n    \"0x99aeb2a5e846b0a2874cca02c66ed40d5569eb65ab2495bc3f964a092e91e1517941f2688e79f8cca49cd3674c4e06dc\",\n    \"0xb7a096dc3bad5ca49bee94efd884aa3ff5615cf3825cf95fbe0ce132e35f46581d6482fa82666c7ef5f1643eaee8f1ca\",\n    \"0x94393b1da6eaac2ffd186b7725eca582f1ddc8cdd916004657f8a564a7c588175cb443fc6943b39029f5bbe0add3fad8\",\n    \"0x884b85fe012ccbcd849cb68c3ad832d83b3ef1c40c3954ffdc97f103b1ed582c801e1a41d9950f6bddc1d11f19d5ec76\",\n    \"0xb00061c00131eded8305a7ce76362163deb33596569afb46fe499a7c9d7a0734c084d336b38d168024c2bb42b58e7660\",\n    \"0xa439153ac8e6ca037381e3240e7ba08d056c83d7090f16ed538df25901835e09e27de2073646e7d7f3c65056af6e4ce7\",\n    \"0x830fc9ca099097d1f38b90e6843dc86f702be9d20bdacc3e52cae659dc41df5b8d2c970effa6f83a5229b0244a86fe22\",\n    \"0xb81ea2ffaaff2bb00dd59a9ab825ba5eed4db0d8ac9c8ed1a632ce8f086328a1cddd045fbe1ace289083c1325881b7e7\",\n    \"0xb51ea03c58daf2db32c99b9c4789b183365168cb5019c72c4cc91ac30b5fb7311d3db76e6fa41b7cd4a8c81e2f6cdc94\",\n    \"0xa4170b2c6d09ca5beb08318730419b6f19215ce6c631c854116f904be3bc30dd85a80c946a8ab054d3e307afaa3f8fbc\",\n    \"0x897cc42ff28971ff54d2a55dd6b35cfb8610ac902f3c06e3a5cea0e0a257e870c471236a8e84709211c742a09c5601a6\",\n    \"0xa18f2e98d389dace36641621488664ecbb422088ab03b74e67009b8b8acacaaa24fdcf42093935f355207d934adc52a8\",\n    \"0x92adcfb678cc2ba19c866f3f2b988fdcb4610567f3ab436cc0cb9acaf5a88414848d71133ebdbec1983e38e6190f1b5f\",\n    \"0xa86d43c2ce01b366330d3b36b3ca85f000c3548b8297e48478da1ee7d70d8576d4650cba7852ed125c0d7cb6109aa7f3\",\n    \"0x8ed31ceed9445437d7732dce78a762d72ff32a7636bfb3fd7974b7ae15db414d8184a1766915244355deb354fbc5803b\",\n    \"0x9268f70032584f416e92225d65af9ea18c466ebc7ae30952d56a4e36fd9ea811dde0a126da9220ba3c596ec54d8a335e\",\n    \"0x9433b99ee94f2d3fbdd63b163a2bdf440379334c52308bd24537f7defd807145a062ff255a50d119a7f29f4b85d250e3\",\n    \"0x90ce664f5e4628a02278f5cf5060d1a34f123854634b1870906e5723ac9afd044d48289be283b267d45fcbf3f4656aaf\",\n    \"0xaaf21c4d59378bb835d42ae5c5e5ab7a3c8c36a59e75997989313197752b79a472d866a23683b329ea69b048b87fa13e\",\n    \"0xb83c0589b304cec9ede549fde54f8a7c2a468c6657da8c02169a6351605261202610b2055c639b9ed2d5b8c401fb8f56\",\n    \"0x9370f326ea0f170c2c05fe2c5a49189f20aec93b6b18a5572a818cd4c2a6adb359e68975557b349fb54f065d572f4c92\",\n    \"0xac3232fa5ce6f03fca238bef1ce902432a90b8afce1c85457a6bee5571c033d4bceefafc863af04d4e85ac72a4d94d51\",\n    \"0x80d9ea168ff821b22c30e93e4c7960ce3ad3c1e6deeebedd342a36d01bd942419b187e2f382dbfd8caa34cca08d06a48\",\n    \"0xa387a3c61676fb3381eefa2a45d82625635a666e999aba30e3b037ec9e040f414f9e1ad9652abd3bcad63f95d85038db\",\n    \"0xa1b229fe32121e0b391b0f6e0180670b9dc89d79f7337de4c77ea7ad0073e9593846f06797c20e923092a08263204416\",\n    \"0x92164a9d841a2b828cedf2511213268b698520f8d1285852186644e9a0c97512cafa4bfbe29af892c929ebccd102e998\",\n    \"0x82ee2fa56308a67c7db4fd7ef539b5a9f26a1c2cc36da8c3206ba4b08258fbb3cec6fe5cdbd111433fb1ba2a1e275927\",\n    \"0x8c77bfe9e191f190a49d46f05600603fa42345592539b82923388d72392404e0b29a493a15e75e8b068dddcd444c2928\",\n    \"0x80b927f93ccf79dcf5c5b20bcf5a7d91d7a17bc0401bb7cc9b53a6797feac31026eb114257621f5a64a52876e4474cc1\",\n    \"0xb6b68b6501c37804d4833d5a063dd108a46310b1400549074e3cac84acc6d88f73948b7ad48d686de89c1ec043ae8c1a\",\n    \"0xab3da00f9bdc13e3f77624f58a3a18fc3728956f84b5b549d62f1033ae4b300538e53896e2d943f160618e05af265117\",\n    \"0xb6830e87233b8eace65327fdc764159645b75d2fd4024bf8f313b2dd5f45617d7ecfb4a0b53ccafb5429815a9a1adde6\",\n    \"0xb9251cfe32a6dc0440615aadcd98b6b1b46e3f4e44324e8f5142912b597ee3526bea2431e2b0282bb58f71be5b63f65e\",\n    \"0xaf8d70711e81cdddfb39e67a1b76643292652584c1ce7ce4feb1641431ad596e75c9120e85f1a341e7a4da920a9cdd94\",\n    \"0x98cd4e996594e89495c078bfd52a4586b932c50a449a7c8dfdd16043ca4cda94dafbaa8ad1b44249c99bbcc52152506e\",\n    \"0xb9fc6d1c24f48404a4a64fbe3e43342738797905db46e4132aee5f086aaa4c704918ad508aaefa455cfe1b36572e6242\",\n    \"0xa365e871d30ba9291cedaba1be7b04e968905d003e9e1af7e3b55c5eb048818ae5b913514fb08b24fb4fbdccbb35d0b8\",\n    \"0x93bf99510971ea9af9f1e364f1234c898380677c8e8de9b0dd24432760164e46c787bc9ec42a7ad450500706cf247b2d\",\n    \"0xb872f825a5b6e7b9c7a9ddfeded3516f0b1449acc9b4fd29fc6eba162051c17416a31e5be6d3563f424d28e65bab8b8f\",\n    \"0xb06b780e5a5e8eb4f4c9dc040f749cf9709c8a4c9ef15e925f442b696e41e5095db0778a6c73bcd329b265f2c6955c8b\",\n    \"0x848f1a981f5fc6cd9180cdddb8d032ad32cdfa614fc750d690dbae36cc0cd355cbf1574af9b3ffc8b878f1b2fafb9544\",\n    \"0xa03f48cbff3e9e8a3a655578051a5ae37567433093ac500ed0021c6250a51b767afac9bdb194ee1e3eac38a08c0eaf45\",\n    \"0xb5be78ce638ff8c4aa84352b536628231d3f7558c5be3bf010b28feac3022e64691fa672f358c8b663904aebe24a54ed\",\n    \"0xa9d4da70ff676fa55d1728ba6ab03b471fa38b08854d99e985d88c2d050102d8ccffbe1c90249a5607fa7520b15fe791\",\n    \"0x8fe9f7092ffb0b69862c8e972fb1ecf54308c96d41354ed0569638bb0364f1749838d6d32051fff1599112978c6e229c\",\n    \"0xae6083e95f37770ecae0df1e010456f165d96cfe9a7278c85c15cffd61034081ce5723e25e2bede719dc9341ec8ed481\",\n    \"0xa260891891103089a7afbd9081ea116cfd596fd1015f5b65e10b0961eb37fab7d09c69b7ce4be8bf35e4131848fb3fe4\",\n    \"0x8d729fa32f6eb9fd2f6a140bef34e8299a2f3111bffd0fe463aa8622c9d98bfd31a1df3f3e87cd5abc52a595f96b970e\",\n    \"0xa30ec6047ae4bc7da4daa7f4c28c93aedb1112cfe240e681d07e1a183782c9ff6783ac077c155af23c69643b712a533f\",\n    \"0xac830726544bfe7b5467339e5114c1a75f2a2a8d89453ce86115e6a789387e23551cd64620ead6283dfa4538eb313d86\",\n    \"0x8445c135b7a48068d8ed3e011c6d818cfe462b445095e2fbf940301e50ded23f272d799eea47683fc027430ce14613ef\",\n    \"0x95785411715c9ae9d8293ce16a693a2aa83e3cb1b4aa9f76333d0da2bf00c55f65e21e42e50e6c5772ce213dd7b4f7a0\",\n    \"0xb273b024fa18b7568c0d1c4d2f0c4e79ec509dafac8c5951f14192d63ddbcf2d8a7512c1c1b615cc38fa3e336618e0c5\",\n    \"0xa78b9d3ea4b6a90572eb27956f411f1d105fdb577ee2ffeec9f221da9b45db84bfe866af1f29597220c75e0c37a628d8\",\n    \"0xa4be2bf058c36699c41513c4d667681ce161a437c09d81383244fc55e1c44e8b1363439d0cce90a3e44581fb31d49493\",\n    \"0xb6eef13040f17dd4eba22aaf284d2f988a4a0c4605db44b8d2f4bf9567ac794550b543cc513c5f3e2820242dd704152e\",\n    \"0x87eb00489071fa95d008c5244b88e317a3454652dcb1c441213aa16b28cd3ecaa9b22fec0bdd483c1df71c37119100b1\",\n    \"0x92d388acdcb49793afca329cd06e645544d2269234e8b0b27d2818c809c21726bc9cf725651b951e358a63c83dedee24\",\n    \"0xae27e219277a73030da27ab5603c72c8bd81b6224b7e488d7193806a41343dff2456132274991a4722fdb0ef265d04cd\",\n    \"0x97583e08ecb82bbc27c0c8476d710389fa9ffbead5c43001bd36c1b018f29faa98de778644883e51870b69c5ffb558b5\",\n    \"0x90a799a8ce73387599babf6b7da12767c0591cadd36c20a7990e7c05ea1aa2b9645654ec65308ee008816623a2757a6a\",\n    \"0xa1b47841a0a2b06efd9ab8c111309cc5fc9e1d5896b3e42ed531f6057e5ade8977c29831ce08dbda40348386b1dcc06d\",\n    \"0xb92b8ef59bbddb50c9457691bc023d63dfcc54e0fd88bd5d27a09e0d98ac290fc90e6a8f6b88492043bf7c87fac8f3e4\",\n    \"0xa9d6240b07d62e22ec8ab9b1f6007c975a77b7320f02504fc7c468b4ee9cfcfd945456ff0128bc0ef2174d9e09333f8d\",\n    \"0x8e96534c94693226dc32bca79a595ca6de503af635f802e86442c67e77564829756961d9b701187fe91318da515bf0e6\",\n    \"0xb6ba290623cd8dd5c2f50931c0045d1cfb0c30877bc8fe58cbc3ff61ee8da100045a39153916efa1936f4aee0892b473\",\n    \"0xb43baa7717fac02d4294f5b3bb5e58a65b3557747e3188b482410388daac7a9c177f762d943fd5dcf871273921213da8\",\n    \"0xb9cf00f8fb5e2ef2b836659fece15e735060b2ea39b8e901d3dcbdcf612be8bf82d013833718c04cd46ffaa70b85f42e\",\n    \"0x8017d0c57419e414cbba504368723e751ef990cc6f05dad7b3c2de6360adc774ad95512875ab8337d110bf39a42026fa\",\n    \"0xae7401048b838c0dcd4b26bb6c56d79d51964a0daba780970b6c97daee4ea45854ea0ac0e4139b3fe60dac189f84df65\",\n    \"0x887b237b0cd0f816b749b21db0b40072f9145f7896c36916296973f9e6990ede110f14e5976c906d08987c9836cca57f\",\n    \"0xa88c3d5770148aee59930561ca1223aceb2c832fb5417e188dca935905301fc4c6c2c9270bc1dff7add490a125eb81c6\",\n    \"0xb6cf9b02c0cd91895ad209e38c54039523f137b5848b9d3ad33ae43af6c20c98434952db375fe378de7866f2d0e8b18a\",\n    \"0x84ef3d322ff580c8ad584b1fe4fe346c60866eb6a56e982ba2cf3b021ecb1fdb75ecc6c29747adda86d9264430b3f816\",\n    \"0xa0561c27224baf0927ad144cb71e31e54a064c598373fcf0d66aebf98ab7af1d8e2f343f77baefff69a6da750a219e11\",\n    \"0xaa5cc43f5b8162b016f5e1b61214c0c9d15b1078911c650b75e6cdfb49b85ee04c6739f5b1687d15908444f691f732de\",\n    \"0xad4ac099b935589c7b8fdfdf3db332b7b82bb948e13a5beb121ebd7db81a87d278024a1434bcf0115c54ca5109585c3d\",\n    \"0x8a00466abf3f109a1dcd19e643b603d3af23d42794ef8ca2514dd507ecea44a031ac6dbc18bd02f99701168b25c1791e\",\n    \"0xb00b5900dfad79645f8bee4e5adc7b84eb22e5b1e67df77ccb505b7fc044a6c08a8ea5faca662414eb945f874f884cea\",\n    \"0x950e204e5f17112250b22ea6bb8423baf522fc0af494366f18fe0f949f51d6e6812074a80875cf1ed9c8e7420058d541\",\n    \"0x91e5cbf8bb1a1d50c81608c9727b414d0dd2fb467ebc92f100882a3772e54f94979cfdf8e373fdef7c7fcdd60fec9e00\",\n    \"0xa093f6a857b8caaff80599c2e89c962b415ecbaa70d8fd973155fa976a284c6b29a855f5f7a3521134d00d2972755188\",\n    \"0xb4d55a3551b00da54cc010f80d99ddd2544bde9219a3173dfaadf3848edc7e4056ab532fb75ac26f5f7141e724267663\",\n    \"0xa03ea050fc9b011d1b04041b5765d6f6453a93a1819cd9bd6328637d0b428f08526466912895dcc2e3008ee58822e9a7\",\n    \"0x99b12b3665e473d01bc6985844f8994fb65cb15745024fb7af518398c4a37ff215da8f054e8fdf3286984ae36a73ca5e\",\n    \"0x9972c7e7a7fb12e15f78d55abcaf322c11249cd44a08f62c95288f34f66b51f146302bce750ff4d591707075d9123bd2\",\n    \"0xa64b4a6d72354e596d87cda213c4fc2814009461570ccb27d455bbe131f8d948421a71925425b546d8cf63d5458cd64b\",\n    \"0x91c215c73b195795ede2228b7ed1f6e37892e0c6b0f4a0b5a16c57aa1100c84df9239054a173b6110d6c2b7f4bf1ce52\",\n    \"0x88807198910ec1303480f76a3683870246a995e36adaeadc29c22f0bdba8152fe705bd070b75de657b04934f7d0ccf80\",\n    \"0xb37c0026c7b32eb02cacac5b55cb5fe784b8e48b2945c64d3037af83ece556a117f0ff053a5968c2f5fa230e291c1238\",\n    \"0x94c768384ce212bc2387e91ce8b45e4ff120987e42472888a317abc9dcdf3563b62e7a61c8e98d7cdcbe272167d91fc6\",\n    \"0xa10c2564936e967a390cb14ef6e8f8b04ea9ece5214a38837eda09e79e0c7970b1f83adf017c10efd6faa8b7ffa2c567\",\n    \"0xa5085eed3a95f9d4b1269182ea1e0d719b7809bf5009096557a0674bde4201b0ddc1f0f16a908fc468846b3721748ce3\",\n    \"0x87468eb620b79a0a455a259a6b4dfbc297d0d53336537b771254dd956b145dc816b195b7002647ea218552e345818a3f\",\n    \"0xace2b77ffb87366af0a9cb5d27d6fc4a14323dbbf1643f5f3c4559306330d86461bb008894054394cbfaefeaa0bc2745\",\n    \"0xb27f56e840a54fbd793f0b7a7631aa4cee64b5947e4382b2dfb5eb1790270288884c2a19afebe5dc0c6ef335d4531c1c\",\n    \"0x876e438633931f7f895062ee16c4b9d10428875f7bc79a8e156a64d379a77a2c45bf5430c5ab94330f03da352f1e9006\",\n    \"0xa2512a252587d200d2092b44c914df54e04ff8bcef36bf631f84bde0cf5a732e3dc7f00f662842cfd74b0b0f7f24180e\",\n    \"0x827f1bc8f54a35b7a4bd8154f79bcc055e45faed2e74adf7cf21cca95df44d96899e847bd70ead6bb27b9c0ed97bbd8b\",\n    \"0xa0c92cf5a9ed843714f3aea9fe7b880f622d0b4a3bf66de291d1b745279accf6ba35097849691370f41732ba64b5966b\",\n    \"0xa63f5c1e222775658421c487b1256b52626c6f79cb55a9b7deb2352622cedffb08502042d622eb3b02c97f9c09f9c957\",\n    \"0x8cc093d52651e65fb390e186db6cc4de559176af4624d1c44cb9b0e836832419dacac7b8db0627b96288977b738d785d\",\n    \"0xaa7b6a17dfcec146134562d32a12f7bd7fe9522e300859202a02939e69dbd345ed7ff164a184296268f9984f9312e8fc\",\n    \"0x8ac76721f0d2b679f023d06cbd28c85ae5f4b43c614867ccee88651d4101d4fd352dbdb65bf36bfc3ebc0109e4b0c6f9\",\n    \"0x8d350f7c05fc0dcd9a1170748846fb1f5d39453e4cb31e6d1457bed287d96fc393b2ecc53793ca729906a33e59c6834a\",\n    \"0xb9913510dfc5056d7ec5309f0b631d1ec53e3a776412ada9aefdaf033c90da9a49fdde6719e7c76340e86599b1f0eec2\",\n    \"0x94955626bf4ce87612c5cfffcf73bf1c46a4c11a736602b9ba066328dc52ad6d51e6d4f53453d4ed55a51e0aad810271\",\n    \"0xb0fcab384fd4016b2f1e53f1aafd160ae3b1a8865cd6c155d7073ecc1664e05b1d8bca1def39c158c7086c4e1103345e\",\n    \"0x827de3f03edfbde08570b72de6662c8bfa499b066a0a27ebad9b481c273097d17a5a0a67f01553da5392ec3f149b2a78\",\n    \"0xab7940384c25e9027c55c40df20bd2a0d479a165ced9b1046958353cd69015eeb1e44ed2fd64e407805ba42df10fc7bf\",\n    \"0x8ad456f6ff8cd58bd57567d931f923d0c99141978511b17e03cab7390a72b9f62498b2893e1b05c7c22dd274e9a31919\",\n    \"0xac75399e999effe564672db426faa17a839e57c5ef735985c70cd559a377adec23928382767b55ed5a52f7b11b54b756\",\n    \"0xb17f975a00b817299ac7af5f2024ea820351805df58b43724393bfb3920a8cd747a3bbd4b8286e795521489db3657168\",\n    \"0xa2bed800a6d95501674d9ee866e7314063407231491d794f8cf57d5be020452729c1c7cefd8c50dc1540181f5caab248\",\n    \"0x9743f5473171271ffdd3cc59a3ae50545901a7b45cd4bc3570db487865f3b73c0595bebabbfe79268809ee1862e86e4a\",\n    \"0xb7eab77c2d4687b60d9d7b04e842b3880c7940140012583898d39fcc22d9b9b0a9be2c2e3788b3e6f30319b39c338f09\",\n    \"0x8e2b8f797a436a1b661140e9569dcf3e1eea0a77c7ff2bc4ff0f3e49af04ed2de95e255df8765f1d0927fb456a9926b1\",\n    \"0x8aefea201d4a1f4ff98ffce94e540bb313f2d4dfe7e9db484a41f13fc316ed02b282e1acc9bc6f56cad2dc2e393a44c9\",\n    \"0xb950c17c0e5ca6607d182144aa7556bb0efe24c68f06d79d6413a973b493bfdf04fd147a4f1ab03033a32004cc3ea66f\",\n    \"0xb7b8dcbb179a07165f2dc6aa829fad09f582a71b05c3e3ea0396bf9e6fe73076f47035c031c2101e8e38e0d597eadd30\",\n    \"0xa9d77ed89c77ec1bf8335d08d41c3c94dcca9fd1c54f22837b4e54506b212aa38d7440126c80648ab7723ff18e65ed72\",\n    \"0xa819d6dfd4aef70e52b8402fe5d135f8082d40eb7d3bb5c4d7997395b621e2bb10682a1bad2c9caa33dd818550fc3ec6\",\n    \"0x8f6ee34128fac8bbf13ce2d68b2bb363eb4fd65b297075f88e1446ddeac242500eeb4ef0735e105882ff5ba8c44c139b\",\n    \"0xb4440e48255c1644bcecf3a1e9958f1ec4901cb5b1122ee5b56ffd02cad1c29c4266999dbb85aa2605c1b125490074d4\",\n    \"0xa43304a067bede5f347775d5811cf65a6380a8d552a652a0063580b5c5ef12a0867a39c7912fa219e184f4538eba1251\",\n    \"0xa891ad67a790089ffc9f6d53e6a3d63d3556f5f693e0cd8a7d0131db06fd4520e719cfcc3934f0a8f62a95f90840f1d4\",\n    \"0xaea6df8e9bb871081aa0fc5a9bafb00be7d54012c5baf653791907d5042a326aeee966fd9012a582cc16695f5baf7042\",\n    \"0x8ffa2660dc52ed1cd4eff67d6a84a8404f358a5f713d04328922269bee1e75e9d49afeec0c8ad751620f22352a438e25\",\n    \"0x87ec6108e2d63b06abed350f8b363b7489d642486f879a6c3aa90e5b0f335efc2ff2834eef9353951a42136f8e6a1b32\",\n    \"0x865619436076c2760d9e87ddc905023c6de0a8d56eef12c98a98c87837f2ca3f27fd26a2ad752252dbcbe2b9f1d5a032\",\n    \"0x980437dce55964293cb315c650c5586ffd97e7a944a83f6618af31c9d92c37b53ca7a21bb5bc557c151b9a9e217e7098\",\n    \"0x95d128fc369df4ad8316b72aea0ca363cbc7b0620d6d7bb18f7076a8717a6a46956ff140948b0cc4f6d2ce33b5c10054\",\n    \"0x8c7212d4a67b9ec70ebbca04358ad2d36494618d2859609163526d7b3acc2fc935ca98519380f55e6550f70a9bc76862\",\n    \"0x893a2968819401bf355e85eee0f0ed0406a6d4a7d7f172d0017420f71e00bb0ba984f6020999a3cdf874d3cd8ebcd371\",\n    \"0x9103c1af82dece25d87274e89ea0acd7e68c2921c4af3d8d7c82ab0ed9990a5811231b5b06113e7fa43a6bd492b4564f\",\n    \"0x99cfd87a94eab7d35466caa4ed7d7bb45e5c932b2ec094258fb14bf205659f83c209b83b2f2c9ccb175974b2a33e7746\",\n    \"0x874b6b93e4ee61be3f00c32dd84c897ccd6855c4b6251eb0953b4023634490ed17753cd3223472873cbc6095b2945075\",\n    \"0x84a32c0dc4ea60d33aac3e03e70d6d639cc9c4cc435c539eff915017be3b7bdaba33349562a87746291ebe9bc5671f24\",\n    \"0xa7057b24208928ad67914e653f5ac1792c417f413d9176ba635502c3f9c688f7e2ee81800d7e3dc0a340c464da2fd9c5\",\n    \"0xa03fb9ed8286aacfa69fbd5d953bec591c2ae4153400983d5dbb6cd9ea37fff46ca9e5cceb9d117f73e9992a6c055ad2\",\n    \"0x863b2de04e89936c9a4a2b40380f42f20aefbae18d03750fd816c658aee9c4a03df7b12121f795c85d01f415baaeaa59\",\n    \"0x8526eb9bd31790fe8292360d7a4c3eed23be23dd6b8b8f01d2309dbfdc0cfd33ad1568ddd7f8a610f3f85a9dfafc6a92\",\n    \"0xb46ab8c5091a493d6d4d60490c40aa27950574a338ea5bbc045be3a114af87bdcb160a8c80435a9b7ad815f3cb56a3f3\",\n    \"0xaeadc47b41a8d8b4176629557646202f868b1d728b2dda58a347d937e7ffc8303f20d26d6c00b34c851b8aeec547885d\",\n    \"0xaebb19fc424d72c1f1822aa7adc744cd0ef7e55727186f8df8771c784925058c248406ebeeaf3c1a9ee005a26e9a10c6\",\n    \"0x8ff96e81c1a4a2ab1b4476c21018fae0a67e92129ee36120cae8699f2d7e57e891f5c624902cb1b845b944926a605cc3\",\n    \"0x8251b8d2c43fadcaa049a9e7aff838dae4fb32884018d58d46403ac5f3beb5c518bfd45f03b8abb710369186075eb71c\",\n    \"0xa8b2a64f865f51a5e5e86a66455c093407933d9d255d6b61e1fd81ffafc9538d73caaf342338a66ba8ee166372a3d105\",\n    \"0xaad915f31c6ba7fdc04e2aaac62e84ef434b7ee76a325f07dc430d12c84081999720181067b87d792efd0117d7ee1eab\",\n    \"0xa13db3bb60389883fd41d565c54fb5180d9c47ce2fe7a169ae96e01d17495f7f4fa928d7e556e7c74319c4c25d653eb2\",\n    \"0xa4491b0198459b3f552855d680a59214eb74e6a4d6c5fa3b309887dc50ebea2ecf6d26c040550f7dc478b452481466fb\",\n    \"0x8f017f13d4b1e3f0c087843582b52d5f8d13240912254d826dd11f8703a99a2f3166dfbdfdffd9a3492979d77524276b\",\n    \"0x96c3d5dcd032660d50d7cd9db2914f117240a63439966162b10c8f1f3cf74bc83b0f15451a43b31dbd85e4a7ce0e4bb1\",\n    \"0xb479ec4bb79573d32e0ec93b92bdd7ec8c26ddb5a2d3865e7d4209d119fd3499eaac527615ffac78c440e60ef3867ae0\",\n    \"0xb2c49c4a33aa94b52b6410b599e81ff15490aafa7e43c8031c865a84e4676354a9c81eb4e7b8be6825fdcefd1e317d44\",\n    \"0x906dc51d6a90c089b6704b47592805578a6eed106608eeb276832f127e1b8e858b72e448edcbefb497d152447e0e68ff\",\n    \"0xb0e81c63b764d7dfbe3f3fddc9905aef50f3633e5d6a4af6b340495124abedcff5700dfd1577bbbed7b6bf97d02719cb\",\n    \"0x9304c64701e3b4ed6d146e48a881f7d83a17f58357cca0c073b2bb593afd2d94f6e2a7a1ec511d0a67ad6ff4c3be5937\",\n    \"0xb6fdbd12ba05aa598d80b83f70a15ef90e5cba7e6e75fa038540ee741b644cd1f408a6cecfd2a891ef8d902de586c6b5\",\n    \"0xb80557871a6521b1b3c74a1ba083ae055b575df607f1f7b04c867ba8c8c181ea68f8d90be6031f4d25002cca27c44da2\",\n    \"0xaa7285b8e9712e06b091f64163f1266926a36607f9d624af9996856ed2aaf03a580cb22ce407d1ade436c28b44ca173f\",\n    \"0x8148d72b975238b51e6ea389e5486940d22641b48637d7dfadfa603a605bfc6d74a016480023945d0b85935e396aea5d\",\n    \"0x8a014933a6aea2684b5762af43dcf4bdbb633cd0428d42d71167a2b6fc563ece5e618bff22f1db2ddb69b845b9a2db19\",\n    \"0x990d91740041db770d0e0eb9d9d97d826f09fd354b91c41e0716c29f8420e0e8aac0d575231efba12fe831091ec38d5a\",\n    \"0x9454d0d32e7e308ddec57cf2522fb1b67a2706e33fb3895e9e1f18284129ab4f4c0b7e51af25681d248d7832c05eb698\",\n    \"0xa5bd434e75bac105cb3e329665a35bce6a12f71dd90c15165777d64d4c13a82bceedb9b48e762bd24034e0fc9fbe45f4\",\n    \"0xb09e3b95e41800d4dc29c6ffdaab2cd611a0050347f6414f154a47ee20ee59bf8cf7181454169d479ebce1eb5c777c46\",\n    \"0xb193e341d6a047d15eea33766d656d807b89393665a783a316e9ba10518e5515c8e0ade3d6e15641d917a8a172a5a635\",\n    \"0xade435ec0671b3621dde69e07ead596014f6e1daa1152707a8c18877a8b067bde2895dd47444ffa69db2bbef1f1d8816\",\n    \"0xa7fd3d6d87522dfc56fb47aef9ce781a1597c56a8bbfd796baba907afdc872f753d732bfda1d3402aee6c4e0c189f52d\",\n    \"0xa298cb4f4218d0464b2fab393e512bbc477c3225aa449743299b2c3572f065bc3a42d07e29546167ed9e1b6b3b3a3af3\",\n    \"0xa9ee57540e1fd9c27f4f0430d194b91401d0c642456c18527127d1f95e2dba41c2c86d1990432eb38a692fda058fafde\",\n    \"0x81d6c1a5f93c04e6d8e5a7e0678c1fc89a1c47a5c920bcd36180125c49fcf7c114866b90e90a165823560b19898a7c16\",\n    \"0xa4b7a1ec9e93c899b9fd9aaf264c50e42c36c0788d68296a471f7a3447af4dbc81e4fa96070139941564083ec5b5b5a1\",\n    \"0xb3364e327d381f46940c0e11e29f9d994efc6978bf37a32586636c0070b03e4e23d00650c1440f448809e1018ef9f6d8\",\n    \"0x8056e0913a60155348300e3a62e28b5e30629a90f7dd4fe11289097076708110a1d70f7855601782a3cdc5bdb1ca9626\",\n    \"0xb4980fd3ea17bac0ba9ee1c470b17e575bb52e83ebdd7d40c93f4f87bebeaff1c8a679f9d3d09d635f068d37d5bd28bd\",\n    \"0x905a9299e7e1853648e398901dfcd437aa575c826551f83520df62984f5679cb5f0ea86aa45ed3e18b67ddc0dfafe809\",\n    \"0xab99553bf31a84f2e0264eb34a08e13d8d15e2484aa9352354becf9a15999c76cc568d68274b70a65e49703fc23540d0\",\n    \"0xa43681597bc574d2dae8964c9a8dc1a07613d7a1272bdcb818d98c85d44e16d744250c33f3b5e4d552d97396b55e601f\",\n    \"0xa54e5a31716fccb50245898c99865644405b8dc920ded7a11f3d19bdc255996054b268e16f2e40273f11480e7145f41e\",\n    \"0x8134f3ad5ef2ad4ba12a8a4e4d8508d91394d2bcdc38b7c8c8c0b0a820357ac9f79d286c65220f471eb1adca1d98fc68\",\n    \"0x94e2f755e60471578ab2c1adb9e9cea28d4eec9b0e92e0140770bca7002c365fcabfe1e5fb4fe6cfe79a0413712aa3ef\",\n    \"0xad48f8d0ce7eb3cc6e2a3086ad96f562e5bed98a360721492ae2e74dc158586e77ec8c35d5fd5927376301b7741bad2b\",\n    \"0x8614f0630bdd7fbad3a31f55afd9789f1c605dc85e7dc67e2edfd77f5105f878bb79beded6e9f0b109e38ea7da67e8d5\",\n    \"0x9804c284c4c5e77dabb73f655b12181534ca877c3e1e134aa3f47c23b7ec92277db34d2b0a5d38d2b69e5d1c3008a3e3\",\n    \"0xa51b99c3088e473afdaa9e0a9f7e75a373530d3b04e44e1148da0726b95e9f5f0c7e571b2da000310817c36f84b19f7f\",\n    \"0xac4ff909933b3b76c726b0a382157cdc74ab851a1ac6cef76953c6444441804cc43abb883363f416592e8f6cfbc4550b\",\n    \"0xae7d915eb9fc928b65a29d6edbc75682d08584d0014f7bcf17d59118421ae07d26a02137d1e4de6938bcd1ab8ef48fad\",\n    \"0x852f7e453b1af89b754df6d11a40d5d41ea057376e8ecacd705aacd2f917457f4a093d6b9a8801837fa0f62986ad7149\",\n    \"0x92c6bf5ada5d0c3d4dd8058483de36c215fa98edab9d75242f3eff9db07c734ad67337da6f0eefe23a487bf75a600dee\",\n    \"0xa2b42c09d0db615853763552a48d2e704542bbd786aae016eb58acbf6c0226c844f5fb31e428cb6450b9db855f8f2a6f\",\n    \"0x880cc07968266dbfdcfbc21815cd69e0eddfee239167ac693fb0413912d816f2578a74f7716eecd6deefa68c6eccd394\",\n    \"0xb885b3ace736cd373e8098bf75ba66fa1c6943ca1bc4408cd98ac7074775c4478594f91154b8a743d9c697e1b29f5840\",\n    \"0xa51ce78de512bd87bfa0835de819941dffbf18bec23221b61d8096fc9436af64e0693c335b54e7bfc763f287bdca2db6\",\n    \"0xa3c76166a3bdb9b06ef696e57603b58871bc72883ee9d45171a30fe6e1d50e30bc9c51b4a0f5a7270e19a77b89733850\",\n    \"0xacefc5c6f8a1e7c24d7b41e0fc7f6f3dc0ede6cf3115ffb9a6e54b1d954cbca9bda8ad7a084be9be245a1b8e9770d141\",\n    \"0xb420ed079941842510e31cfad117fa11fb6b4f97dfbc6298cb840f27ebaceba23eeaf3f513bcffbf5e4aae946310182d\",\n    \"0x95c3bb5ef26c5ed2f035aa5d389c6b3c15a6705b9818a3fefaed28922158b35642b2e8e5a1a620fdad07e75ad4b43af4\",\n    \"0x825149f9081ecf07a2a4e3e8b5d21bade86c1a882475d51c55ee909330b70c5a2ac63771c8600c6f38df716af61a3ea1\",\n    \"0x873b935aae16d9f08adbc25353cee18af2f1b8d5f26dec6538d6bbddc515f2217ed7d235dcfea59ae61b428798b28637\",\n    \"0x9294150843a2bedcedb3bb74c43eb28e759cf9499582c5430bccefb574a8ddd4f11f9929257ff4c153990f9970a2558f\",\n    \"0xb619563a811cc531da07f4f04e5c4c6423010ff9f8ed7e6ec9449162e3d501b269fb1c564c09c0429431879b0f45df02\",\n    \"0x91b509b87eb09f007d839627514658c7341bc76d468920fe8a740a8cb96a7e7e631e0ea584a7e3dc1172266f641d0f5c\",\n    \"0x8b8aceace9a7b9b4317f1f01308c3904d7663856946afbcea141a1c615e21ccad06b71217413e832166e9dd915fbe098\",\n    \"0x87b3b36e725833ea0b0f54753c3728c0dbc87c52d44d705ffc709f2d2394414c652d3283bab28dcce09799504996cee0\",\n    \"0xb2670aad5691cbf308e4a6a77a075c4422e6cbe86fdba24e9f84a313e90b0696afb6a067eebb42ba2d10340d6a2f6e51\",\n    \"0x876784a9aff3d54faa89b2bacd3ff5862f70195d0b2edc58e8d1068b3c9074c0da1cfa23671fe12f35e33b8a329c0ccd\",\n    \"0x8b48b9e758e8a8eae182f5cbec96f67d20cca6d3eee80a2d09208eb1d5d872e09ef23d0df8ebbb9b01c7449d0e3e3650\",\n    \"0xb79303453100654c04a487bdcadc9e3578bc80930c489a7069a52e8ca1dba36c492c8c899ce025f8364599899baa287d\",\n    \"0x961b35a6111da54ece6494f24dacd5ea46181f55775b5f03df0e370c34a5046ac2b4082925855325bb42bc2a2c98381d\",\n    \"0xa31feb1be3f5a0247a1f7d487987eb622e34fca817832904c6ee3ee60277e5847945a6f6ea1ac24542c72e47bdf647df\",\n    \"0xa12a2aa3e7327e457e1aae30e9612715dd2cfed32892c1cd6dcda4e9a18203af8a44afb46d03b2eed89f6b9c5a2c0c23\",\n    \"0xa08265a838e69a2ca2f80fead6ccf16f6366415b920c0b22ee359bcd8d4464ecf156f400a16a7918d52e6d733dd64211\",\n    \"0xb723d6344e938d801cca1a00032af200e541d4471fd6cbd38fb9130daa83f6a1dffbbe7e67fc20f9577f884acd7594b2\",\n    \"0xa6733d83ec78ba98e72ddd1e7ff79b7adb0e559e256760d0c590a986e742445e8cdf560d44b29439c26d87edd0b07c8c\",\n    \"0xa61c2c27d3f7b9ff4695a17afedf63818d4bfba390507e1f4d0d806ce8778d9418784430ce3d4199fd3bdbc2504d2af3\",\n    \"0x8332f3b63a6dc985376e8b1b25eeae68be6160fbe40053ba7bcf6f073204f682da72321786e422d3482fd60c9e5aa034\",\n    \"0xa280f44877583fbb6b860d500b1a3f572e3ee833ec8f06476b3d8002058e25964062feaa1e5bec1536d734a5cfa09145\",\n    \"0xa4026a52d277fcea512440d2204f53047718ebfcae7b48ac57ea7f6bfbc5de9d7304db9a9a6cbb273612281049ddaec5\",\n    \"0x95cdf69c831ab2fad6c2535ede9c07e663d2ddccc936b64e0843d2df2a7b1c31f1759c3c20f1e7a57b1c8f0dbb21b540\",\n    \"0x95c96cec88806469c277ab567863c5209027cecc06c7012358e5f555689c0d9a5ffb219a464f086b45817e8536b86d2f\",\n    \"0xafe38d4684132a0f03d806a4c8df556bf589b25271fbc6fe2e1ed16de7962b341c5003755da758d0959d2e6499b06c68\",\n    \"0xa9b77784fda64987f97c3a23c5e8f61b918be0f7c59ba285084116d60465c4a2aaafc8857eb16823282cc83143eb9126\",\n    \"0xa830f05881ad3ce532a55685877f529d32a5dbe56cea57ffad52c4128ee0fad0eeaf0da4362b55075e77eda7babe70e5\",\n    \"0x992b3ad190d6578033c13ed5abfee4ef49cbc492babb90061e3c51ee4b5790cdd4c8fc1abff1fa2c00183b6b64f0bbbe\",\n    \"0xb1015424d9364aeff75de191652dc66484fdbec3e98199a9eb9671ec57bec6a13ff4b38446e28e4d8aedb58dd619cd90\",\n    \"0xa745304604075d60c9db36cada4063ac7558e7ec2835d7da8485e58d8422e817457b8da069f56511b02601289fbb8981\",\n    \"0xa5ba4330bc5cb3dbe0486ddf995632a7260a46180a08f42ae51a2e47778142132463cc9f10021a9ad36986108fefa1a9\",\n    \"0xb419e9fd4babcaf8180d5479db188bb3da232ae77a1c4ed65687c306e6262f8083070a9ac32220cddb3af2ec73114092\",\n    \"0xa49e23dc5f3468f3bf3a0bb7e4a114a788b951ff6f23a3396ae9e12cbff0abd1240878a3d1892105413dbc38818e807c\",\n    \"0xb7ecc7b4831f650202987e85b86bc0053f40d983f252e9832ef503aea81c51221ce93279da4aa7466c026b2d2070e55d\",\n    \"0x96a8c35cb87f84fa84dcd6399cc2a0fd79cc9158ef4bdde4bae31a129616c8a9f2576cd19baa3f497ca34060979aed7d\",\n    \"0x8681b2c00aa62c2b519f664a95dcb8faef601a3b961bb4ce5d85a75030f40965e2983871d41ea394aee934e859581548\",\n    \"0x85c229a07efa54a713d0790963a392400f55fbb1a43995a535dc6c929f20d6a65cf4efb434e0ad1cb61f689b8011a3bc\",\n    \"0x90856f7f3444e5ad44651c28e24cc085a5db4d2ffe79aa53228c26718cf53a6e44615f3c5cda5aa752d5f762c4623c66\",\n    \"0x978999b7d8aa3f28a04076f74d11c41ef9c89fdfe514936c4238e0f13c38ec97e51a5c078ebc6409e517bfe7ccb42630\",\n    \"0xa099914dd7ed934d8e0d363a648e9038eb7c1ec03fa04dbcaa40f7721c618c3ef947afef7a16b4d7ac8c12aa46637f03\",\n    \"0xab2a104fed3c83d16f2cda06878fa5f30c8c9411de71bfb67fd2fc9aa454dcbcf3d299d72f8cc12e919466a50fcf7426\",\n    \"0xa4471d111db4418f56915689482f6144efc4664cfb0311727f36c864648d35734351becc48875df96f4abd3cfcf820f9\",\n    \"0x83be11727cd30ea94ccc8fa31b09b81c9d6a9a5d3a4686af9da99587332fe78c1f94282f9755854bafd6033549afec91\",\n    \"0x88020ff971dc1a01a9e993cd50a5d2131ffdcbb990c1a6aaa54b20d8f23f9546a70918ea57a21530dcc440c1509c24ad\",\n    \"0xae24547623465e87905eaffa1fa5d52bb7c453a8dbd89614fa8819a2abcedaf455c2345099b7324ae36eb0ad7c8ef977\",\n    \"0xb59b0c60997de1ee00b7c388bc7101d136c9803bf5437b1d589ba57c213f4f835a3e4125b54738e78abbc21b000f2016\",\n    \"0xa584c434dfe194546526691b68fa968c831c31da42303a1d735d960901c74011d522246f37f299555416b8cf25c5a548\",\n    \"0x80408ce3724f4837d4d52376d255e10f69eb8558399ae5ca6c11b78b98fe67d4b93157d2b9b639f1b5b64198bfe87713\",\n    \"0xabb941e8d406c2606e0ddc35c113604fdd9d249eacc51cb64e2991e551b8639ce44d288cc92afa7a1e7fc599cfc84b22\",\n    \"0xb223173f560cacb1c21dba0f1713839e348ad02cbfdef0626748604c86f89e0f4c919ed40b583343795bdd519ba952c8\",\n    \"0xaf1c70512ec3a19d98b8a1fc3ff7f7f5048a27d17d438d43f561974bbdd116fcd5d5c21040f3447af3f0266848d47a15\",\n    \"0x8a44809568ebe50405bede19b4d2607199159b26a1b33e03d180e6840c5cf59d991a4fb150d111443235d75ecad085b7\",\n    \"0xb06207cdca46b125a27b3221b5b50cf27af4c527dd7c80e2dbcebbb09778a96df3af67e50f07725239ce3583dad60660\",\n    \"0x993352d9278814ec89b26a11c4a7c4941bf8f0e6781ae79559d14749ee5def672259792db4587f85f0100c7bb812f933\",\n    \"0x9180b8a718b971fd27bc82c8582d19c4b4f012453e8c0ffeeeffe745581fc6c07875ab28be3af3fa3896d19f0c89ac5b\",\n    \"0x8b8e1263eb48d0fe304032dd5ea1f30e73f0121265f7458ba9054d3626894e8a5fef665340abd2ede9653045c2665938\",\n    \"0x99a2beee4a10b7941c24b2092192faf52b819afd033e4a2de050fd6c7f56d364d0cf5f99764c3357cf32399e60fc5d74\",\n    \"0x946a4aad7f8647ea60bee2c5fcdeb6f9a58fb2cfca70c4d10e458027a04846e13798c66506151be3df9454b1e417893f\",\n    \"0xa672a88847652d260b5472d6908d1d57e200f1e492d30dd1cecc441cdfc9b76e016d9bab560efd4d7f3c30801de884a9\",\n    \"0x9414e1959c156cde1eb24e628395744db75fc24b9df4595350aaad0bc38e0246c9b4148f6443ef68b8e253a4a6bcf11c\",\n    \"0x9316e9e4ec5fab4f80d6540df0e3a4774db52f1d759d2e5b5bcd3d7b53597bb007eb1887cb7dc61f62497d51ffc8d996\",\n    \"0x902d6d77bb49492c7a00bc4b70277bc28c8bf9888f4307bb017ac75a962decdedf3a4e2cf6c1ea9f9ba551f4610cbbd7\",\n    \"0xb07025a18b0e32dd5e12ec6a85781aa3554329ea12c4cd0d3b2c22e43d777ef6f89876dd90a9c8fb097ddf61cf18adc5\",\n    \"0xb355a849ad3227caa4476759137e813505ec523cbc2d4105bc7148a4630f9e81918d110479a2d5f5e4cd9ccec9d9d3e3\",\n    \"0xb49532cfdf02ee760109881ad030b89c48ee3bb7f219ccafc13c93aead754d29bdafe345be54c482e9d5672bd4505080\",\n    \"0x9477802410e263e4f938d57fa8f2a6cac7754c5d38505b73ee35ea3f057aad958cb9722ba6b7b3cfc4524e9ca93f9cdc\",\n    \"0x9148ea83b4436339580f3dbc9ba51509e9ab13c03063587a57e125432dd0915f5d2a8f456a68f8fff57d5f08c8f34d6e\",\n    \"0xb00b6b5392b1930b54352c02b1b3b4f6186d20bf21698689bbfc7d13e86538a4397b90e9d5c93fd2054640c4dbe52a4f\",\n    \"0x926a9702500441243cd446e7cbf15dde16400259726794694b1d9a40263a9fc9e12f7bcbf12a27cb9aaba9e2d5848ddc\",\n    \"0xa0c6155f42686cbe7684a1dc327100962e13bafcf3db97971fc116d9f5c0c8355377e3d70979cdbd58fd3ea52440901c\",\n    \"0xa277f899f99edb8791889d0817ea6a96c24a61acfda3ad8c3379e7c62b9d4facc4b965020b588651672fd261a77f1bfc\",\n    \"0x8f528cebb866b501f91afa50e995234bef5bf20bff13005de99cb51eaac7b4f0bf38580cfd0470de40f577ead5d9ba0f\",\n    \"0x963fc03a44e9d502cc1d23250efef44d299befd03b898d07ce63ca607bb474b5cf7c965a7b9b0f32198b04a8393821f7\",\n    \"0xab087438d0a51078c378bf4a93bd48ef933ff0f1fa68d02d4460820df564e6642a663b5e50a5fe509527d55cb510ae04\",\n    \"0xb0592e1f2c54746bb076be0fa480e1c4bebc4225e1236bcda3b299aa3853e3afb401233bdbcfc4a007b0523a720fbf62\",\n    \"0x851613517966de76c1c55a94dc4595f299398a9808f2d2f0a84330ba657ab1f357701d0895f658c18a44cb00547f6f57\",\n    \"0xa2fe9a1dd251e72b0fe4db27be508bb55208f8f1616b13d8be288363ec722826b1a1fd729fc561c3369bf13950bf1fd6\",\n    \"0xb896cb2bc2d0c77739853bc59b0f89b2e008ba1f701c9cbe3bef035f499e1baee8f0ff1e794854a48c320586a2dfc81a\",\n    \"0xa1b60f98e5e5106785a9b81a85423452ee9ef980fa7fa8464f4366e73f89c50435a0c37b2906052b8e58e212ebd366cf\",\n    \"0xa853b0ebd9609656636df2e6acd5d8839c0fda56f7bf9288a943b06f0b67901a32b95e016ca8bc99bd7b5eab31347e72\",\n    \"0xb290fa4c1346963bd5225235e6bdf7c542174dab4c908ab483d1745b9b3a6015525e398e1761c90e4b49968d05e30eea\",\n    \"0xb0f65a33ad18f154f1351f07879a183ad62e5144ad9f3241c2d06533dad09cbb2253949daff1bb02d24d16a3569f7ef0\",\n    \"0xa00db59b8d4218faf5aeafcd39231027324408f208ec1f54d55a1c41228b463b88304d909d16b718cfc784213917b71e\",\n    \"0xb8d695dd33dc2c3bc73d98248c535b2770ad7fa31aa726f0aa4b3299efb0295ba9b4a51c71d314a4a1bd5872307534d1\",\n    \"0xb848057cca2ca837ee49c42b88422303e58ea7d2fc76535260eb5bd609255e430514e927cc188324faa8e657396d63ec\",\n    \"0x92677836061364685c2aaf0313fa32322746074ed5666fd5f142a7e8f87135f45cd10e78a17557a4067a51dfde890371\",\n    \"0xa854b22c9056a3a24ab164a53e5c5cf388616c33e67d8ebb4590cb16b2e7d88b54b1393c93760d154208b5ca822dc68f\",\n    \"0x86fff174920388bfab841118fb076b2b0cdec3fdb6c3d9a476262f82689fb0ed3f1897f7be9dbf0932bb14d346815c63\",\n    \"0x99661cf4c94a74e182752bcc4b98a8c2218a8f2765642025048e12e88ba776f14f7be73a2d79bd21a61def757f47f904\",\n    \"0x8a8893144d771dca28760cba0f950a5d634195fd401ec8cf1145146286caffb0b1a6ba0c4c1828d0a5480ce49073c64c\",\n    \"0x938a59ae761359ee2688571e7b7d54692848eb5dde57ffc572b473001ea199786886f8c6346a226209484afb61d2e526\",\n    \"0x923f68a6aa6616714cf077cf548aeb845bfdd78f2f6851d8148cba9e33a374017f2f3da186c39b82d14785a093313222\",\n    \"0xac923a93d7da7013e73ce8b4a2b14b8fd0cc93dc29d5de941a70285bdd19be4740fedfe0c56b046689252a3696e9c5bc\",\n    \"0xb49b32c76d4ec1a2c68d4989285a920a805993bc6fcce6dacd3d2ddae73373050a5c44ba8422a3781050682fa0ef6ba2\",\n    \"0x8a367941c07c3bdca5712524a1411bad7945c7c48ffc7103b1d4dff2c25751b0624219d1ccde8c3f70c465f954be5445\",\n    \"0xb838f029df455efb6c530d0e370bbbf7d87d61a9aea3d2fe5474c5fe0a39cf235ceecf9693c5c6c5820b1ba8f820bd31\",\n    \"0xa8983b7c715eaac7f13a001d2abc462dfc1559dab4a6b554119c271aa8fe00ffcf6b6949a1121f324d6d26cb877bcbae\",\n    \"0xa2afb24ad95a6f14a6796315fbe0d8d7700d08f0cfaf7a2abe841f5f18d4fecf094406cbd54da7232a159f9c5b6e805e\",\n    \"0x87e8e95ad2d62f947b2766ff405a23f7a8afba14e7f718a691d95369c79955cdebe24c54662553c60a3f55e6322c0f6f\",\n    \"0x87c2cbcecb754e0cc96128e707e5c5005c9de07ffd899efa3437cadc23362f5a1d3fcdd30a1f5bdc72af3fb594398c2a\",\n    \"0x91afd6ee04f0496dc633db88b9370d41c428b04fd991002502da2e9a0ef051bcd7b760e860829a44fbe5539fa65f8525\",\n    \"0x8c50e5d1a24515a9dd624fe08b12223a75ca55196f769f24748686315329b337efadca1c63f88bee0ac292dd0a587440\",\n    \"0x8a07e8f912a38d94309f317c32068e87f68f51bdfa082d96026f5f5f8a2211621f8a3856dda8069386bf15fb2d28c18f\",\n    \"0x94ad1dbe341c44eeaf4dc133eed47d8dbfe752575e836c075745770a6679ff1f0e7883b6aa917462993a7f469d74cab5\",\n    \"0x8745f8bd86c2bb30efa7efb7725489f2654f3e1ac4ea95bd7ad0f3cfa223055d06c187a16192d9d7bdaea7b050c6a324\",\n    \"0x900d149c8d79418cda5955974c450a70845e02e5a4ecbcc584a3ca64d237df73987c303e3eeb79da1af83bf62d9e579f\",\n    \"0x8f652ab565f677fb1a7ba03b08004e3cda06b86c6f1b0b9ab932e0834acf1370abb2914c15b0d08327b5504e5990681c\",\n    \"0x9103097d088be1f75ab9d3da879106c2f597e2cc91ec31e73430647bdd5c33bcfd771530d5521e7e14df6acda44f38a6\",\n    \"0xb0fec7791cfb0f96e60601e1aeced9a92446b61fedab832539d1d1037558612d78419efa87ff5f6b7aab8fd697d4d9de\",\n    \"0xb9d2945bdb188b98958854ba287eb0480ef614199c4235ce5f15fc670b8c5ffe8eeb120c09c53ea8a543a022e6a321ac\",\n    \"0xa9461bb7d5490973ebaa51afc0bb4a5e42acdccb80e2f939e88b77ac28a98870e103e1042899750f8667a8cc9123bae9\",\n    \"0xa37fdf11d4bcb2aed74b9f460a30aa34afea93386fa4cdb690f0a71bc58f0b8df60bec56e7a24f225978b862626fa00e\",\n    \"0xa214420e183e03d531cf91661466ea2187d84b6e814b8b20b3730a9400a7d25cf23181bb85589ebc982cec414f5c2923\",\n    \"0xad09a45a698a6beb3e0915f540ef16e9af7087f53328972532d6b5dfe98ce4020555ece65c6cbad8bd6be8a4dfefe6fd\",\n    \"0xab6742800b02728c92d806976764cb027413d6f86edd08ad8bb5922a2969ee9836878cd39db70db0bd9a2646862acc4f\",\n    \"0x974ca9305bd5ea1dc1755dff3b63e8bfe9f744321046c1395659bcea2a987b528e64d5aa96ac7b015650b2253b37888d\",\n    \"0x84eee9d6bce039c52c2ebc4fccc0ad70e20c82f47c558098da4be2f386a493cbc76adc795b5488c8d11b6518c2c4fab8\",\n    \"0x875d7bda46efcb63944e1ccf760a20144df3b00d53282b781e95f12bfc8f8316dfe6492c2efbf796f1150e36e436e9df\",\n    \"0xb68a2208e0c587b5c31b5f6cb32d3e6058a9642e2d9855da4f85566e1412db528475892060bb932c55b3a80877ad7b4a\",\n    \"0xba006368ecab5febb6ab348644d9b63de202293085ed468df8bc24d992ae8ce468470aa37f36a73630c789fb9c819b30\",\n    \"0x90a196035150846cd2b482c7b17027471372a8ce7d914c4d82b6ea7fa705d8ed5817bd42d63886242585baf7d1397a1c\",\n    \"0xa223b4c85e0daa8434b015fd9170b5561fe676664b67064974a1e9325066ecf88fc81f97ab5011c59fad28cedd04b240\",\n    \"0x82e8ec43139cf15c6bbeed484b62e06cded8a39b5ce0389e4cbe9c9e9c02f2f0275d8d8d4e8dfec8f69a191bef220408\",\n    \"0x81a3fc07a7b68d92c6ee4b6d28f5653ee9ec85f7e2ee1c51c075c1b130a8c5097dc661cf10c5aff1c7114b1a6a19f11a\",\n    \"0x8ed2ef8331546d98819a5dd0e6c9f8cb2630d0847671314a28f277faf68da080b53891dd75c82cbcf7788b255490785d\",\n    \"0xacecabf84a6f9bbed6b2fc2e7e4b48f02ef2f15e597538a73aea8f98addc6badda15e4695a67ecdb505c1554e8f345ec\",\n    \"0xb8f51019b2aa575f8476e03dcadf86cc8391f007e5f922c2a36b2daa63f5a503646a468990cd5c65148d323942193051\",\n    \"0xaaa595a84b403ec65729bc1c8055a94f874bf9adddc6c507b3e1f24f79d3ad359595a672b93aab3394db4e2d4a7d8970\",\n    \"0x895144c55fcbd0f64d7dd69e6855cfb956e02b5658eadf0f026a70703f3643037268fdd673b0d21b288578a83c6338dd\",\n    \"0xa2e92ae6d0d237d1274259a8f99d4ea4912a299816350b876fba5ebc60b714490e198a916e1c38c6e020a792496fa23c\",\n    \"0xa45795fda3b5bb0ad1d3c628f6add5b2a4473a1414c1a232e80e70d1cfffd7f8a8d9861f8df2946999d7dbb56bf60113\",\n    \"0xb6659bf7f6f2fef61c39923e8c23b8c70e9c903028d8f62516d16755cd3fba2fe41c285aa9432dc75ab08f8a1d8a81fc\",\n    \"0xa735609a6bc5bfd85e58234fc439ff1f58f1ff1dd966c5921d8b649e21f006bf2b8642ad8a75063c159aaf6935789293\",\n    \"0xa3c622eb387c9d15e7bda2e3e84d007cb13a6d50d655c3f2f289758e49d3b37b9a35e4535d3cc53d8efd51f407281f19\",\n    \"0x8afe147b53ad99220f5ef9d763bfc91f9c20caecbcf823564236fb0e6ede49414c57d71eec4772c8715cc65a81af0047\",\n    \"0xb5f0203233cf71913951e9c9c4e10d9243e3e4a1f2cb235bf3f42009120ba96e04aa414c9938ea8873b63148478927e8\",\n    \"0x93c52493361b458d196172d7ba982a90a4f79f03aa8008edc322950de3ce6acf4c3977807a2ffa9e924047e02072b229\",\n    \"0xb9e72b805c8ac56503f4a86c82720afbd5c73654408a22a2ac0b2e5caccdfb0e20b59807433a6233bc97ae58cf14c70a\",\n    \"0xaf0475779b5cee278cca14c82da2a9f9c8ef222eb885e8c50cca2315fea420de6e04146590ed0dd5a29c0e0812964df5\",\n    \"0xb430ccab85690db02c2d0eb610f3197884ca12bc5f23c51e282bf3a6aa7e4a79222c3d8761454caf55d6c01a327595f9\",\n    \"0x830032937418b26ee6da9b5206f3e24dc76acd98589e37937e963a8333e5430abd6ce3dd93ef4b8997bd41440eed75d6\",\n    \"0x8820a6d73180f3fe255199f3f175c5eb770461ad5cfdde2fb11508041ed19b8c4ce66ad6ecebf7d7e836cc2318df47ca\",\n    \"0xaef1393e7d97278e77bbf52ef6e1c1d5db721ccf75fe753cf47a881fa034ca61eaa5098ee5a344c156d2b14ff9e284ad\",\n    \"0x8a4a26c07218948c1196c45d927ef4d2c42ade5e29fe7a91eaebe34a29900072ce5194cf28d51f746f4c4c649daf4396\",\n    \"0x84011dc150b7177abdcb715efbd8c201f9cb39c36e6069af5c50a096021768ba40cef45b659c70915af209f904ede3b6\",\n    \"0xb1bd90675411389bb66910b21a4bbb50edce5330850c5ab0b682393950124252766fc81f5ecfc72fb7184387238c402e\",\n    \"0x8dfdcd30583b696d2c7744655f79809f451a60c9ad5bf1226dc078b19f4585d7b3ef7fa9d54e1ac09520d95cbfd20928\",\n    \"0xb351b4dc6d98f75b8e5a48eb7c6f6e4b78451991c9ba630e5a1b9874c15ac450cd409c1a024713bf2cf82dc400e025ef\",\n    \"0xa462b8bc97ac668b97b28b3ae24b9f5de60e098d7b23ecb600d2194cd35827fb79f77c3e50d358f5bd72ee83fef18fa0\",\n    \"0xa183753265c5f7890270821880cce5f9b2965b115ba783c6dba9769536f57a04465d7da5049c7cf8b3fcf48146173c18\",\n    \"0xa8a771b81ed0d09e0da4d79f990e58eabcd2be3a2680419502dd592783fe52f657fe55125b385c41d0ba3b9b9cf54a83\",\n    \"0xa71ec577db46011689d073245e3b1c3222a9b1fe6aa5b83629adec5733dd48617ebea91346f0dd0e6cdaa86e4931b168\",\n    \"0xa334b8b244f0d598a02da6ae0f918a7857a54dce928376c4c85df15f3b0f2ba3ac321296b8b7c9dd47d770daf16c8f8c\",\n    \"0xa29037f8ef925c417c90c4df4f9fb27fb977d04e2b3dd5e8547d33e92ab72e7a00f5461de21e28835319eae5db145eb7\",\n    \"0xb91054108ae78b00e3298d667b913ebc44d8f26e531eae78a8fe26fdfb60271c97efb2dee5f47ef5a3c15c8228138927\",\n    \"0x926c13efbe90604f6244be9315a34f72a1f8d1aab7572df431998949c378cddbf2fe393502c930fff614ff06ae98a0ce\",\n    \"0x995c758fd5600e6537089b1baa4fbe0376ab274ff3e82a17768b40df6f91c2e443411de9cafa1e65ea88fb8b87d504f4\",\n    \"0x9245ba307a7a90847da75fca8d77ec03fdfc812c871e7a2529c56a0a79a6de16084258e7a9ac4ae8a3756f394336e21c\",\n    \"0x99e0cfa2bb57a7e624231317044c15e52196ecce020db567c8e8cb960354a0be9862ee0c128c60b44777e65ac315e59f\",\n    \"0xad4f6b3d27bbbb744126601053c3dc98c07ff0eb0b38a898bd80dce778372846d67e5ab8fb34fb3ad0ef3f235d77ba7f\",\n    \"0xa0f12cae3722bbbca2e539eb9cc7614632a2aefe51410430070a12b5bc5314ecec5857b7ff8f41e9980cac23064f7c56\",\n    \"0xb487f1bc59485848c98222fd3bc36c8c9bb3d2912e2911f4ceca32c840a7921477f9b1fe00877e05c96c75d3eecae061\",\n    \"0xa6033db53925654e18ecb3ce715715c36165d7035db9397087ac3a0585e587998a53973d011ac6d48af439493029cee6\",\n    \"0xa6b4d09cd01c70a3311fd131d3710ccf97bde3e7b80efd5a8c0eaeffeb48cca0f951ced905290267b115b06d46f2693b\",\n    \"0xa9dff1df0a8f4f218a98b6f818a693fb0d611fed0fc3143537cbd6578d479af13a653a8155e535548a2a0628ae24fa58\",\n    \"0xa58e469f65d366b519f9a394cacb7edaddac214463b7b6d62c2dbc1316e11c6c5184ce45c16de2d77f990dcdd8b55430\",\n    \"0x989e71734f8119103586dc9a3c5f5033ddc815a21018b34c1f876cdfc112efa868d5751bf6419323e4e59fa6a03ece1c\",\n    \"0xa2da00e05036c884369e04cf55f3de7d659cd5fa3f849092b2519dd263694efe0f051953d9d94b7e121f0aee8b6174d7\",\n    \"0x968f3c029f57ee31c4e1adea89a7f92e28483af9a74f30fbdb995dc2d40e8e657dff8f8d340d4a92bf65f54440f2859f\",\n    \"0x932778df6f60ac1639c1453ef0cbd2bf67592759dcccb3e96dcc743ff01679e4c7dd0ef2b0833dda548d32cb4eba49e2\",\n    \"0xa805a31139f8e0d6dae1ac87d454b23a3dc9fc653d4ca18d4f8ebab30fc189c16e73981c2cb7dd6f8c30454a5208109d\",\n    \"0xa9ba0991296caa2aaa4a1ceacfb205544c2a2ec97088eace1d84ee5e2767656a172f75d2f0c4e16a3640a0e0dec316e0\",\n    \"0xb1e49055c968dced47ec95ae934cf45023836d180702e20e2df57e0f62fb85d7ac60d657ba3ae13b8560b67210449459\",\n    \"0xa94e1da570a38809c71e37571066acabff7bf5632737c9ab6e4a32856924bf6211139ab3cedbf083850ff2d0e0c0fcfc\",\n    \"0x88ef1bb322000c5a5515b310c838c9af4c1cdbb32eab1c83ac3b2283191cd40e9573747d663763a28dad0d64adc13840\",\n    \"0xa987ce205f923100df0fbd5a85f22c9b99b9b9cbe6ddfa8dfda1b8fe95b4f71ff01d6c5b64ca02eb24edb2b255a14ef0\",\n    \"0x84fe8221a9e95d9178359918a108de4763ebfa7a6487facb9c963406882a08a9a93f492f8e77cf9e7ea41ae079c45993\",\n    \"0xaa1cf3dc7c5dcfa15bbbc811a4bb6dbac4fba4f97fb1ed344ab60264d7051f6eef19ea9773441d89929ee942ed089319\",\n    \"0x8f6a7d610d59d9f54689bbe6a41f92d9f6096cde919c1ab94c3c7fcecf0851423bc191e5612349e10f855121c0570f56\",\n    \"0xb5af1fa7894428a53ea520f260f3dc3726da245026b6d5d240625380bfb9c7c186df0204bb604efac5e613a70af5106e\",\n    \"0xa5bce6055ff812e72ce105f147147c7d48d7a2313884dd1f488b1240ee320f13e8a33f5441953a8e7a3209f65b673ce1\",\n    \"0xb9b55b4a1422677d95821e1d042ab81bbf0bf087496504021ec2e17e238c2ca6b44fb3b635a5c9eac0871a724b8d47c3\",\n    \"0x941c38e533ce4a673a3830845b56786585e5fe49c427f2e5c279fc6db08530c8f91db3e6c7822ec6bb4f956940052d18\",\n    \"0xa38e191d66c625f975313c7007bbe7431b5a06ed2da1290a7d5d0f2ec73770d476efd07b8e632de64597d47df175cbb0\",\n    \"0x94ba76b667abf055621db4c4145d18743a368d951565632ed4e743dd50dd3333507c0c34f286a5c5fdbf38191a2255cd\",\n    \"0xa5ca38c60be5602f2bfa6e00c687ac96ac36d517145018ddbee6f12eb0faa63dd57909b9eeed26085fe5ac44e55d10ab\",\n    \"0xb00fea3b825e60c1ed1c5deb4b551aa65a340e5af36b17d5262c9cd2c508711e4dc50dc2521a2c16c7c901902266e64a\",\n    \"0x971b86fc4033485e235ccb0997a236206ba25c6859075edbcdf3c943116a5030b7f75ebca9753d863a522ba21a215a90\",\n    \"0xb3b31f52370de246ee215400975b674f6da39b2f32514fe6bd54e747752eedca22bb840493b44a67df42a3639c5f901f\",\n    \"0xaffbbfac9c1ba7cbfa1839d2ae271dd6149869b75790bf103230637da41857fc326ef3552ff31c15bda0694080198143\",\n    \"0xa95d42aa7ef1962520845aa3688f2752d291926f7b0d73ea2ee24f0612c03b43f2b0fe3c9a9a99620ffc8d487b981bc2\",\n    \"0x914a266065caf64985e8c5b1cb2e3f4e3fe94d7d085a1881b1fefa435afef4e1b39a98551d096a62e4f5cc1a7f0fdc2e\",\n    \"0x81a0b4a96e2b75bc1bf2dbd165d58d55cfd259000a35504d1ffb18bc346a3e6f07602c683723864ffb980f840836fd8d\",\n    \"0x91c1556631cddd4c00b65b67962b39e4a33429029d311c8acf73a18600e362304fb68bccb56fde40f49e95b7829e0b87\",\n    \"0x8befbacc19e57f7c885d1b7a6028359eb3d80792fe13b92a8400df21ce48deb0bb60f2ddb50e3d74f39f85d7eab23adc\",\n    \"0x92f9458d674df6e990789690ec9ca73dacb67fc9255b58c417c555a8cc1208ace56e8e538f86ba0f3615573a0fbac00d\",\n    \"0xb4b1b3062512d6ae7417850c08c13f707d5838e43d48eb98dd4621baf62eee9e82348f80fe9b888a12874bfa538771f8\",\n    \"0xa13c4a3ac642ede37d9c883f5319e748d2b938f708c9d779714108a449b343f7b71a6e3ef4080fee125b416762920273\",\n    \"0xaf44983d5fc8cceee0551ef934e6e653f2d3efa385e5c8a27a272463a6f333e290378cc307c2b664eb923c78994e706e\",\n    \"0xa389fd6c59fe2b4031cc244e22d3991e541bd203dd5b5e73a6159e72df1ab41d49994961500dcde7989e945213184778\",\n    \"0x8d2141e4a17836c548de9598d7b298b03f0e6c73b7364979a411c464e0628e21cff6ac3d6decdba5d1c4909eff479761\",\n    \"0x980b22ef53b7bdf188a3f14bc51b0dbfdf9c758826daa3cbc1e3986022406a8aa9a6a79e400567120b88c67faa35ce5f\",\n    \"0xa28882f0a055f96df3711de5d0aa69473e71245f4f3e9aa944e9d1fb166e02caa50832e46da6d3a03b4801735fd01b29\",\n    \"0x8db106a37d7b88f5d995c126abb563934dd8de516af48e85695d02b1aea07f79217e3cdd03c6f5ca57421830186c772b\",\n    \"0xb5a7e50da0559a675c472f7dfaee456caab6695ab7870541b2be8c2b118c63752427184aad81f0e1afc61aef1f28c46f\",\n    \"0x9962118780e20fe291d10b64f28d09442a8e1b5cffd0f3dd68d980d0614050a626c616b44e9807fbee7accecae00686a\",\n    \"0xb38ddf33745e8d2ad6a991aefaf656a33c5f8cbe5d5b6b6fd03bd962153d8fd0e01b5f8f96d80ae53ab28d593ab1d4e7\",\n    \"0x857dc12c0544ff2c0c703761d901aba636415dee45618aba2e3454ff9cbc634a85c8b05565e88520ff9be2d097c8b2b1\",\n    \"0xa80d465c3f8cc63af6d74a6a5086b626c1cb4a8c0fee425964c3bd203d9d7094e299f81ce96d58afc20c8c9a029d9dae\",\n    \"0x89e1c8fbde8563763be483123a3ed702efac189c6d8ab4d16c85e74bbaf856048cc42d5d6e138633a38572ba5ec3f594\",\n    \"0x893a594cf495535f6d216508f8d03c317dcf03446668cba688da90f52d0111ac83d76ad09bf5ea47056846585ee5c791\",\n    \"0xaadbd8be0ae452f7f9450c7d2957598a20cbf10139a4023a78b4438172d62b18b0de39754dd2f8862dbd50a3a0815e53\",\n    \"0xae7d39670ecca3eb6db2095da2517a581b0e8853bdfef619b1fad9aacd443e7e6a40f18209fadd44038a55085c5fe8b2\",\n    \"0x866ef241520eacb6331593cfcb206f7409d2f33d04542e6e52cba5447934e02d44c471f6c9a45963f9307e9809ab91d9\",\n    \"0xb1a09911ad3864678f7be79a9c3c3eb5c84a0a45f8dcb52c67148f43439aeaaa9fd3ed3471276b7e588b49d6ebe3033a\",\n    \"0xadd07b7f0dbb34049cd8feeb3c18da5944bf706871cfd9f14ff72f6c59ad217ebb1f0258b13b167851929387e4e34cfe\",\n    \"0xae048892d5c328eefbdd4fba67d95901e3c14d974bfc0a1fc68155ca9f0d59e61d7ba17c6c9948b120cf35fd26e6fee9\",\n    \"0x9185b4f3b7da0ddb4e0d0f09b8a9e0d6943a4611e43f13c3e2a767ed8592d31e0ba3ebe1914026a3627680274291f6e5\",\n    \"0xa9c022d4e37b0802284ce3b7ee9258628ab4044f0db4de53d1c3efba9de19d15d65cc5e608dbe149c21c2af47d0b07b5\",\n    \"0xb24dbd5852f8f24921a4e27013b6c3fa8885b973266cb839b9c388efad95821d5d746348179dcc07542bd0d0aefad1ce\",\n    \"0xb5fb4f279300876a539a27a441348764908bc0051ebd66dc51739807305e73db3d2f6f0f294ffb91b508ab150eaf8527\",\n    \"0xace50841e718265b290c3483ed4b0fdd1175338c5f1f7530ae9a0e75d5f80216f4de37536adcbc8d8c95982e88808cd0\",\n    \"0xb19cadcde0f63bd1a9c24bd9c2806f53c14c0b9735bf351601498408ba503ddbd2037c891041cbba47f58b8c483f3b21\",\n    \"0xb6061e63558d312eb891b97b39aa552fa218568d79ee26fe6dd5b864aea9e3216d8f2e2f3b093503be274766dac41426\",\n    \"0x89730fdb2876ab6f0fe780d695f6e12090259027e789b819956d786e977518057e5d1d7f5ab24a3ae3d5d4c97773bd2b\",\n    \"0xb6fa841e81f9f2cad0163a02a63ae96dc341f7ae803b616efc6e1da2fbea551c1b96b11ad02c4afbdf6d0cc9f23da172\",\n    \"0x8fb66187182629c861ddb6896d7ed3caf2ad050c3dba8ab8eb0d7a2c924c3d44c48d1a148f9e33fb1f061b86972f8d21\",\n    \"0x86022ac339c1f84a7fa9e05358c1a5b316b4fc0b83dbe9c8c7225dc514f709d66490b539359b084ce776e301024345fa\",\n    \"0xb50b9c321468da950f01480bb62b6edafd42f83c0001d6e97f2bd523a1c49a0e8574fb66380ea28d23a7c4d54784f9f0\",\n    \"0xa31c05f7032f30d1dac06678be64d0250a071fd655e557400e4a7f4c152be4d5c7aa32529baf3e5be7c4bd49820054f6\",\n    \"0xb95ac0848cd322684772119f5b682d90a66bbf9dac411d9d86d2c34844bbd944dbaf8e47aa41380455abd51687931a78\",\n    \"0xae4a6a5ce9553b65a05f7935e61e496a4a0f6fd8203367a2c627394c9ce1e280750297b74cdc48fd1d9a31e93f97bef4\",\n    \"0xa22daf35f6e9b05e52e0b07f7bd1dbbebd2c263033fb0e1b2c804e2d964e2f11bc0ece6aca6af079dd3a9939c9c80674\",\n    \"0x902150e0cb1f16b9b59690db35281e28998ce275acb313900da8b2d8dfd29fa1795f8ca3ff820c31d0697de29df347c1\",\n    \"0xb17b5104a5dc665cdd7d47e476153d715eb78c6e5199303e4b5445c21a7fa7cf85fe7cfd08d7570f4e84e579b005428c\",\n    \"0xa03f49b81c15433f121680aa02d734bb9e363af2156654a62bcb5b2ba2218398ccb0ff61104ea5d7df5b16ea18623b1e\",\n    \"0x802101abd5d3c88876e75a27ffc2f9ddcce75e6b24f23dba03e5201281a7bd5cc7530b6a003be92d225093ca17d3c3bb\",\n    \"0xa4d183f63c1b4521a6b52226fc19106158fc8ea402461a5cccdaa35fee93669df6a8661f45c1750cd01308149b7bf08e\",\n    \"0x8d17c22e0c8403b69736364d460b3014775c591032604413d20a5096a94d4030d7c50b9fe3240e31d0311efcf9816a47\",\n    \"0x947225acfcce5992eab96276f668c3cbe5f298b90a59f2bb213be9997d8850919e8f496f182689b5cbd54084a7332482\",\n    \"0x8df6f4ed216fc8d1905e06163ba1c90d336ab991a18564b0169623eb39b84e627fa267397da15d3ed754d1f3423bff07\",\n    \"0x83480007a88f1a36dea464c32b849a3a999316044f12281e2e1c25f07d495f9b1710b4ba0d88e9560e72433addd50bc2\",\n    \"0xb3019d6e591cf5b33eb972e49e06c6d0a82a73a75d78d383dd6f6a4269838289e6e07c245f54fed67f5c9bb0fd5e1c5f\",\n    \"0x92e8ce05e94927a9fb02debadb99cf30a26172b2705003a2c0c47b3d8002bf1060edb0f6a5750aad827c98a656b19199\",\n    \"0xac2aff801448dbbfc13cca7d603fd9c69e82100d997faf11f465323b97255504f10c0c77401e4d1890339d8b224f5803\",\n    \"0xb0453d9903d08f508ee27e577445dc098baed6cde0ac984b42e0f0efed62760bd58d5816cf1e109d204607b7b175e30c\",\n    \"0xae68dc4ba5067e825d46d2c7c67f1009ceb49d68e8d3e4c57f4bcd299eb2de3575d42ea45e8722f8f28497a6e14a1cfe\",\n    \"0xb22486c2f5b51d72335ce819bbafb7fa25eb1c28a378a658f13f9fc79cd20083a7e573248d911231b45a5cf23b561ca7\",\n    \"0x89d1201d1dbd6921867341471488b4d2fd0fc773ae1d4d074c78ae2eb779a59b64c00452c2a0255826fca6b3d03be2b1\",\n    \"0xa2998977c91c7a53dc6104f5bc0a5b675e5350f835e2f0af69825db8af4aeb68435bdbcc795f3dd1f55e1dd50bc0507f\",\n    \"0xb0be4937a925b3c05056ed621910d535ccabf5ab99fd3b9335080b0e51d9607d0fd36cb5781ff340018f6acfca4a9736\",\n    \"0xaea145a0f6e0ba9df8e52e84bb9c9de2c2dc822f70d2724029b153eb68ee9c17de7d35063dcd6a39c37c59fdd12138f7\",\n    \"0x91cb4545d7165ee8ffbc74c874baceca11fdebbc7387908d1a25877ca3c57f2c5def424dab24148826832f1e880bede0\",\n    \"0xb3b579cb77573f19c571ad5eeeb21f65548d7dff9d298b8d7418c11f3e8cd3727c5b467f013cb87d6861cfaceee0d2e3\",\n    \"0xb98a1eeec2b19fecc8378c876d73645aa52fb99e4819903735b2c7a885b242787a30d1269a04bfb8573d72d9bbc5f0f0\",\n    \"0x940c1f01ed362bd588b950c27f8cc1d52276c71bb153d47f07ec85b038c11d9a8424b7904f424423e714454d5e80d1cd\",\n    \"0xaa343a8ecf09ce11599b8cf22f7279cf80f06dbf9f6d62cb05308dbbb39c46fd0a4a1240b032665fbb488a767379b91b\",\n    \"0x87c3ac72084aca5974599d3232e11d416348719e08443acaba2b328923af945031f86432e170dcdd103774ec92e988c9\",\n    \"0x91d6486eb5e61d2b9a9e742c20ec974a47627c6096b3da56209c2b4e4757f007e793ebb63b2b246857c9839b64dc0233\",\n    \"0xaebcd3257d295747dd6fc4ff910d839dd80c51c173ae59b8b2ec937747c2072fa85e3017f9060aa509af88dfc7529481\",\n    \"0xb3075ba6668ca04eff19efbfa3356b92f0ab12632dcda99cf8c655f35b7928c304218e0f9799d68ef9f809a1492ff7db\",\n    \"0x93ba7468bb325639ec2abd4d55179c69fd04eaaf39fc5340709227bbaa4ad0a54ea8b480a1a3c8d44684e3be0f8d1980\",\n    \"0xa6aef86c8c0d92839f38544d91b767c582568b391071228ff5a5a6b859c87bf4f81a7d926094a4ada1993ddbd677a920\",\n    \"0x91dcd6d14207aa569194aa224d1e5037b999b69ade52843315ca61ba26abe9a76412c9e88259bc5cf5d7b95b97d9c3bc\",\n    \"0xb3b483d31c88f78d49bd065893bc1e3d2aa637e27dedb46d9a7d60be7660ce7a10aaaa7deead362284a52e6d14021178\",\n    \"0x8e5730070acf8371461ef301cc4523e8e672aa0e3d945d438a0e0aa6bdf8cb9c685dcf38df429037b0c8aff3955c6f5b\",\n    \"0xb8c6d769890a8ee18dc4f9e917993315877c97549549b34785a92543cbeec96a08ae3a28d6e809c4aacd69de356c0012\",\n    \"0x95ca86cd384eaceaa7c077c5615736ca31f36824bd6451a16142a1edc129fa42b50724aeed7c738f08d7b157f78b569e\",\n    \"0x94df609c6d71e8eee7ab74226e371ccc77e01738fe0ef1a6424435b4570fe1e5d15797b66ed0f64eb88d4a3a37631f0e\",\n    \"0x89057b9783212add6a0690d6bb99097b182738deff2bd9e147d7fd7d6c8eacb4c219923633e6309ad993c24572289901\",\n    \"0x83a0f9f5f265c5a0e54defa87128240235e24498f20965009fef664f505a360b6fb4020f2742565dfc7746eb185bcec0\",\n    \"0x91170da5306128931349bc3ed50d7df0e48a68b8cc8420975170723ac79d8773e4fa13c5f14dc6e3fafcad78379050b1\",\n    \"0xb7178484d1b55f7e56a4cc250b6b2ec6040437d96bdfddfa7b35ed27435860f3855c2eb86c636f2911b012eb83b00db8\",\n    \"0xac0b00c4322d1e4208e09cd977b4e54d221133ff09551f75b32b0b55d0e2be80941dda26257b0e288c162e63c7e9cf68\",\n    \"0x9690ed9e7e53ed37ff362930e4096b878b12234c332fd19d5d064824084245952eda9f979e0098110d6963e468cf513e\",\n    \"0xb6fa547bb0bb83e5c5be0ed462a8783fba119041c136a250045c09d0d2af330c604331e7de960df976ff76d67f8000cd\",\n    \"0x814603907c21463bcf4e59cfb43066dfe1a50344ae04ef03c87c0f61b30836c3f4dea0851d6fa358c620045b7f9214c8\",\n    \"0x9495639e3939fad2a3df00a88603a5a180f3c3a0fe4d424c35060e2043e0921788003689887b1ed5be424d9a89bb18bb\",\n    \"0xaba4c02d8d57f2c92d5bc765885849e9ff8393d6554f5e5f3e907e5bfac041193a0d8716d7861104a4295d5a03c36b03\",\n    \"0x8ead0b56c1ca49723f94a998ba113b9058059321da72d9e395a667e6a63d5a9dac0f5717cec343f021695e8ced1f72af\",\n    \"0xb43037f7e3852c34ed918c5854cd74e9d5799eeddfe457d4f93bb494801a064735e326a76e1f5e50a339844a2f4a8ec9\",\n    \"0x99db8422bb7302199eb0ff3c3d08821f8c32f53a600c5b6fb43e41205d96adae72be5b460773d1280ad1acb806af9be8\",\n    \"0x8a9be08eae0086c0f020838925984df345c5512ff32e37120b644512b1d9d4fecf0fd30639ca90fc6cf334a86770d536\",\n    \"0x81b43614f1c28aa3713a309a88a782fb2bdfc4261dd52ddc204687791a40cf5fd6a263a8179388596582cccf0162efc2\",\n    \"0xa9f3a8b76912deb61d966c75daf5ddb868702ebec91bd4033471c8e533183df548742a81a2671de5be63a502d827437d\",\n    \"0x902e2415077f063e638207dc7e14109652e42ab47caccd6204e2870115791c9defac5425fd360b37ac0f7bd8fe7011f8\",\n    \"0xaa18e4fdc1381b59c18503ae6f6f2d6943445bd00dd7d4a2ad7e5adad7027f2263832690be30d456e6d772ad76f22350\",\n    \"0xa348b40ba3ba7d81c5d4631f038186ebd5e5f314f1ea737259151b07c3cc8cf0c6ed4201e71bcc1c22fefda81a20cde6\",\n    \"0xaa1306f7ac1acbfc47dc6f7a0cb6d03786cec8c8dc8060388ccda777bca24bdc634d03e53512c23dba79709ff64f8620\",\n    \"0x818ccfe46e700567b7f3eb400e5a35f6a5e39b3db3aa8bc07f58ace35d9ae5a242faf8dbccd08d9a9175bbce15612155\",\n    \"0xb7e3da2282b65dc8333592bb345a473f03bd6df69170055fec60222de9897184536bf22b9388b08160321144d0940279\",\n    \"0xa4d976be0f0568f4e57de1460a1729129252b44c552a69fceec44e5b97c96c711763360d11f9e5bf6d86b4976bf40d69\",\n    \"0x85d185f0397c24c2b875b09b6328a23b87982b84ee880f2677a22ff4c9a1ba9f0fea000bb3f7f66375a00d98ebafce17\",\n    \"0xb4ccbb8c3a2606bd9b87ce022704663af71d418351575f3b350d294f4efc68c26f9a2ce49ff81e6ff29c3b63d746294e\",\n    \"0x93ffd3265fddb63724dfde261d1f9e22f15ecf39df28e4d89e9fea03221e8e88b5dd9b77628bacaa783c6f91802d47cc\",\n    \"0xb1fd0f8d7a01378e693da98d03a2d2fda6b099d03454b6f2b1fa6472ff6bb092751ce6290059826b74ac0361eab00e1e\",\n    \"0xa89f440c71c561641589796994dd2769616b9088766e983c873fae0716b95c386c8483ab8a4f367b6a68b72b7456dd32\",\n    \"0xaf4fe92b01d42d03dd5d1e7fa55e96d4bbcb7bf7d4c8c197acd16b3e0f3455807199f683dcd263d74547ef9c244b35cc\",\n    \"0xa8227f6e0a344dfe76bfbe7a1861be32c4f4bed587ccce09f9ce2cf481b2dda8ae4f566154bc663d15f962f2d41761bd\",\n    \"0xa7b361663f7495939ed7f518ba45ea9ff576c4e628995b7aea026480c17a71d63fc2c922319f0502eb7ef8f14a406882\",\n    \"0x8ddcf382a9f39f75777160967c07012cfa89e67b19714a7191f0c68eaf263935e5504e1104aaabd0899348c972a8d3c6\",\n    \"0x98c95b9f6f5c91f805fb185eedd06c6fc4457d37dd248d0be45a6a168a70031715165ea20606245cbdf8815dc0ac697f\",\n    \"0x805b44f96e001e5909834f70c09be3efcd3b43632bcac5b6b66b6d227a03a758e4b1768ce2a723045681a1d34562aaeb\",\n    \"0xb0e81b07cdc45b3dca60882676d9badb99f25c461b7efe56e3043b80100bb62d29e1873ae25eb83087273160ece72a55\",\n    \"0xb0c53f0abe78ee86c7b78c82ae1f7c070bb0b9c45c563a8b3baa2c515d482d7507bb80771e60b38ac13f78b8af92b4a9\",\n    \"0xa7838ef6696a9e4d2e5dfd581f6c8d6a700467e8fd4e85adabb5f7a56f514785dd4ab64f6f1b48366f7d94728359441b\",\n    \"0x88c76f7700a1d23c30366a1d8612a796da57b2500f97f88fdf2d76b045a9d24e7426a8ffa2f4e86d3046937a841dad58\",\n    \"0xad8964baf98c1f02e088d1d9fcb3af6b1dfa44cdfe0ed2eae684e7187c33d3a3c28c38e8f4e015f9c04d451ed6f85ff6\",\n    \"0x90e9d00a098317ececaa9574da91fc149eda5b772dedb3e5a39636da6603aa007804fa86358550cfeff9be5a2cb7845e\",\n    \"0xa56ff4ddd73d9a6f5ab23bb77efa25977917df63571b269f6a999e1ad6681a88387fcc4ca3b26d57badf91b236503a29\",\n    \"0x97ad839a6302c410a47e245df84c01fb9c4dfef86751af3f9340e86ff8fc3cd52fa5ff0b9a0bd1d9f453e02ca80658a6\",\n    \"0xa4c8c44cbffa804129e123474854645107d1f0f463c45c30fd168848ebea94880f7c0c5a45183e9eb837f346270bdb35\",\n    \"0xa72e53d0a1586d736e86427a93569f52edd2f42b01e78aee7e1961c2b63522423877ae3ac1227a2cf1e69f8e1ff15bc3\",\n    \"0x8559f88a7ef13b4f09ac82ae458bbae6ab25671cfbf52dae7eac7280d6565dd3f0c3286aec1a56a8a16dc3b61d78ce47\",\n    \"0x8221503f4cdbed550876c5dc118a3f2f17800c04e8be000266633c83777b039a432d576f3a36c8a01e8fd18289ebc10b\",\n    \"0x99bfbe5f3e46d4d898a578ba86ed26de7ed23914bd3bcdf3c791c0bcd49398a52419077354a5ab75cea63b6c871c6e96\",\n    \"0xaa134416d8ff46f2acd866c1074af67566cfcf4e8be8d97329dfa0f603e1ff208488831ce5948ac8d75bfcba058ddcaa\",\n    \"0xb02609d65ebfe1fe8e52f21224a022ea4b5ea8c1bd6e7b9792eed8975fc387cdf9e3b419b8dd5bcce80703ab3a12a45f\",\n    \"0xa4f14798508698fa3852e5cac42a9db9797ecee7672a54988aa74037d334819aa7b2ac7b14efea6b81c509134a6b7ad2\",\n    \"0x884f01afecbcb987cb3e7c489c43155c416ed41340f61ecb651d8cba884fb9274f6d9e7e4a46dd220253ae561614e44c\",\n    \"0xa05523c9e71dce1fe5307cc71bd721feb3e1a0f57a7d17c7d1c9fb080d44527b7dbaa1f817b1af1c0b4322e37bc4bb1e\",\n    \"0x8560aec176a4242b39f39433dd5a02d554248c9e49d3179530815f5031fee78ba9c71a35ceeb2b9d1f04c3617c13d8f0\",\n    \"0x996aefd402748d8472477cae76d5a2b92e3f092fc834d5222ae50194dd884c9fb8b6ed8e5ccf8f6ed483ddbb4e80c747\",\n    \"0x8fd09900320000cbabc40e16893e2fcf08815d288ec19345ad7b6bb22f7d78a52b6575a3ca1ca2f8bc252d2eafc928ec\",\n    \"0x939e51f73022bc5dc6862a0adf8fb8a3246b7bfb9943cbb4b27c73743926cc20f615a036c7e5b90c80840e7f1bfee0e7\",\n    \"0xa0a6258700cadbb9e241f50766573bf9bdb7ad380b1079dc3afb4054363d838e177b869cad000314186936e40359b1f2\",\n    \"0x972699a4131c8ed27a2d0e2104d54a65a7ff1c450ad9da3a325c662ab26869c21b0a84d0700b98c8b5f6ce3b746873d7\",\n    \"0xa454c7fe870cb8aa6491eafbfb5f7872d6e696033f92e4991d057b59d70671f2acdabef533e229878b60c7fff8f748b1\",\n    \"0xa167969477214201f09c79027b10221e4707662e0c0fde81a0f628249f2f8a859ce3d30a7dcc03b8ecca8f7828ad85c7\",\n    \"0x8ff6b7265175beb8a63e1dbf18c9153fb2578c207c781282374f51b40d57a84fd2ef2ea2b9c6df4a54646788a62fd17f\",\n    \"0xa3d7ebeccde69d73d8b3e76af0da1a30884bb59729503ff0fb0c3bccf9221651b974a6e72ea33b7956fc3ae758226495\",\n    \"0xb71ef144c9a98ce5935620cb86c1590bd4f48e5a2815d25c0cdb008fde628cf628c31450d3d4f67abbfeb16178a74cfd\",\n    \"0xb5e0a16d115134f4e2503990e3f2035ed66b9ccf767063fe6747870d97d73b10bc76ed668550cb82eedc9a2ca6f75524\",\n    \"0xb30ffaaf94ee8cbc42aa2c413175b68afdb207dbf351fb20be3852cb7961b635c22838da97eaf43b103aff37e9e725cc\",\n    \"0x98aa7d52284f6c1f22e272fbddd8c8698cf8f5fbb702d5de96452141fafb559622815981e50b87a72c2b1190f59a7deb\",\n    \"0x81fbacda3905cfaf7780bb4850730c44166ed26a7c8d07197a5d4dcd969c09e94a0461638431476c16397dd7bdc449f9\",\n    \"0x95e47021c1726eac2e5853f570d6225332c6e48e04c9738690d53e07c6b979283ebae31e2af1fc9c9b3e59f87e5195b1\",\n    \"0xac024a661ba568426bb8fce21780406537f518075c066276197300841e811860696f7588188bc01d90bace7bc73d56e3\",\n    \"0xa4ebcaf668a888dd404988ab978594dee193dad2d0aec5cdc0ccaf4ec9a7a8228aa663db1da8ddc52ec8472178e40c32\",\n    \"0xa20421b8eaf2199d93b083f2aff37fb662670bd18689d046ae976d1db1fedd2c2ff897985ecc6277b396db7da68bcb27\",\n    \"0x8bc33d4b40197fd4d49d1de47489d10b90d9b346828f53a82256f3e9212b0cbc6930b895e879da9cec9fedf026aadb3e\",\n    \"0xaaafdd1bec8b757f55a0433eddc0a39f818591954fd4e982003437fcceb317423ad7ee74dbf17a2960380e7067a6b4e2\",\n    \"0xaad34277ebaed81a6ec154d16736866f95832803af28aa5625bf0461a71d02b1faba02d9d9e002be51c8356425a56867\",\n    \"0x976e9c8b150d08706079945bd0e84ab09a648ecc6f64ded9eb5329e57213149ae409ae93e8fbd8eda5b5c69f5212b883\",\n    \"0x8097fae1653247d2aed4111533bc378171d6b2c6d09cbc7baa9b52f188d150d645941f46d19f7f5e27b7f073c1ebd079\",\n    \"0x83905f93b250d3184eaba8ea7d727c4464b6bdb027e5cbe4f597d8b9dc741dcbea709630bd4fd59ce24023bec32fc0f3\",\n    \"0x8095030b7045cff28f34271386e4752f9a9a0312f8df75de4f424366d78534be2b8e1720a19cb1f9a2d21105d790a225\",\n    \"0xa7b7b73a6ae2ed1009c49960374b0790f93c74ee03b917642f33420498c188a169724945a975e5adec0a1e83e07fb1b2\",\n    \"0x856a41c54df393b6660b7f6354572a4e71c8bfca9cabaffb3d4ef2632c015e7ee2bc10056f3eccb3dbed1ad17d939178\",\n    \"0xa8f7a55cf04b38cd4e330394ee6589da3a07dc9673f74804fdf67b364e0b233f14aec42e783200a2e4666f7c5ff62490\",\n    \"0x82c529f4e543c6bca60016dc93232c115b359eaee2798a9cf669a654b800aafe6ab4ba58ea8b9cdda2b371c8d62fa845\",\n    \"0x8caab020c1baddce77a6794113ef1dfeafc5f5000f48e97f4351b588bf02f1f208101745463c480d37f588d5887e6d8c\",\n    \"0x8fa91b3cc400f48b77b6fd77f3b3fbfb3f10cdff408e1fd22d38f77e087b7683adad258804409ba099f1235b4b4d6fea\",\n    \"0x8aa02787663d6be9a35677d9d8188b725d5fcd770e61b11b64e3def8808ea5c71c0a9afd7f6630c48634546088fcd8e2\",\n    \"0xb5635b7b972e195cab878b97dea62237c7f77eb57298538582a330b1082f6207a359f2923864630136d8b1f27c41b9aa\",\n    \"0x8257bb14583551a65975946980c714ecd6e5b629672bb950b9caacd886fbd22704bc9e3ba7d30778adab65dc74f0203a\",\n    \"0xab5fe1cd12634bfa4e5c60d946e2005cbd38f1063ec9a5668994a2463c02449a0a185ef331bd86b68b6e23a8780cb3ba\",\n    \"0xa7d3487da56cda93570cc70215d438204f6a2709bfb5fda6c5df1e77e2efc80f4235c787e57fbf2c74aaff8cbb510a14\",\n    \"0xb61cff7b4c49d010e133319fb828eb900f8a7e55114fc86b39c261a339c74f630e1a7d7e1350244ada566a0ff3d46c4b\",\n    \"0x8d4d1d55d321d278db7a85522ccceca09510374ca81d4d73e3bb5249ace7674b73900c35a531ec4fa6448fabf7ad00dc\",\n    \"0x966492248aee24f0f56c8cfca3c8ec6ba3b19abb69ae642041d4c3be8523d22c65c4dafcab4c58989ccc4e0bd2f77919\",\n    \"0xb20c320a90cb220b86e1af651cdc1e21315cd215da69f6787e28157172f93fc8285dcd59b039c626ed8ca4633cba1a47\",\n    \"0xaae9e6b22f018ceb5c0950210bb8182cb8cb61014b7e14581a09d36ebd1bbfebdb2b82afb7fdb0cf75e58a293d9c456d\",\n    \"0x875547fb67951ad37b02466b79f0c9b985ccbc500cfb431b17823457dc79fb9597ec42cd9f198e15523fcd88652e63a4\",\n    \"0x92afce49773cb2e20fb21e4f86f18e0959ebb9c33361547ddb30454ee8e36b1e234019cbdca0e964cb292f7f77df6b90\",\n    \"0x8af85343dfe1821464c76ba11c216cbef697b5afc69c4d821342e55afdac047081ec2e3f7b09fc14b518d9a23b78c003\",\n    \"0xb7de4a1648fd63f3a918096ea669502af5357438e69dac77cb8102b6e6c15c76e033cfaa80dafc806e535ede5c1a20aa\",\n    \"0xac80e9b545e8bd762951d96c9ce87f629d01ffcde07efc2ef7879ca011f1d0d8a745abf26c9d452541008871304fac00\",\n    \"0xa4cf0f7ed724e481368016c38ea5816698a5f68eb21af4d3c422d2ba55f96a33e427c2aa40de1b56a7cfac7f7cf43ab0\",\n    \"0x899b0a678bb2db2cae1b44e75a661284844ebcdd87abf308fedeb2e4dbe5c5920c07db4db7284a7af806a2382e8b111a\",\n    \"0xaf0588a2a4afce2b1b13c1230816f59e8264177e774e4a341b289a101dcf6af813638fed14fb4d09cb45f35d5d032609\",\n    \"0xa4b8df79e2be76e9f5fc5845f06fe745a724cf37c82fcdb72719b77bdebea3c0e763f37909373e3a94480cc5e875cba0\",\n    \"0x83e42c46d88930c8f386b19fd999288f142d325e2ebc86a74907d6d77112cb0d449bc511c95422cc810574031a8cbba9\",\n    \"0xb5e39534070de1e5f6e27efbdd3dc917d966c2a9b8cf2d893f964256e95e954330f2442027dc148c776d63a95bcde955\",\n    \"0x958607569dc28c075e658cd4ae3927055c6bc456eef6212a6fea8205e48ed8777a8064f584cda38fe5639c371e2e7fba\",\n    \"0x812adf409fa63575113662966f5078a903212ffb65c9b0bbe62da0f13a133443a7062cb8fd70f5e5dd5559a32c26d2c8\",\n    \"0xa679f673e5ce6a3cce7fa31f22ee3785e96bcb55e5a776e2dd3467bef7440e3555d1a9b87cb215e86ee9ed13a090344b\",\n    \"0xafedbb34508b159eb25eb2248d7fe328f86ef8c7d84c62d5b5607d74aae27cc2cc45ee148eb22153b09898a835c58df4\",\n    \"0xb75505d4f6b67d31e665cfaf5e4acdb5838ae069166b7fbcd48937c0608a59e40a25302fcc1873d2e81c1782808c70f0\",\n    \"0xb62515d539ec21a155d94fc00ea3c6b7e5f6636937bce18ed5b618c12257fb82571886287fd5d1da495296c663ebc512\",\n    \"0xab8e1a9446bbdd588d1690243b1549d230e6149c28f59662b66a8391a138d37ab594df38e7720fae53217e5c3573b5be\",\n    \"0xb31e8abf4212e03c3287bb2c0a153065a7290a16764a0bac8f112a72e632185a654bb4e88fdd6053e6c7515d9719fadb\",\n    \"0xb55165477fe15b6abd2d0f4fddaa9c411710dcc4dd712daba3d30e303c9a3ee5415c256f9dc917ecf18c725b4dbab059\",\n    \"0xa0939d4f57cacaae549b78e87cc234de4ff6a35dc0d9cd5d7410abc30ebcd34c135e008651c756e5a9d2ca79c40ef42b\",\n    \"0x8cf10e50769f3443340844aad4d56ec790850fed5a41fcbd739abac4c3015f0a085a038fbe7fae9f5ad899cce5069f6b\",\n    \"0x924055e804d82a99ea4bb160041ea4dc14b568abf379010bc1922fde5d664718c31d103b8b807e3a1ae809390e708c73\",\n    \"0x8ec0f9d26f71b0f2e60a179e4fd1778452e2ffb129d50815e5d7c7cb9415fa69ae5890578086e8ef6bfde35ad2a74661\",\n    \"0x98c7f12b15ec4426b59f737f73bf5faea4572340f4550b7590dfb7f7ffedb2372e3e555977c63946d579544c53210ad0\",\n    \"0x8a935f7a955c78f69d66f18eee0092e5e833fa621781c9581058e219af4d7ceee48b84e472e159dda6199715fb2f9acf\",\n    \"0xb78d4219f95a2dbfaa7d0c8a610c57c358754f4f43c2af312ab0fe8f10a5f0177e475332fb8fd23604e474fc2abeb051\",\n    \"0x8d086a14803392b7318c28f1039a17e3cfdcece8abcaca3657ec3d0ac330842098a85c0212f889fabb296dfb133ce9aa\",\n    \"0xa53249f417aac82f2c2a50c244ce21d3e08a5e5a8bd33bec2a5ab0d6cd17793e34a17edfa3690899244ce201e2fb9986\",\n    \"0x8619b0264f9182867a1425be514dc4f1ababc1093138a728a28bd7e4ecc99b9faaff68c23792264bc6e4dce5f52a5c52\",\n    \"0x8c171edbbbde551ec19e31b2091eb6956107dd9b1f853e1df23bff3c10a3469ac77a58335eee2b79112502e8e163f3de\",\n    \"0xa9d19ec40f0ca07c238e9337c6d6a319190bdba2db76fb63902f3fb459aeeb50a1ac30db5b25ee1b4201f3ca7164a7f4\",\n    \"0xb9c6ec14b1581a03520b8d2c1fbbc31fb8ceaef2c0f1a0d0080b6b96e18442f1734bea7ef7b635d787c691de4765d469\",\n    \"0x8cb437beb4cfa013096f40ccc169a713dc17afee6daa229a398e45fd5c0645a9ad2795c3f0cd439531a7151945d7064d\",\n    \"0xa6e8740cc509126e146775157c2eb278003e5bb6c48465c160ed27888ca803fa12eee1f6a8dd7f444f571664ed87fdc1\",\n    \"0xb75c1fecc85b2732e96b3f23aefb491dbd0206a21d682aee0225838dc057d7ed3b576176353e8e90ae55663f79e986e4\",\n    \"0xad8d249b0aea9597b08358bce6c77c1fd552ef3fbc197d6a1cfe44e5e6f89b628b12a6fb04d5dcfcbacc51f46e4ae7bb\",\n    \"0xb998b2269932cbd58d04b8e898d373ac4bb1a62e8567484f4f83e224061bc0f212459f1daae95abdbc63816ae6486a55\",\n    \"0x827988ef6c1101cddc96b98f4a30365ff08eea2471dd949d2c0a9b35c3bbfa8c07054ad1f4c88c8fbf829b20bb5a9a4f\",\n    \"0x8692e638dd60babf7d9f2f2d2ce58e0ac689e1326d88311416357298c6a2bffbfebf55d5253563e7b3fbbf5072264146\",\n    \"0xa685d75b91aea04dbc14ab3c1b1588e6de96dae414c8e37b8388766029631b28dd860688079b12d09cd27f2c5af11adf\",\n    \"0xb57eced93eec3371c56679c259b34ac0992286be4f4ff9489d81cf9712403509932e47404ddd86f89d7c1c3b6391b28c\",\n    \"0xa1c8b4e42ebcbd8927669a97f1b72e236fb19249325659e72be7ddaaa1d9e81ca2abb643295d41a8c04a2c01f9c0efd7\",\n    \"0x877c33de20d4ed31674a671ba3e8f01a316581e32503136a70c9c15bf0b7cb7b1cba6cd4eb641fad165fb3c3c6c235fd\",\n    \"0xa2a469d84ec478da40838f775d11ad38f6596eb41caa139cc190d6a10b5108c09febae34ffdafac92271d2e73c143693\",\n    \"0x972f817caedb254055d52e963ed28c206848b6c4cfdb69dbc961c891f8458eaf582a6d4403ce1177d87bc2ea410ef60a\",\n    \"0xaccbd739e138007422f28536381decc54bb6bd71d93edf3890e54f9ef339f83d2821697d1a4ac1f5a98175f9a9ecb9b5\",\n    \"0x8940f8772e05389f823b62b3adc3ed541f91647f0318d7a0d3f293aeeb421013de0d0a3664ea53dd24e5fbe02d7efef6\",\n    \"0x8ecce20f3ef6212edef07ec4d6183fda8e0e8cad2c6ccd0b325e75c425ee1faba00b5c26b4d95204238931598d78f49d\",\n    \"0x97cc72c36335bd008afbed34a3b0c7225933faba87f7916d0a6d2161e6f82e0cdcda7959573a366f638ca75d30e9dab1\",\n    \"0x9105f5de8699b5bdb6bd3bb6cc1992d1eac23929c29837985f83b22efdda92af64d9c574aa9640475087201bbbe5fd73\",\n    \"0x8ffb33c4f6d05c413b9647eb6933526a350ed2e4278ca2ecc06b0e8026d8dbe829c476a40e45a6df63a633090a3f82ef\",\n    \"0x8bfc6421fdc9c2d2aaa68d2a69b1a2728c25b84944cc3e6a57ff0c94bfd210d1cbf4ff3f06702d2a8257024d8be7de63\",\n    \"0xa80e1dc1dddfb41a70220939b96dc6935e00b32fb8be5dff4eed1f1c650002ff95e4af481c43292e3827363b7ec4768a\",\n    \"0x96f714ebd54617198bd636ba7f7a7f8995a61db20962f2165078d9ed8ee764d5946ef3cbdc7ebf8435bb8d5dd4c1deac\",\n    \"0x8cdb0890e33144d66391d2ae73f5c71f5a861f72bc93bff6cc399fc25dd1f9e17d8772592b44593429718784802ac377\",\n    \"0x8ccf9a7f80800ee770b92add734ed45a73ecc31e2af0e04364eefc6056a8223834c7c0dc9dfc52495bdec6e74ce69994\",\n    \"0xaa0875f423bd68b5f10ba978ddb79d3b96ec093bfbac9ff366323193e339ed7c4578760fb60f60e93598bdf1e5cc4995\",\n    \"0xa9214f523957b59c7a4cb61a40251ad72aba0b57573163b0dc0f33e41d2df483fb9a1b85a5e7c080e9376c866790f8cb\",\n    \"0xb6224b605028c6673a536cc8ff9aeb94e7a22e686fda82cf16068d326469172f511219b68b2b3affb7933af0c1f80d07\",\n    \"0xb6d58968d8a017c6a34e24c2c09852f736515a2c50f37232ac6b43a38f8faa7572cc31dade543b594b61b5761c4781d0\",\n    \"0x8a97cefe5120020c38deeb861d394404e6c993c6cbd5989b6c9ebffe24f46ad11b4ba6348e2991cbf3949c28cfc3c99d\",\n    \"0x95bf046f8c3a9c0ce2634be4de3713024daec3fc4083e808903b25ce3ac971145af90686b451efcc72f6b22df0216667\",\n    \"0xa6a4e2f71b8fa28801f553231eff2794c0f10d12e7e414276995e21195abc9c2983a8997e41af41e78d19ff6fbb2680b\",\n    \"0x8e5e62a7ca9c2f58ebaab63db2ff1fb1ff0877ae94b7f5e2897f273f684ae639dff44cc65718f78a9c894787602ab26a\",\n    \"0x8542784383eec4f565fcb8b9fc2ad8d7a644267d8d7612a0f476fc8df3aff458897a38003d506d24142ad18f93554f2b\",\n    \"0xb7db68ba4616ea072b37925ec4fb39096358c2832cc6d35169e032326b2d6614479f765ae98913c267105b84afcb9bf2\",\n    \"0x8b31dbb9457d23d416c47542c786e07a489af35c4a87dadb8ee91bea5ac4a5315e65625d78dad2cf8f9561af31b45390\",\n    \"0xa8545a1d91ac17257732033d89e6b7111db8242e9c6ebb0213a88906d5ef407a2c6fdb444e29504b06368b6efb4f4839\",\n    \"0xb1bd85d29ebb28ccfb05779aad8674906b267c2bf8cdb1f9a0591dd621b53a4ee9f2942687ee3476740c0b4a7621a3ae\",\n    \"0xa2b54534e152e46c50d91fff03ae9cd019ff7cd9f4168b2fe7ac08ef8c3bbc134cadd3f9d6bd33d20ae476c2a8596c8a\",\n    \"0xb19b571ff4ae3e9f5d95acda133c455e72c9ea9973cae360732859836c0341c4c29ab039224dc5bc3deb824e031675d8\",\n    \"0x940b5f80478648bac025a30f3efeb47023ce20ee98be833948a248bca6979f206bb28fc0f17b90acf3bb4abd3d14d731\",\n    \"0x8f106b40588586ac11629b96d57808ad2808915d89539409c97414aded90b4ff23286a692608230a52bff696055ba5d6\",\n    \"0xae6bda03aa10da3d2abbc66d764ca6c8d0993e7304a1bdd413eb9622f3ca1913baa6da1e9f4f9e6cf847f14f44d6924d\",\n    \"0xa18e7796054a340ef826c4d6b5a117b80927afaf2ebd547794c400204ae2caf277692e2eabb55bc2f620763c9e9da66d\",\n    \"0x8d2d25180dc2c65a4844d3e66819ccfcf48858f0cc89e1c77553b463ec0f7feb9a4002ce26bc618d1142549b9850f232\",\n    \"0x863f413a394de42cc8166c1c75d513b91d545fff1de6b359037a742c70b008d34bf8e587afa2d62c844d0c6f0ea753e7\",\n    \"0x83cd0cf62d63475e7fcad18a2e74108499cdbf28af2113cfe005e3b5887794422da450b1944d0a986eb7e1f4c3b18f25\",\n    \"0xb4f8b350a6d88fea5ab2e44715a292efb12eb52df738c9b2393da3f1ddee68d0a75b476733ccf93642154bceb208f2b8\",\n    \"0xb3f52aaa4cd4221cb9fc45936cc67fd3864bf6d26bf3dd86aa85aa55ecfc05f5e392ecce5e7cf9406b4b1c4fce0398c8\",\n    \"0xb33137084422fb643123f40a6df2b498065e65230fc65dc31791c330e898c51c3a65ff738930f32c63d78f3c9315f85b\",\n    \"0x91452bfa75019363976bb7337fe3a73f1c10f01637428c135536b0cdc7da5ce558dae3dfc792aa55022292600814a8ef\",\n    \"0xad6ba94c787cd4361ca642c20793ea44f1f127d4de0bb4a77c7fbfebae0fcadbf28e2cb6f0c12c12a07324ec8c19761d\",\n    \"0x890aa6248b17f1501b0f869c556be7bf2b1d31a176f9978bb97ab7a6bd4138eed32467951c5ef1871944b7f620542f43\",\n    \"0x82111db2052194ee7dd22ff1eafffac0443cf969d3762cceae046c9a11561c0fdce9c0711f88ac01d1bed165f8a7cee3\",\n    \"0xb1527b71df2b42b55832f72e772a466e0fa05743aacc7814f4414e4bcc8d42a4010c9e0fd940e6f254cafedff3cd6543\",\n    \"0x922370fa49903679fc565f09c16a5917f8125e72acfeb060fcdbadbd1644eb9f4016229756019c93c6d609cda5d5d174\",\n    \"0xaa4c7d98a96cab138d2a53d4aee8ebff6ef903e3b629a92519608d88b3bbd94de5522291a1097e6acf830270e64c8ee1\",\n    \"0xb3dc21608a389a72d3a752883a382baaafc61ecc44083b832610a237f6a2363f24195acce529eb4aed4ef0e27a12b66e\",\n    \"0x94619f5de05e07b32291e1d7ab1d8b7337a2235e49d4fb5f3055f090a65e932e829efa95db886b32b153bdd05a53ec8c\",\n    \"0xade1e92722c2ffa85865d2426fb3d1654a16477d3abf580cfc45ea4b92d5668afc9d09275d3b79283e13e6b39e47424d\",\n    \"0xb7201589de7bed094911dd62fcd25c459a8e327ac447b69f541cdba30233063e5ddffad0b67e9c3e34adcffedfd0e13d\",\n    \"0x809d325310f862d6549e7cb40f7e5fc9b7544bd751dd28c4f363c724a0378c0e2adcb5e42ec8f912f5f49f18f3365c07\",\n    \"0xa79c20aa533de7a5d671c99eb9eb454803ba54dd4f2efa3c8fec1a38f8308e9905c71e9282955225f686146388506ff6\",\n    \"0xa85eeacb5e8fc9f3ed06a3fe2dc3108ab9f8c5877b148c73cf26e4e979bf5795edbe2e63a8d452565fd1176ed40402b2\",\n    \"0x97ef55662f8a1ec0842b22ee21391227540adf7708f491436044f3a2eb18c471525e78e1e14fa292507c99d74d7437c6\",\n    \"0x93110d64ed5886f3d16ce83b11425576a3a7a9bb831cd0de3f9a0b0f2270a730d68136b4ef7ff035ede004358f419b5c\",\n    \"0xac9ed0a071517f0ae4f61ce95916a90ba9a77a3f84b0ec50ef7298acdcd44d1b94525d191c39d6bd1bb68f4471428760\",\n    \"0x98abd6a02c7690f5a339adf292b8c9368dfc12e0f8069cf26a5e0ce54b4441638f5c66ea735142f3c28e00a0024267e6\",\n    \"0xb51efb73ba6d44146f047d69b19c0722227a7748b0e8f644d0fc9551324cf034c041a2378c56ce8b58d06038fb8a78de\",\n    \"0x8f115af274ef75c1662b588b0896b97d71f8d67986ae846792702c4742ab855952865ce236b27e2321967ce36ff93357\",\n    \"0xb3c4548f14d58b3ab03c222da09e4381a0afe47a72d18d50a94e0008797f78e39e99990e5b4757be62310d400746e35a\",\n    \"0xa9b1883bd5f31f909b8b1b6dcb48c1c60ed20aa7374b3ffa7f5b2ed036599b5bef33289d23c80a5e6420d191723b92f7\",\n    \"0x85d38dffd99487ae5bb41ab4a44d80a46157bbbe8ef9497e68f061721f74e4da513ccc3422936b059575975f6787c936\",\n    \"0xadf870fcb96e972c033ab7a35d28ae79ee795f82bc49c3bd69138f0e338103118d5529c53f2d72a9c0d947bf7d312af2\",\n    \"0xab4c7a44e2d9446c6ff303eb49aef0e367a58b22cc3bb27b4e69b55d1d9ee639c9234148d2ee95f9ca8079b1457d5a75\",\n    \"0xa386420b738aba2d7145eb4cba6d643d96bda3f2ca55bb11980b318d43b289d55a108f4bc23a9606fb0bccdeb3b3bb30\",\n    \"0x847020e0a440d9c4109773ecca5d8268b44d523389993b1f5e60e541187f7c597d79ebd6e318871815e26c96b4a4dbb1\",\n    \"0xa530aa7e5ca86fcd1bec4b072b55cc793781f38a666c2033b510a69e110eeabb54c7d8cbcb9c61fee531a6f635ffa972\",\n    \"0x87364a5ea1d270632a44269d686b2402da737948dac27f51b7a97af80b66728b0256547a5103d2227005541ca4b7ed04\",\n    \"0x8816fc6e16ea277de93a6d793d0eb5c15e9e93eb958c5ef30adaf8241805adeb4da8ce19c3c2167f971f61e0b361077d\",\n    \"0x8836a72d301c42510367181bb091e4be377777aed57b73c29ef2ce1d475feedd7e0f31676284d9a94f6db01cc4de81a2\",\n    \"0xb0d9d8b7116156d9dde138d28aa05a33e61f8a85839c1e9071ccd517b46a5b4b53acb32c2edd7150c15bc1b4bd8db9e3\",\n    \"0xae931b6eaeda790ba7f1cd674e53dc87f6306ff44951fa0df88d506316a5da240df9794ccbd7215a6470e6b31c5ea193\",\n    \"0x8c6d5bdf87bd7f645419d7c6444e244fe054d437ed1ba0c122fde7800603a5fadc061e5b836cb22a6cfb2b466f20f013\",\n    \"0x90d530c6d0cb654999fa771b8d11d723f54b8a8233d1052dc1e839ea6e314fbed3697084601f3e9bbb71d2b4eaa596df\",\n    \"0xb0d341a1422588c983f767b1ed36c18b141774f67ef6a43cff8e18b73a009da10fc12120938b8bba27f225bdfd3138f9\",\n    \"0xa131b56f9537f460d304e9a1dd75702ace8abd68cb45419695cb8dee76998139058336c87b7afd6239dc20d7f8f940cc\",\n    \"0xaa6c51fa28975f709329adee1bbd35d49c6b878041841a94465e8218338e4371f5cb6c17f44a63ac93644bf28f15d20f\",\n    \"0x88440fb584a99ebd7f9ea04aaf622f6e44e2b43bbb49fb5de548d24a238dc8f26c8da2ccf03dd43102bda9f16623f609\",\n    \"0x9777b8695b790e702159a4a750d5e7ff865425b95fa0a3c15495af385b91c90c00a6bd01d1b77bffe8c47d01baae846f\",\n    \"0x8b9d764ece7799079e63c7f01690c8eff00896a26a0d095773dea7a35967a8c40db7a6a74692f0118bf0460c26739af4\",\n    \"0x85808c65c485520609c9e61fa1bb67b28f4611d3608a9f7a5030ee61c3aa3c7e7dc17fff48af76b4aecee2cb0dbd22ac\",\n    \"0xad2783a76f5b3db008ef5f7e67391fda4e7e36abde6b3b089fc4835b5c339370287935af6bd53998bed4e399eda1136d\",\n    \"0x96f18ec03ae47c205cc4242ca58e2eff185c9dca86d5158817e2e5dc2207ab84aadda78725f8dc080a231efdc093b940\",\n    \"0x97de1ab6c6cc646ae60cf7b86df73b9cf56cc0cd1f31b966951ebf79fc153531af55ca643b20b773daa7cab784b832f7\",\n    \"0x870ba266a9bfa86ef644b1ef025a0f1b7609a60de170fe9508de8fd53170c0b48adb37f19397ee8019b041ce29a16576\",\n    \"0xad990e888d279ac4e8db90619d663d5ae027f994a3992c2fbc7d262b5990ae8a243e19157f3565671d1cb0de17fe6e55\",\n    \"0x8d9d5adcdd94c5ba3be4d9a7428133b42e485f040a28d16ee2384758e87d35528f7f9868de9bd23d1a42a594ce50a567\",\n    \"0x85a33ed75d514ece6ad78440e42f7fcdb59b6f4cff821188236d20edae9050b3a042ce9bc7d2054296e133d033e45022\",\n    \"0x92afd2f49a124aaba90de59be85ff269457f982b54c91b06650c1b8055f9b4b0640fd378df02a00e4fc91f7d226ab980\",\n    \"0x8c0ee09ec64bd831e544785e3d65418fe83ed9c920d9bb4d0bf6dd162c1264eb9d6652d2def0722e223915615931581c\",\n    \"0x8369bedfa17b24e9ad48ebd9c5afea4b66b3296d5770e09b00446c5b0a8a373d39d300780c01dcc1c6752792bccf5fd0\",\n    \"0x8b9e960782576a59b2eb2250d346030daa50bbbec114e95cdb9e4b1ba18c3d34525ae388f859708131984976ca439d94\",\n    \"0xb682bface862008fea2b5a07812ca6a28a58fd151a1d54c708fc2f8572916e0d678a9cb8dc1c10c0470025c8a605249e\",\n    \"0xa38d5e189bea540a824b36815fc41e3750760a52be0862c4cac68214febdc1a754fb194a7415a8fb7f96f6836196d82a\",\n    \"0xb9e7fbda650f18c7eb8b40e42cc42273a7298e65e8be524292369581861075c55299ce69309710e5b843cb884de171bd\",\n    \"0xb6657e5e31b3193874a1bace08f42faccbd3c502fb73ad87d15d18a1b6c2a146f1baa929e6f517db390a5a47b66c0acf\",\n    \"0xae15487312f84ed6265e4c28327d24a8a0f4d2d17d4a5b7c29b974139cf93223435aaebe3af918f5b4bb20911799715f\",\n    \"0x8bb4608beb06bc394e1a70739b872ce5a2a3ffc98c7547bf2698c893ca399d6c13686f6663f483894bccaabc3b9c56ad\",\n    \"0xb58ac36bc6847077584308d952c5f3663e3001af5ecf2e19cb162e1c58bd6c49510205d453cffc876ca1dc6b8e04a578\",\n    \"0x924f65ced61266a79a671ffb49b300f0ea44c50a0b4e3b02064faa99fcc3e4f6061ea8f38168ab118c5d47bd7804590e\",\n    \"0x8d67d43b8a06b0ff4fafd7f0483fa9ed1a9e3e658a03fb49d9d9b74e2e24858dc1bed065c12392037b467f255d4e5643\",\n    \"0xb4d4f87813125a6b355e4519a81657fa97c43a6115817b819a6caf4823f1d6a1169683fd68f8d025cdfa40ebf3069acb\",\n    \"0xa7fd4d2c8e7b59b8eed3d4332ae94b77a89a2616347402f880bc81bde072220131e6dbec8a605be3a1c760b775375879\",\n    \"0x8d4a7d8fa6f55a30df37bcf74952e2fa4fd6676a2e4606185cf154bdd84643fd01619f8fb8813a564f72e3f574f8ce30\",\n    \"0x8086fb88e6260e9a9c42e9560fde76315ff5e5680ec7140f2a18438f15bc2cc7d7d43bfb5880b180b738c20a834e6134\",\n    \"0x916c4c54721de03934fee6f43de50bb04c81f6f8dd4f6781e159e71c40c60408aa54251d457369d133d4ba3ed7c12cb4\",\n    \"0x902e5bf468f11ed9954e2a4a595c27e34abe512f1d6dc08bbca1c2441063f9af3dc5a8075ab910a10ff6c05c1c644a35\",\n    \"0xa1302953015e164bf4c15f7d4d35e3633425a78294406b861675667eec77765ff88472306531e5d3a4ec0a2ff0dd6a9e\",\n    \"0x87874461df3c9aa6c0fa91325576c0590f367075f2f0ecfeb34afe162c04c14f8ce9d608c37ac1adc8b9985bc036e366\",\n    \"0x84b50a8a61d3cc609bfb0417348133e698fe09a6d37357ce3358de189efcf35773d78c57635c2d26c3542b13cc371752\",\n    \"0xacaed2cff8633d12c1d12bb7270c54d65b0b0733ab084fd47f81d0a6e1e9b6f300e615e79538239e6160c566d8bb8d29\",\n    \"0x889e6a0e136372ca4bac90d1ab220d4e1cad425a710e8cdd48b400b73bb8137291ceb36a39440fa84305783b1d42c72f\",\n    \"0x90952e5becec45b2b73719c228429a2c364991cf1d5a9d6845ae5b38018c2626f4308daa322cab1c72e0f6c621bb2b35\",\n    \"0x8f5a97a801b6e9dcd66ccb80d337562c96f7914e7169e8ff0fda71534054c64bf2a9493bb830623d612cfe998789be65\",\n    \"0x84f3df8b9847dcf1d63ca470dc623154898f83c25a6983e9b78c6d2d90a97bf5e622445be835f32c1e55e6a0a562ea78\",\n    \"0x91d12095cd7a88e7f57f254f02fdb1a1ab18984871dead2f107404bcf8069fe68258c4e6f6ebd2477bddf738135400bb\",\n    \"0xb771a28bc04baef68604d4723791d3712f82b5e4fe316d7adc2fc01b935d8e644c06d59b83bcb542afc40ebafbee0683\",\n    \"0x872f6341476e387604a7e93ae6d6117e72d164e38ebc2b825bc6df4fcce815004d7516423c190c1575946b5de438c08d\",\n    \"0x90d6b4aa7d40a020cdcd04e8b016d041795961a8e532a0e1f4041252131089114a251791bf57794cadb7d636342f5d1c\",\n    \"0x899023ba6096a181448d927fed7a0fe858be4eac4082a42e30b3050ee065278d72fa9b9d5ce3bc1372d4cbd30a2f2976\",\n    \"0xa28f176571e1a9124f95973f414d5bdbf5794d41c3839d8b917100902ac4e2171eb940431236cec93928a60a77ede793\",\n    \"0x838dbe5bcd29c4e465d02350270fa0036cd46f8730b13d91e77afb7f5ed16525d0021d3b2ae173a76c378516a903e0cb\",\n    \"0x8e105d012dd3f5d20f0f1c4a7e7f09f0fdd74ce554c3032e48da8cce0a77260d7d47a454851387770f5c256fa29bcb88\",\n    \"0x8f4df0f9feeb7a487e1d138d13ea961459a6402fd8f8cabb226a92249a0d04ded5971f3242b9f90d08da5ff66da28af6\",\n    \"0xad1cfda4f2122a20935aa32fb17c536a3653a18617a65c6836700b5537122af5a8206befe9eaea781c1244c43778e7f1\",\n    \"0x832c6f01d6571964ea383292efc8c8fa11e61c0634a25fa180737cc7ab57bc77f25e614aac9a2a03d98f27b3c1c29de2\",\n    \"0x903f89cc13ec6685ac7728521898781fecb300e9094ef913d530bf875c18bcc3ceed7ed51e7b482d45619ab4b025c2e9\",\n    \"0xa03c474bb915aad94f171e8d96f46abb2a19c9470601f4c915512ec8b9e743c3938450a2a5b077b4618b9df8809e1dc1\",\n    \"0x83536c8456f306045a5f38ae4be2e350878fa7e164ea408d467f8c3bc4c2ee396bd5868008c089183868e4dfad7aa50b\",\n    \"0x88f26b4ea1b236cb326cd7ad7e2517ec8c4919598691474fe15d09cabcfc37a8d8b1b818f4d112432ee3a716b0f37871\",\n    \"0xa44324e3fe96e9c12b40ded4f0f3397c8c7ee8ff5e96441118d8a6bfad712d3ac990b2a6a23231a8f691491ac1fd480f\",\n    \"0xb0de4693b4b9f932191a21ee88629964878680152a82996c0019ffc39f8d9369bbe2fe5844b68d6d9589ace54af947e4\",\n    \"0x8e5d8ba948aea5fd26035351a960e87f0d23efddd8e13236cc8e4545a3dda2e9a85e6521efb8577e03772d3637d213d9\",\n    \"0x93efc82d2017e9c57834a1246463e64774e56183bb247c8fc9dd98c56817e878d97b05f5c8d900acf1fbbbca6f146556\",\n    \"0x8731176363ad7658a2862426ee47a5dce9434216cef60e6045fa57c40bb3ce1e78dac4510ae40f1f31db5967022ced32\",\n    \"0xb10c9a96745722c85bdb1a693100104d560433d45b9ac4add54c7646a7310d8e9b3ca9abd1039d473ae768a18e489845\",\n    \"0xa2ac374dfbb464bf850b4a2caf15b112634a6428e8395f9c9243baefd2452b4b4c61b0cb2836d8eae2d57d4900bf407e\",\n    \"0xb69fe3ded0c4f5d44a09a0e0f398221b6d1bf5dbb8bc4e338b93c64f1a3cac1e4b5f73c2b8117158030ec03787f4b452\",\n    \"0x8852cdbaf7d0447a8c6f211b4830711b3b5c105c0f316e3a6a18dcfbb9be08bd6f4e5c8ae0c3692da08a2dfa532f9d5c\",\n    \"0x93bbf6d7432a7d98ade3f94b57bf9f4da9bc221a180a370b113066dd42601bb9e09edd79e2e6e04e00423399339eebda\",\n    \"0xa80941c391f1eeafc1451c59e4775d6a383946ff22997aeaadf806542ba451d3b0f0c6864eeba954174a296efe2c1550\",\n    \"0xa045fe2bb011c2a2f71a0181a8f457a3078470fb74c628eab8b59aef69ffd0d649723bf74d6885af3f028bc5a104fb39\",\n    \"0xb9d8c35911009c4c8cad64692139bf3fc16b78f5a19980790cb6a7aea650a25df4231a4437ae0c351676a7e42c16134f\",\n    \"0x94c79501ded0cfcbab99e1841abe4a00a0252b3870e20774c3da16c982d74c501916ec28304e71194845be6e3113c7ab\",\n    \"0x900a66418b082a24c6348d8644ddb1817df5b25cb33044a519ef47cc8e1f7f1e38d2465b7b96d32ed472d2d17f8414c6\",\n    \"0xb26f45d393b8b2fcb29bdbb16323dc7f4b81c09618519ab3a39f8ee5bd148d0d9f3c0b5dfab55b5ce14a1cb9206d777b\",\n    \"0xaa1a87735fc493a80a96a9a57ca40a6d9c32702bfcaa9869ce1a116ae65d69cefe2f3e79a12454b4590353e96f8912b4\",\n    \"0xa922b188d3d0b69b4e4ea2a2aa076566962844637da12c0832105d7b31dea4a309eee15d12b7a336be3ea36fcbd3e3b7\",\n    \"0x8f3841fcf4105131d8c4d9885e6e11a46c448226401cf99356c291fadb864da9fa9d30f3a73c327f23f9fd99a11d633e\",\n    \"0x9791d1183fae270e226379af6c497e7da803ea854bb20afa74b253239b744c15f670ee808f708ede873e78d79a626c9a\",\n    \"0xa4cad52e3369491ada61bf28ada9e85de4516d21c882e5f1cd845bea9c06e0b2887b0c5527fcff6fc28acd3c04f0a796\",\n    \"0xb9ac86a900899603452bd11a7892a9bfed8054970bfcbeaa8c9d1930db891169e38d6977f5258c25734f96c8462eee3b\",\n    \"0xa3a154c28e5580656a859f4efc2f5ebfa7eaa84ca40e3f134fa7865e8581586db74992dbfa4036aa252fba103773ddde\",\n    \"0x95cc2a0c1885a029e094f5d737e3ecf4d26b99036453a8773c77e360101f9f98676ee246f6f732a377a996702d55691f\",\n    \"0x842651bbe99720438d8d4b0218feb60481280c05beb17750e9ca0d8c0599a60f873b7fbdcc7d8835ba9a6d57b16eec03\",\n    \"0x81ee54699da98f5620307893dcea8f64670609fa20e5622265d66283adeac122d458b3308c5898e6c57c298db2c8b24f\",\n    \"0xb97868b0b2bc98032d68352a535a1b341b9ff3c7af4e3a7f3ebc82d3419daa1b5859d6aedc39994939623c7cd878bd9b\",\n    \"0xb60325cd5d36461d07ef253d826f37f9ee6474a760f2fff80f9873d01fd2b57711543cdc8d7afa1c350aa753c2e33dea\",\n    \"0x8c205326c11d25a46717b780c639d89714c7736c974ae71287e3f4b02e6605ac2d9b4928967b1684f12be040b7bf2dd3\",\n    \"0x95a392d82db51e26ade6c2ccd3396d7e40aff68fa570b5951466580d6e56dda51775dce5cf3a74a7f28c3cb2eb551c4d\",\n    \"0x8f2cc8071eb56dffb70bda6dd433b556221dc8bba21c53353c865f00e7d4d86c9e39f119ea9a8a12ef583e9a55d9a6b6\",\n    \"0x9449a71af9672aaf8856896d7e3d788b22991a7103f75b08c0abbcc2bfe60fda4ed8ce502cea4511ff0ea52a93e81222\",\n    \"0x857090ab9fdb7d59632d068f3cc8cf27e61f0d8322d30e6b38e780a1f05227199b4cd746aac1311c36c659ef20931f28\",\n    \"0x98a891f4973e7d9aaf9ac70854608d4f7493dffc7e0987d7be9dd6029f6ea5636d24ef3a83205615ca1ff403750058e1\",\n    \"0xa486e1365bbc278dd66a2a25d258dc82f46b911103cb16aab3945b9c95ae87b386313a12b566df5b22322ede0afe25ad\",\n    \"0xa9a1eb399ed95d396dccd8d1ac718043446f8b979ec62bdce51c617c97a312f01376ab7fb87d27034e5f5570797b3c33\",\n    \"0xb7abc3858d7a74bb446218d2f5a037e0fae11871ed9caf44b29b69c500c1fa1dcfad64c9cdccc9d80d5e584f06213deb\",\n    \"0x8cfb09fe2e202faa4cebad932b1d35f5ca204e1c2a0c740a57812ac9a6792130d1312aabd9e9d4c58ca168bfebd4c177\",\n    \"0xa90a305c2cd0f184787c6be596fa67f436afd1f9b93f30e875f817ac2aae8bdd2e6e656f6be809467e6b3ad84adb86b1\",\n    \"0x80a9ef993c2b009ae172cc8f7ec036f5734cf4f4dfa06a7db4d54725e7fbfae5e3bc6f22687bdbb6961939d6f0c87537\",\n    \"0x848ade1901931e72b955d7db1893f07003e1708ff5d93174bac5930b9a732640f0578839203e9b77eb27965c700032d3\",\n    \"0x93fdf4697609c5ae9c33b9ca2f5f1af44abeb2b98dc4fdf732cf7388de086f410730dc384d9b7a7f447bb009653c8381\",\n    \"0x89ce3fb805aea618b5715c0d22a9f46da696b6fa86794f56fdf1d44155a33d42daf1920bcbe36cbacf3cf4c92df9cbc7\",\n    \"0x829ce2c342cf82aa469c65f724f308f7a750bd1494adc264609cd790c8718b8b25b5cab5858cf4ee2f8f651d569eea67\",\n    \"0xaf2f0cee7bf413204be8b9df59b9e4991bc9009e0d6dbe6815181df0ec2ca93ab8f4f3135b1c14d8f53d74bff0bd6f27\",\n    \"0xb87998cecf7b88cde93d1779f10a521edd5574a2fbd240102978639ec57433ba08cdb53849038a329cebbe74657268d2\",\n    \"0xa64542a1261a6ed3d720c2c3a802303aad8c4c110c95d0f12e05c1065e66f42da494792b6bfc5b9272363f3b1d457f58\",\n    \"0x86a6fd042e4f282fadf07a4bfee03fc96a3aea49f7a00f52bf249a20f1ec892326855410e61f37fbb27d9305eb2fc713\",\n    \"0x967ea5bc403b6db269682f7fd0df90659350d7e1aa66bc4fab4c9dfcd75ed0bba4b52f1cebc5f34dc8ba810793727629\",\n    \"0xa52990f9f3b8616ce3cdc2c74cd195029e6a969753dcf2d1630438700e7d6ebde36538532b3525ac516f5f2ce9dd27a3\",\n    \"0xa64f7ff870bab4a8bf0d4ef6f5c744e9bf1021ed08b4c80903c7ad318e80ba1817c3180cc45cb5a1cae1170f0241655f\",\n    \"0xb00f706fa4de1f663f021e8ad3d155e84ce6084a409374b6e6cd0f924a0a0b51bebaaaf1d228c77233a73b0a5a0df0e9\",\n    \"0x8b882cc3bff3e42babdb96df95fb780faded84887a0a9bab896bef371cdcf169d909f5658649e93006aa3c6e1146d62e\",\n    \"0x9332663ef1d1dcf805c3d0e4ce7a07d9863fb1731172e766b3cde030bf81682cc011e26b773fb9c68e0477b4ae2cfb79\",\n    \"0xa8aa8151348dbd4ef40aaeb699b71b4c4bfd3218560c120d85036d14f678f6736f0ec68e80ce1459d3d35feccc575164\",\n    \"0xa16cd8b729768f51881c213434aa28301fa78fcb554ddd5f9012ee1e4eae7b5cb3dd88d269d53146dea92d10790faf0b\",\n    \"0x86844f0ef9d37142faf3b1e196e44fbe280a3ba4189aa05c356778cb9e3b388a2bff95eed305ada8769935c9974e4c57\",\n    \"0xae2eec6b328fccf3b47bcdac32901ac2744a51beb410b04c81dea34dee4912b619466a4f5e2780d87ecefaebbe77b46d\",\n    \"0x915df4c38d301c8a4eb2dc5b1ba0ffaad67cbb177e0a80095614e9c711f4ef24a4cef133f9d982a63d2a943ba6c8669d\",\n    \"0xae6a2a4dedfc2d1811711a8946991fede972fdf2a389b282471280737536ffc0ac3a6d885b1f8bda0366eb0b229b9979\",\n    \"0xa9b628c63d08b8aba6b1317f6e91c34b2382a6c85376e8ef2410a463c6796740ae936fc4e9e0737cb9455d1daa287bd8\",\n    \"0x848e30bf7edf2546670b390d5cf9ab71f98fcb6add3c0b582cb34996c26a446dee5d1bde4fdcde4fc80c10936e117b29\",\n    \"0x907d6096c7c8c087d1808dd995d5d2b9169b3768c3f433475b50c2e2bd4b082f4d543afd8b0b0ddffa9c66222a72d51d\",\n    \"0xa59970a2493b07339124d763ac9d793c60a03354539ecbcf6035bc43d1ea6e35718202ae6d7060b7d388f483d971573c\",\n    \"0xb9cfef2af9681b2318f119d8611ff6d9485a68d8044581b1959ab1840cbca576dbb53eec17863d2149966e9feb21122f\",\n    \"0xad47271806161f61d3afa45cdfe2babceef5e90031a21779f83dc8562e6076680525b4970b2f11fe9b2b23c382768323\",\n    \"0x8e425a99b71677b04fe044625d338811fbb8ee32368a424f6ab2381c52e86ee7a6cecedf777dc97181519d41c351bc22\",\n    \"0x86b55b54d7adefc12954a9252ee23ae83efe8b5b4b9a7dc307904413e5d69868c7087a818b2833f9b004213d629be8ad\",\n    \"0xa14fda6b93923dd11e564ae4457a66f397741527166e0b16a8eb91c6701c244fd1c4b63f9dd3515193ec88fa6c266b35\",\n    \"0xa9b17c36ae6cd85a0ed7f6cabc5b47dc8f80ced605db327c47826476dc1fb8f8669aa7a7dc679fbd4ee3d8e8b4bd6a6f\",\n    \"0x82a0829469c1458d959c821148f15dacae9ea94bf56c59a6ab2d4dd8b3d16d73e313b5a3912a6c1f131d73a8f06730c4\",\n    \"0xb22d56d549a53eaef549595924bdb621ff807aa4513feedf3fdcbf7ba8b6b9cfa4481c2f67fc642db397a6b794a8b63a\",\n    \"0x974c59c24392e2cb9294006cbe3c52163e255f3bd0c2b457bdc68a6338e6d5b6f87f716854492f8d880a6b896ccf757c\",\n    \"0xb70d247ba7cad97c50b57f526c2ba915786e926a94e8f8c3eebc2e1be6f4255411b9670e382060049c8f4184302c40b2\",\n    \"0xad80201fe75ef21c3ddbd98cf23591e0d7a3ba1036dfe77785c32f44755a212c31f0ceb0a0b6f5ee9b6dc81f358d30c3\",\n    \"0x8c656e841f9bb90b9a42d425251f3fdbc022a604d75f5845f479ed4be23e02aaf9e6e56cde351dd7449c50574818a199\",\n    \"0x8b88dd3fa209d3063b7c5b058f7249ee9900fbc2287d16da61a0704a0a1d71e45d9c96e1cda7fdf9654534ec44558b22\",\n    \"0x961da00cc8750bd84d253c08f011970ae1b1158ad6778e8ed943d547bceaf52d6d5a212a7de3bf2706688c4389b827d2\",\n    \"0xa5dd379922549a956033e3d51a986a4b1508e575042b8eaa1df007aa77cf0b8c2ab23212f9c075702788fa9c53696133\",\n    \"0xac8fcfde3a349d1e93fc8cf450814e842005c545c4844c0401bc80e6b96cdb77f29285a14455e167c191d4f312e866cd\",\n    \"0xac63d79c799783a8466617030c59dd5a8f92ee6c5204676fd8d881ce5f7f8663bdbeb0379e480ea9b6340ab0dc88e574\",\n    \"0x805874fde19ce359041ae2bd52a39e2841acabfd31f965792f2737d7137f36d4e4722ede8340d8c95afa6af278af8acb\",\n    \"0x8d2f323a228aa8ba7b7dc1399138f9e6b41df1a16a7069003ab8104b8b68506a45141bc5fe66acf430e23e13a545190b\",\n    \"0xa1610c721a2d9af882bb6b39bea97cff1527a3aea041d25934de080214ae77c959e79957164440686d15ab301e897d4d\",\n    \"0xaba16d29a47fc36f12b654fde513896723e2c700c4190f11b26aa4011da57737ad717daa02794aa3246e4ae5f0b0cc3a\",\n    \"0xa406db2f15fdd135f346cc4846623c47edd195e80ba8c7cb447332095314d565e4040694ca924696bb5ee7f8996ea0ba\",\n    \"0x8b30e2cd9b47d75ba57b83630e40f832249af6c058d4f490416562af451993eec46f3e1f90bc4d389e4c06abd1b32a46\",\n    \"0xaacf9eb7036e248e209adbfc3dd7ce386569ea9b312caa4b240726549db3c68c4f1c8cbf8ed5ea9ea60c7e57c9df3b8e\",\n    \"0xb20fcac63bf6f5ee638a42d7f89be847f348c085ddcbec3fa318f4323592d136c230495f188ef2022aa355cc2b0da6f9\",\n    \"0x811eff750456a79ec1b1249d76d7c1547065b839d8d4aaad860f6d4528eb5b669473dcceeeea676cddbc3980b68461b7\",\n    \"0xb52d14ae33f4ab422f953392ae76a19c618cc31afc96290bd3fe2fb44c954b5c92c4789f3f16e8793f2c0c1691ade444\",\n    \"0xa7826dafeeba0db5b66c4dfcf2b17fd7b40507a5a53ac2e42942633a2cb30b95ba1739a6e9f3b7a0e0f1ec729bf274e2\",\n    \"0x8acfd83ddf7c60dd7c8b20c706a3b972c65d336b8f9b3d907bdd8926ced271430479448100050b1ef17578a49c8fa616\",\n    \"0xaf0c69f65184bb06868029ad46f8465d75c36814c621ac20a5c0b06a900d59305584f5a6709683d9c0e4b6cd08d650a6\",\n    \"0xb6cc8588191e00680ee6c3339bd0f0a17ad8fd7f4be57d5d7075bede0ea593a19e67f3d7c1a20114894ee5bfcab71063\",\n    \"0xa82fd4f58635129dbb6cc3eb9391cf2d28400018b105fc41500fbbd12bd890b918f97d3d359c29dd3b4c4e34391dfab0\",\n    \"0x92fc544ed65b4a3625cf03c41ddff7c039bc22d22c0d59dcc00efd5438401f2606adb125a1d5de294cca216ec8ac35a3\",\n    \"0x906f67e4a32582b71f15940523c0c7ce370336935e2646bdaea16a06995256d25e99df57297e39d6c39535e180456407\",\n    \"0x97510337ea5bbd5977287339197db55c60533b2ec35c94d0a460a416ae9f60e85cee39be82abeeacd5813cf54df05862\",\n    \"0x87e6894643815c0ea48cb96c607266c5ee4f1f82ba5fe352fb77f9b6ed14bfc2b8e09e80a99ac9047dfcf62b2ae26795\",\n    \"0xb6fd55dd156622ad7d5d51b7dde75e47bd052d4e542dd6449e72411f68275775c846dde301e84613312be8c7bce58b07\",\n    \"0xb98461ac71f554b2f03a94e429b255af89eec917e208a8e60edf5fc43b65f1d17a20de3f31d2ce9f0cb573c25f2f4d98\",\n    \"0x96f0dea40ca61cefbee41c4e1fe9a7d81fbe1f49bb153d083ab70f5d0488a1f717fd28cedcf6aa18d07cce2c62801898\",\n    \"0x8d7c3ab310184f7dc34b6ce4684e4d29a31e77b09940448ea4daac730b7eb308063125d4dd229046cf11bfd521b771e0\",\n    \"0x96f0564898fe96687918bbf0a6adead99cf72e3a35ea3347e124af9d006221f8e82e5a9d2fe80094d5e8d48e610f415e\",\n    \"0xad50fcb92c2675a398cf07d4c40a579e44bf8d35f27cc330b57e54d5ea59f7d898af0f75dccfe3726e5471133d70f92b\",\n    \"0x828beed62020361689ae7481dd8f116902b522fb0c6c122678e7f949fdef70ead011e0e6bffd25678e388744e17cdb69\",\n    \"0x8349decac1ca16599eee2efc95bcaabf67631107da1d34a2f917884bd70dfec9b4b08ab7bc4379d6c73b19c0b6e54fb8\",\n    \"0xb2a6a2e50230c05613ace9e58bb2e98d94127f196f02d9dddc53c43fc68c184549ca12d713cb1b025d8260a41e947155\",\n    \"0x94ff52181aadae832aed52fc3b7794536e2a31a21fc8be3ea312ca5c695750d37f08002f286b33f4023dba1e3253ecfa\",\n    \"0xa21d56153c7e5972ee9a319501be4faff199fdf09bb821ea9ce64aa815289676c00f105e6f00311b3a5b627091b0d0fc\",\n    \"0xa27a60d219f1f0c971db73a7f563b371b5c9fc3ed1f72883b2eac8a0df6698400c9954f4ca17d7e94e44bd4f95532afb\",\n    \"0xa2fc56fae99b1f18ba5e4fe838402164ce82f8a7f3193d0bbd360c2bac07c46f9330c4c7681ffb47074c6f81ee6e7ac6\",\n    \"0xb748e530cd3afb96d879b83e89c9f1a444f54e55372ab1dcd46a0872f95ce8f49cf2363fc61be82259e04f555937ed16\",\n    \"0x8bf8993e81080c7cbba1e14a798504af1e4950b2f186ab3335b771d6acaee4ffe92131ae9c53d74379d957cb6344d9cd\",\n    \"0x96774d0ef730d22d7ab6d9fb7f90b9ead44285219d076584a901960542756700a2a1603cdf72be4708b267200f6c36a9\",\n    \"0xb47703c2ab17be1e823cc7bf3460db1d6760c0e33862c90ca058845b2ff234b0f9834ddba2efb2ee1770eb261e7d8ffd\",\n    \"0x84319e67c37a9581f8b09b5e4d4ae88d0a7fb4cbb6908971ab5be28070c3830f040b1de83ee663c573e0f2f6198640e4\",\n    \"0x96811875fa83133e0b3c0e0290f9e0e28bca6178b77fdf5350eb19344d453dbd0d71e55a0ef749025a5a2ca0ad251e81\",\n    \"0x81a423423e9438343879f2bfd7ee9f1c74ebebe7ce3cfffc8a11da6f040cc4145c3b527bd3cf63f9137e714dbcb474ef\",\n    \"0xb8c3535701ddbeec2db08e17a4fa99ba6752d32ece5331a0b8743676f421fcb14798afc7c783815484f14693d2f70db8\",\n    \"0x81aee980c876949bf40782835eec8817d535f6f3f7e00bf402ddd61101fdcd60173961ae90a1cf7c5d060339a18c959d\",\n    \"0x87e67b928d97b62c49dac321ce6cb680233f3a394d4c9a899ac2e8db8ccd8e00418e66cdfd68691aa3cb8559723b580c\",\n    \"0x8eac204208d99a2b738648df96353bbb1b1065e33ee4f6bba174b540bbbd37d205855e1f1e69a6b7ff043ca377651126\",\n    \"0x848e6e7a54ad64d18009300b93ea6f459ce855971dddb419b101f5ac4c159215626fadc20cc3b9ab1701d8f6dfaddd8b\",\n    \"0x88aa123d9e0cf309d46dddb6acf634b1ade3b090a2826d6e5e78669fa1220d6df9a6697d7778cd9b627db17eea846126\",\n    \"0x9200c2a629b9144d88a61151b661b6c4256cc5dadfd1e59a8ce17a013c2d8f7e754aabe61663c3b30f1bc47784c1f8cf\",\n    \"0xb6e1a2827c3bdda91715b0e1b1f10dd363cef337e7c80cac1f34165fc0dea7c8b69747e310563db5818390146ce3e231\",\n    \"0x92c333e694f89f0d306d54105b2a5dcc912dbe7654d9e733edab12e8537350815be472b063e56cfde5286df8922fdecb\",\n    \"0xa6fac04b6d86091158ebb286586ccfec2a95c9786e14d91a9c743f5f05546073e5e3cc717635a0c602cad8334e922346\",\n    \"0xa581b4af77feebc1fb897d49b5b507c6ad513d8f09b273328efbb24ef0d91eb740d01b4d398f2738125dacfe550330cd\",\n    \"0x81c4860cccf76a34f8a2bc3f464b7bfd3e909e975cce0d28979f457738a56e60a4af8e68a3992cf273b5946e8d7f76e2\",\n    \"0x8d1eaa09a3180d8af1cbaee673db5223363cc7229a69565f592fa38ba0f9d582cedf91e15dabd06ebbf2862fc0feba54\",\n    \"0x9832f49b0147f4552402e54593cfa51f99540bffada12759b71fcb86734be8e500eea2d8b3d036710bdf04c901432de9\",\n    \"0x8bdb0e8ec93b11e5718e8c13cb4f5de545d24829fd76161216340108098dfe5148ed25e3b57a89a516f09fa79043734d\",\n    \"0xab96f06c4b9b0b2c0571740b24fca758e6976315053a7ecb20119150a9fa416db2d3a2e0f8168b390bb063f0c1caf785\",\n    \"0xab777f5c52acd62ecf4d1f168b9cc8e1a9b45d4ec6a8ff52c583e867c2239aba98d7d3af977289b367edce03d9c2dfb1\",\n    \"0xa09d3ce5e748da84802436951acc3d3ea5d8ec1d6933505ed724d6b4b0d69973ab0930daec9c6606960f6e541e4a3ce2\",\n    \"0x8ef94f7be4d85d5ad3d779a5cf4d7b2fc3e65c52fb8e1c3c112509a4af77a0b5be994f251e5e40fabeeb1f7d5615c22b\",\n    \"0xa7406a5bf5708d9e10922d3c5c45c03ef891b8d0d74ec9f28328a72be4cdc05b4f2703fa99366426659dfca25d007535\",\n    \"0xb7f52709669bf92a2e070bfe740f422f0b7127392c5589c7f0af71bb5a8428697c762d3c0d74532899da24ea7d8695c2\",\n    \"0xb9dfb0c8df84104dbf9239ccefa4672ef95ddabb8801b74997935d1b81a78a6a5669a3c553767ec19a1281f6e570f4ff\",\n    \"0xae4d5c872156061ce9195ac640190d8d71dd406055ee43ffa6f9893eb24b870075b74c94d65bc1d5a07a6573282b5520\",\n    \"0xafe6bd3eb72266d333f1807164900dcfa02a7eb5b1744bb3c86b34b3ee91e3f05e38fa52a50dc64eeb4bdb1dd62874b8\",\n    \"0x948043cf1bc2ef3c01105f6a78dc06487f57548a3e6ef30e6ebc51c94b71e4bf3ff6d0058c72b6f3ecc37efd7c7fa8c0\",\n    \"0xa22fd17c2f7ffe552bb0f23fa135584e8d2d8d75e3f742d94d04aded2a79e22a00dfe7acbb57d44e1cdb962fb22ae170\",\n    \"0x8cd0f4e9e4fb4a37c02c1bde0f69359c43ab012eb662d346487be0c3758293f1ca560122b059b091fddce626383c3a8f\",\n    \"0x90499e45f5b9c81426f3d735a52a564cafbed72711d9279fdd88de8038e953bc48c57b58cba85c3b2e4ce56f1ddb0e11\",\n    \"0x8c30e4c034c02958384564cac4f85022ef36ab5697a3d2feaf6bf105049675bbf23d01b4b6814711d3d9271abff04cac\",\n    \"0x81f7999e7eeea30f3e1075e6780bbf054f2fb6f27628a2afa4d41872a385b4216dd5f549da7ce6cf39049b2251f27fb7\",\n    \"0xb36a7191f82fc39c283ffe53fc1f5a9a00b4c64eee7792a8443475da9a4d226cf257f226ea9d66e329af15d8f04984ec\",\n    \"0xaad4da528fdbb4db504f3041c747455baff5fcd459a2efd78f15bdf3aea0bdb808343e49df88fe7a7c8620009b7964a3\",\n    \"0x99ebd8c6dd5dd299517fb6381cfc2a7f443e6e04a351440260dd7c2aee3f1d8ef06eb6c18820b394366ecdfd2a3ce264\",\n    \"0x8873725b81871db72e4ec3643084b1cdce3cbf80b40b834b092767728605825c19b6847ad3dcf328438607e8f88b4410\",\n    \"0xb008ee2f895daa6abd35bd39b6f7901ae4611a11a3271194e19da1cdcc7f1e1ea008fe5c5440e50d2c273784541ad9c5\",\n    \"0x9036feafb4218d1f576ef89d0e99124e45dacaa6d816988e34d80f454d10e96809791d5b78f7fd65f569e90d4d7238c5\",\n    \"0x92073c1d11b168e4fa50988b0288638b4868e48bbc668c5a6dddf5499875d53be23a285acb5e4bad60114f6cf6c556e9\",\n    \"0x88c87dfcb8ba6cbfe7e1be081ccfadbd589301db2cb7c99f9ee5d7db90aa297ed1538d5a867678a763f2deede5fd219a\",\n    \"0xb42a562805c661a50f5dea63108002c0f27c0da113da6a9864c9feb5552225417c0356c4209e8e012d9bcc9d182c7611\",\n    \"0x8e6317d00a504e3b79cd47feb4c60f9df186467fe9ca0f35b55c0364db30528f5ff071109dabb2fc80bb9cd4949f0c24\",\n    \"0xb7b1ea6a88694f8d2f539e52a47466695e39e43a5eb9c6f23bca15305fe52939d8755cc3ac9d6725e60f82f994a3772f\",\n    \"0xa3cd55161befe795af93a38d33290fb642b8d80da8b786c6e6fb02d393ea308fbe87f486994039cbd7c7b390414594b6\",\n    \"0xb416d2d45b44ead3b1424e92c73c2cf510801897b05d1724ff31cbd741920cd858282fb5d6040fe1f0aa97a65bc49424\",\n    \"0x950ee01291754feace97c2e933e4681e7ddfbc4fcd079eb6ff830b0e481d929c93d0c7fb479c9939c28ca1945c40da09\",\n    \"0x869bd916aee8d86efe362a49010382674825d49195b413b4b4018e88ce43fe091b475d0b863ff0ba2259400f280c2b23\",\n    \"0x9782f38cd9c9d3385ec286ebbc7cba5b718d2e65a5890b0a5906b10a89dc8ed80d417d71d7c213bf52f2af1a1f513ea7\",\n    \"0x91cd33bc2628d096269b23faf47ee15e14cb7fdc6a8e3a98b55e1031ea0b68d10ba30d97e660f7e967d24436d40fad73\",\n    \"0x8becc978129cc96737034c577ae7225372dd855da8811ae4e46328e020c803833b5bdbc4a20a93270e2b8bd1a2feae52\",\n    \"0xa36b1d8076783a9522476ce17f799d78008967728ce920531fdaf88303321bcaf97ecaa08e0c01f77bc32e53c5f09525\",\n    \"0xb4720e744943f70467983aa34499e76de6d59aa6fadf86f6b787fdce32a2f5b535b55db38fe2da95825c51002cfe142d\",\n    \"0x91ad21fc502eda3945f6de874d1b6bf9a9a7711f4d61354f9e5634fc73f9c06ada848de15ab0a75811d3250be862827d\",\n    \"0x84f78e2ebf5fc077d78635f981712daf17e2475e14c2a96d187913006ad69e234746184a51a06ef510c9455b38acb0d7\",\n    \"0x960aa7906e9a2f11db64a26b5892ac45f20d2ccb5480f4888d89973beb6fa0dfdc06d68d241ff5ffc7f1b82b1aac242d\",\n    \"0xa99365dcd1a00c66c9db6924b97c920f5c723380e823b250db85c07631b320ec4e92e586f7319e67a522a0578f7b6d6c\",\n    \"0xa25d92d7f70cf6a88ff317cfec071e13774516da664f5fac0d4ecaa65b8bf4eb87a64a4d5ef2bd97dfae98d388dbf5cc\",\n    \"0xa7af47cd0041295798f9779020a44653007444e8b4ef0712982b06d0dcdd434ec4e1f7c5f7a049326602cb605c9105b7\",\n    \"0xaefe172eac5568369a05980931cc476bebd9dea573ba276d59b9d8c4420784299df5a910033b7e324a6c2dfc62e3ef05\",\n    \"0xb69bc9d22ffa645baa55e3e02522e9892bb2daa7fff7c15846f13517d0799766883ee09ae0869df4139150c5b843ca8a\",\n    \"0x95a10856140e493354fdd12722c7fdded21b6a2ffbc78aa2697104af8ad0c8e2206f44b0bfee077ef3949d46bbf7c16b\",\n    \"0x891f2fcd2c47cbea36b7fa715968540c233313f05333f09d29aba23c193f462ed490dd4d00969656e89c53155fdfe710\",\n    \"0xa6c33e18115e64e385c843dde34e8a228222795c7ca90bc2cc085705d609025f3351d9be61822c69035a49fb3e48f2d5\",\n    \"0xb87fb12f12c0533b005adad0487f03393ff682e13575e3cb57280c3873b2c38ba96a63c49eef7a442753d26b7005230b\",\n    \"0xb905c02ba451bfd411c135036d92c27af3b0b1c9c2f1309d6948544a264b125f39dd41afeff4666b12146c545adc168a\",\n    \"0x8b29c513f43a78951cf742231cf5457a6d9d55edf45df5481a0f299a418d94effef561b15d2c1a01d1b8067e7153fda9\",\n    \"0xb9941cccd51dc645920d2781c81a317e5a33cb7cf76427b60396735912cb6d2ca9292bb4d36b6392467d390d2c58d9f3\",\n    \"0xa8546b627c76b6ef5c93c6a98538d8593dbe21cb7673fd383d5401b0c935eea0bdeeefeb1af6ad41bad8464fb87bbc48\",\n    \"0xaa286b27de2812de63108a1aec29d171775b69538dc6198640ac1e96767c2b83a50391f49259195957d457b493b667c9\",\n    \"0xa932fb229f641e9abbd8eb2bd874015d97b6658ab6d29769fc23b7db9e41dd4f850382d4c1f08af8f156c5937d524473\",\n    \"0xa1412840fcc86e2aeec175526f2fb36e8b3b8d21a78412b7266daf81e51b3f68584ed8bd42a66a43afdd8c297b320520\",\n    \"0x89c78be9efb624c97ebca4fe04c7704fa52311d183ffd87737f76b7dadc187c12c982bd8e9ed7cd8beb48cdaafd2fd01\",\n    \"0xa3f5ddec412a5bec0ce15e3bcb41c6214c2b05d4e9135a0d33c8e50a78eaba71e0a5a6ea8b45854dec5c2ed300971fc2\",\n    \"0x9721f9cec7a68b7758e3887548790de49fa6a442d0396739efa20c2f50352a7f91d300867556d11a703866def2d5f7b5\",\n    \"0xa23764e140a87e5991573521af039630dd28128bf56eed2edbed130fd4278e090b60cf5a1dca9de2910603d44b9f6d45\",\n    \"0xa1a6494a994215e48ab55c70efa8ffdddce6e92403c38ae7e8dd2f8288cad460c6c7db526bbdf578e96ca04d9fe12797\",\n    \"0xb1705ea4cb7e074efe0405fc7b8ee2ec789af0426142f3ec81241cacd4f7edcd88e39435e4e4d8e7b1df64f3880d6613\",\n    \"0x85595d061d677116089a6064418b93eb44ff79e68d12bd9625078d3bbc440a60d0b02944eff6054433ee34710ae6fbb4\",\n    \"0x9978d5e30bedb7526734f9a1febd973a70bfa20890490e7cc6f2f9328feab1e24f991285dbc3711d892514e2d7d005ad\",\n    \"0xaf30243c66ea43b9f87a061f947f7bce745f09194f6e95f379c7582b9fead920e5d6957eaf05c12ae1282ada4670652f\",\n    \"0xa1930efb473f88001e47aa0b2b2a7566848cccf295792e4544096ecd14ee5d7927c173a8576b405bfa2eec551cd67eb5\",\n    \"0xb0446d1c590ee5a45f7e22d269c044f3848c97aec1d226b44bfd0e94d9729c28a38bccddc3a1006cc5fe4e3c24f001f2\",\n    \"0xb8a8380172df3d84b06176df916cf557966d4f2f716d3e9437e415d75b646810f79f2b2b71d857181b7fc944018883a3\",\n    \"0xa563afec25b7817bfa26e19dc9908bc00aa8fc3d19be7d6de23648701659009d10e3e4486c28e9c6b13d48231ae29ac5\",\n    \"0xa5a8e80579de886fb7d6408f542791876885947b27ad6fa99a8a26e381f052598d7b4e647b0115d4b5c64297e00ce28e\",\n    \"0x8f87afcc7ad33c51ac719bade3cd92da671a37a82c14446b0a2073f4a0a23085e2c8d31913ed2d0be928f053297de8f6\",\n    \"0xa43c455ce377e0bc434386c53c752880687e017b2f5ae7f8a15c044895b242dffde4c92fb8f8bb50b18470b17351b156\",\n    \"0x8368f8b12a5bceb1dba25adb3a2e9c7dc9b1a77a1f328e5a693f5aec195cd1e06b0fe9476b554c1c25dac6c4a5b640a3\",\n    \"0x919878b27f3671fc78396f11531c032f3e2bd132d04cc234fa4858676b15fb1db3051c0b1db9b4fc49038216f11321ce\",\n    \"0xb48cd67fb7f1242696c1f877da4bdf188eac676cd0e561fbac1a537f7b8229aff5a043922441d603a26aae56a15faee4\",\n    \"0xa3e0fdfd4d29ea996517a16f0370b54787fefe543c2fe73bfc6f9e560c1fd30dad8409859e2d7fa2d44316f24746c712\",\n    \"0x8bb156ade8faf149df7bea02c140c7e392a4742ae6d0394d880a849127943e6f26312033336d3b9fdc0092d71b5efe87\",\n    \"0x8845e5d5cc555ca3e0523244300f2c8d7e4d02aaebcb5bd749d791208856c209a6f84dd99fd55968c9f0ab5f82916707\",\n    \"0xa3e90bb5c97b07789c2f32dff1aec61d0a2220928202f5ad5355ae71f8249237799d6c8a22602e32e572cb12eabe0c17\",\n    \"0xb150bcc391884c996149dc3779ce71f15dda63a759ee9cc05871f5a8379dcb62b047098922c0f26c7bd04deb394c33f9\",\n    \"0x95cd4ad88d51f0f2efcfd0c2df802fe252bb9704d1afbf9c26a248df22d55da87bdfaf41d7bc6e5df38bd848f0b13f42\",\n    \"0xa05a49a31e91dff6a52ac8b9c2cfdd646a43f0d488253f9e3cfbce52f26667166bbb9b608fc358763a65cbf066cd6d05\",\n    \"0xa59c3c1227fdd7c2e81f5e11ef5c406da44662987bac33caed72314081e2eed66055d38137e01b2268e58ec85dd986c0\",\n    \"0xb7020ec3bd73a99861f0f1d88cf5a19abab1cbe14b7de77c9868398c84bb8e18dbbe9831838a96b6d6ca06e82451c67b\",\n    \"0x98d1ff2525e9718ee59a21d8900621636fcd873d9a564b8dceb4be80a194a0148daf1232742730b3341514b2e5a5436c\",\n    \"0x886d97b635975fc638c1b6afc493e5998ca139edba131b75b65cfe5a8e814f11bb678e0eeee5e6e5cd913ad3f2fefdfc\",\n    \"0x8fb9fd928d38d5d813b671c924edd56601dd7163b686c13f158645c2f869d9250f3859aa5463a39258c90fef0f41190a\",\n    \"0xaac35e1cd655c94dec3580bb3800bd9c2946c4a9856f7d725af15fbea6a2d8ca51c8ad2772abed60ee0e3fb9cb24046b\",\n    \"0xb8d71fa0fa05ac9e443c9b4929df9e7f09a919be679692682e614d24227e04894bfc14a5c73a62fb927fedff4a0e4aa7\",\n    \"0xa45a19f11fbbb531a704badbb813ed8088ab827c884ee4e4ebf363fa1132ff7cfa9d28be9c85b143e4f7cdbc94e7cf1a\",\n    \"0x82b54703a4f295f5471b255ab59dce00f0fe90c9fb6e06b9ee48b15c91d43f4e2ef4a96c3118aeb03b08767be58181bb\",\n    \"0x8283264c8e6d2a36558f0d145c18576b6600ff45ff99cc93eca54b6c6422993cf392668633e5df396b9331e873d457e5\",\n    \"0x8c549c03131ead601bc30eb6b9537b5d3beb7472f5bb1bcbbfd1e9f3704477f7840ab3ab7f7dc13bbbbcdff886a462d4\",\n    \"0xafbb0c520ac1b5486513587700ad53e314cb74bfbc12e0b5fbdcfdaac36d342e8b59856196a0d84a25cff6e6e1d17e76\",\n    \"0x89e4c22ffb51f2829061b3c7c1983c5c750cad158e3a825d46f7cf875677da5d63f653d8a297022b5db5845c9271b32b\",\n    \"0xafb27a86c4c2373088c96b9adf4433f2ebfc78ac5c526e9f0510670b6e4e5e0057c0a4f75b185e1a30331b9e805c1c15\",\n    \"0xa18e16b57445f88730fc5d3567bf5a176861dc14c7a08ed2996fe80eed27a0e7628501bcb78a1727c5e9ac55f29c12c4\",\n    \"0x93d61bf88b192d6825cf4e1120af1c17aa0f994d158b405e25437eaeefae049f7b721a206e7cc8a04fdc29d3c42580a1\",\n    \"0xa99f2995a2e3ed2fd1228d64166112038de2f516410aa439f4c507044e2017ea388604e2d0f7121256fadf7fbe7023d1\",\n    \"0x914fd91cffc23c32f1c6d0e98bf660925090d873367d543034654389916f65f552e445b0300b71b61b721a72e9a5983c\",\n    \"0xb42a578a7787b71f924e7def425d849c1c777156b1d4170a8ee7709a4a914e816935131afd9a0412c4cb952957b20828\",\n    \"0x82fb30590e84b9e45db1ec475a39971cf554dc01bcc7050bc89265740725c02e2be5a972168c5170c86ae83e5b0ad2c0\",\n    \"0xb14f8d8e1e93a84976289e0cf0dfa6f3a1809e98da16ee5c4932d0e1ed6bf8a07697fdd4dd86a3df84fb0003353cdcc0\",\n    \"0x85d7a2f4bda31aa2cb208b771fe03291a4ebdaf6f1dc944c27775af5caec412584c1f45bc741fca2a6a85acb3f26ad7d\",\n    \"0xaf02e56ce886ff2253bc0a68faad76f25ead84b2144e5364f3fb9b648f03a50ee9dc0b2c33ebacf7c61e9e43201ef9ef\",\n    \"0x87e025558c8a0b0abd06dfc350016847ea5ced7af2d135a5c9eec9324a4858c4b21510fb0992ec52a73447f24945058e\",\n    \"0x80fff0bafcd058118f5e7a4d4f1ae0912efeb281d2cbe4d34ba8945cc3dbe5d8baf47fb077343b90b8d895c90b297aca\",\n    \"0xb6edcf3a40e7b1c3c0148f47a263cd819e585a51ef31c2e35a29ce6f04c53e413f743034c0d998d9c00a08ba00166f31\",\n    \"0xabb87ed86098c0c70a76e557262a494ff51a30fb193f1c1a32f8e35eafa34a43fcc07aa93a3b7a077d9e35afa07b1a3d\",\n    \"0xa280214cd3bb0fb7ecd2d8bcf518cbd9078417f2b91d2533ec2717563f090fb84f2a5fcfdbbeb2a2a1f8a71cc5aa5941\",\n    \"0xa63083ca7238ea2b57d15a475963cf1d4f550d8cd76db290014a0461b90351f1f26a67d674c837b0b773b330c7c3d534\",\n    \"0xa8fa39064cb585ece5263e2f42f430206476bf261bd50f18d2b694889bd79d04d56410664cecad62690e5c5a20b3f6ff\",\n    \"0x85ba52ce9d700a5dcf6c5b00559acbe599d671ce5512467ff4b6179d7fad550567ce2a9c126a50964e3096458ea87920\",\n    \"0xb913501e1008f076e5eac6d883105174f88b248e1c9801e568fefaffa1558e4909364fc6d9512aa4d125cbd7cc895f05\",\n    \"0x8eb33b5266c8f2ed4725a6ad147a322e44c9264cf261c933cbbe230a43d47fca0f29ec39756b20561dabafadd5796494\",\n    \"0x850ebc8b661a04318c9db5a0515066e6454fa73865aa4908767a837857ecd717387f614acb614a88e075d4edc53a2f5a\",\n    \"0xa08d6b92d866270f29f4ce23a3f5d99b36b1e241a01271ede02817c8ec3f552a5c562db400766c07b104a331835c0c64\",\n    \"0x8131804c89bb3e74e9718bfc4afa547c1005ff676bd4db9604335032b203390cfa54478d45c6c78d1fe31a436ed4be9f\",\n    \"0x9106d94f23cc1eacec8316f16d6f0a1cc160967c886f51981fdb9f3f12ee1182407d2bb24e5b873de58cb1a3ee915a6b\",\n    \"0xa13806bfc3eae7a7000c9d9f1bd25e10218d4e67f59ae798b145b098bca3edad2b1040e3fc1e6310e612fb8818f459ac\",\n    \"0x8c69fbca502046cb5f6db99900a47b34117aef3f4b241690cdb3b84ca2a2fc7833e149361995dc41fa78892525bce746\",\n    \"0x852c473150c91912d58ecb05769222fa18312800c3f56605ad29eec9e2d8667b0b81c379048d3d29100ed2773bb1f3c5\",\n    \"0xb1767f6074426a00e01095dbb1795beb4e4050c6411792cbad6537bc444c3165d1058bafd1487451f9c5ddd209e0ae7e\",\n    \"0x80c600a5fe99354ce59ff0f84c760923dc8ff66a30bf47dc0a086181785ceb01f9b951c4e66df800ea6d705e8bc47055\",\n    \"0xb5cf19002fbc88a0764865b82afcb4d64a50196ea361e5c71dff7de084f4dcbbc34ec94a45cc9e0247bd51da565981aa\",\n    \"0x93e67a254ea8ce25e112d93cc927fadaa814152a2c4ec7d9a56eaa1ed47aec99b7e9916b02e64452cc724a6641729bbb\",\n    \"0xace70b32491bda18eee4a4d041c3bc9effae9340fe7e6c2f5ad975ee0874c17f1a7da7c96bd85fccff9312c518fac6e9\",\n    \"0xab4cfa02065017dd7f1aadc66f2c92f78f0f11b8597c03a5d69d82cb2eaf95a4476a836ac102908f137662472c8d914b\",\n    \"0xa40b8cd8deb8ae503d20364d64cab7c2801b7728a9646ed19c65edea6a842756a2f636283494299584ad57f4bb12cd0b\",\n    \"0x8594e11d5fc2396bcd9dbf5509ce4816dbb2b7305168021c426171fb444d111da5a152d6835ad8034542277011c26c0e\",\n    \"0x8024de98c26b4c994a66628dc304bb737f4b6859c86ded552c5abb81fd4c6c2e19d5a30beed398a694b9b2fdea1dd06a\",\n    \"0x8843f5872f33f54df8d0e06166c1857d733995f67bc54abb8dfa94ad92407cf0179bc91b0a50bbb56cdc2b350d950329\",\n    \"0xb8bab44c7dd53ef9edf497dcb228e2a41282c90f00ba052fc52d57e87b5c8ab132d227af1fcdff9a12713d1f980bcaae\",\n    \"0x982b4d7b29aff22d527fd82d2a52601d95549bfb000429bb20789ed45e5abf1f4b7416c7b7c4b79431eb3574b29be658\",\n    \"0x8eb1f571b6a1878e11e8c1c757e0bc084bab5e82e897ca9be9b7f4b47b91679a8190bf0fc8f799d9b487da5442415857\",\n    \"0xa6e74b588e5af935c8b243e888582ef7718f8714569dd4992920740227518305eb35fab674d21a5551cca44b3e511ef2\",\n    \"0xa30fc2f3a4cb4f50566e82307de73cd7bd8fe2c1184e9293c136a9b9e926a018d57c6e4f308c95b9eb8299e94d90a2a1\",\n    \"0xa50c5869ca5d2b40722c056a32f918d47e0b65ca9d7863ca7d2fb4a7b64fe523fe9365cf0573733ceaadebf20b48fff8\",\n    \"0x83bbdd32c04d17581418cf360749c7a169b55d54f2427390defd9f751f100897b2d800ce6636c5bbc046c47508d60c8c\",\n    \"0xa82904bdf614de5d8deaff688c8a5e7ac5b3431687acbcda8fa53960b7c417a39c8b2e462d7af91ce6d79260f412db8e\",\n    \"0xa4362e31ff4b05d278b033cf5eebea20de01714ae16d4115d04c1da4754269873afc8171a6f56c5104bfd7b0db93c3e7\",\n    \"0xb5b8daa63a3735581e74a021b684a1038cea77168fdb7fdf83c670c2cfabcfc3ab2fc7359069b5f9048188351aef26b5\",\n    \"0xb48d723894b7782d96ac8433c48faca1bdfa5238019c451a7f47d958097cce3ae599b876cf274269236b9d6ff8b6d7ca\",\n    \"0x98ffff6a61a3a6205c7820a91ca2e7176fab5dba02bc194c4d14942ac421cb254183c705506ab279e4f8db066f941c6c\",\n    \"0xae7db24731da2eaa6efc4f7fcba2ecc26940ddd68038dce43acf2cee15b72dc4ef42a7bfdd32946d1ed78786dd7696b3\",\n    \"0xa656db14f1de9a7eb84f6301b4acb2fbf78bfe867f48a270e416c974ab92821eb4df1cb881b2d600cfed0034ac784641\",\n    \"0xaa315f8ecba85a5535e9a49e558b15f39520fce5d4bf43131bfbf2e2c9dfccc829074f9083e8d49f405fb221d0bc4c3c\",\n    \"0x90bffba5d9ff40a62f6c8e9fc402d5b95f6077ed58d030c93e321b8081b77d6b8dac3f63a92a7ddc01585cf2c127d66c\",\n    \"0xabdd733a36e0e0f05a570d0504e73801bf9b5a25ff2c78786f8b805704997acb2e6069af342538c581144d53149fa6d3\",\n    \"0xb4a723bb19e8c18a01bd449b1bb3440ddb2017f10bb153da27deb7a6a60e9bb37619d6d5435fbb1ba617687838e01dd0\",\n    \"0x870016b4678bab3375516db0187a2108b2e840bae4d264b9f4f27dbbc7cc9cac1d7dc582d7a04d6fd1ed588238e5e513\",\n    \"0x80d33d2e20e8fc170aa3cb4f69fffb72aeafb3b5bb4ea0bc79ab55da14142ca19b2d8b617a6b24d537366e3b49cb67c3\",\n    \"0xa7ee76aec273aaae03b3b87015789289551969fb175c11557da3ab77e39ab49d24634726f92affae9f4d24003050d974\",\n    \"0x8415ea4ab69d779ebd42d0fe0c6aef531d6a465a5739e429b1fcf433ec45aa8296c527e965a20f0ec9f340c9273ea3cf\",\n    \"0x8c7662520794e8b4405d0b33b5cac839784bc86a5868766c06cbc1fa306dbe334978177417b31baf90ce7b0052a29c56\",\n    \"0x902b2abecc053a3dbdea9897ee21e74821f3a1b98b2d560a514a35799f4680322550fd3a728d4f6d64e1de98033c32b8\",\n    \"0xa05e84ed9ecab8d508d670c39f2db61ad6e08d2795ec32a3c9d0d3737ef3801618f4fc2a95f90ec2f068606131e076c5\",\n    \"0x8b9208ff4d5af0c2e3f53c9375da666773ac57197dfabb0d25b1c8d0588ba7f3c15ee9661bb001297f322ea2fbf6928b\",\n    \"0xa3c827741b34a03254d4451b5ab74a96f2b9f7fb069e2f5adaf54fd97cc7a4d516d378db5ca07da87d8566d6eef13726\",\n    \"0x8509d8a3f4a0ed378e0a1e28ea02f6bf1d7f6c819c6c2f5297c7df54c895b848f841653e32ba2a2c22c2ff739571acb8\",\n    \"0xa0ce988b7d3c40b4e496aa83a09e4b5472a2d98679622f32bea23e6d607bc7de1a5374fb162bce0549a67dad948519be\",\n    \"0xaa8a3dd12bd60e3d2e05f9c683cdcb8eab17fc59134815f8d197681b1bcf65108cba63ac5c58ee632b1e5ed6bba5d474\",\n    \"0x8b955f1d894b3aefd883fb4b65f14cd37fc2b9db77db79273f1700bef9973bf3fd123897ea2b7989f50003733f8f7f21\",\n    \"0xac79c00ddac47f5daf8d9418d798d8af89fc6f1682e7e451f71ea3a405b0d36af35388dd2a332af790bc83ca7b819328\",\n    \"0xa0d44dd2a4438b809522b130d0938c3fe7c5c46379365dbd1810a170a9aa5818e1c783470dd5d0b6d4ac7edbb7330910\",\n    \"0xa30b69e39ad43dd540a43c521f05b51b5f1b9c4eed54b8162374ae11eac25da4f5756e7b70ce9f3c92c2eeceee7431ed\",\n    \"0xac43220b762c299c7951222ea19761ab938bf38e4972deef58ed84f4f9c68c230647cf7506d7cbfc08562fcca55f0485\",\n    \"0xb28233b46a8fb424cfa386a845a3b5399d8489ceb83c8f3e05c22c934798d639c93718b7b68ab3ce24c5358339e41cbb\",\n    \"0xac30d50ee8ce59a10d4b37a3a35e62cdb2273e5e52232e202ca7d7b8d09d28958ee667fae41a7bb6cdc6fe8f6e6c9c85\",\n    \"0xb199842d9141ad169f35cc7ff782b274cbaa645fdb727761e0a89edbf0d781a15f8218b4bf4eead326f2903dd88a9cc1\",\n    \"0x85e018c7ddcad34bb8285a737c578bf741ccd547e68c734bdb3808380e12c5d4ef60fc896b497a87d443ff9abd063b38\",\n    \"0x8c856e6ba4a815bdb891e1276f93545b7072f6cb1a9aa6aa5cf240976f29f4dee01878638500a6bf1daf677b96b54343\",\n    \"0xb8a47555fa8710534150e1a3f13eab33666017be6b41005397afa647ea49708565f2b86b77ad4964d140d9ced6b4d585\",\n    \"0x8cd1f1db1b2f4c85a3f46211599caf512d5439e2d8e184663d7d50166fd3008f0e9253272f898d81007988435f715881\",\n    \"0xb1f34b14612c973a3eceb716dc102b82ab18afef9de7630172c2780776679a7706a4874e1df3eaadf541fb009731807f\",\n    \"0xb25464af9cff883b55be2ff8daf610052c02df9a5e147a2cf4df6ce63edcdee6dc535c533590084cc177da85c5dc0baa\",\n    \"0x91c3c4b658b42d8d3448ae1415d4541d02379a40dc51e36a59bd6e7b9ba3ea51533f480c7c6e8405250ee9b96a466c29\",\n    \"0x86dc027b95deb74c36a58a1333a03e63cb5ae22d3b29d114cfd2271badb05268c9d0c819a977f5e0c6014b00c1512e3a\",\n    \"0xae0e6ff58eb5fa35da5107ebeacf222ab8f52a22bb1e13504247c1dfa65320f40d97b0e6b201cb6613476687cb2f0681\",\n    \"0x8f13415d960b9d7a1d93ef28afc2223e926639b63bdefce0f85e945dfc81670a55df288893a0d8b3abe13c5708f82f91\",\n    \"0x956f67ca49ad27c1e3a68c1faad5e7baf0160c459094bf6b7baf36b112de935fdfd79fa4a9ea87ea8de0ac07272969f4\",\n    \"0x835e45e4a67df9fb51b645d37840b3a15c171d571a10b03a406dd69d3c2f22df3aa9c5cbe1e73f8d767ce01c4914ea9a\",\n    \"0x919b938e56d4b32e2667469d0bdccb95d9dda3341aa907683ee70a14bbbe623035014511c261f4f59b318b610ac90aa3\",\n    \"0x96b48182121ccd9d689bf1dfdc228175564cd68dc904a99c808a7f0053a6f636c9d953e12198bdf2ea49ea92772f2e18\",\n    \"0xac5e5a941d567fa38fdbcfa8cf7f85bb304e3401c52d88752bcd516d1fa9bac4572534ea2205e38423c1df065990790f\",\n    \"0xac0bd594fb85a8d4fc26d6df0fa81f11919401f1ecf9168b891ec7f061a2d9368af99f7fd8d9b43b2ce361e7b8482159\",\n    \"0x83d92c69ca540d298fe80d8162a1c7af3fa9b49dfb69e85c1d136a3ec39fe419c9fa78e0bb6d96878771fbd37fe92e40\",\n    \"0xb35443ae8aa66c763c2db9273f908552fe458e96696b90e41dd509c17a5c04ee178e3490d9c6ba2dc0b8f793c433c134\",\n    \"0x923b2d25aa45b2e580ffd94cbb37dc8110f340f0f011217ee1bd81afb0714c0b1d5fb4db86006cdd2457563276f59c59\",\n    \"0x96c9125d38fca1a61ac21257b696f8ac3dae78def50285e44d90ea293d591d1c58f703540a7e4e99e070afe4646bbe15\",\n    \"0xb57946b2332077fbcdcb406b811779aefd54473b5559a163cd65cb8310679b7e2028aa55c12a1401fdcfcac0e6fae29a\",\n    \"0x845daedc5cf972883835d7e13c937b63753c2200324a3b8082a6c4abb4be06c5f7c629d4abe4bfaf1d80a1f073eb6ce6\",\n    \"0x91a55dfd0efefcd03dc6dacc64ec93b8d296cb83c0ee72400a36f27246e7f2a60e73b7b70ba65819e9cfb73edb7bd297\",\n    \"0x8874606b93266455fe8fdd25df9f8d2994e927460af06f2e97dd4d2d90db1e6b06d441b72c2e76504d753badca87fb37\",\n    \"0x8ee99e6d231274ff9252c0f4e84549da173041299ad1230929c3e3d32399731c4f20a502b4a307642cac9306ccd49d3c\",\n    \"0x8836497714a525118e20849d6933bb8535fb6f72b96337d49e3133d936999c90a398a740f42e772353b5f1c63581df6d\",\n    \"0xa6916945e10628f7497a6cdc5e2de113d25f7ade3e41e74d3de48ccd4fce9f2fa9ab69645275002e6f49399b798c40af\",\n    \"0x9597706983107eb23883e0812e1a2c58af7f3499d50c6e29b455946cb9812fde1aa323d9ed30d1c0ffd455abe32303cd\",\n    \"0xa24ee89f7f515cc33bdbdb822e7d5c1877d337f3b2162303cfc2dae028011c3a267c5cb4194afa63a4856a6e1c213448\",\n    \"0x8cd25315e4318801c2776824ae6e7d543cb85ed3bc2498ba5752df2e8142b37653cf9e60104d674be3aeb0a66912e97a\",\n    \"0xb5085ecbe793180b40dbeb879f4c976eaaccaca3a5246807dced5890e0ed24d35f3f86955e2460e14fb44ff5081c07ba\",\n    \"0x960188cc0b4f908633a6840963a6fa2205fc42c511c6c309685234911c5304ef4c304e3ae9c9c69daa2fb6a73560c256\",\n    \"0xa32d0a70bf15d569b4cda5aebe3e41e03c28bf99cdd34ffa6c5d58a097f322772acca904b3a47addb6c7492a7126ebac\",\n    \"0x977f72d06ad72d4aa4765e0f1f9f4a3231d9f030501f320fe7714cc5d329d08112789fa918c60dd7fdb5837d56bb7fc6\",\n    \"0x99fa038bb0470d45852bb871620d8d88520adb701712fcb1f278fed2882722b9e729e6cdce44c82caafad95e37d0e6f7\",\n    \"0xb855e8f4fc7634ada07e83b6c719a1e37acb06394bc8c7dcab7747a8c54e5df3943915f021364bd019fdea103864e55f\",\n    \"0x88bc2cd7458532e98c596ef59ea2cf640d7cc31b4c33cef9ed065c078d1d4eb49677a67de8e6229cc17ea48bace8ee5a\",\n    \"0xaaa78a3feaa836d944d987d813f9b9741afb076e6aca1ffa42682ab06d46d66e0c07b8f40b9dbd63e75e81efa1ef7b08\",\n    \"0xb7b080420cc4d808723b98b2a5b7b59c81e624ab568ecdfdeb8bf3aa151a581b6f56e983ef1b6f909661e25db40b0c69\",\n    \"0xabee85c462ac9a2c58e54f06c91b3e5cd8c5f9ab5b5deb602b53763c54826ed6deb0d6db315a8d7ad88733407e8d35e2\",\n    \"0x994d075c1527407547590df53e9d72dd31f037c763848d1662eebd4cefec93a24328c986802efa80e038cb760a5300f5\",\n    \"0xab8777640116dfb6678e8c7d5b36d01265dfb16321abbfc277da71556a34bb3be04bc4ae90124ed9c55386d2bfb3bda0\",\n    \"0x967e3a828bc59409144463bcf883a3a276b5f24bf3cbfdd7a42343348cba91e00b46ac285835a9b91eef171202974204\",\n    \"0x875a9f0c4ffe5bb1d8da5e3c8e41d0397aa6248422a628bd60bfae536a651417d4e8a7d2fb98e13f2dad3680f7bd86d3\",\n    \"0xacaa330c3e8f95d46b1880126572b238dbb6d04484d2cd4f257ab9642d8c9fc7b212188b9c7ac9e0fd135c520d46b1bf\",\n    \"0xaceb762edbb0f0c43dfcdb01ea7a1ac5918ca3882b1e7ebc4373521742f1ed5250d8966b498c00b2b0f4d13212e6dd0b\",\n    \"0x81d072b4ad258b3646f52f399bced97c613b22e7ad76373453d80b1650c0ca87edb291a041f8253b649b6e5429bb4cff\",\n    \"0x980a47d27416ac39c7c3a0ebe50c492f8c776ea1de44d5159ac7d889b6d554357f0a77f0e5d9d0ff41aae4369eba1fc2\",\n    \"0x8b4dfd5ef5573db1476d5e43aacfb5941e45d6297794508f29c454fe50ea622e6f068b28b3debe8635cf6036007de2e3\",\n    \"0xa60831559d6305839515b68f8c3bc7abbd8212cc4083502e19dd682d56ca37c9780fc3ce4ec2eae81ab23b221452dc57\",\n    \"0x951f6b2c1848ced9e8a2339c65918e00d3d22d3e59a0a660b1eca667d18f8430d737884e9805865ef3ed0fe1638a22d9\",\n    \"0xb02e38fe790b492aa5e89257c4986c9033a8b67010fa2add9787de857d53759170fdd67715ca658220b4e14b0ca48124\",\n    \"0xa51007e4346060746e6b0e4797fc08ef17f04a34fe24f307f6b6817edbb8ce2b176f40771d4ae8a60d6152cbebe62653\",\n    \"0xa510005b05c0b305075b27b243c9d64bcdce85146b6ed0e75a3178b5ff9608213f08c8c9246f2ca6035a0c3e31619860\",\n    \"0xaaff4ef27a7a23be3419d22197e13676d6e3810ceb06a9e920d38125745dc68a930f1741c9c2d9d5c875968e30f34ab5\",\n    \"0x864522a9af9857de9814e61383bebad1ba9a881696925a0ea6bfc6eff520d42c506bbe5685a9946ed710e889765be4a0\",\n    \"0xb63258c080d13f3b7d5b9f3ca9929f8982a6960bdb1b0f8676f4dca823971601672f15e653917bf5d3746bb220504913\",\n    \"0xb51ce0cb10869121ae310c7159ee1f3e3a9f8ad498827f72c3d56864808c1f21fa2881788f19ece884d3f705cd7bd0c5\",\n    \"0x95d9cecfc018c6ed510e441cf84c712d9909c778c16734706c93222257f64dcd2a9f1bd0b400ca271e22c9c487014274\",\n    \"0x8beff4d7d0140b86380ff4842a9bda94c2d2be638e20ac68a4912cb47dbe01a261857536375208040c0554929ced1ddc\",\n    \"0x891ff49258749e2b57c1e9b8e04b12c77d79c3308b1fb615a081f2aacdfb4b39e32d53e069ed136fdbd43c53b87418fa\",\n    \"0x9625cad224e163d387738825982d1e40eeff35fe816d10d7541d15fdc4d3eee48009090f3faef4024b249205b0b28f72\",\n    \"0x8f3947433d9bd01aa335895484b540a9025a19481a1c40b4f72dd676bfcf332713714fd4010bde936eaf9470fd239ed0\",\n    \"0xa00ec2d67789a7054b53f0e858a8a232706ccc29a9f3e389df7455f1a51a2e75801fd78469a13dbc25d28399ae4c6182\",\n    \"0xa3f65884506d4a62b8775a0ea0e3d78f5f46bc07910a93cd604022154eabdf1d73591e304d61edc869e91462951975e1\",\n    \"0xa14eef4fd5dfac311713f0faa9a60415e3d30b95a4590cbf95f2033dffb4d16c02e7ceff3dcd42148a4e3bc49cce2dd4\",\n    \"0x8afa11c0eef3c540e1e3460bc759bb2b6ea90743623f88e62950c94e370fe4fd01c22b6729beba4dcd4d581198d9358f\",\n    \"0xafb05548a69f0845ffcc5f5dc63e3cdb93cd270f5655173b9a950394b0583663f2b7164ba6df8d60c2e775c1d9f120af\",\n    \"0x97f179e01a947a906e1cbeafa083960bc9f1bade45742a3afee488dfb6011c1c6e2db09a355d77f5228a42ccaa7bdf8e\",\n    \"0x8447fca4d35f74b3efcbd96774f41874ca376bf85b79b6e66c92fa3f14bdd6e743a051f12a7fbfd87f319d1c6a5ce217\",\n    \"0xa57ca39c23617cd2cf32ff93b02161bd7baf52c4effb4679d9d5166406e103bc8f3c6b5209e17c37dbb02deb8bc72ddd\",\n    \"0x9667c7300ff80f0140be002b0e36caab07aaee7cce72679197c64d355e20d96196acaf54e06e1382167d081fe6f739c1\",\n    \"0x828126bb0559ce748809b622677267ca896fa2ee76360fd2c02990e6477e06a667241379ca7e65d61a5b64b96d7867de\",\n    \"0x8b8835dea6ba8cf61c91f01a4b3d2f8150b687a4ee09b45f2e5fc8f80f208ae5d142d8e3a18153f0722b90214e60c5a7\",\n    \"0xa98e8ff02049b4da386e3ee93db23bbb13dfeb72f1cfde72587c7e6d962780b7671c63e8ac3fbaeb1a6605e8d79e2f29\",\n    \"0x87a4892a0026d7e39ef3af632172b88337cb03669dea564bcdb70653b52d744730ebb5d642e20cb627acc9dbb547a26b\",\n    \"0x877352a22fc8052878a57effc159dac4d75fe08c84d3d5324c0bab6d564cdf868f33ceee515eee747e5856b62cfa0cc7\",\n    \"0x8b801ba8e2ff019ee62f64b8cb8a5f601fc35423eb0f9494b401050103e1307dc584e4e4b21249cd2c686e32475e96c3\",\n    \"0xa9e7338d6d4d9bfec91b2af28a8ed13b09415f57a3a00e5e777c93d768fdb3f8e4456ae48a2c6626b264226e911a0e28\",\n    \"0x99c05fedf40ac4726ed585d7c1544c6e79619a0d3fb6bda75a08c7f3c0008e8d5e19ed4da48de3216135f34a15eba17c\",\n    \"0xa61cce8a1a8b13a4a650fdbec0eeea8297c352a8238fb7cac95a0df18ed16ee02a3daa2de108fa122aca733bd8ad7855\",\n    \"0xb97f37da9005b440b4cb05870dd881bf8491fe735844f2d5c8281818583b38e02286e653d9f2e7fa5e74c3c3eb616540\",\n    \"0xa72164a8554da8e103f692ac5ebb4aece55d5194302b9f74b6f2a05335b6e39beede0bf7bf8c5bfd4d324a784c5fb08c\",\n    \"0xb87e8221c5341cd9cc8bb99c10fe730bc105550f25ed4b96c0d45e6142193a1b2e72f1b3857373a659b8c09be17b3d91\",\n    \"0xa41fb1f327ef91dcb7ac0787918376584890dd9a9675c297c45796e32d6e5985b12f9b80be47fc3a8596c245f419d395\",\n    \"0x90dafa3592bdbb3465c92e2a54c2531822ba0459d45d3e7a7092fa6b823f55af28357cb51896d4ec2d66029c82f08e26\",\n    \"0xa0a9adc872ebc396557f484f1dd21954d4f4a21c4aa5eec543f5fa386fe590839735c01f236574f7ff95407cd12de103\",\n    \"0xb8c5c940d58be7538acf8672852b5da3af34f82405ef2ce8e4c923f1362f97fc50921568d0fd2fe846edfb0823e62979\",\n    \"0x85aaf06a8b2d0dac89dafd00c28533f35dbd074978c2aaa5bef75db44a7b12aeb222e724f395513b9a535809a275e30b\",\n    \"0x81f3cbe82fbc7028c26a6c1808c604c63ba023a30c9f78a4c581340008dbda5ec07497ee849a2183fcd9124f7936af32\",\n    \"0xa11ac738de75fd60f15a34209d3825d5e23385796a4c7fc5931822f3f380af977dd0f7b59fbd58eed7777a071e21b680\",\n    \"0x85a279c493de03db6fa6c3e3c1b1b29adc9a8c4effc12400ae1128da8421954fa8b75ad19e5388fe4543b76fb0812813\",\n    \"0x83a217b395d59ab20db6c4adb1e9713fc9267f5f31a6c936042fe051ce8b541f579442f3dcf0fa16b9e6de9fd3518191\",\n    \"0x83a0b86e7d4ed8f9ccdc6dfc8ff1484509a6378fa6f09ed908e6ab9d1073f03011dc497e14304e4e3d181b57de06a5ab\",\n    \"0xa63ad69c9d25704ce1cc8e74f67818e5ed985f8f851afa8412248b2df5f833f83b95b27180e9e7273833ed0d07113d3b\",\n    \"0x99b1bc2021e63b561fe44ddd0af81fcc8627a91bfeecbbc989b642bc859abc0c8d636399701aad7bbaf6a385d5f27d61\",\n    \"0xb53434adb66f4a807a6ad917c6e856321753e559b1add70824e5c1e88191bf6993fccb9b8b911fc0f473fb11743acacd\",\n    \"0x97ed3b9e6fb99bf5f945d4a41f198161294866aa23f2327818cdd55cb5dc4c1a8eff29dd8b8d04902d6cd43a71835c82\",\n    \"0xb1e808260e368a18d9d10bdea5d60223ba1713b948c782285a27a99ae50cc5fc2c53d407de07155ecc16fb8a36d744a0\",\n    \"0xa3eb4665f18f71833fec43802730e56b3ee5a357ea30a888ad482725b169d6f1f6ade6e208ee081b2e2633079b82ba7d\",\n    \"0xab8beb2c8353fc9f571c18fdd02bdb977fc883313469e1277b0372fbbb33b80dcff354ca41de436d98d2ed710faa467e\",\n    \"0xaa9071cfa971e4a335a91ad634c98f2be51544cb21f040f2471d01bb97e1df2277ae1646e1ea8f55b7ba9f5c8c599b39\",\n    \"0x80b7dbfdcaf40f0678012acc634eba44ea51181475180d9deb2050dc4f2de395289edd0223018c81057ec79b04b04c49\",\n    \"0x89623d7f6cb17aa877af14de842c2d4ab7fd576d61ddd7518b5878620a01ded40b6010de0da3cdf31d837eecf30e9847\",\n    \"0xa773bb024ae74dd24761f266d4fb27d6fd366a8634febe8235376b1ae9065c2fe12c769f1d0407867dfbe9f5272c352f\",\n    \"0x8455a561c3aaa6ba64c881a5e13921c592b3a02e968f4fb24a2243c36202795d0366d9cc1a24e916f84d6e158b7aeac7\",\n    \"0x81d8bfc4b283cf702a40b87a2b96b275bdbf0def17e67d04842598610b67ea08c804d400c3e69fa09ea001eaf345b276\",\n    \"0xb8f8f82cb11fea1c99467013d7e167ff03deb0c65a677fab76ded58826d1ba29aa7cf9fcd7763615735ea3ad38e28719\",\n    \"0x89a6a04baf9cccc1db55179e1650b1a195dd91fb0aebc197a25143f0f393524d2589975e3fbfc2547126f0bced7fd6f2\",\n    \"0xb81b2162df045390f04df07cbd0962e6b6ca94275a63edded58001a2f28b2ae2af2c7a6cba4ecd753869684e77e7e799\",\n    \"0xa3757f722776e50de45c62d9c4a2ee0f5655a512344c4cbec542d8045332806568dd626a719ef21a4eb06792ca70f204\",\n    \"0x8c5590df96ec22179a4e8786de41beb44f987a1dcc508eb341eecbc0b39236fdfad47f108f852e87179ccf4e10091e59\",\n    \"0x87502f026ed4e10167419130b88c3737635c5b9074c364e1dd247cef5ef0fc064b4ae99b187e33301e438bbd2fe7d032\",\n    \"0xaf925a2165e980ced620ff12289129fe17670a90ae0f4db9d4b39bd887ccb1f5d2514ac9ecf910f6390a8fc66bd5be17\",\n    \"0x857fca899828cf5c65d26e3e8a6e658542782fc72762b3b9c73514919f83259e0f849a9d4838b40dc905fe43024d0d23\",\n    \"0x87ffebdbfb69a9e1007ebac4ffcb4090ff13705967b73937063719aa97908986effcb7262fdadc1ae0f95c3690e3245d\",\n    \"0xa9ff6c347ac6f4c6ab993b748802e96982eaf489dc69032269568412fc9a79e7c2850dfc991b28211b3522ee4454344b\",\n    \"0xa65b3159df4ec48bebb67cb3663cd744027ad98d970d620e05bf6c48f230fa45bf17527fe726fdf705419bb7a1bb913e\",\n    \"0x84b97b1e6408b6791831997b03cd91f027e7660fd492a93d95daafe61f02427371c0e237c75706412f442991dfdff989\",\n    \"0xab761c26527439b209af0ae6afccd9340bbed5fbe098734c3145b76c5d2cd7115d9227b2eb523882b7317fbb09180498\",\n    \"0xa0479a8da06d7a69c0b0fee60df4e691c19c551f5e7da286dab430bfbcabf31726508e20d26ea48c53365a7f00a3ad34\",\n    \"0xa732dfc9baa0f4f40b5756d2e8d8937742999623477458e0bc81431a7b633eefc6f53b3b7939fe0a020018549c954054\",\n    \"0x901502436a1169ba51dc479a5abe7c8d84e0943b16bc3c6a627b49b92cd46263c0005bc324c67509edd693f28e612af1\",\n    \"0xb627aee83474e7f84d1bab9b7f6b605e33b26297ac6bbf52d110d38ba10749032bd551641e73a383a303882367af429b\",\n    \"0x95108866745760baef4a46ef56f82da6de7e81c58b10126ebd2ba2cd13d339f91303bf2fb4dd104a6956aa3b13739503\",\n    \"0x899ed2ade37236cec90056f3569bc50f984f2247792defafcceb49ad0ca5f6f8a2f06573705300e07f0de0c759289ff5\",\n    \"0xa9f5eee196d608efe4bcef9bf71c646d27feb615e21252cf839a44a49fd89da8d26a758419e0085a05b1d59600e2dc42\",\n    \"0xb36c6f68fed6e6c85f1f4a162485f24817f2843ec5cbee45a1ebfa367d44892e464949c6669f7972dc7167af08d55d25\",\n    \"0xaaaede243a9a1b6162afbc8f571a52671a5a4519b4062e3f26777664e245ba873ed13b0492c5dbf0258c788c397a0e9e\",\n    \"0x972b4fb39c31cbe127bf9a32a5cc10d621ebdd9411df5e5da3d457f03b2ab2cd1f6372d8284a4a9400f0b06ecdbfd38e\",\n    \"0x8f6ca1e110e959a4b1d9a5ce5f212893cec21db40d64d5ac4d524f352d72198f923416a850bf845bc5a22a79c0ea2619\",\n    \"0xa0f3c93b22134f66f04b2553a53b738644d1665ceb196b8494b315a4c28236fb492017e4a0de4224827c78e42f9908b7\",\n    \"0x807fb5ee74f6c8735b0b5ca07e28506214fe4047dbeb00045d7c24f7849e98706aea79771241224939cb749cf1366c7d\",\n    \"0x915eb1ff034224c0b645442cdb7d669303fdc00ca464f91aaf0b6fde0b220a3a74ff0cb043c26c9f3a5667b3fdaa9420\",\n    \"0x8fda6cef56ed33fefffa9e6ac8e6f76b1af379f89761945c63dd448801f7bb8ca970504a7105fac2f74f652ccff32327\",\n    \"0x87380cffdcffb1d0820fa36b63cc081e72187f86d487315177d4d04da4533eb19a0e2ff6115ceab528887819c44a5164\",\n    \"0x8cd89e03411a18e7f16f968b89fb500c36d47d229f6487b99e62403a980058db5925ce249206743333538adfad168330\",\n    \"0x974451b1df33522ce7056de9f03e10c70bf302c44b0741a59df3d6877d53d61a7394dcee1dd46e013d7cb9d73419c092\",\n    \"0x98c35ddf645940260c490f384a49496a7352bb8e3f686feed815b1d38f59ded17b1ad6e84a209e773ed08f7b8ff1e4c2\",\n    \"0x963f386cf944bb9b2ddebb97171b64253ea0a2894ac40049bdd86cda392292315f3a3d490ca5d9628c890cfb669f0acb\",\n    \"0x8d507712152babd6d142ee682638da8495a6f3838136088df9424ef50d5ec28d815a198c9a4963610b22e49b4cdf95e9\",\n    \"0x83d4bc6b0be87c8a4f1e9c53f257719de0c73d85b490a41f7420e777311640937320557ff2f1d9bafd1daaa54f932356\",\n    \"0x82f5381c965b7a0718441131c4d13999f4cdce637698989a17ed97c8ea2e5bdb5d07719c5f7be8688edb081b23ede0f4\",\n    \"0xa6ebecab0b72a49dfd01d69fa37a7f74d34fb1d4fef0aa10e3d6fceb9eccd671225c230af89f6eb514250e41a5f91f52\",\n    \"0x846d185bdad6e11e604df7f753b7a08a28b643674221f0e750ebdb6b86ec584a29c869e131bca868972a507e61403f6a\",\n    \"0x85a98332292acb744bd1c0fd6fdcf1f889a78a2c9624d79413ffa194cc8dfa7821a4b60cde8081d4b5f71f51168dd67f\",\n    \"0x8f7d97c3b4597880d73200d074eb813d95432306e82dafc70b580b8e08cb8098b70f2d07b4b3ac6a4d77e92d57035031\",\n    \"0x8185439c8751e595825d7053518cbe121f191846a38d4dbcb558c3f9d7a3104f3153401adaaaf27843bbe2edb504bfe3\",\n    \"0xb3c00d8ece1518fca6b1215a139b0a0e26d9cba1b3a424f7ee59f30ce800a5db967279ed60958dd1f3ee69cf4dd1b204\",\n    \"0xa2e6cb6978e883f9719c3c0d44cfe8de0cc6f644b98f98858433bea8bbe7b612c8aca5952fccce4f195f9d54f9722dc2\",\n    \"0x99663087e3d5000abbec0fbda4e7342ec38846cc6a1505191fb3f1a337cb369455b7f8531a6eb8b0f7b2c4baf83cbe2b\",\n    \"0xab0836c6377a4dbc7ca6a4d6cf021d4cd60013877314dd05f351706b128d4af6337711ed3443cb6ca976f40d74070a9a\",\n    \"0x87abfd5126152fd3bac3c56230579b489436755ea89e0566aa349490b36a5d7b85028e9fb0710907042bcde6a6f5d7e3\",\n    \"0x974ba1033f75f60e0cf7c718a57ae1da3721cf9d0fb925714c46f027632bdd84cd9e6de4cf4d00bc55465b1c5ebb7384\",\n    \"0xa607b49d73689ac64f25cec71221d30d53e781e1100d19a2114a21da6507a60166166369d860bd314acb226596525670\",\n    \"0xa7c2b0b915d7beba94954f2aa7dd08ec075813661e2a3ecca5d28a0733e59583247fed9528eb28aba55b972cdbaf06eb\",\n    \"0xb8b3123e44128cc8efbe3270f2f94e50ca214a4294c71c3b851f8cbb70cb67fe9536cf07d04bf7fe380e5e3a29dd3c15\",\n    \"0xa59a07e343b62ad6445a0859a32b58c21a593f9ddbfe52049650f59628c93715aa1f4e1f45b109321756d0eeec8a5429\",\n    \"0x94f51f8a4ed18a6030d0aaa8899056744bd0e9dc9ac68f62b00355cddab11da5da16798db75f0bfbce0e5bdfe750c0b6\",\n    \"0x97460a97ca1e1fa5ce243b81425edc0ec19b7448e93f0b55bc9785eedeeafe194a3c8b33a61a5c72990edf375f122777\",\n    \"0x8fa859a089bc17d698a7ee381f37ce9beadf4e5b44fce5f6f29762bc04f96faff5d58c48c73631290325f05e9a1ecf49\",\n    \"0xabdf38f3b20fc95eff31de5aa9ef1031abfa48f1305ee57e4d507594570401503476d3bcc493838fc24d6967a3082c7f\",\n    \"0xb8914bfb82815abb86da35c64d39ab838581bc0bf08967192697d9663877825f2b9d6fbdcf9b410463482b3731361aef\",\n    \"0xa8187f9d22b193a5f578999954d6ec9aa9b32338ccadb8a3e1ce5bad5ea361d69016e1cdfac44e9d6c54e49dd88561b9\",\n    \"0xaac262cb7cba7fd62c14daa7b39677cabc1ef0947dd06dd89cac8570006a200f90d5f0353e84f5ff03179e3bebe14231\",\n    \"0xa630ef5ece9733b8c46c0a2df14a0f37647a85e69c63148e79ffdcc145707053f9f9d305c3f1cf3c7915cb46d33abd07\",\n    \"0xb102c237cb2e254588b6d53350dfda6901bd99493a3fbddb4121d45e0b475cf2663a40d7b9a75325eda83e4ba1e68cb3\",\n    \"0x86a930dd1ddcc16d1dfa00aa292cb6c2607d42c367e470aa920964b7c17ab6232a7108d1c2c11fc40fb7496547d0bbf8\",\n    \"0xa832fdc4500683e72a96cce61e62ac9ee812c37fe03527ad4cf893915ca1962cee80e72d4f82b20c8fc0b764376635a1\",\n    \"0x88ad985f448dabb04f8808efd90f273f11f5e6d0468b5489a1a6a3d77de342992a73eb842d419034968d733f101ff683\",\n    \"0x98a8538145f0d86f7fbf9a81c9140f6095c5bdd8960b1c6f3a1716428cd9cca1bf8322e6d0af24e6169abcf7df2b0ff6\",\n    \"0x9048c6eba5e062519011e177e955a200b2c00b3a0b8615bdecdebc217559d41058d3315f6d05617be531ef0f6aef0e51\",\n    \"0x833bf225ab6fc68cdcacf1ec1b50f9d05f5410e6cdcd8d56a3081dc2be8a8d07b81534d1ec93a25c2e270313dfb99e3b\",\n    \"0xa84bcd24c3da5e537e64a811b93c91bfc84d7729b9ead7f79078989a6eb76717d620c1fad17466a0519208651e92f5ff\",\n    \"0xb7cdd0a3fbd79aed93e1b5a44ca44a94e7af5ed911e4492f332e3a5ed146c7286bde01b52276a2fcc02780d2109874dd\",\n    \"0x8a19a09854e627cb95750d83c20c67442b66b35896a476358f993ba9ac114d32c59c1b3d0b8787ee3224cf3888b56c64\",\n    \"0xa9abd5afb8659ee52ada8fa5d57e7dd355f0a7350276f6160bec5fbf70d5f99234dd179eb221c913e22a49ec6d267846\",\n    \"0x8c13c4274c0d30d184e73eaf812200094bbbd57293780bdadbceb262e34dee5b453991e7f37c7333a654fc71c69d6445\",\n    \"0xa4320d73296ff8176ce0127ca1921c450e2a9c06eff936681ebaffb5a0b05b17fded24e548454de89aca2dcf6d7a9de4\",\n    \"0xb2b8b3e15c1f645f07783e5628aba614e60157889db41d8161d977606788842b67f83f361eae91815dc0abd84e09abd5\",\n    \"0xad26c3aa35ddfddc15719b8bb6c264aaec7065e88ac29ba820eb61f220fef451609a7bb037f3722d022e6c86e4f1dc88\",\n    \"0xb8615bf43e13ae5d7b8dd903ce37190800cd490f441c09b22aa29d7a29ed2c0417b7a08ead417868f1de2589deaadd80\",\n    \"0x8d3425e1482cd1e76750a76239d33c06b3554c3c3c87c15cb7ab58b1cee86a4c5c4178b44e23f36928365a1b484bde02\",\n    \"0x806893a62e38c941a7dd6f249c83af16596f69877cc737d8f73f6b8cd93cbc01177a7a276b2b8c6b0e5f2ad864db5994\",\n    \"0x86618f17fa4b0d65496b661bbb5ba3bc3a87129d30a4b7d4f515b904f4206ca5253a41f49fd52095861e5e065ec54f21\",\n    \"0x9551915da1304051e55717f4c31db761dcdcf3a1366c89a4af800a9e99aca93a357bf928307f098e62b44a02cb689a46\",\n    \"0x8f79c4ec0ec1146cb2a523b52fe33def90d7b5652a0cb9c2d1c8808a32293e00aec6969f5b1538e3a94cd1efa3937f86\",\n    \"0xa0c03e329a707300081780f1e310671315b4c6a4cedcb29697aedfabb07a9d5df83f27b20e9c44cf6b16e39d9ded5b98\",\n    \"0x86a7cfa7c8e7ce2c01dd0baec2139e97e8e090ad4e7b5f51518f83d564765003c65968f85481bbb97cb18f005ccc7d9f\",\n    \"0xa33811770c6dfda3f7f74e6ad0107a187fe622d61b444bbd84fd7ef6e03302e693b093df76f6ab39bb4e02afd84a575a\",\n    \"0x85480f5c10d4162a8e6702b5e04f801874d572a62a130be94b0c02b58c3c59bdcd48cd05f0a1c2839f88f06b6e3cd337\",\n    \"0x8e181011564b17f7d787fe0e7f3c87f6b62da9083c54c74fd6c357a1f464c123c1d3d8ade3cf72475000b464b14e2be3\",\n    \"0x8ee178937294b8c991337e0621ab37e9ffa4ca2bdb3284065c5e9c08aad6785d50cf156270ff9daf9a9127289710f55b\",\n    \"0x8bd1e8e2d37379d4b172f1aec96f2e41a6e1393158d7a3dbd9a95c8dd4f8e0b05336a42efc11a732e5f22b47fc5c271d\",\n    \"0x8f3da353cd487c13136a85677de8cedf306faae0edec733cf4f0046f82fa4639db4745b0095ff33a9766aba50de0cbcf\",\n    \"0x8d187c1e97638df0e4792b78e8c23967dac43d98ea268ca4aabea4e0fa06cb93183fd92d4c9df74118d7cc27bf54415e\",\n    \"0xa4c992f08c2f8bac0b74b3702fb0c75c9838d2ce90b28812019553d47613c14d8ce514d15443159d700b218c5a312c49\",\n    \"0xa6fd1874034a34c3ea962a316c018d9493d2b3719bb0ec4edbc7c56b240802b2228ab49bee6f04c8a3e9f6f24a48c1c2\",\n    \"0xb2efed8e799f8a15999020900dc2c58ece5a3641c90811b86a5198e593d7318b9d53b167818ccdfbe7df2414c9c34011\",\n    \"0x995ff7de6181ddf95e3ead746089c6148da3508e4e7a2323c81785718b754d356789b902e7e78e2edc6b0cbd4ff22c78\",\n    \"0x944073d24750a9068cbd020b834afc72d2dde87efac04482b3287b40678ad07588519a4176b10f2172a2c463d063a5cd\",\n    \"0x99db4b1bb76475a6fd75289986ef40367960279524378cc917525fb6ba02a145a218c1e9caeb99332332ab486a125ac0\",\n    \"0x89fce4ecd420f8e477af4353b16faabb39e063f3f3c98fde2858b1f2d1ef6eed46f0975a7c08f233b97899bf60ccd60a\",\n    \"0x8c09a4f07a02b80654798bc63aada39fd638d3e3c4236ccd8a5ca280350c31e4a89e5f4c9aafb34116e71da18c1226b8\",\n    \"0x85325cfa7ded346cc51a2894257eab56e7488dbff504f10f99f4cd2b630d913003761a50f175ed167e8073f1b6b63fb0\",\n    \"0xb678b4fbec09a8cc794dcbca185f133578f29e354e99c05f6d07ac323be20aecb11f781d12898168e86f2e0f09aca15e\",\n    \"0xa249cfcbca4d9ba0a13b5f6aac72bf9b899adf582f9746bb2ad043742b28915607467eb794fca3704278f9136f7642be\",\n    \"0x9438e036c836a990c5e17af3d78367a75b23c37f807228362b4d13e3ddcb9e431348a7b552d09d11a2e9680704a4514f\",\n    \"0x925ab70450af28c21a488bfb5d38ac994f784cf249d7fd9ad251bb7fd897a23e23d2528308c03415074d43330dc37ef4\",\n    \"0xa290563904d5a8c0058fc8330120365bdd2ba1fdbaef7a14bc65d4961bb4217acfaed11ab82669e359531f8bf589b8db\",\n    \"0xa7e07a7801b871fc9b981a71e195a3b4ba6b6313bc132b04796a125157e78fe5c11a3a46cf731a255ac2d78a4ae78cd0\",\n    \"0xb26cd2501ee72718b0eebab6fb24d955a71f363f36e0f6dff0ab1d2d7836dab88474c0cef43a2cc32701fca7e82f7df3\",\n    \"0xa1dc3b6c968f3de00f11275092290afab65b2200afbcfa8ddc70e751fa19dbbc300445d6d479a81bda3880729007e496\",\n    \"0xa9bc213e28b630889476a095947d323b9ac6461dea726f2dc9084473ae8e196d66fb792a21905ad4ec52a6d757863e7d\",\n    \"0xb25d178df8c2df8051e7c888e9fa677fde5922e602a95e966db9e4a3d6b23ce043d7dc48a5b375c6b7c78e966893e8c3\",\n    \"0xa1c8d88d72303692eaa7adf68ea41de4febec40cc14ae551bb4012afd786d7b6444a3196b5d9d5040655a3366d96b7cd\",\n    \"0xb22bd44f9235a47118a9bbe2ba5a2ba9ec62476061be2e8e57806c1a17a02f9a51403e849e2e589520b759abd0117683\",\n    \"0xb8add766050c0d69fe81d8d9ea73e1ed05f0135d093ff01debd7247e42dbb86ad950aceb3b50b9af6cdc14ab443b238f\",\n    \"0xaf2cf95f30ef478f018cf81d70d47d742120b09193d8bb77f0d41a5d2e1a80bfb467793d9e2471b4e0ad0cb2c3b42271\",\n    \"0x8af5ef2107ad284e246bb56e20fef2a255954f72de791cbdfd3be09f825298d8466064f3c98a50496c7277af32b5c0bc\",\n    \"0x85dc19558572844c2849e729395a0c125096476388bd1b14fa7f54a7c38008fc93e578da3aac6a52ff1504d6ca82db05\",\n    \"0xae8c9b43c49572e2e166d704caf5b4b621a3b47827bb2a3bcd71cdc599bba90396fd9a405261b13e831bb5d44c0827d7\",\n    \"0xa7ba7efede25f02e88f6f4cbf70643e76784a03d97e0fbd5d9437c2485283ad7ca3abb638a5f826cd9f6193e5dec0b6c\",\n    \"0x94a9d122f2f06ef709fd8016fd4b712d88052245a65a301f5f177ce22992f74ad05552b1f1af4e70d1eac62cef309752\",\n    \"0x82d999b3e7cf563833b8bc028ff63a6b26eb357dfdb3fd5f10e33a1f80a9b2cfa7814d871b32a7ebfbaa09e753e37c02\",\n    \"0xaec6edcde234df502a3268dd2c26f4a36a2e0db730afa83173f9c78fcb2b2f75510a02b80194327b792811caefda2725\",\n    \"0x94c0bfa66c9f91d462e9194144fdd12d96f9bbe745737e73bab8130607ee6ea9d740e2cfcbbd00a195746edb6369ee61\",\n    \"0xab7573dab8c9d46d339e3f491cb2826cabe8b49f85f1ede78d845fc3995537d1b4ab85140b7d0238d9c24daf0e5e2a7e\",\n    \"0x87e8b16832843251fe952dadfd01d41890ed4bb4b8fa0254550d92c8cced44368225eca83a6c3ad47a7f81ff8a80c984\",\n    \"0x9189d2d9a7c64791b19c0773ad4f0564ce6bea94aa275a917f78ad987f150fdb3e5e26e7fef9982ac184897ecc04683f\",\n    \"0xb3661bf19e2da41415396ae4dd051a9272e8a2580b06f1a1118f57b901fa237616a9f8075af1129af4eabfefedbe2f1c\",\n    \"0xaf43c86661fb15daf5d910a4e06837225e100fb5680bd3e4b10f79a2144c6ec48b1f8d6e6b98e067d36609a5d038889a\",\n    \"0x82ac0c7acaa83ddc86c5b4249aae12f28155989c7c6b91e5137a4ce05113c6cbc16f6c44948b0efd8665362d3162f16a\",\n    \"0x8f268d1195ab465beeeb112cd7ffd5d5548559a8bc01261106d3555533fc1971081b25558d884d552df0db1cddda89d8\",\n    \"0x8ef7caa5521f3e037586ce8ac872a4182ee20c7921c0065ed9986c047e3dda08294da1165f385d008b40d500f07d895f\",\n    \"0x8c2f98f6880550573fad46075d3eba26634b5b025ce25a0b4d6e0193352c8a1f0661064027a70fe8190b522405f9f4e3\",\n    \"0xb7653f353564feb164f0f89ec7949da475b8dad4a4d396d252fc2a884f6932d027b7eb2dc4d280702c74569319ed701a\",\n    \"0xa026904f4066333befd9b87a8fad791d014096af60cdd668ef919c24dbe295ff31f7a790e1e721ba40cf5105abca67f4\",\n    \"0x988f982004ada07a22dd345f2412a228d7a96b9cae2c487de42e392afe1e35c2655f829ce07a14629148ce7079a1f142\",\n    \"0x9616add009067ed135295fb74d5b223b006b312bf14663e547a0d306694ff3a8a7bb9cfc466986707192a26c0bce599f\",\n    \"0xad4c425de9855f6968a17ee9ae5b15e0a5b596411388cf976df62ecc6c847a6e2ddb2cea792a5f6e9113c2445dba3e5c\",\n    \"0xb698ac9d86afa3dc69ff8375061f88e3b0cff92ff6dfe747cebaf142e813c011851e7a2830c10993b715e7fd594604a9\",\n    \"0xa386fa189847bb3b798efca917461e38ead61a08b101948def0f82cd258b945ed4d45b53774b400af500670149e601b7\",\n    \"0x905c95abda2c68a6559d8a39b6db081c68cef1e1b4be63498004e1b2f408409be9350b5b5d86a30fd443e2b3e445640a\",\n    \"0x9116dade969e7ce8954afcdd43e5cab64dc15f6c1b8da9d2d69de3f02ba79e6c4f6c7f54d6bf586d30256ae405cd1e41\",\n    \"0xa3084d173eacd08c9b5084a196719b57e47a0179826fda73466758235d7ecdb87cbcf097bd6b510517d163a85a7c7edd\",\n    \"0x85bb00415ad3c9be99ff9ba83672cc59fdd24356b661ab93713a3c8eab34e125d8867f628a3c3891b8dc056e69cd0e83\",\n    \"0x8d58541f9f39ed2ee4478acce5d58d124031338ec11b0d55551f00a5a9a6351faa903a5d7c132dc5e4bb026e9cbd18e4\",\n    \"0xa622adf72dc250e54f672e14e128c700166168dbe0474cecb340da175346e89917c400677b1bc1c11fcc4cc26591d9db\",\n    \"0xb3f865014754b688ca8372e8448114fff87bf3ca99856ab9168894d0c4679782c1ced703f5b74e851b370630f5e6ee86\",\n    \"0xa7e490b2c40c2446fcd91861c020da9742c326a81180e38110558bb5d9f2341f1c1885e79b364e6419023d1cbdc47380\",\n    \"0xb3748d472b1062e54572badbb8e87ac36534407f74932e7fc5b8392d008e8e89758f1671d1e4d30ab0fa40551b13bb5e\",\n    \"0x89898a5c5ec4313aabc607b0049fd1ebad0e0c074920cf503c9275b564d91916c2c446d3096491c950b7af3ac5e4b0ed\",\n    \"0x8eb8c83fef2c9dd30ea44e286e9599ec5c20aba983f702e5438afe2e5b921884327ad8d1566c72395587efac79ca7d56\",\n    \"0xb92479599e806516ce21fb0bd422a1d1d925335ebe2b4a0a7e044dd275f30985a72b97292477053ac5f00e081430da80\",\n    \"0xa34ae450a324fe8a3c25a4d653a654f9580ed56bbea213b8096987bbad0f5701d809a17076435e18017fea4d69f414bc\",\n    \"0x81381afe6433d62faf62ea488f39675e0091835892ecc238e02acf1662669c6d3962a71a3db652f6fe3bc5f42a0e5dc5\",\n    \"0xa430d475bf8580c59111103316fe1aa79c523ea12f1d47a976bbfae76894717c20220e31cf259f08e84a693da6688d70\",\n    \"0xb842814c359754ece614deb7d184d679d05d16f18a14b288a401cef5dad2cf0d5ee90bad487b80923fc5573779d4e4e8\",\n    \"0x971d9a2627ff2a6d0dcf2af3d895dfbafca28b1c09610c466e4e2bff2746f8369de7f40d65b70aed135fe1d72564aa88\",\n    \"0x8f4ce1c59e22b1ce7a0664caaa7e53735b154cfba8d2c5cc4159f2385843de82ab58ed901be876c6f7fce69cb4130950\",\n    \"0x86cc9dc321b6264297987000d344fa297ef45bcc2a4df04e458fe2d907ad304c0ea2318e32c3179af639a9a56f3263cf\",\n    \"0x8229e0876dfe8f665c3fb19b250bd89d40f039bbf1b331468b403655be7be2e104c2fd07b9983580c742d5462ca39a43\",\n    \"0x99299d73066e8eb128f698e56a9f8506dfe4bd014931e86b6b487d6195d2198c6c5bf15cccb40ccf1f8ddb57e9da44a2\",\n    \"0xa3a3be37ac554c574b393b2f33d0a32a116c1a7cfeaf88c54299a4da2267149a5ecca71f94e6c0ef6e2f472b802f5189\",\n    \"0xa91700d1a00387502cdba98c90f75fbc4066fefe7cc221c8f0e660994c936badd7d2695893fde2260c8c11d5bdcdd951\",\n    \"0x8e03cae725b7f9562c5c5ab6361644b976a68bada3d7ca508abca8dfc80a469975689af1fba1abcf21bc2a190dab397d\",\n    \"0xb01461ad23b2a8fa8a6d241e1675855d23bc977dbf4714add8c4b4b7469ccf2375cec20e80cedfe49361d1a30414ac5b\",\n    \"0xa2673bf9bc621e3892c3d7dd4f1a9497f369add8cbaa3472409f4f86bd21ac67cfac357604828adfee6ada1835365029\",\n    \"0xa042dff4bf0dfc33c178ba1b335e798e6308915128de91b12e5dbbab7c4ac8d60a01f6aea028c3a6d87b9b01e4e74c01\",\n    \"0x86339e8a75293e4b3ae66b5630d375736b6e6b6b05c5cda5e73fbf7b2f2bd34c18a1d6cefede08625ce3046e77905cb8\",\n    \"0xaf2ebe1b7d073d03e3d98bc61af83bf26f7a8c130fd607aa92b75db22d14d016481b8aa231e2c9757695f55b7224a27f\",\n    \"0xa00ee882c9685e978041fd74a2c465f06e2a42ffd3db659053519925be5b454d6f401e3c12c746e49d910e4c5c9c5e8c\",\n    \"0x978a781c0e4e264e0dad57e438f1097d447d891a1e2aa0d5928f79a9d5c3faae6f258bc94fdc530b7b2fa6a9932bb193\",\n    \"0xaa4b7ce2e0c2c9e9655bf21e3e5651c8503bce27483017b0bf476be743ba06db10228b3a4c721219c0779747f11ca282\",\n    \"0xb003d1c459dacbcf1a715551311e45d7dbca83a185a65748ac74d1800bbeaba37765d9f5a1a221805c571910b34ebca8\",\n    \"0x95b6e531b38648049f0d19de09b881baa1f7ea3b2130816b006ad5703901a05da57467d1a3d9d2e7c73fb3f2e409363c\",\n    \"0xa6cf9c06593432d8eba23a4f131bb7f72b9bd51ab6b4b772a749fe03ed72b5ced835a349c6d9920dba2a39669cb7c684\",\n    \"0xaa3d59f6e2e96fbb66195bc58c8704e139fa76cd15e4d61035470bd6e305db9f98bcbf61ac1b95e95b69ba330454c1b3\",\n    \"0xb57f97959c208361de6d7e86dff2b873068adb0f158066e646f42ae90e650079798f165b5cd713141cd3a2a90a961d9a\",\n    \"0xa76ee8ed9052f6a7a8c69774bb2597be182942f08115baba03bf8faaeaee526feba86120039fe8ca7b9354c3b6e0a8e6\",\n    \"0x95689d78c867724823f564627d22d25010f278674c6d2d0cdb10329169a47580818995d1d727ce46c38a1e47943ebb89\",\n    \"0xab676d2256c6288a88e044b3d9ffd43eb9d5aaee00e8fc60ac921395fb835044c71a26ca948e557fed770f52d711e057\",\n    \"0x96351c72785c32e5d004b6f4a1259fb8153d631f0c93fed172f18e8ba438fbc5585c1618deeabd0d6d0b82173c2e6170\",\n    \"0x93dd8d3db576418e22536eba45ab7f56967c6c97c64260d6cddf38fb19c88f2ec5cd0e0156f50e70855eee8a2b879ffd\",\n    \"0xad6ff16f40f6de3d7a737f8e6cebd8416920c4ff89dbdcd75eabab414af9a6087f83ceb9aff7680aa86bff98bd09c8cc\",\n    \"0x84de53b11671abc9c38710e19540c5c403817562aeb22a88404cdaff792c1180f717dbdfe8f54940c062c4d032897429\",\n    \"0x872231b9efa1cdd447b312099a5c164c560440a9441d904e70f5abfc3b2a0d16be9a01aca5e0a2599a61e19407587e3d\",\n    \"0x88f44ac27094a2aa14e9dc40b099ee6d68f97385950f303969d889ee93d4635e34dff9239103bdf66a4b7cbba3e7eb7a\",\n    \"0xa59afebadf0260e832f6f44468443562f53fbaf7bcb5e46e1462d3f328ac437ce56edbca617659ac9883f9e13261fad7\",\n    \"0xb1990e42743a88de4deeacfd55fafeab3bc380cb95de43ed623d021a4f2353530bcab9594389c1844b1c5ea6634c4555\",\n    \"0x85051e841149a10e83f56764e042182208591396d0ce78c762c4a413e6836906df67f38c69793e158d64fef111407ba3\",\n    \"0x9778172bbd9b1f2ec6bbdd61829d7b39a7df494a818e31c654bf7f6a30139899c4822c1bf418dd4f923243067759ce63\",\n    \"0x9355005b4878c87804fc966e7d24f3e4b02bed35b4a77369d01f25a3dcbff7621b08306b1ac85b76fe7b4a3eb5f839b1\",\n    \"0x8f9dc6a54fac052e236f8f0e1f571ac4b5308a43acbe4cc8183bce26262ddaf7994e41cf3034a4cbeca2c505a151e3b1\",\n    \"0x8cc59c17307111723fe313046a09e0e32ea0cce62c13814ab7c6408c142d6a0311d801be4af53fc9240523f12045f9ef\",\n    \"0x8e6057975ed40a1932e47dd3ac778f72ee2a868d8540271301b1aa6858de1a5450f596466494a3e0488be4fbeb41c840\",\n    \"0x812145efbd6559ae13325d56a15940ca4253b17e72a9728986b563bb5acc13ec86453796506ac1a8f12bd6f9e4a288c3\",\n    \"0x911da0a6d6489eb3dab2ec4a16e36127e8a291ae68a6c2c9de33e97f3a9b1f00da57a94e270a0de79ecc5ecb45d19e83\",\n    \"0xb72ea85973f4b2a7e6e71962b0502024e979a73c18a9111130e158541fa47bbaaf53940c8f846913a517dc69982ba9e1\",\n    \"0xa7a56ad1dbdc55f177a7ad1d0af78447dc2673291e34e8ab74b26e2e2e7d8c5fe5dc89e7ef60f04a9508847b5b3a8188\",\n    \"0xb52503f6e5411db5d1e70f5fb72ccd6463fa0f197b3e51ca79c7b5a8ab2e894f0030476ada72534fa4eb4e06c3880f90\",\n    \"0xb51c7957a3d18c4e38f6358f2237b3904618d58b1de5dec53387d25a63772e675a5b714ad35a38185409931157d4b529\",\n    \"0xb86b4266e719d29c043d7ec091547aa6f65bbf2d8d831d1515957c5c06513b72aa82113e9645ad38a7bc3f5383504fa6\",\n    \"0xb95b547357e6601667b0f5f61f261800a44c2879cf94e879def6a105b1ad2bbf1795c3b98a90d588388e81789bd02681\",\n    \"0xa58fd4c5ae4673fa350da6777e13313d5d37ed1dafeeb8f4f171549765b84c895875d9d3ae6a9741f3d51006ef81d962\",\n    \"0x9398dc348d078a604aadc154e6eef2c0be1a93bb93ba7fe8976edc2840a3a318941338cc4d5f743310e539d9b46613d2\",\n    \"0x902c9f0095014c4a2f0dccaaab543debba6f4cc82c345a10aaf4e72511725dbed7a34cd393a5f4e48a3e5142b7be84ed\",\n    \"0xa7c0447849bb44d04a0393a680f6cd390093484a79a147dd238f5d878030d1c26646d88211108e59fe08b58ad20c6fbd\",\n    \"0x80db045535d6e67a422519f5c89699e37098449d249698a7cc173a26ccd06f60238ae6cc7242eb780a340705c906790c\",\n    \"0x8e52b451a299f30124505de2e74d5341e1b5597bdd13301cc39b05536c96e4380e7f1b5c7ef076f5b3005a868657f17c\",\n    \"0x824499e89701036037571761e977654d2760b8ce21f184f2879fda55d3cda1e7a95306b8abacf1caa79d3cc075b9d27f\",\n    \"0x9049b956b77f8453d2070607610b79db795588c0cec12943a0f5fe76f358dea81e4f57a4692112afda0e2c05c142b26f\",\n    \"0x81911647d818a4b5f4990bfd4bc13bf7be7b0059afcf1b6839333e8569cdb0172fd2945410d88879349f677abaed5eb3\",\n    \"0xad4048f19b8194ed45b6317d9492b71a89a66928353072659f5ce6c816d8f21e69b9d1817d793effe49ca1874daa1096\",\n    \"0x8d22f7b2ddb31458661abd34b65819a374a1f68c01fc6c9887edeba8b80c65bceadb8f57a3eb686374004b836261ef67\",\n    \"0x92637280c259bc6842884db3d6e32602a62252811ae9b019b3c1df664e8809ffe86db88cfdeb8af9f46435c9ee790267\",\n    \"0xa2f416379e52e3f5edc21641ea73dc76c99f7e29ea75b487e18bd233856f4c0183429f378d2bfc6cd736d29d6cadfa49\",\n    \"0x882cb6b76dbdc188615dcf1a8439eba05ffca637dd25197508156e03c930b17b9fed2938506fdd7b77567cb488f96222\",\n    \"0xb68b621bb198a763fb0634eddb93ed4b5156e59b96c88ca2246fd1aea3e6b77ed651e112ac41b30cd361fadc011d385e\",\n    \"0xa3cb22f6b675a29b2d1f827cacd30df14d463c93c3502ef965166f20d046af7f9ab7b2586a9c64f4eae4fad2d808a164\",\n    \"0x8302d9ce4403f48ca217079762ce42cee8bc30168686bb8d3a945fbd5acd53b39f028dce757b825eb63af2d5ae41169d\",\n    \"0xb2eef1fbd1a176f1f4cd10f2988c7329abe4eb16c7405099fb92baa724ab397bc98734ef7d4b24c0f53dd90f57520d04\",\n    \"0xa1bbef0bd684a3f0364a66bde9b29326bac7aa3dde4caed67f14fb84fed3de45c55e406702f1495a3e2864d4ee975030\",\n    \"0x976acdb0efb73e3a3b65633197692dedc2adaed674291ae3df76b827fc866d214e9cac9ca46baefc4405ff13f953d936\",\n    \"0xb9fbf71cc7b6690f601f0b1c74a19b7d14254183a2daaafec7dc3830cba5ae173d854bbfebeca985d1d908abe5ef0cda\",\n    \"0x90591d7b483598c94e38969c4dbb92710a1a894bcf147807f1bcbd8aa3ac210b9f2be65519aa829f8e1ccdc83ad9b8cf\",\n    \"0xa30568577c91866b9c40f0719d46b7b3b2e0b4a95e56196ac80898a2d89cc67880e1229933f2cd28ee3286f8d03414d7\",\n    \"0x97589a88c3850556b359ec5e891f0937f922a751ac7c95949d3bbc7058c172c387611c0f4cb06351ef02e5178b3dd9e4\",\n    \"0x98e7bbe27a1711f4545df742f17e3233fbcc63659d7419e1ca633f104cb02a32c84f2fac23ca2b84145c2672f68077ab\",\n    \"0xa7ddb91636e4506d8b7e92aa9f4720491bb71a72dadc47c7f4410e15f93e43d07d2b371951a0e6a18d1bd087aa96a5c4\",\n    \"0xa7c006692227a06db40bceac3d5b1daae60b5692dd9b54772bedb5fea0bcc91cbcdb530cac31900ffc70c5b3ffadc969\",\n    \"0x8d3ec6032778420dfa8be52066ba0e623467df33e4e1901dbadd586c5d750f4ccde499b5197e26b9ea43931214060f69\",\n    \"0x8d9a8410518ea64f89df319bfd1fc97a0971cdb9ad9b11d1f8fe834042ea7f8dce4db56eeaf179ff8dda93b6db93e5ce\",\n    \"0xa3c533e9b3aa04df20b9ff635cb1154ce303e045278fcf3f10f609064a5445552a1f93989c52ce852fd0bbd6e2b6c22e\",\n    \"0x81934f3a7f8c1ae60ec6e4f212986bcc316118c760a74155d06ce0a8c00a9b9669ec4e143ca214e1b995e41271774fd9\",\n    \"0xab8e2d01a71192093ef8fafa7485e795567cc9db95a93fb7cc4cf63a391ef89af5e2bfad4b827fffe02b89271300407f\",\n    \"0x83064a1eaa937a84e392226f1a60b7cfad4efaa802f66de5df7498962f7b2649924f63cd9962d47906380b97b9fe80e1\",\n    \"0xb4f5e64a15c6672e4b55417ee5dc292dcf93d7ea99965a888b1cc4f5474a11e5b6520eacbcf066840b343f4ceeb6bf33\",\n    \"0xa63d278b842456ef15c278b37a6ea0f27c7b3ffffefca77c7a66d2ea06c33c4631eb242bbb064d730e70a8262a7b848a\",\n    \"0x83a41a83dbcdf0d22dc049de082296204e848c453c5ab1ba75aa4067984e053acf6f8b6909a2e1f0009ed051a828a73b\",\n    \"0x819485b036b7958508f15f3c19436da069cbe635b0318ebe8c014cf1ef9ab2df038c81161b7027475bcfa6fff8dd9faf\",\n    \"0xaa40e38172806e1e045e167f3d1677ef12d5dcdc89b43639a170f68054bd196c4fae34c675c1644d198907a03f76ba57\",\n    \"0x969bae484883a9ed1fbed53b26b3d4ee4b0e39a6c93ece5b3a49daa01444a1c25727dabe62518546f36b047b311b177c\",\n    \"0x80a9e73a65da99664988b238096a090d313a0ee8e4235bc102fa79bb337b51bb08c4507814eb5baec22103ec512eaab0\",\n    \"0x86604379aec5bddda6cbe3ef99c0ac3a3c285b0b1a15b50451c7242cd42ae6b6c8acb717dcca7917838432df93a28502\",\n    \"0xa23407ee02a495bed06aa7e15f94cfb05c83e6d6fba64456a9bbabfa76b2b68c5c47de00ba169e710681f6a29bb41a22\",\n    \"0x98cff5ecc73b366c6a01b34ac9066cb34f7eeaf4f38a5429bad2d07e84a237047e2a065c7e8a0a6581017dadb4695deb\",\n    \"0x8de9f68a938f441f3b7ab84bb1f473c5f9e5c9e139e42b7ccee1d254bd57d0e99c2ccda0f3198f1fc5737f6023dd204e\",\n    \"0xb0ce48d815c2768fb472a315cad86aa033d0e9ca506f146656e2941829e0acb735590b4fbc713c2d18d3676db0a954ac\",\n    \"0x82f485cdefd5642a6af58ac6817991c49fac9c10ace60f90b27f1788cc026c2fe8afc83cf499b3444118f9f0103598a8\",\n    \"0x82c24550ed512a0d53fc56f64cc36b553823ae8766d75d772dacf038c460f16f108f87a39ceef7c66389790f799dbab3\",\n    \"0x859ffcf1fe9166388316149b9acc35694c0ea534d43f09dae9b86f4aa00a23b27144dda6a352e74b9516e8c8d6fc809c\",\n    \"0xb8f7f353eec45da77fb27742405e5ad08d95ec0f5b6842025be9def3d9892f85eb5dd0921b41e6eff373618dba215bca\",\n    \"0x8ccca4436f9017e426229290f5cd05eac3f16571a4713141a7461acfe8ae99cd5a95bf5b6df129148693c533966145da\",\n    \"0xa2c67ecc19c0178b2994846fea4c34c327a5d786ac4b09d1d13549d5be5996d8a89021d63d65cb814923388f47cc3a03\",\n    \"0xaa0ff87d676b418ec08f5cbf577ac7e744d1d0e9ebd14615b550eb86931eafd2a36d4732cc5d6fab1713fd7ab2f6f7c0\",\n    \"0x8aef4730bb65e44efd6bb9441c0ae897363a2f3054867590a2c2ecf4f0224e578c7a67f10b40f8453d9f492ac15a9b2d\",\n    \"0x86a187e13d8fba5addcfdd5b0410cedd352016c930f913addd769ee09faa6be5ca3e4b1bdb417a965c643a99bd92be42\",\n    \"0xa0a4e9632a7a094b14b29b78cd9c894218cdf6783e61671e0203865dc2a835350f465fbaf86168f28af7c478ca17bc89\",\n    \"0xa8c7b02d8deff2cd657d8447689a9c5e2cd74ef57c1314ac4d69084ac24a7471954d9ff43fe0907d875dcb65fd0d3ce5\",\n    \"0x97ded38760aa7be6b6960b5b50e83b618fe413cbf2bcc1da64c05140bcc32f5e0e709cd05bf8007949953fac5716bad9\",\n    \"0xb0d293835a24d64c2ae48ce26e550b71a8c94a0883103757fb6b07e30747f1a871707d23389ba2b2065fa6bafe220095\",\n    \"0x8f9e291bf849feaa575592e28e3c8d4b7283f733d41827262367ea1c40f298c7bcc16505255a906b62bf15d9f1ba85fb\",\n    \"0x998f4e2d12708b4fd85a61597ca2eddd750f73c9e0c9b3cf0825d8f8e01f1628fd19797dcaed3b16dc50331fc6b8b821\",\n    \"0xb30d1f8c115d0e63bf48f595dd10908416774c78b3bbb3194192995154d80ea042d2e94d858de5f8aa0261b093c401fd\",\n    \"0xb5d9c75bb41f964cbff3f00e96d9f1480c91df8913f139f0d385d27a19f57a820f838eb728e46823cbff00e21c660996\",\n    \"0xa6edec90b5d25350e2f5f0518777634f9e661ec9d30674cf5b156c4801746d62517751d90074830ac0f4b09911c262f1\",\n    \"0x82f98da1264b6b75b8fbeb6a4d96d6a05b25c24db0d57ba3a38efe3a82d0d4e331b9fc4237d6494ccfe4727206457519\",\n    \"0xb89511843453cf4ecd24669572d6371b1e529c8e284300c43e0d5bb6b3aaf35aeb634b3cb5c0a2868f0d5e959c1d0772\",\n    \"0xa82bf065676583e5c1d3b81987aaae5542f522ba39538263a944bb33ea5b514c649344a96c0205a3b197a3f930fcda6c\",\n    \"0xa37b47ea527b7e06c460776aa662d9a49ff4149d3993f1a974b0dd165f7171770d189b0e2ea54fd5fccb6a14b116e68a\",\n    \"0xa1017677f97dda818274d47556d09d0e4ccacb23a252f82a6cfe78c630ad46fb9806307445a59fb61262182de3a2b29c\",\n    \"0xb01e9fcac239ba270e6877b79273ddd768bf8a51d2ed8a051b1c11e18eff3de5920e2fcbfbd26f06d381eddd3b1f1e1b\",\n    \"0x82fcd53d803b1c8e4ed76adc339b7f3a5962d37042b9683aabac7513ac68775d4a566a9460183926a6a95dbe7d551a1f\",\n    \"0xa763e78995d55cd21cdb7ef75d9642d6e1c72453945e346ab6690c20a4e1eeec61bb848ef830ae4b56182535e3c71d8f\",\n    \"0xb769f4db602251d4b0a1186782799bdcef66de33c110999a5775c50b349666ffd83d4c89714c4e376f2efe021a5cfdb2\",\n    \"0xa59cbd1b785efcfa6e83fc3b1d8cf638820bc0c119726b5368f3fba9dce8e3414204fb1f1a88f6c1ff52e87961252f97\",\n    \"0x95c8c458fd01aa23ecf120481a9c6332ebec2e8bb70a308d0576926a858457021c277958cf79017ddd86a56cacc2d7db\",\n    \"0x82eb41390800287ae56e77f2e87709de5b871c8bdb67c10a80fc65f3acb9f7c29e8fa43047436e8933f27449ea61d94d\",\n    \"0xb3ec25e3545eb83aed2a1f3558d1a31c7edde4be145ecc13b33802654b77dc049b4f0065069dd9047b051e52ab11dcdd\",\n    \"0xb78a0c715738f56f0dc459ab99e252e3b579b208142836b3c416b704ca1de640ca082f29ebbcee648c8c127df06f6b1e\",\n    \"0xa4083149432eaaf9520188ebf4607d09cf664acd1f471d4fb654476e77a9eaae2251424ffda78d09b6cb880df35c1219\",\n    \"0x8c52857d68d6e9672df3db2df2dbf46b516a21a0e8a18eec09a6ae13c1ef8f369d03233320dd1c2c0bbe00abfc1ea18b\",\n    \"0x8c856089488803066bff3f8d8e09afb9baf20cecc33c8823c1c0836c3d45498c3de37e87c016b705207f60d2b00f8609\",\n    \"0x831a3df39be959047b2aead06b4dcd3012d7b29417f642b83c9e8ce8de24a3dbbd29c6fdf55e2db3f7ea04636c94e403\",\n    \"0xaed84d009f66544addabe404bf6d65af7779ce140dc561ff0c86a4078557b96b2053b7b8a43432ffb18cd814f143b9da\",\n    \"0x93282e4d72b0aa85212a77b336007d8ba071eea17492da19860f1ad16c1ea8867ccc27ef5c37c74b052465cc11ea4f52\",\n    \"0xa7b78b8c8d057194e8d68767f1488363f77c77bddd56c3da2bc70b6354c7aa76247c86d51f7371aa38a4aa7f7e3c0bb7\",\n    \"0xb1c77283d01dcd1bde649b5b044eac26befc98ff57cbee379fb5b8e420134a88f2fc7f0bf04d15e1fbd45d29e7590fe6\",\n    \"0xa4aa8de70330a73b2c6458f20a1067eed4b3474829b36970a8df125d53bbdda4f4a2c60063b7cccb0c80fc155527652f\",\n    \"0x948a6c79ba1b8ad7e0bed2fae2f0481c4e41b4d9bbdd9b58164e28e9065700e83f210c8d5351d0212e0b0b68b345b3a5\",\n    \"0x86a48c31dcbbf7b082c92d28e1f613a2378a910677d7db3a349dc089e4a1e24b12eee8e8206777a3a8c64748840b7387\",\n    \"0x976adb1af21e0fc34148917cf43d933d7bfd3fd12ed6c37039dcd5a4520e3c6cf5868539ba5bf082326430deb8a4458d\",\n    \"0xb93e1a4476f2c51864bb4037e7145f0635eb2827ab91732b98d49b6c07f6ac443111aa1f1da76d1888665cb897c3834e\",\n    \"0x8afd46fb23bf869999fa19784b18a432a1f252d09506b8dbb756af900518d3f5f244989b3d7c823d9029218c655d3dc6\",\n    \"0x83f1e59e3abeed18cdc632921672673f1cb6e330326e11c4e600e13e0d5bc11bdc970ae12952e15103a706fe720bf4d6\",\n    \"0x90ce4cc660714b0b673d48010641c09c00fc92a2c596208f65c46073d7f349dd8e6e077ba7dcef9403084971c3295b76\",\n    \"0x8b09b0f431a7c796561ecf1549b85048564de428dac0474522e9558b6065fede231886bc108539c104ce88ebd9b5d1b0\",\n    \"0x85d6e742e2fb16a7b0ba0df64bc2c0dbff9549be691f46a6669bca05e89c884af16822b85faefefb604ec48c8705a309\",\n    \"0xa87989ee231e468a712c66513746fcf03c14f103aadca0eac28e9732487deb56d7532e407953ab87a4bf8961588ef7b0\",\n    \"0xb00da10efe1c29ee03c9d37d5918e391ae30e48304e294696b81b434f65cf8c8b95b9d1758c64c25e534d045ba28696f\",\n    \"0x91c0e1fb49afe46c7056400baa06dbb5f6e479db78ee37e2d76c1f4e88994357e257b83b78624c4ef6091a6c0eb8254d\",\n    \"0x883fb797c498297ccbf9411a3e727c3614af4eccde41619b773dc7f3259950835ee79453debf178e11dec4d3ada687a0\",\n    \"0xa14703347e44eb5059070b2759297fcfcfc60e6893c0373eea069388eba3950aa06f1c57cd2c30984a2d6f9e9c92c79e\",\n    \"0xafebc7585b304ceba9a769634adff35940e89cd32682c78002822aab25eec3edc29342b7f5a42a56a1fec67821172ad5\",\n    \"0xaea3ff3822d09dba1425084ca95fd359718d856f6c133c5fabe2b2eed8303b6e0ba0d8698b48b93136a673baac174fd9\",\n    \"0xaf2456a09aa777d9e67aa6c7c49a1845ea5cdda2e39f4c935c34a5f8280d69d4eec570446998cbbe31ede69a91e90b06\",\n    \"0x82cada19fed16b891ef3442bafd49e1f07c00c2f57b2492dd4ee36af2bd6fd877d6cb41188a4d6ce9ec8d48e8133d697\",\n    \"0x82a21034c832287f616619a37c122cee265cc34ae75e881fcaea4ea7f689f3c2bc8150bbf7dbcfd123522bfb7f7b1d68\",\n    \"0x86877217105f5d0ec3eeff0289fc2a70d505c9fdf7862e8159553ef60908fb1a27bdaf899381356a4ef4649072a9796c\",\n    \"0x82b196e49c6e861089a427c0b4671d464e9d15555ffb90954cd0d630d7ae02eb3d98ceb529d00719c2526cd96481355a\",\n    \"0xa29b41d0d43d26ce76d4358e0db2b77df11f56e389f3b084d8af70a636218bd3ac86b36a9fe46ec9058c26a490f887f7\",\n    \"0xa4311c4c20c4d7dd943765099c50f2fd423e203ccfe98ff00087d205467a7873762510cac5fdce7a308913ed07991ed7\",\n    \"0xb1f040fc5cc51550cb2c25cf1fd418ecdd961635a11f365515f0cb4ffb31da71f48128c233e9cc7c0cf3978d757ec84e\",\n    \"0xa9ebae46f86d3bd543c5f207ed0d1aed94b8375dc991161d7a271f01592912072e083e2daf30c146430894e37325a1b9\",\n    \"0x826418c8e17ad902b5fe88736323a47e0ca7a44bce4cbe27846ec8fe81de1e8942455dda6d30e192cdcc73e11df31256\",\n    \"0x85199db563427c5edcbac21f3d39fec2357be91fb571982ddcdc4646b446ad5ced84410de008cb47b3477ee0d532daf8\",\n    \"0xb7eed9cd400b2ca12bf1d9ae008214b8561fb09c8ad9ff959e626ffde00fee5ff2f5b6612e231f2a1a9b1646fcc575e3\",\n    \"0x8b40bf12501dcbac78f5a314941326bfcddf7907c83d8d887d0bb149207f85d80cd4dfbd7935439ea7b14ea39a3fded7\",\n    \"0x83e3041af302485399ba6cd5120e17af61043977083887e8d26b15feec4a6b11171ac5c06e6ad0971d4b58a81ff12af3\",\n    \"0x8f5b9a0eecc589dbf8c35a65d5e996a659277ef6ea509739c0cb7b3e2da9895e8c8012de662e5b23c5fa85d4a8f48904\",\n    \"0x835d71ed5e919d89d8e6455f234f3ff215462c4e3720c371ac8c75e83b19dfe3ae15a81547e4dc1138e5f5997f413cc9\",\n    \"0x8b7d2e4614716b1db18e9370176ea483e6abe8acdcc3dcdf5fb1f4d22ca55d652feebdccc171c6de38398d9f7bfdec7a\",\n    \"0x93eace72036fe57d019676a02acf3d224cf376f166658c1bf705db4f24295881d477d6fdd7916efcfceff8c7a063deda\",\n    \"0xb1ac460b3d516879a84bc886c54f020a9d799e7c49af3e4d7de5bf0d2793c852254c5d8fe5616147e6659512e5ccb012\",\n    \"0xacd0947a35cb167a48bcd9667620464b54ac0e78f9316b4aa92dcaab5422d7a732087e52e1c827faa847c6b2fe6e7766\",\n    \"0x94ac33d21c3d12ff762d32557860e911cd94d666609ddcc42161b9c16f28d24a526e8b10bb03137257a92cec25ae637d\",\n    \"0x832e02058b6b994eadd8702921486241f9a19e68ed1406dad545e000a491ae510f525ccf9d10a4bba91c68f2c53a0f58\",\n    \"0x9471035d14f78ff8f463b9901dd476b587bb07225c351161915c2e9c6114c3c78a501379ab6fb4eb03194c457cbd22bf\",\n    \"0xab64593e034c6241d357fcbc32d8ea5593445a5e7c24cac81ad12bd2ef01843d477a36dc1ba21dbe63b440750d72096a\",\n    \"0x9850f3b30045e927ad3ec4123a32ed2eb4c911f572b6abb79121873f91016f0d80268de8b12e2093a4904f6e6cab7642\",\n    \"0x987212c36b4722fe2e54fa30c52b1e54474439f9f35ca6ad33c5130cd305b8b54b532dd80ffd2c274105f20ce6d79f6e\",\n    \"0x8b4d0c6abcb239b5ed47bef63bc17efe558a27462c8208fa652b056e9eae9665787cd1aee34fbb55beb045c8bfdb882b\",\n    \"0xa9f3483c6fee2fe41312d89dd4355d5b2193ac413258993805c5cbbf0a59221f879386d3e7a28e73014f10e65dd503d9\",\n    \"0xa2225da3119b9b7c83d514b9f3aeb9a6d9e32d9cbf9309cbb971fd53c4b2c001d10d880a8ad8a7c281b21d85ceca0b7c\",\n    \"0xa050be52e54e676c151f7a54453bbb707232f849beab4f3bf504b4d620f59ed214409d7c2bd3000f3ff13184ccda1c35\",\n    \"0xadbccf681e15b3edb6455a68d292b0a1d0f5a4cb135613f5e6db9943f02181341d5755875db6ee474e19ace1c0634a28\",\n    \"0x8b6eff675632a6fad0111ec72aacc61c7387380eb87933fd1d098856387d418bd38e77d897e65d6fe35951d0627c550b\",\n    \"0xaabe2328ddf90989b15e409b91ef055cb02757d34987849ae6d60bef2c902bf8251ed21ab30acf39e500d1d511e90845\",\n    \"0x92ba4eb1f796bc3d8b03515f65c045b66e2734c2da3fc507fdd9d6b5d1e19ab3893726816a32141db7a31099ca817d96\",\n    \"0x8a98b3cf353138a1810beb60e946183803ef1d39ac4ea92f5a1e03060d35a4774a6e52b14ead54f6794d5f4022b8685c\",\n    \"0x909f8a5c13ec4a59b649ed3bee9f5d13b21d7f3e2636fd2bb3413c0646573fdf9243d63083356f12f5147545339fcd55\",\n    \"0x9359d914d1267633141328ed0790d81c695fea3ddd2d406c0df3d81d0c64931cf316fe4d92f4353c99ff63e2aefc4e34\",\n    \"0xb88302031681b54415fe8fbfa161c032ea345c6af63d2fb8ad97615103fd4d4281c5a9cae5b0794c4657b97571a81d3b\",\n    \"0x992c80192a519038082446b1fb947323005b275e25f2c14c33cc7269e0ec038581cc43705894f94bad62ae33a8b7f965\",\n    \"0xa78253e3e3eece124bef84a0a8807ce76573509f6861d0b6f70d0aa35a30a123a9da5e01e84969708c40b0669eb70aa6\",\n    \"0x8d5724de45270ca91c94792e8584e676547d7ac1ac816a6bb9982ee854eb5df071d20545cdfd3771cd40f90e5ba04c8e\",\n    \"0x825a6f586726c68d45f00ad0f5a4436523317939a47713f78fd4fe81cd74236fdac1b04ecd97c2d0267d6f4981d7beb1\"\n  ],\n  \"g2_monomial\": [\n    \"0x93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8\",\n    \"0xb5bfd7dd8cdeb128843bc287230af38926187075cbfbefa81009a2ce615ac53d2914e5870cb452d2afaaab24f3499f72185cbfee53492714734429b7b38608e23926c911cceceac9a36851477ba4c60b087041de621000edc98edada20c1def2\",\n    \"0xb5337ba0ce5d37224290916e268e2060e5c14f3f9fc9e1ec3af5a958e7a0303122500ce18f1a4640bf66525bd10e763501fe986d86649d8d45143c08c3209db3411802c226e9fe9a55716ac4a0c14f9dcef9e70b2bb309553880dc5025eab3cc\",\n    \"0xb3c1dcdc1f62046c786f0b82242ef283e7ed8f5626f72542aa2c7a40f14d9094dd1ebdbd7457ffdcdac45fd7da7e16c51200b06d791e5e43e257e45efdf0bd5b06cd2333beca2a3a84354eb48662d83aef5ecf4e67658c851c10b13d8d87c874\",\n    \"0x954d91c7688983382609fca9e211e461f488a5971fd4e40d7e2892037268eacdfd495cfa0a7ed6eb0eb11ac3ae6f651716757e7526abe1e06c64649d80996fd3105c20c4c94bc2b22d97045356fe9d791f21ea6428ac48db6f9e68e30d875280\",\n    \"0x88a6b6bb26c51cf9812260795523973bb90ce80f6820b6c9048ab366f0fb96e48437a7f7cb62aedf64b11eb4dfefebb0147608793133d32003cb1f2dc47b13b5ff45f1bb1b2408ea45770a08dbfaec60961acb8119c47b139a13b8641e2c9487\",\n    \"0x85cd7be9728bd925d12f47fb04b32d9fad7cab88788b559f053e69ca18e463113ecc8bbb6dbfb024835f901b3a957d3108d6770fb26d4c8be0a9a619f6e3a4bf15cbfd48e61593490885f6cee30e4300c5f9cf5e1c08e60a2d5b023ee94fcad0\",\n    \"0x80477dba360f04399821a48ca388c0fa81102dd15687fea792ee8c1114e00d1bc4839ad37ac58900a118d863723acfbe08126ea883be87f50e4eabe3b5e72f5d9e041db8d9b186409fd4df4a7dde38c0e0a3b1ae29b098e5697e7f110b6b27e4\",\n    \"0xb7a6aec08715a9f8672a2b8c367e407be37e59514ac19dd4f0942a68007bba3923df22da48702c63c0d6b3efd3c2d04e0fe042d8b5a54d562f9f33afc4865dcbcc16e99029e25925580e87920c399e710d438ac1ce3a6dc9b0d76c064a01f6f7\",\n    \"0xac1b001edcea02c8258aeffbf9203114c1c874ad88dae1184fadd7d94cd09053649efd0ca413400e6e9b5fa4eac33261000af88b6bd0d2abf877a4f0355d2fb4d6007adb181695201c5432e50b850b51b3969f893bddf82126c5a71b042b7686\",\n    \"0x90043fda4de53fb364fab2c04be5296c215599105ecff0c12e4917c549257125775c29f2507124d15f56e30447f367db0596c33237242c02d83dfd058735f1e3c1ff99069af55773b6d51d32a68bf75763f59ec4ee7267932ae426522b8aaab6\",\n    \"0xa8660ce853e9dc08271bf882e29cd53397d63b739584dda5263da4c7cc1878d0cf6f3e403557885f557e184700575fee016ee8542dec22c97befe1d10f414d22e84560741cdb3e74c30dda9b42eeaaf53e27822de2ee06e24e912bf764a9a533\",\n    \"0x8fe3921a96d0d065e8aa8fce9aa42c8e1461ca0470688c137be89396dd05103606dab6cdd2a4591efd6addf72026c12e065da7be276dee27a7e30afa2bd81c18f1516e7f068f324d0bad9570b95f6bd02c727cd2343e26db0887c3e4e26dceda\",\n    \"0x8ae1ad97dcb9c192c9a3933541b40447d1dc4eebf380151440bbaae1e120cc5cdf1bcea55180b128d8e180e3af623815191d063cc0d7a47d55fb7687b9d87040bf7bc1a7546b07c61db5ccf1841372d7c2fe4a5431ffff829f3c2eb590b0b710\",\n    \"0x8c2fa96870a88150f7876c931e2d3cc2adeaaaf5c73ef5fa1cf9dfa0991ae4819f9321af7e916e5057d87338e630a2f21242c29d76963cf26035b548d2a63d8ad7bd6efefa01c1df502cbdfdfe0334fb21ceb9f686887440f713bf17a89b8081\",\n    \"0xb9aa98e2f02bb616e22ee5dd74c7d1049321ac9214d093a738159850a1dbcc7138cb8d26ce09d8296368fd5b291d74fa17ac7cc1b80840fdd4ee35e111501e3fa8485b508baecda7c1ab7bd703872b7d64a2a40b3210b6a70e8a6ffe0e5127e3\",\n    \"0x9292db67f8771cdc86854a3f614a73805bf3012b48f1541e704ea4015d2b6b9c9aaed36419769c87c49f9e3165f03edb159c23b3a49c4390951f78e1d9b0ad997129b17cdb57ea1a6638794c0cca7d239f229e589c5ae4f9fe6979f7f8cba1d7\",\n    \"0x91cd9e86550f230d128664f7312591fee6a84c34f5fc7aed557bcf986a409a6de722c4330453a305f06911d2728626e611acfdf81284f77f60a3a1595053a9479964fd713117e27c0222cc679674b03bc8001501aaf9b506196c56de29429b46\",\n    \"0xa9516b73f605cc31b89c68b7675dc451e6364595243d235339437f556cf22d745d4250c1376182273be2d99e02c10eee047410a43eff634d051aeb784e76cb3605d8e079b9eb6ad1957dfdf77e1cd32ce4a573c9dfcc207ca65af6eb187f6c3d\",\n    \"0xa9667271f7d191935cc8ad59ef3ec50229945faea85bfdfb0d582090f524436b348aaa0183b16a6231c00332fdac2826125b8c857a2ed9ec66821cfe02b3a2279be2412441bc2e369b255eb98614e4be8490799c4df22f18d47d24ec70bba5f7\",\n    \"0xa4371144d2aa44d70d3cb9789096d3aa411149a6f800cb46f506461ee8363c8724667974252f28aea61b6030c05930ac039c1ee64bb4bd56532a685cae182bf2ab935eee34718cffcb46cae214c77aaca11dbb1320faf23c47247db1da04d8dc\",\n    \"0x89a7eb441892260b7e81168c386899cd84ffc4a2c5cad2eae0d1ab9e8b5524662e6f660fe3f8bfe4c92f60b060811bc605b14c5631d16709266886d7885a5eb5930097127ec6fb2ebbaf2df65909cf48f253b3d5e22ae48d3e9a2fd2b01f447e\",\n    \"0x9648c42ca97665b5eccb49580d8532df05eb5a68db07f391a2340769b55119eaf4c52fe4f650c09250fa78a76c3a1e271799b8333cc2628e3d4b4a6a3e03da1f771ecf6516dd63236574a7864ff07e319a6f11f153406280d63af9e2b5713283\",\n    \"0x9663bf6dd446ea7a90658ee458578d4196dc0b175ef7fcfa75f44d41670850774c2e46c5a6be132a2c072a3c0180a24f0305d1acac49d2d79878e5cda80c57feda3d01a6af12e78b5874e2a4b3717f11c97503b41a4474e2e95b179113726199\",\n    \"0xb212aeb4814e0915b432711b317923ed2b09e076aaf558c3ae8ef83f9e15a83f9ea3f47805b2750ab9e8106cb4dc6ad003522c84b03dc02829978a097899c773f6fb31f7fe6b8f2d836d96580f216fec20158f1590c3e0d7850622e15194db05\",\n    \"0x925f005059bf07e9ceccbe66c711b048e236ade775720d0fe479aebe6e23e8af281225ad18e62458dc1b03b42ad4ca290d4aa176260604a7aad0d9791337006fbdebe23746f8060d42876f45e4c83c3643931392fde1cd13ff8bddf8111ef974\",\n    \"0x9553edb22b4330c568e156a59ef03b26f5c326424f830fe3e8c0b602f08c124730ffc40bc745bec1a22417adb22a1a960243a10565c2be3066bfdb841d1cd14c624cd06e0008f4beb83f972ce6182a303bee3fcbcabc6cfe48ec5ae4b7941bfc\",\n    \"0x935f5a404f0a78bdcce709899eda0631169b366a669e9b58eacbbd86d7b5016d044b8dfc59ce7ed8de743ae16c2343b50e2f925e88ba6319e33c3fc76b314043abad7813677b4615c8a97eb83cc79de4fedf6ccbcfa4d4cbf759a5a84e4d9742\",\n    \"0xa5b014ab936eb4be113204490e8b61cd38d71da0dec7215125bcd131bf3ab22d0a32ce645bca93e7b3637cf0c2db3d6601a0ddd330dc46f9fae82abe864ffc12d656c88eb50c20782e5bb6f75d18760666f43943abb644b881639083e122f557\",\n    \"0x935b7298ae52862fa22bf03bfc1795b34c70b181679ae27de08a9f5b4b884f824ef1b276b7600efa0d2f1d79e4a470d51692fd565c5cf8343dd80e5d3336968fc21c09ba9348590f6206d4424eb229e767547daefa98bc3aa9f421158dee3f2a\",\n    \"0x9830f92446e708a8f6b091cc3c38b653505414f8b6507504010a96ffda3bcf763d5331eb749301e2a1437f00e2415efb01b799ad4c03f4b02de077569626255ac1165f96ea408915d4cf7955047620da573e5c439671d1fa5c833fb11de7afe6\",\n    \"0x840dcc44f673fff3e387af2bb41e89640f2a70bcd2b92544876daa92143f67c7512faf5f90a04b7191de01f3e2b1bde00622a20dc62ca23bbbfaa6ad220613deff43908382642d4d6a86999f662efd64b1df448b68c847cfa87630a3ffd2ec76\",\n    \"0x92950c895ed54f7f876b2fda17ecc9c41b7accfbdd42c210cc5b475e0737a7279f558148531b5c916e310604a1de25a80940c94fe5389ae5d6a5e9c371be67bceea1877f5401725a6595bcf77ece60905151b6dfcb68b75ed2e708c73632f4fd\",\n    \"0x8010246bf8e94c25fd029b346b5fbadb404ef6f44a58fd9dd75acf62433d8cc6db66974f139a76e0c26dddc1f329a88214dbb63276516cf325c7869e855d07e0852d622c332ac55609ba1ec9258c45746a2aeb1af0800141ee011da80af175d4\",\n    \"0xb0f1bad257ebd187bdc3f37b23f33c6a5d6a8e1f2de586080d6ada19087b0e2bf23b79c1b6da1ee82271323f5bdf3e1b018586b54a5b92ab6a1a16bb3315190a3584a05e6c37d5ca1e05d702b9869e27f513472bcdd00f4d0502a107773097da\",\n    \"0x9636d24f1ede773ce919f309448dd7ce023f424afd6b4b69cb98c2a988d849a283646dc3e469879daa1b1edae91ae41f009887518e7eb5578f88469321117303cd3ac2d7aee4d9cb5f82ab9ae3458e796dfe7c24284b05815acfcaa270ff22e2\",\n    \"0xb373feb5d7012fd60578d7d00834c5c81df2a23d42794fed91aa9535a4771fde0341c4da882261785e0caca40bf83405143085e7f17e55b64f6c5c809680c20b050409bf3702c574769127c854d27388b144b05624a0e24a1cbcc4d08467005b\",\n    \"0xb15680648949ce69f82526e9b67d9b55ce5c537dc6ab7f3089091a9a19a6b90df7656794f6edc87fb387d21573ffc847062623685931c2790a508cbc8c6b231dd2c34f4d37d4706237b1407673605a604bcf6a50cc0b1a2db20485e22b02c17e\",\n    \"0x8817e46672d40c8f748081567b038a3165f87994788ec77ee8daea8587f5540df3422f9e120e94339be67f186f50952504cb44f61e30a5241f1827e501b2de53c4c64473bcc79ab887dd277f282fbfe47997a930dd140ac08b03efac88d81075\",\n    \"0xa6e4ef6c1d1098f95aae119905f87eb49b909d17f9c41bcfe51127aa25fee20782ea884a7fdf7d5e9c245b5a5b32230b07e0dbf7c6743bf52ee20e2acc0b269422bd6cf3c07115df4aa85b11b2c16630a07c974492d9cdd0ec325a3fabd95044\",\n    \"0x8634aa7c3d00e7f17150009698ce440d8e1b0f13042b624a722ace68ead870c3d2212fbee549a2c190e384d7d6ac37ce14ab962c299ea1218ef1b1489c98906c91323b94c587f1d205a6edd5e9d05b42d591c26494a6f6a029a2aadb5f8b6f67\",\n    \"0x821a58092900bdb73decf48e13e7a5012a3f88b06288a97b855ef51306406e7d867d613d9ec738ebacfa6db344b677d21509d93f3b55c2ebf3a2f2a6356f875150554c6fff52e62e3e46f7859be971bf7dd9d5b3e1d799749c8a97c2e04325df\",\n    \"0x8dba356577a3a388f782e90edb1a7f3619759f4de314ad5d95c7cc6e197211446819c4955f99c5fc67f79450d2934e3c09adefc91b724887e005c5190362245eec48ce117d0a94d6fa6db12eda4ba8dde608fbbd0051f54dcf3bb057adfb2493\",\n    \"0xa32a690dc95c23ed9fb46443d9b7d4c2e27053a7fcc216d2b0020a8cf279729c46114d2cda5772fd60a97016a07d6c5a0a7eb085a18307d34194596f5b541cdf01b2ceb31d62d6b55515acfd2b9eec92b27d082fbc4dc59fc63b551eccdb8468\",\n    \"0xa040f7f4be67eaf0a1d658a3175d65df21a7dbde99bfa893469b9b43b9d150fc2e333148b1cb88cfd0447d88fa1a501d126987e9fdccb2852ecf1ba907c2ca3d6f97b055e354a9789854a64ecc8c2e928382cf09dda9abde42bbdf92280cdd96\",\n    \"0x864baff97fa60164f91f334e0c9be00a152a416556b462f96d7c43b59fe1ebaff42f0471d0bf264976f8aa6431176eb905bd875024cf4f76c13a70bede51dc3e47e10b9d5652d30d2663b3af3f08d5d11b9709a0321aba371d2ef13174dcfcaf\",\n    \"0x95a46f32c994133ecc22db49bad2c36a281d6b574c83cfee6680b8c8100466ca034b815cfaedfbf54f4e75188e661df901abd089524e1e0eb0bf48d48caa9dd97482d2e8c1253e7e8ac250a32fd066d5b5cb08a8641bdd64ecfa48289dca83a3\",\n    \"0xa2cce2be4d12144138cb91066e0cd0542c80b478bf467867ebef9ddaf3bd64e918294043500bf5a9f45ee089a8d6ace917108d9ce9e4f41e7e860cbce19ac52e791db3b6dde1c4b0367377b581f999f340e1d6814d724edc94cb07f9c4730774\",\n    \"0xb145f203eee1ac0a1a1731113ffa7a8b0b694ef2312dabc4d431660f5e0645ef5838e3e624cfe1228cfa248d48b5760501f93e6ab13d3159fc241427116c4b90359599a4cb0a86d0bb9190aa7fabff482c812db966fd2ce0a1b48cb8ac8b3bca\",\n    \"0xadabe5d215c608696e03861cbd5f7401869c756b3a5aadc55f41745ad9478145d44393fec8bb6dfc4ad9236dc62b9ada0f7ca57fe2bae1b71565dbf9536d33a68b8e2090b233422313cc96afc7f1f7e0907dc7787806671541d6de8ce47c4cd0\",\n    \"0xae7845fa6b06db53201c1080e01e629781817f421f28956589c6df3091ec33754f8a4bd4647a6bb1c141ac22731e3c1014865d13f3ed538dcb0f7b7576435133d9d03be655f8fbb4c9f7d83e06d1210aedd45128c2b0c9bab45a9ddde1c862a5\",\n    \"0x9159eaa826a24adfa7adf6e8d2832120ebb6eccbeb3d0459ffdc338548813a2d239d22b26451fda98cc0c204d8e1ac69150b5498e0be3045300e789bcb4e210d5cd431da4bdd915a21f407ea296c20c96608ded0b70d07188e96e6c1a7b9b86b\",\n    \"0xa9fc6281e2d54b46458ef564ffaed6944bff71e389d0acc11fa35d3fcd8e10c1066e0dde5b9b6516f691bb478e81c6b20865281104dcb640e29dc116daae2e884f1fe6730d639dbe0e19a532be4fb337bf52ae8408446deb393d224eee7cfa50\",\n    \"0x84291a42f991bfb36358eedead3699d9176a38f6f63757742fdbb7f631f2c70178b1aedef4912fed7b6cf27e88ddc7eb0e2a6aa4b999f3eb4b662b93f386c8d78e9ac9929e21f4c5e63b12991fcde93aa64a735b75b535e730ff8dd2abb16e04\",\n    \"0xa1b7fcacae181495d91765dfddf26581e8e39421579c9cbd0dd27a40ea4c54af3444a36bf85a11dda2114246eaddbdd619397424bb1eb41b5a15004b902a590ede5742cd850cf312555be24d2df8becf48f5afba5a8cd087cb7be0a521728386\",\n    \"0x92feaaf540dbd84719a4889a87cdd125b7e995a6782911931fef26da9afcfbe6f86aaf5328fe1f77631491ce6239c5470f44c7791506c6ef1626803a5794e76d2be0af92f7052c29ac6264b7b9b51f267ad820afc6f881460521428496c6a5f1\",\n    \"0xa525c925bfae1b89320a5054acc1fa11820f73d0cf28d273092b305467b2831fab53b6daf75fb926f332782d50e2522a19edcd85be5eb72f1497193c952d8cd0bcc5d43b39363b206eae4cb1e61668bde28a3fb2fc1e0d3d113f6dfadb799717\",\n    \"0x98752bb6f5a44213f40eda6aa4ff124057c1b13b6529ab42fe575b9afa66e59b9c0ed563fb20dff62130c436c3e905ee17dd8433ba02c445b1d67182ab6504a90bbe12c26a754bbf734665c622f76c62fe2e11dd43ce04fd2b91a8463679058b\",\n    \"0xa9aa9a84729f7c44219ff9e00e651e50ddea3735ef2a73fdf8ed8cd271961d8ed7af5cd724b713a89a097a3fe65a3c0202f69458a8b4c157c62a85668b12fc0d3957774bc9b35f86c184dd03bfefd5c325da717d74192cc9751c2073fe9d170e\",\n    \"0xb221c1fd335a4362eff504cd95145f122bf93ea02ae162a3fb39c75583fc13a932d26050e164da97cff3e91f9a7f6ff80302c19dd1916f24acf6b93b62f36e9665a8785413b0c7d930c7f1668549910f849bca319b00e59dd01e5dec8d2edacc\",\n    \"0xa71e2b1e0b16d754b848f05eda90f67bedab37709550171551050c94efba0bfc282f72aeaaa1f0330041461f5e6aa4d11537237e955e1609a469d38ed17f5c2a35a1752f546db89bfeff9eab78ec944266f1cb94c1db3334ab48df716ce408ef\",\n    \"0xb990ae72768779ba0b2e66df4dd29b3dbd00f901c23b2b4a53419226ef9232acedeb498b0d0687c463e3f1eead58b20b09efcefa566fbfdfe1c6e48d32367936142d0a734143e5e63cdf86be7457723535b787a9cfcfa32fe1d61ad5a2617220\",\n    \"0x8d27e7fbff77d5b9b9bbc864d5231fecf817238a6433db668d5a62a2c1ee1e5694fdd90c3293c06cc0cb15f7cbeab44d0d42be632cb9ff41fc3f6628b4b62897797d7b56126d65b694dcf3e298e3561ac8813fbd7296593ced33850426df42db\",\n    \"0xa92039a08b5502d5b211a7744099c9f93fa8c90cedcb1d05e92f01886219dd464eb5fb0337496ad96ed09c987da4e5f019035c5b01cc09b2a18b8a8dd419bc5895388a07e26958f6bd26751929c25f89b8eb4a299d822e2d26fec9ef350e0d3c\",\n    \"0x92dcc5a1c8c3e1b28b1524e3dd6dbecd63017c9201da9dbe077f1b82adc08c50169f56fc7b5a3b28ec6b89254de3e2fd12838a761053437883c3e01ba616670cea843754548ef84bcc397de2369adcca2ab54cd73c55dc68d87aec3fc2fe4f10\"\n  ]\n}"
  },
  {
    "path": "kurtosis/src/nodes/nodes.star",
    "content": "CONSENSUS_DEFAULT_SETTINGS = {\n    \"specs\": {\n        \"min_cpu\": 0,\n        \"max_cpu\": 2000,\n        \"min_memory\": 0,\n        \"max_memory\": 2048,\n    },\n    \"images\": {\n        \"beaconkit\": \"beacond:kurtosis-local\",\n    },\n    \"labels\": {},\n    \"node_selectors\": {},\n    \"config\": {\n        \"timeout_propose\": \"3s\",\n        \"timeout_prevote\": \"1s\",\n        \"timeout_precommit\": \"1s\",\n        \"max_num_inbound_peers\": 40,\n        \"max_num_outbound_peers\": 10,\n    },\n    \"app\": {\n        \"payload-timeout\": \"1.5s\",\n    },\n}\n\nEXECUTION_DEFAULT_SETTINGS = {\n    \"specs\": {\n        \"min_cpu\": 0,\n        \"max_cpu\": 2000,\n        \"min_memory\": 0,\n        \"max_memory\": 2048,\n    },\n    \"images\": {\n        \"reth\": \"ghcr.io/berachain/bera-reth:nightly\",\n    },\n    \"labels\": {},\n    \"node_selectors\": {},\n}\n\nCL_TYPE = \"beaconkit\"\n\ndef parse_nodes_from_dict(vals, settings):\n    node_type = vals[\"type\"]\n    node_list = []\n\n    consensus_settings = parse_consensus_settings(settings)\n    execution_settings = parse_execution_settings(settings)\n\n    count = 0\n    for val_configuration in vals[\"nodes\"]:\n        replicas = 1\n        if \"replicas\" in val_configuration:\n            replicas = val_configuration[\"replicas\"]\n        if replicas != 0:\n            for i in range(replicas):\n                val_struct = parse_node_from_dict(node_type, val_configuration, consensus_settings, execution_settings, count)\n                node_list.append(val_struct)\n                count += 1\n\n    return node_list\n\ndef parse_node_from_dict(node_type, val, consensus_settings, execution_settings, index):\n    # if kzg implementation is not provided, give default\n    kzg_impl = \"crate-crypto/go-kzg-4844\"\n    if \"kzg_impl\" in val:\n        kzg_impl = val[\"kzg_impl\"]\n\n    return struct(\n        node_type = node_type,\n        el_type = val[\"el_type\"],\n        el_image = execution_settings.images[val[\"el_type\"]],\n        cl_type = CL_TYPE,\n        cl_image = consensus_settings.images[CL_TYPE],\n        index = index,\n        cl_service_name = \"cl-{}-{}-{}\".format(node_type, CL_TYPE, index),\n        el_service_name = \"el-{}-{}-{}\".format(node_type, val[\"el_type\"], index),\n        consensus_settings = consensus_settings,\n        execution_settings = execution_settings,\n        kzg_impl = kzg_impl,\n    )\n\ndef parse_consensus_settings(settings):\n    consensus_settings = {}\n    if \"consensus_settings\" in settings:\n        consensus_settings = dict(settings[\"consensus_settings\"])\n    consensus_settings = parse_default_node_settings(consensus_settings, CONSENSUS_DEFAULT_SETTINGS)\n    consensus_settings = parse_extra_consensus_settings(consensus_settings)\n\n    return get_consensus_struct(consensus_settings)\n\ndef parse_extra_consensus_settings(settings):\n    config_settings = parse_consensus_config_settings(settings[\"config\"]) if \"config\" in settings else parse_consensus_config_settings(CONSENSUS_DEFAULT_SETTINGS[\"config\"])\n    app_settings = parse_consensus_app_settings(settings[\"app\"]) if \"app\" in settings else parse_consensus_app_settings(CONSENSUS_DEFAULT_SETTINGS[\"app\"])\n\n    consensus_settings = dict(settings)\n    consensus_settings[\"config\"] = config_settings\n    consensus_settings[\"app\"] = app_settings\n\n    return consensus_settings\n\ndef parse_consensus_config_settings(config_settings):\n    config_settings = dict(config_settings)\n\n    if \"timeout_propose\" not in config_settings:\n        config_settings[\"timeout_propose\"] = CONSENSUS_DEFAULT_SETTINGS[\"config\"][\"timeout_propose\"]\n    if \"timeout_prevote\" not in config_settings:\n        config_settings[\"timeout_prevote\"] = CONSENSUS_DEFAULT_SETTINGS[\"config\"][\"timeout_prevote\"]\n    if \"timeout_precommit\" not in config_settings:\n        config_settings[\"timeout_precommit\"] = CONSENSUS_DEFAULT_SETTINGS[\"config\"][\"timeout_precommit\"]\n    if \"max_num_inbound_peers\" not in config_settings:\n        config_settings[\"max_num_inbound_peers\"] = CONSENSUS_DEFAULT_SETTINGS[\"config\"][\"max_num_inbound_peers\"]\n    if \"max_num_outbound_peers\" not in config_settings:\n        config_settings[\"max_num_outbound_peers\"] = CONSENSUS_DEFAULT_SETTINGS[\"config\"][\"max_num_outbound_peers\"]\n\n    return struct(\n        timeout_propose = config_settings[\"timeout_propose\"],\n        timeout_prevote = config_settings[\"timeout_prevote\"],\n        timeout_precommit = config_settings[\"timeout_precommit\"],\n        max_num_inbound_peers = config_settings[\"max_num_inbound_peers\"],\n        max_num_outbound_peers = config_settings[\"max_num_outbound_peers\"],\n    )\n\ndef parse_consensus_app_settings(app_settings):\n    app_settings = dict(app_settings)\n\n    if \"payload_timeout\" not in app_settings:\n        app_settings[\"payload_timeout\"] = CONSENSUS_DEFAULT_SETTINGS[\"app\"][\"payload_timeout\"]\n\n    return struct(\n        payload_timeout = app_settings[\"payload_timeout\"],\n    )\n\ndef parse_execution_settings(settings):\n    execution_settings = {}\n    if \"execution_settings\" in settings:\n        execution_settings = dict(settings[\"execution_settings\"])\n    execution_settings = parse_default_node_settings(execution_settings, EXECUTION_DEFAULT_SETTINGS)\n    return get_execution_struct(execution_settings)\n\ndef parse_default_node_settings(settings, default_settings):\n    node_settings = dict(settings)\n    if \"specs\" not in node_settings:\n        node_settings[\"specs\"] = default_settings[\"specs\"]\n\n    node_specs = dict(node_settings[\"specs\"])\n    if \"min_cpu\" not in node_specs:\n        node_specs[\"min_cpu\"] = default_settings[\"specs\"][\"min_cpu\"]\n    if \"max_cpu\" not in node_specs:\n        node_specs[\"max_cpu\"] = default_settings[\"specs\"][\"max_cpu\"]\n    if \"min_memory\" not in node_specs:\n        node_specs[\"min_memory\"] = default_settings[\"specs\"][\"min_memory\"]\n    if \"max_memory\" not in node_specs:\n        node_specs[\"max_memory\"] = default_settings[\"specs\"][\"max_memory\"]\n    if \"images\" not in node_settings:\n        node_settings[\"images\"] = default_settings[\"images\"]\n    if \"labels\" not in node_settings:\n        node_settings[\"labels\"] = default_settings[\"labels\"]\n    if \"node_selectors\" not in node_settings:\n        node_settings[\"node_selectors\"] = default_settings[\"node_selectors\"]\n\n    node_specs = struct(\n        min_cpu = node_specs[\"min_cpu\"],\n        max_cpu = node_specs[\"max_cpu\"],\n        min_memory = node_specs[\"min_memory\"],\n        max_memory = node_specs[\"max_memory\"],\n    )\n    node_settings[\"specs\"] = node_specs\n\n    return node_settings\n\ndef get_consensus_struct(consensus_settings):\n    return struct(\n        specs = consensus_settings[\"specs\"],\n        images = consensus_settings[\"images\"],\n        labels = consensus_settings[\"labels\"],\n        node_selectors = consensus_settings[\"node_selectors\"],\n        config = consensus_settings[\"config\"],\n        app = consensus_settings[\"app\"],\n    )\n\ndef get_execution_struct(execution_settings):\n    return struct(\n        specs = execution_settings[\"specs\"],\n        images = execution_settings[\"images\"],\n        labels = execution_settings[\"labels\"],\n        node_selectors = execution_settings[\"node_selectors\"],\n    )\n\ndef int_to_hex(plan, n):\n    \"\"\"Convert integer to hex string with '0x' prefix using shell printf\"\"\"\n    result = plan.run_sh(\n        run = 'printf \"0x%x\" ' + str(n),\n        description = \"Converting {} to hex\".format(n),\n    )\n    return str(result.output.strip())\n\ndef render_genesis_template(plan, template_path, chain_id, chain_id_hex, genesis_deposits_root, genesis_deposit_count_hex):\n    \"\"\"Helper function to render a specific genesis template\"\"\"\n    genesis_template = read_file(src = template_path)\n\n    artifact = plan.render_templates(\n        config = {\n            \"genesis.json\": struct(\n                template = genesis_template,\n                data = {\n                    \"CHAIN_ID\": chain_id,\n                    \"CHAIN_ID_HEX\": chain_id_hex,\n                    \"GENESIS_DEPOSIT_COUNT_HEX\": genesis_deposit_count_hex,\n                    \"GENESIS_DEPOSITS_ROOT\": genesis_deposits_root,\n                },\n            ),\n        },\n        # As we are rendering the template twice, add GENESIS_DEPOSITS_ROOT to the name\n        name = template_path + \"_\" + genesis_deposits_root,\n        description = \"Rendering genesis.json template\",\n    )\n    return artifact\n\ndef create_genesis_files_part1(plan, chain_id):\n    \"\"\"Creates genesis files for all client types and returns them as a dict\"\"\"\n\n    # Convert chain_id to hexadecimal string\n    chain_id_hex = int_to_hex(plan, int(chain_id))\n\n    genesis_files = {}\n\n    # Render default genesis for all clients\n    default_artifact = render_genesis_template(\n        plan,\n        \"../networks/kurtosis-devnet/network-configs/genesis.json.template\",\n        chain_id,\n        chain_id_hex,\n        \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n    )\n    genesis_files[\"default\"] = default_artifact\n\n    return genesis_files\n\n# This has the deposit contract storage slots and we need to modify the eth genesis files with them.\ndef create_genesis_files_part2(plan, chain_id, genesis_deposits_root, genesis_deposit_count_hex):\n    \"\"\"Creates genesis files for all client types and returns them as a dict\"\"\"\n\n    # Convert chain_id to hexadecimal string\n    chain_id_hex = int_to_hex(plan, int(chain_id))\n\n    genesis_files = {}\n\n    # Render default genesis for all clients\n    default_artifact = render_genesis_template(\n        plan,\n        \"../networks/kurtosis-devnet/network-configs/genesis.json.template\",\n        chain_id,\n        chain_id_hex,\n        genesis_deposits_root,\n        genesis_deposit_count_hex,\n    )\n    genesis_files[\"default\"] = default_artifact\n\n    return genesis_files\n"
  },
  {
    "path": "kurtosis/src/observability/grafana/dashboard-providers.yml.tmpl",
    "content": "apiVersion: 1\n\nproviders:\n  # <string> an unique provider name. Required\n  - name: '{{ .DashboardProviderName }}'\n    # <int> Org id. Default to 1\n    orgId: 1\n    # <string> name of the dashboard folder.\n    folder: ''\n    # <string> folder UID. will be automatically generated if not specified\n    folderUid: ''\n    # <string> provider type. Default to 'file'\n    type: file\n    # <bool> disable dashboard deletion\n    disableDeletion: false\n    # <int> how often Grafana will scan for changed dashboards\n    updateIntervalSeconds: 10\n    # <bool> allow updating provisioned dashboards from the UI\n    allowUiUpdates: true\n    editable: true\n    options:\n      # <string, required> path to dashboard files on disk. Required when using the 'file' type\n      path: {{ .DashboardsDirpath }}\n      # <bool> use folder names from filesystem to create folders in Grafana\n      foldersFromFilesStructure: true"
  },
  {
    "path": "kurtosis/src/observability/grafana/datasource.yml.tmpl",
    "content": "apiVersion: 1\n\n# can add support for non prometheus datasource to this package in the future\ndatasources:\n  - name: prometheus\n    type: prometheus\n    access: proxy\n    orgId: 1\n    url: {{ .PrometheusURL }}\n    basicAuth: false\n    isDefault: true\n    editable: true"
  },
  {
    "path": "kurtosis/src/observability/grafana/grafana.star",
    "content": "CONFIG_DIR_PATH = \"/config\"\nDASHBOARDS_DIR_PATH = \"/dashboards\"\n\ndef start(plan, prometheus_url):\n    run(plan, prometheus_url, \"github.com/berachain/helm-charts/grafana-dashboards\")\n\ndef run(\n        plan,\n        prometheus_url,\n        grafana_dashboards_location,\n        name = \"grafana\",\n        grafana_dashboards_name = \"Grafana Dashboards in Kurtosis\"):\n    \"\"\"Runs provided Grafana dashboards in Kurtosis.\n\n    Args:\n        prometheus_url(string): Prometheus endpoint that will populate Grafana dashboard data.\n        grafana_dashboards_location(string): Where to find config for Grafana dashboard(s) (usually sitting somewhere repo of that's importing this package))\n        grafana_dashboards_name(string): Name of Grafana Dashboard provider.\n    \"\"\"\n\n    # create config files artifacts based on datasource and dashboard providers info\n    datasource_config_template = read_file(src = \"./datasource.yml.tmpl\")\n    dashboard_provider_config_template = read_file(src = \"./dashboard-providers.yml.tmpl\")\n    grafana_config_files_artifact = plan.render_templates(\n        config = {\n            \"datasources/datasource.yml\": struct(\n                template = datasource_config_template,\n                data = {\"PrometheusURL\": prometheus_url},\n            ),\n            \"dashboards/dashboard-providers.yml\": struct(\n                template = dashboard_provider_config_template,\n                data = {\n                    \"DashboardProviderName\": grafana_dashboards_name,\n                    \"DashboardsDirpath\": DASHBOARDS_DIR_PATH,\n                },\n            ),\n        },\n    )\n\n    # grab grafana dashboards from given location and upload them into enclave as a files artifact\n    # grafana_dashboards_files_artifact = plan.upload_files(src = grafana_dashboards_location, name = \"grafana-dashboards\")\n\n    plan.add_service(name = name, config = ServiceConfig(\n        image = \"grafana/grafana-enterprise:9.5.12\",\n        ports = {\n            \"dashboards\": PortSpec(\n                number = 3000,\n                transport_protocol = \"TCP\",\n                application_protocol = \"http\",\n            ),\n        },\n        env_vars = {\n            \"GF_PATHS_PROVISIONING\": CONFIG_DIR_PATH,\n            \"GF_AUTH_ANONYMOUS_ENABLED\": \"true\",\n            \"GF_AUTH_ANONYMOUS_ORG_ROLE\": \"Admin\",\n            \"GF_AUTH_ANONYMOUS_ORG_NAME\": \"Main Org.\",\n        },\n        files = {\n            CONFIG_DIR_PATH: grafana_config_files_artifact,\n            # DASHBOARDS_DIR_PATH: grafana_dashboards_files_artifact,\n        },\n    ))\n"
  },
  {
    "path": "kurtosis/src/observability/prometheus/prometheus.star",
    "content": "prometheus = import_module(\"github.com/kurtosis-tech/prometheus-package/main.star\")\n\n\"\"\"\nA service should follow the format of below example:\n\n{\n    ## required\n    \"name\": \"api_service\",\n    \"service\": Service(\n        ip_address=\"0.0.0.0\",\n        ports={\n            \"metrics\": PortSpec(\n                number=8080\n            )\n        }\n    ),\n    \"metrics_path\": \"/metrics\",\n\n    ## optional\n    \"labels\": {\n        \"service_type\": \"api\"\n    },\n    \"scrape_interval\": \"60s\"\n}\n\"\"\"\n\ndef start(plan, services):\n    metrics_jobs = []\n    for service in services:\n        constant_labels = {}  # use no constant labels if none provided\n        if \"labels\" in service:\n            constant_labels = service[\"labels\"]\n\n        scrape_interval = prometheus.DEFAULT_SCRAPE_INTERVAL  # use 5s as default scrape interval\n        if \"scrape_interval\" in service:\n            scrape_interval = service[\"scrape_interval\"]\n\n        metrics_job = {\n            \"Name\": \"{0}\".format(service[\"name\"]),\n            \"Endpoint\": \"{0}:{1}\".format(service[\"service\"].ip_address, service[\"service\"].ports[\"metrics\"].number),\n            \"Labels\": constant_labels,\n            \"MetricsPath\": service[\"metrics_path\"],\n            \"ScrapeInterval\": scrape_interval,\n        }\n        metrics_jobs.append(metrics_job)\n\n    prometheus_url = prometheus.run(plan, metrics_jobs)\n    plan.print(prometheus_url)\n    return prometheus_url\n"
  },
  {
    "path": "kurtosis/src/observability/pyroscope/pyroscope.star",
    "content": "\"\"\"\nA package to install pyroscope:\n\"\"\"\n\ndef run(plan, name = \"pyroscope\"):\n    plan.add_service(name = name, config = ServiceConfig(\n        image = \"grafana/pyroscope:latest\",\n        ports = {\n            \"pyroscope\": PortSpec(\n                number = 4040,\n                transport_protocol = \"TCP\",\n                application_protocol = \"http\",\n            ),\n        },\n    ))\n"
  },
  {
    "path": "kurtosis/src/services/blockscout/launcher.star",
    "content": "shared_utils = import_module(\"github.com/ethpandaops/ethereum-package/src/shared_utils/shared_utils.star\")\npostgres = import_module(\"github.com/kurtosis-tech/postgres-package/main.star\")\n\nIMAGE_NAME_BLOCKSCOUT = \"blockscout/blockscout:6.6.0\"\nIMAGE_NAME_BLOCKSCOUT_VERIF = \"ghcr.io/blockscout/smart-contract-verifier:v1.10.0\"\n\nSERVICE_NAME_BLOCKSCOUT = \"blockscout\"\n\nHTTP_PORT_ID = \"http\"\nHTTP_PORT_NUMBER = 4000\nHTTP_PORT_NUMBER_VERIF = 8050\n\nBLOCKSCOUT_MIN_CPU = 100\nBLOCKSCOUT_MAX_CPU = 1000\nBLOCKSCOUT_MIN_MEMORY = 1024\nBLOCKSCOUT_MAX_MEMORY = 2048\n\nBLOCKSCOUT_VERIF_MIN_CPU = 10\nBLOCKSCOUT_VERIF_MAX_CPU = 1000\nBLOCKSCOUT_VERIF_MIN_MEMORY = 10\nBLOCKSCOUT_VERIF_MAX_MEMORY = 1024\n\nUSED_PORTS = {\n    HTTP_PORT_ID: shared_utils.new_port_spec(\n        HTTP_PORT_NUMBER,\n        shared_utils.TCP_PROTOCOL,\n        shared_utils.HTTP_APPLICATION_PROTOCOL,\n    ),\n}\n\nVERIF_USED_PORTS = {\n    HTTP_PORT_ID: shared_utils.new_port_spec(\n        HTTP_PORT_NUMBER_VERIF,\n        shared_utils.TCP_PROTOCOL,\n        shared_utils.HTTP_APPLICATION_PROTOCOL,\n    ),\n}\n\ndef launch_blockscout(\n        plan,\n        full_node_el_clients,\n        client_from_user,\n        persistent,\n        verifier_image = None):\n    postgres_output = postgres.run(\n        plan,\n        service_name = \"{}-postgres\".format(SERVICE_NAME_BLOCKSCOUT),\n        database = \"blockscout\",\n        extra_configs = [\"max_connections=1000\"],\n        persistent = persistent,\n    )\n    el_client_info = {}\n\n    # Get the full_node_el_clients that match the client_from_user\n    for full_node_el_client_name, full_node_el_client_service in full_node_el_clients.items():\n        if full_node_el_client_name in client_from_user:\n            rpc_port = full_node_el_client_service.ports[\"eth-json-rpc\"].number\n            name = full_node_el_client_name\n            ip_address = full_node_el_client_service.ip_address\n\n            el_client_info = get_el_client_info(\n                ip_address,\n                rpc_port,\n                name,\n            )\n            break\n\n    config_verif = get_config_verif(verifier_image)\n    verif_service_name = \"{}-verif\".format(SERVICE_NAME_BLOCKSCOUT)\n    verif_service = plan.add_service(verif_service_name, config_verif)\n    verif_url = \"http://{}:{}/api\".format(\n        verif_service.hostname,\n        verif_service.ports[\"http\"].number,\n    )\n\n    config_backend = get_config_backend(\n        postgres_output,\n        el_client_info.get(\"RPC_Url\"),\n        verif_url,\n        el_client_info.get(\"Eth_Type\"),\n    )\n    blockscout_service = plan.add_service(SERVICE_NAME_BLOCKSCOUT, config_backend)\n    plan.print(blockscout_service)\n\n    blockscout_url = \"http://{}:{}\".format(\n        blockscout_service.hostname,\n        blockscout_service.ports[\"http\"].number,\n    )\n\n    return blockscout_url\n\ndef get_config_verif(verifier_image = None):\n    return ServiceConfig(\n        image = verifier_image or IMAGE_NAME_BLOCKSCOUT_VERIF,\n        ports = VERIF_USED_PORTS,\n        env_vars = {\n            \"SMART_CONTRACT_VERIFIER__SERVER__HTTP__ADDR\": \"0.0.0.0:{}\".format(\n                HTTP_PORT_NUMBER_VERIF,\n            ),\n        },\n        min_cpu = BLOCKSCOUT_VERIF_MIN_CPU,\n        max_cpu = BLOCKSCOUT_VERIF_MAX_CPU,\n        min_memory = BLOCKSCOUT_VERIF_MIN_MEMORY,\n        max_memory = BLOCKSCOUT_VERIF_MAX_MEMORY,\n    )\n\ndef get_config_backend(\n        postgres_output,\n        el_client_rpc_url,\n        verif_url,\n        el_client_name):\n    database_url = \"{protocol}://{user}:{password}@{hostname}:{port}/{database}\".format(\n        protocol = \"postgresql\",\n        user = postgres_output.user,\n        password = postgres_output.password,\n        hostname = postgres_output.service.hostname,\n        port = postgres_output.port.number,\n        database = postgres_output.database,\n    )\n\n    return ServiceConfig(\n        image = IMAGE_NAME_BLOCKSCOUT,\n        ports = USED_PORTS,\n        cmd = [\n            \"/bin/sh\",\n            \"-c\",\n            'bin/blockscout eval \"Elixir.Explorer.ReleaseTasks.create_and_migrate()\" && bin/blockscout start',\n        ],\n        env_vars = {\n            \"ETHEREUM_JSONRPC_VARIANT\": el_client_name,\n            \"ETHEREUM_JSONRPC_HTTP_URL\": el_client_rpc_url,\n            \"ETHEREUM_JSONRPC_TRACE_URL\": el_client_rpc_url,\n            \"DATABASE_URL\": database_url,\n            \"COIN\": \"ETH\",\n            \"MICROSERVICE_SC_VERIFIER_ENABLED\": \"true\",\n            \"MICROSERVICE_SC_VERIFIER_URL\": verif_url,\n            \"MICROSERVICE_SC_VERIFIER_TYPE\": \"sc_verifier\",\n            \"INDEXER_DISABLE_PENDING_TRANSACTIONS_FETCHER\": \"true\",\n            \"ECTO_USE_SSL\": \"false\",\n            \"NETWORK\": \"Kurtosis\",\n            \"SUBNETWORK\": \"Kurtosis\",\n            \"API_V2_ENABLED\": \"true\",\n            \"PORT\": \"{}\".format(HTTP_PORT_NUMBER),\n            \"SECRET_KEY_BASE\": \"56NtB48ear7+wMSf0IQuWDAAazhpb31qyc7GiyspBP2vh7t5zlCsF5QDv76chXeN\",\n        },\n        min_cpu = BLOCKSCOUT_MIN_CPU,\n        max_cpu = BLOCKSCOUT_MAX_CPU,\n        min_memory = BLOCKSCOUT_MIN_MEMORY,\n        max_memory = BLOCKSCOUT_MAX_MEMORY,\n    )\n\nBLOCKSCOUT_JSONRPC_VARIANT = {\n    \"reth\": \"geth\",\n}\n\ndef get_el_client_info(ip_addr, rpc_port_num, full_name):\n    el_client_rpc_url = \"http://{}:{}/\".format(\n        ip_addr,\n        rpc_port_num,\n    )\n    el_client_type = full_name.split(\"-\")[2]\n    return {\n        \"RPC_Url\": el_client_rpc_url,\n        \"Eth_Type\": BLOCKSCOUT_JSONRPC_VARIANT.get(el_client_type, el_client_type),\n    }\n"
  },
  {
    "path": "kurtosis/src/services/service.star",
    "content": "def parse_service_from_dict(service):\n    if \"replicas\" not in service:\n        service[\"replicas\"] = 1\n    if \"client\" not in service:\n        service[\"client\"] = None\n    if \"verifier_image\" not in service:\n        service[\"verifier_image\"] = None\n    return struct(\n        name = service[\"name\"],\n        replicas = service[\"replicas\"],\n        client = service[\"client\"],\n        verifier_image = service[\"verifier_image\"],\n    )\n"
  },
  {
    "path": "kurtosis/src/services/spamoor/launcher.star",
    "content": "SERVICE_NAME = \"spamoor\"\nIMAGE_NAME = \"ethpandaops/spamoor:latest\"\n\nENTRYPOINT_ARGS = [\"/bin/sh\", \"-c\"]\n\n# The min/max CPU/memory that spamoor can use\nMIN_CPU = 100\nMAX_CPU = 500\nMIN_MEMORY = 20\nMAX_MEMORY = 300\n\ndef launch_spamoor(plan, funding_account, rpc_endpoint):\n    config = get_config(funding_account, rpc_endpoint)\n    plan.add_service(SERVICE_NAME, config)\n    plan.print(config)\n\ndef get_config(funding_account, rpc_endpoint):\n    blob_cmd = \"./spamoor blob-combined -p {0} -b 6 -t 3 --max-pending 9 -h {1}\".format(\n        funding_account.private_key,\n        rpc_endpoint,\n    )\n\n    return ServiceConfig(\n        image = IMAGE_NAME,\n        entrypoint = ENTRYPOINT_ARGS,\n        cmd = [blob_cmd],\n        min_cpu = MIN_CPU,\n        max_cpu = MAX_CPU,\n        min_memory = MIN_MEMORY,\n        max_memory = MAX_MEMORY,\n    )\n"
  },
  {
    "path": "kurtosis/src/services/tx_fuzz/launcher.star",
    "content": "shared_utils = import_module(\"github.com/ethpandaops/ethereum-package/src/shared_utils/shared_utils.star\")\nconstants = import_module(\"../../constants.star\")\nexecution = import_module(\"../../nodes/execution/execution.star\")\nSERVICE_NAME = \"tx-fuzz\"\n\n# The min/max CPU/memory that tx-spammer can use\nMIN_CPU = 100\nMAX_CPU = 2000\nMIN_MEMORY = 128\nMAX_MEMORY = 1024\n\ndef launch_tx_fuzzes(plan, amount, next_free_prefunded_account, full_node_el_client_configs, full_node_el_clients, tx_spammer_extra_args):\n    tx_fuzz_service_configs = {}\n    for i in range(amount):\n        full_node_service_name = full_node_el_client_configs[i % len(full_node_el_client_configs)][\"name\"]\n        fuzzing_node = full_node_el_clients[full_node_service_name]\n        tx_fuzz_config = get_config(\n            constants.PRE_FUNDED_ACCOUNTS[next_free_prefunded_account].private_key,\n            \"http://{}:{}\".format(fuzzing_node.ip_address, execution.RPC_PORT_NUM),\n            tx_spammer_extra_args,\n        )\n        tx_fuzz_service_configs[SERVICE_NAME + \"-\" + str(i)] = tx_fuzz_config\n        next_free_prefunded_account += 1\n\n    plan.add_services(tx_fuzz_service_configs)\n    return next_free_prefunded_account\n\ndef launch_tx_fuzz(\n        plan,\n        id,\n        prefunded_private_key,\n        el_uri,\n        tx_spammer_extra_args):\n    config = get_config(\n        prefunded_private_key,\n        el_uri,\n        tx_spammer_extra_args,\n    )\n    plan.add_service(\n        SERVICE_NAME + \"-\" + str(id),\n        config,\n    )\n\ndef get_config(\n        prefunded_private_key,\n        el_uri,\n        tx_spammer_extra_args):\n    tx_spammer_image = \"ethpandaops/tx-fuzz:master\"\n\n    entrypoint = [\n        \"/bin/sh\",\n        \"-c\",\n    ]\n\n    # A sleep is added to ensure the full node is up in single-node deployments\n    cmd = \" \".join([\n        \"sleep\",\n        \"5\",\n        \"&&\",\n        \"/tx-fuzz.bin\",\n        \"spam\",\n        \"--rpc={}\".format(el_uri),\n        \"--sk={0}\".format(prefunded_private_key),\n        \"--accounts=100\",\n        \"--txcount=100\",\n        \"--slot-time=2\",\n    ])\n\n    if len(tx_spammer_extra_args) > 0:\n        cmd.extend([param for param in tx_spammer_extra_args])\n\n    return ServiceConfig(\n        image = tx_spammer_image,\n        cmd = [cmd],\n        entrypoint = entrypoint,\n        min_cpu = MIN_CPU,\n        max_cpu = MAX_CPU,\n        min_memory = MIN_MEMORY,\n        max_memory = MAX_MEMORY,\n    )\n"
  },
  {
    "path": "log/mod.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage log\n\n// Logger represents a basic logger that is extremely similar to the Cosmos-SDK\n// Logger interface.\ntype Logger interface {\n\t// Info takes a message and a set of key/value pairs and logs with level\n\t// INFO.\n\t// The key of the tuple must be a string.\n\tInfo(msg string, keyVals ...any)\n\t// Warn takes a message and a set of key/value pairs and logs with level\n\t// WARN.\n\t// The key of the tuple must be a string.\n\tWarn(msg string, keyVals ...any)\n\t// Error takes a message and a set of key/value pairs and logs with level\n\t// ERR.\n\t// The key of the tuple must be a string.\n\tError(msg string, keyVals ...any)\n\t// Debug takes a message and a set of key/value pairs and logs with level\n\t// DEBUG.\n\t// The key of the tuple must be a string.\n\tDebug(msg string, keyVals ...any)\n}\n\n// ConfigurableLogger extends the basic logger with the ability to configure\n// the logger with a config.\ntype ConfigurableLogger[LoggerT, ConfigT any] interface {\n\tConfigurable[LoggerT, ConfigT]\n\tLogger\n}\n\ntype Configurable[LoggerT, ConfigT any] interface {\n\tWithConfig(config ConfigT) LoggerT\n}\n\n// ColorLogger extends the basic logger with the ability to configure the\n// logger with key and key value colors.\ntype Colorable interface {\n\t// AddKeyColor sets the log color for a key.\n\tAddKeyColor(key any, color Color)\n\t// AddKeyValColor sets the log color for a key and its value.\n\tAddKeyValColor(key any, val any, color Color)\n}\n\n// AdvancedLogger extends the color logger with the ability to wrap the logger\n// with additional context and to access the underlying logger implementation.\ntype AdvancedLogger[LoggerT any] interface {\n\tLogger\n\tColorable\n\t// With returns a new wrapped logger with additional context provided by a\n\t// set.\n\tWith(keyVals ...any) LoggerT\n}\n\n// Color is a string that holds the hex color code for the color.\ntype Color string\n\n// Raw returns the raw color code.\nfunc (c Color) Raw() string {\n\treturn string(c)\n}\n\nconst (\n\t// colours.\n\tReset   Color = \"\\x1b[0m\"\n\tBlack   Color = \"\\x1b[30m\"\n\tRed     Color = \"\\x1b[31m\"\n\tGreen   Color = \"\\x1b[32m\"\n\tYellow  Color = \"\\x1b[33m\"\n\tBlue    Color = \"\\x1b[34m\"\n\tMagenta Color = \"\\x1b[35m\"\n\tCyan    Color = \"\\x1b[36m\"\n\tWhite   Color = \"\\x1b[37m\"\n\n\tGray          Color = \"\\x1b[90m\"\n\tBrightRed     Color = \"\\x1b[91m\"\n\tBrightGreen   Color = \"\\x1b[92m\"\n\tBrightYellow  Color = \"\\x1b[93m\"\n\tBrightBlue    Color = \"\\x1b[94m\"\n\tBrightMagenta Color = \"\\x1b[95m\"\n\tBrightCyan    Color = \"\\x1b[96m\"\n\tBrightWhite   Color = \"\\x1b[97m\"\n\n\tBrightBackgroundWhite Color = \"\\x1b[107m\"\n\tBrightBackgroundBlue  Color = \"\\x1b[104m\"\n)\n"
  },
  {
    "path": "log/noop/noop.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage noop\n\nimport \"github.com/berachain/beacon-kit/log\"\n\n// Logger is a logger that performs no operations. It can be used in\n// environments where logging should be disabled. It implements the Logger\n// interface with no-op methods.\ntype Logger[ImplT any] struct{}\n\n// NewLogger creates a blank no-op AdvancedLogger.\nfunc NewLogger[ImplT any]() *Logger[ImplT] {\n\treturn &Logger[ImplT]{}\n}\n\n// Info logs an informational message with associated key-value pairs. This\n// method does nothing.\nfunc (n *Logger[ImplT]) Info(string, ...any) {\n\t// No operation\n}\n\n// Warn logs a warning message with associated key-value pairs. This method does\n// nothing.\nfunc (n *Logger[ImplT]) Warn(string, ...any) {\n\t// No operation\n}\n\n// Error logs an error message with associated key-value pairs. This method does\n// nothing.\nfunc (n *Logger[ImplT]) Error(string, ...any) {\n\t// No operation\n}\n\n// Debug logs a debug message with associated key-value pairs. This method does\n// nothing.\nfunc (n *Logger[ImplT]) Debug(string, ...any) {\n\t// No operation\n}\n\n// With returns a new AdvancedLogger with the provided key-value pairs. This\n// method does nothing.\nfunc (n *Logger[ImplT]) With(...any) ImplT {\n\t//nolint:errcheck // should be safe\n\treturn any(n).(ImplT)\n}\n\nfunc (n *Logger[ImplT]) Impl() any {\n\treturn nil\n}\n\nfunc (n *Logger[ImplT]) AddKeyColor(any, log.Color) {\n\t// No operation\n}\n\nfunc (n *Logger[ImplT]) AddKeyValColor(any, any, log.Color) {\n\t// No operation\n}\n"
  },
  {
    "path": "log/noop/noop_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage noop_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/log/noop\"\n)\n\nfunc TestNewLogger(t *testing.T) {\n\tt.Parallel()\n\tlogger := noop.NewLogger[any]()\n\tif logger == nil {\n\t\tt.Error(\"Expected NewLogger to return a non-nil logger\")\n\t}\n}\n\nfunc TestLogger_Info(t *testing.T) {\n\tt.Parallel()\n\tlogger := noop.NewLogger[any]()\n\tlogger.Info(\"test message\", \"key1\", \"value1\", \"key2\", \"value2\")\n\t// Since it's a no-op logger, there's nothing to assert. This test just\n\t// ensures no panic occurs.\n}\n\nfunc TestLogger_Warn(t *testing.T) {\n\tt.Parallel()\n\tlogger := noop.NewLogger[any]()\n\tlogger.Warn(\"test warning\", \"key1\", \"value1\", \"key2\", \"value2\")\n\t// Since it's a no-op logger, there's nothing to assert. This test just\n\t// ensures no panic occurs.\n}\n\nfunc TestLogger_Error(t *testing.T) {\n\tt.Parallel()\n\tlogger := noop.NewLogger[any]()\n\tlogger.Error(\"test error\", \"key1\", \"value1\", \"key2\", \"value2\")\n\t// Since it's a no-op logger, there's nothing to assert. This test just\n\t// ensures no panic occurs.\n}\n\nfunc TestLogger_Debug(t *testing.T) {\n\tt.Parallel()\n\tlogger := noop.NewLogger[any]()\n\tlogger.Debug(\"test debug\", \"key1\", \"value1\", \"key2\", \"value2\")\n\t// Since it's a no-op logger, there's nothing to assert. This test just\n\t// ensures no panic occurs.\n}\n"
  },
  {
    "path": "log/phuslu/buffer.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage phuslu\n\nimport \"sync\"\n\n// byteBuffer is a byte buffer.\ntype byteBuffer struct {\n\tBytes []byte\n}\n\n// byteBufferPool is a pool of byte buffers.\n//\n//nolint:gochecknoglobals // buffer pool\nvar byteBufferPool = sync.Pool{\n\tNew: func() any {\n\t\treturn &byteBuffer{\n\t\t\tBytes: make([]byte, 0),\n\t\t}\n\t},\n}\n\n// Reset resets the byte buffer.\nfunc (b *byteBuffer) Reset() {\n\tb.Bytes = b.Bytes[:0]\n}\n"
  },
  {
    "path": "log/phuslu/config.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage phuslu\n\n// Config is a structure that defines the configuration for the logger.\ntype Config struct {\n\t// TimeFormat is a string that defines the format of the time in\n\t// the logger.\n\tTimeFormat string `mapstructure:\"time-format\"`\n\t// Logger will log messages with verbosity up to LogLevel.\n\tLogLevel string `mapstructure:\"log-level\"`\n\t// pretty or json.\n\tStyle string `mapstructure:\"style\"`\n}\n\n// DefaultConfig is a function that returns a new Config with default values.\nfunc DefaultConfig() Config {\n\treturn Config{\n\t\tTimeFormat: \"RFC3339\",\n\t\tLogLevel:   \"info\",\n\t\tStyle:      StylePretty,\n\t}\n}\n"
  },
  {
    "path": "log/phuslu/formatter.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIred BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage phuslu\n\nimport (\n\t\"io\"\n\n\t\"github.com/phuslu/log\"\n)\n\n// Formatter is a custom formatter for log messages.\ntype Formatter struct {\n\t// KeyColors applies specific colors to log entries based on their keys.\n\tkeyColors map[string]Color\n\t// KeyValColors applies specific colors to log entries based on their keys\n\t// and values.\n\tkeyValColors map[string]Color\n}\n\n// NewFormatter creates a new Formatter with default settings.\nfunc NewFormatter() *Formatter {\n\treturn &Formatter{\n\t\tkeyColors:    make(map[string]Color),\n\t\tkeyValColors: make(map[string]Color),\n\t}\n}\n\n// Format formats the log message.\nfunc (f *Formatter) Format(\n\tout io.Writer,\n\targs *log.FormatterArgs,\n) (int, error) {\n\tbuffer, ok := byteBufferPool.Get().(*byteBuffer)\n\tif !ok {\n\t\tpanic(\"failed to get byte buffer from pool\")\n\t}\n\n\tbuffer.Reset()\n\tdefer byteBufferPool.Put(buffer)\n\n\tvar color, label string\n\tswitch args.Level {\n\tcase \"trace\":\n\t\tcolor, label = traceColor.Raw(), traceLabel\n\tcase \"debug\":\n\t\tcolor, label = debugColor.Raw(), debugLabel\n\tcase \"info\":\n\t\tcolor, label = infoColor.Raw(), infoLabel\n\tcase \"warn\":\n\t\tcolor, label = warnColor.Raw(), warnLabel\n\tcase \"error\":\n\t\tcolor, label = errorColor.Raw(), errorLabel\n\tcase \"fatal\":\n\t\tcolor, label = fatalColor.Raw(), fatalLabel\n\tcase \"panic\":\n\t\tcolor, label = panicColor.Raw(), panicLabel\n\tdefault:\n\t\tcolor, label = defaultColor.Raw(), defaultLabel\n\t}\n\n\tf.printWithColor(args, buffer, color, label)\n\tf.ensureLineBreak(buffer)\n\n\tif args.Stack != \"\" {\n\t\tbuffer.Bytes = append(buffer.Bytes, args.Stack...)\n\t\tif args.Stack[len(args.Stack)-1] != '\\n' {\n\t\t\tbuffer.Bytes = append(buffer.Bytes, '\\n')\n\t\t}\n\t}\n\n\treturn out.Write(buffer.Bytes)\n}\n\n// AddKeyColor adds a key and color to the keyColors map.\nfunc (f *Formatter) AddKeyColor(key string, color Color) {\n\tf.keyColors[key] = color\n}\n\n// AddKeyValColor adds a key and color to the keyValColors map.\nfunc (f *Formatter) AddKeyValColor(key string, val string, color Color) {\n\tf.keyValColors[key+val] = color\n}\n\n// printWithColor prints the log message with color.\nfunc (f *Formatter) printWithColor(\n\targs *log.FormatterArgs,\n\tb *byteBuffer,\n\tcolor, label string,\n) {\n\tvar (\n\t\tok      bool\n\t\tkvColor Color\n\t\tkColor  Color\n\t)\n\tf.formatHeader(args, b, color, label)\n\n\tb.Bytes = append(b.Bytes, ' ')\n\tb.Bytes = append(b.Bytes, args.Message...)\n\tfor _, kv := range args.KeyValues {\n\t\tb.Bytes = append(b.Bytes, ' ')\n\t\t// apply the key+value color if configured, otherwise apply key color\n\t\tif kvColor, ok = f.keyValColors[kv.Key+kv.Value]; ok {\n\t\t\tb.Bytes = append(b.Bytes, kvColor.Raw()...)\n\t\t} else if kColor, ok = f.keyColors[kv.Key]; ok {\n\t\t\tb.Bytes = append(b.Bytes, kColor.Raw()...)\n\t\t}\n\t\tb.Bytes = append(b.Bytes, kv.Key...)\n\t\tb.Bytes = append(b.Bytes, '=')\n\t\tb.Bytes = append(b.Bytes, kv.Value...)\n\t\tb.Bytes = append(b.Bytes, reset...)\n\t}\n}\n\n// formatHeader formats the header of the log message.\nfunc (f *Formatter) formatHeader(\n\targs *log.FormatterArgs,\n\tb *byteBuffer,\n\tcolor, label string,\n) {\n\tb.Bytes = append(b.Bytes, gray...)\n\tb.Bytes = append(b.Bytes, args.Time...)\n\tb.Bytes = append(b.Bytes, ' ')\n\tb.Bytes = append(b.Bytes, color...)\n\tb.Bytes = append(b.Bytes, label...)\n\tif args.Caller != \"\" {\n\t\tb.Bytes = append(b.Bytes, args.Goid...)\n\t\tb.Bytes = append(b.Bytes, ' ')\n\t\tb.Bytes = append(b.Bytes, args.Caller...)\n\t\tb.Bytes = append(b.Bytes, ' ')\n\t}\n\tb.Bytes = append(b.Bytes, reset...)\n}\n\n// ensureLineBreak ensures the log message ends with a line break.\nfunc (f *Formatter) ensureLineBreak(b *byteBuffer) {\n\tif b.Bytes == nil {\n\t\tb.Bytes = make([]byte, 0)\n\t}\n\tlength := len(b.Bytes)\n\tif length == 0 || b.Bytes[length-1] != '\\n' {\n\t\tb.Bytes = append(b.Bytes, '\\n')\n\t}\n}\n"
  },
  {
    "path": "log/phuslu/logger.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage phuslu\n\nimport (\n\t\"io\"\n\n\t\"github.com/phuslu/log\"\n)\n\n// Logger is a wrapper around phuslogger.\ntype Logger struct {\n\t// logger is the underlying logger implementation.\n\tlogger *log.Logger\n\t// context is a map of key-value pairs that are added to every log entry.\n\tcontext log.Fields\n\t// out is the writer to write logs to.\n\tout io.Writer\n\t// formatter is the formatter to use for the logger.\n\tformatter *Formatter\n}\n\n// NewLogger initializes a new wrapped phuslogger with the provided config.\nfunc NewLogger(\n\tout io.Writer,\n\tcfg *Config,\n) *Logger {\n\tlogger := &Logger{\n\t\tlogger:    &log.Logger{},\n\t\tcontext:   make(log.Fields),\n\t\tout:       out,\n\t\tformatter: NewFormatter(),\n\t}\n\tlogger.WithConfig(cfg)\n\treturn logger\n}\n\n// Info logs a message at level Info.\nfunc (l *Logger) Info(msg string, keyVals ...any) {\n\tif l.logger.Level > log.InfoLevel {\n\t\treturn\n\t}\n\tl.msgWithContext(msg, l.logger.Info(), keyVals...)\n}\n\n// Warn logs a message at level Warn.\nfunc (l *Logger) Warn(msg string, keyVals ...any) {\n\tif l.logger.Level > log.WarnLevel {\n\t\treturn\n\t}\n\tl.msgWithContext(msg, l.logger.Warn(), keyVals...)\n}\n\n// Error logs a message at level Error.\nfunc (l *Logger) Error(msg string, keyVals ...any) {\n\tif l.logger.Level > log.ErrorLevel {\n\t\treturn\n\t}\n\tl.msgWithContext(msg, l.logger.Error(), keyVals...)\n}\n\n// Debug logs a message at level Debug.\nfunc (l *Logger) Debug(msg string, keyVals ...any) {\n\tif l.logger.Level > log.DebugLevel {\n\t\treturn\n\t}\n\tl.msgWithContext(msg, l.logger.Debug(), keyVals...)\n}\n\n// Impl returns the underlying logger implementation.\nfunc (l *Logger) Impl() any {\n\treturn l.logger\n}\n\n// With returns a new wrapped logger with additional context provided by a set.\nfunc (l Logger) With(keyVals ...any) *Logger {\n\tnewLogger := l\n\n\t// Perform a deep copy of the map with preallocated size.\n\tnewLogger.context = make(log.Fields, len(l.context)+len(keyVals)/2)\n\tfor k, v := range l.context {\n\t\tnewLogger.context[k] = v\n\t}\n\n\t// Add the new context to the existing context.\n\tfor i := 0; i < len(keyVals); i += 2 {\n\t\tkey, ok := keyVals[i].(string)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tnewLogger.context[key] = keyVals[i+1]\n\t}\n\n\treturn &newLogger\n}\n\n// Writer returns the io.Writer of the logger.\nfunc (l *Logger) Writer() io.Writer {\n\treturn l.out\n}\n\n// msgWithContext logs a message with keyVals and current context.\nfunc (l *Logger) msgWithContext(\n\tmsg string, e *log.Entry, keyVals ...any,\n) {\n\te.Fields(l.context).KeysAndValues(keyVals...).Msg(msg)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   config                                   */\n/* -------------------------------------------------------------------------- */\n\n// Temporary workaround to allow dynamic configuration post-logger creation.\n// This is necessary due to dependencies on runtime-populated configurations.\nfunc (l *Logger) WithConfig(cfg *Config) *Logger {\n\t// Use default config if nil.\n\tif cfg == nil {\n\t\tc := DefaultConfig()\n\t\tcfg = &c\n\t}\n\tl.withTimeFormat(cfg.TimeFormat)\n\tl.withStyle(cfg.Style)\n\tl.withLogLevel(cfg.LogLevel)\n\treturn l\n}\n\n// AddKeyColor applies a color to log entries based on their keys.\nfunc (l *Logger) AddKeyColor(key any, color Color) {\n\t//nolint:errcheck // should be safe\n\tl.formatter.AddKeyColor(key.(string), color)\n}\n\n// AddKeyValColor applies specific colors to log entries based on their keys and\n// values.\nfunc (l *Logger) AddKeyValColor(key any, val any, color Color) {\n\t//nolint:errcheck // should be safe\n\tl.formatter.AddKeyValColor(key.(string), val.(string), color)\n}\n\n// sets the style of the logger.\nfunc (l *Logger) withStyle(style string) {\n\tif style == StylePretty {\n\t\tl.useConsoleWriter()\n\t} else if style == StyleJSON {\n\t\tl.useJSONWriter()\n\t}\n}\n\n// SetLevel sets the log level of the logger.\nfunc (l *Logger) withLogLevel(level string) {\n\tl.logger.Level = log.ParseLevel(level)\n}\n\n// useConsoleWriter sets the logger to use a console writer.\nfunc (l *Logger) useConsoleWriter() {\n\tl.setWriter(&log.ConsoleWriter{\n\t\tWriter:    l.out,\n\t\tFormatter: l.formatter.Format,\n\t})\n}\n\n// useJSONWriter sets the logger to use a IOWriter wrapper.\nfunc (l *Logger) useJSONWriter() {\n\tl.setWriter(log.IOWriter{Writer: l.out})\n}\n\n// setWriter sets the writer of the logger.\nfunc (l *Logger) setWriter(writer log.Writer) {\n\tl.logger.Writer = writer\n}\n"
  },
  {
    "path": "log/phuslu/style.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage phuslu\n\nimport \"github.com/berachain/beacon-kit/log\"\n\ntype Color = log.Color\n\nconst (\n\treset                 = log.Reset\n\tblack                 = log.Black\n\tred                   = log.Red\n\tgreen                 = log.Green\n\tyellow                = log.Yellow\n\tblue                  = log.Blue\n\tmagenta               = log.Magenta\n\tcyan                  = log.Cyan\n\twhite                 = log.White\n\tgray                  = log.Gray\n\tlightWhite            = log.BrightWhite\n\tbrightBackgroundWhite = log.BrightBackgroundWhite\n\n\t// log levels.\n\ttraceColor   = magenta\n\tdebugColor   = yellow\n\tinfoColor    = green\n\twarnColor    = yellow\n\terrorColor   = red\n\tfatalColor   = red\n\tpanicColor   = red\n\tdefaultColor = gray\n\tapiColor     = blue\n\ttraceLabel   = \"TRCE\"\n\tdebugLabel   = \"DBUG\"\n\tinfoLabel    = \"INFO\"\n\twarnLabel    = \"WARN\"\n\terrorLabel   = \"ERRR\"\n\tfatalLabel   = \"FATAL\"\n\tpanicLabel   = \"PANIC\"\n\tdefaultLabel = \"???\"\n\tapiLabel     = \"API\"\n\n\t// output styles flags.\n\tStylePretty = \"pretty\"\n\tStyleJSON   = \"json\"\n)\n"
  },
  {
    "path": "log/phuslu/time.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage phuslu\n\nimport (\n\t\"time\"\n)\n\nconst (\n\t// time formats.\n\trfc3339     = \"RFC3339\"\n\trfc3339Nano = \"RFC3339Nano\"\n\trfc1123     = \"RFC1123\"\n\trfc1123Z    = \"RFC1123Z\"\n\tkitchen     = \"Kitchen\"\n\tlayout      = \"Layout\"\n\tansic       = \"ANSIC\"\n\tunixDate    = \"UnixDate\"\n\trubyDate    = \"RubyDate\"\n\ttimeOnly    = \"TimeOnly\"\n\tdateOnly    = \"DateOnly\"\n)\n\n// withTimeFormat sets the time format for the logger.\nfunc (l *Logger) withTimeFormat(formatStr string) {\n\tl.logger.TimeFormat = parseFormat(formatStr)\n}\n\n// parseFormat parses the time format string.\nfunc parseFormat(formatStr string) string {\n\tswitch formatStr {\n\tcase rfc3339:\n\t\treturn time.RFC3339\n\tcase rfc3339Nano:\n\t\treturn time.RFC3339Nano\n\tcase rfc1123:\n\t\treturn time.RFC1123\n\tcase rfc1123Z:\n\t\treturn time.RFC1123Z\n\tcase kitchen:\n\t\treturn time.Kitchen\n\tcase layout:\n\t\treturn time.Layout\n\tcase ansic:\n\t\treturn time.ANSIC\n\tcase unixDate:\n\t\treturn time.UnixDate\n\tcase rubyDate:\n\t\treturn time.RubyDate\n\tcase timeOnly:\n\t\treturn time.TimeOnly\n\tcase dateOnly:\n\t\treturn time.DateOnly\n\tdefault:\n\t\treturn time.RFC3339\n\t}\n}\n"
  },
  {
    "path": "node-api/backend/backend.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage backend\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n\n\tcorestore \"cosmossdk.io/core/store\"\n\t\"cosmossdk.io/log\"\n\t\"cosmossdk.io/store\"\n\tsdkmetrics \"cosmossdk.io/store/metrics\"\n\tstoretypes \"cosmossdk.io/store/types\"\n\t\"github.com/berachain/beacon-kit/chain\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tcometbft \"github.com/berachain/beacon-kit/consensus/cometbft/service\"\n\t\"github.com/berachain/beacon-kit/node-core/components/metrics\"\n\t\"github.com/berachain/beacon-kit/node-core/components/storage\"\n\t\"github.com/berachain/beacon-kit/node-core/types\"\n\t\"github.com/berachain/beacon-kit/state-transition/core/state\"\n\tkvstorage \"github.com/berachain/beacon-kit/storage\"\n\t\"github.com/berachain/beacon-kit/storage/beacondb\"\n\t\"github.com/berachain/beacon-kit/storage/db\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\tdbm \"github.com/cosmos/cosmos-db\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n\tgenutiltypes \"github.com/cosmos/cosmos-sdk/x/genutil/types\"\n)\n\n// Backend is the db access layer for the beacon node-api.\n// It serves as a wrapper around the storage backend and provides an abstraction\n// over building the query context for a given state.\ntype Backend struct {\n\tsb     *storage.Backend\n\tcs     chain.Spec\n\tcmtCfg *cmtcfg.Config // used to fetch genesis data upon LoadData\n\tnode   types.ConsensusService\n\n\t// Genesis related data\n\tsp           GenesisStateProcessor // only needed to recreate genesis state upon API loading\n\tdb           dbm.DB                // in-memory DB to store genesis state\n\tmuSt         sync.RWMutex          // mutex to allow initializing and copying genesisState in a safe way\n\tcms          storetypes.CommitMultiStore\n\tgenesisState *state.StateDB // caches genesis data to serve API requests\n}\n\n// New creates and returns a new Backend instance.\nfunc New(\n\tstorageBackend *storage.Backend,\n\tsp GenesisStateProcessor,\n\tcs chain.Spec,\n\tcmtCfg *cmtcfg.Config,\n\tconsensusService types.ConsensusService,\n) *Backend {\n\tb := &Backend{\n\t\tsb:     storageBackend,\n\t\tsp:     sp,\n\t\tcs:     cs,\n\t\tcmtCfg: cmtCfg,\n\t\tnode:   consensusService,\n\t}\n\n\t// genesis data will be cached in LoadData\n\treturn b\n}\n\nfunc (b *Backend) LoadData(_ context.Context) error {\n\tswitch err := b.node.IsAppReady(); {\n\tcase err == nil:\n\t\t// chain finally ready, time to loading genesis\n\t\t//nolint:contextcheck // loadGenesisState creates its own context for in-memory store\n\t\treturn b.loadGenesisState()\n\tcase errors.Is(err, cometbft.ErrAppNotReady):\n\t\t// start anyhow, we'll init genesis state later on\n\t\treturn nil\n\tdefault:\n\t\treturn fmt.Errorf(\"unable to check whether app is ready: %w\", err)\n\t}\n}\n\nfunc (b *Backend) Close() error {\n\tif b.db == nil {\n\t\treturn nil\n\t}\n\treturn b.db.Close()\n}\n\ntype backendKVStoreService struct {\n\tctx sdk.Context\n}\n\nfunc (kvs *backendKVStoreService) OpenKVStore(context.Context) corestore.KVStore {\n\t//nolint:contextcheck // fine with this node-api backend\n\tstore := sdk.UnwrapSDKContext(kvs.ctx).KVStore(backendStoreKey)\n\treturn kvstorage.NewKVStore(store)\n}\n\n//nolint:gochecknoglobals // fine with this node-api backend\nvar backendStoreKey = storetypes.NewKVStoreKey(\"backend-genesis\")\n\nfunc (b *Backend) loadGenesisState() error {\n\tb.muSt.Lock()\n\tdefer b.muSt.Unlock()\n\n\tif b.genesisState != nil {\n\t\t// genesis state already initialized, we're fine\n\t\treturn nil\n\t}\n\n\t// 1- Load Genesis bytes\n\tgenesisData, err := b.parseGenesisBytes()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// 2- Create Genesis Store\n\tif err = b.initGenesisState(); err != nil {\n\t\treturn fmt.Errorf(\"backend data loading:%w\", err)\n\t}\n\n\t// 3- Reprocess Genesis via state Processor. This is safe\n\t// since it's done on its own state AND state processor does not\n\t// make any call to the EVM during genesis processing.\n\t// Note: we process genesis here as soon as node start, but\n\t// chain would wait for genesisTime to come if genesisTime\n\t// is set in the future. We replicate this behaviour with checkChainIsReady.\n\tif _, err = b.sp.InitializeBeaconStateFromEth1(\n\t\tb.genesisState,\n\t\tgenesisData.GetDeposits(),\n\t\tgenesisData.GetExecutionPayloadHeader(),\n\t\tgenesisData.GetForkVersion(),\n\t); err != nil {\n\t\treturn fmt.Errorf(\"failed processing genesis: %w\", err)\n\t}\n\n\t_ = b.cms.Commit() // not really necessary for in-memoryDB. Still.\n\treturn nil\n}\n\nfunc (b *Backend) parseGenesisBytes() (ctypes.Genesis, error) {\n\tappGenesis, err := genutiltypes.AppGenesisFromFile(b.cmtCfg.GenesisFile())\n\tif err != nil {\n\t\treturn ctypes.Genesis{}, fmt.Errorf(\"failed loading app genesis from file: %w\", err)\n\t}\n\tgen, err := appGenesis.ToGenesisDoc()\n\tif err != nil {\n\t\treturn ctypes.Genesis{}, fmt.Errorf(\"failed parsing app genesis: %w\", err)\n\t}\n\tvar genesisState map[string]json.RawMessage\n\tif err = json.Unmarshal(gen.AppState, &genesisState); err != nil {\n\t\treturn ctypes.Genesis{}, fmt.Errorf(\"failed to unmarshal genesis state: %w\", err)\n\t}\n\tdata := []byte(genesisState[\"beacon\"])\n\n\tgenesisData := ctypes.Genesis{}\n\tif err = json.Unmarshal(data, &genesisData); err != nil {\n\t\treturn ctypes.Genesis{}, fmt.Errorf(\"failed to unmarshal genesis data: %w\", err)\n\t}\n\treturn genesisData, nil\n}\n\nfunc (b *Backend) initGenesisState() error {\n\tvar err error\n\tb.db, err = db.OpenDB(\"\", dbm.MemDBBackend)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed opening mem db: %w\", err)\n\t}\n\tvar (\n\t\tnopLog     = log.NewNopLogger()\n\t\tnopMetrics = sdkmetrics.NewNoOpMetrics()\n\t)\n\n\tb.cms = store.NewCommitMultiStore(b.db, nopLog, nopMetrics)\n\n\tb.cms.MountStoreWithDB(backendStoreKey, storetypes.StoreTypeIAVL, nil)\n\tif err = b.cms.LoadLatestVersion(); err != nil {\n\t\treturn fmt.Errorf(\"backend data loading: failed to load latest version: %w\", err)\n\t}\n\n\tctx := sdk.NewContext(b.cms, true, nopLog)\n\tbackendStoreService := &backendKVStoreService{\n\t\tctx: ctx,\n\t}\n\tkvStore := beacondb.New(backendStoreService)\n\n\tsdkCtx := sdk.NewContext(b.cms.CacheMultiStore(), true, log.NewNopLogger())\n\tb.genesisState = state.NewBeaconStateFromDB(\n\t\tkvStore.WithContext(sdkCtx),\n\t\tb.cs,\n\t\tsdkCtx.Logger(),\n\t\tmetrics.NewNoOpTelemetrySink(),\n\t)\n\treturn nil\n}\n"
  },
  {
    "path": "node-api/backend/backend_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage backend_test\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"cosmossdk.io/log\"\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\tcometbft \"github.com/berachain/beacon-kit/consensus/cometbft/service\"\n\t\"github.com/berachain/beacon-kit/node-api/backend\"\n\t\"github.com/berachain/beacon-kit/node-api/backend/mocks\"\n\t\"github.com/berachain/beacon-kit/node-core/components/metrics\"\n\t\"github.com/berachain/beacon-kit/node-core/components/storage\"\n\tcoremocks \"github.com/berachain/beacon-kit/node-core/types/mocks\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/state-transition/core/state\"\n\tstatetransition \"github.com/berachain/beacon-kit/testing/state-transition\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\tgenutiltypes \"github.com/cosmos/cosmos-sdk/x/genutil/types\"\n\t\"github.com/stretchr/testify/mock\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestBackendLoadData(t *testing.T) {\n\tt.Parallel()\n\n\t// some genesis data, to check they match with what it's in the state that backend returns\n\tvar (\n\t\texpectedGenesisPayload *types.ExecutionPayloadHeader\n\t\texpectedGenesisFork    *types.Fork\n\t)\n\n\ttestCases := []struct {\n\t\tname                string\n\t\tsetMockExpectations func(\n\t\t\t*coremocks.ConsensusService,\n\t\t\t*mocks.GenesisStateProcessor,\n\t\t)\n\t\tcheck func(t *testing.T, b *backend.Backend, errLoad error)\n\t}{\n\t\t{\n\t\t\tname: \"success\",\n\t\t\tsetMockExpectations: func(\n\t\t\t\tcs *coremocks.ConsensusService,\n\t\t\t\tsp *mocks.GenesisStateProcessor,\n\t\t\t) {\n\t\t\t\tt.Helper()\n\n\t\t\t\tcs.EXPECT().IsAppReady().Return(nil) // mark the app as ready\n\t\t\t\tsp.EXPECT().InitializeBeaconStateFromEth1(\n\t\t\t\t\tmock.Anything,\n\t\t\t\t\tmock.Anything,\n\t\t\t\t\tmock.Anything,\n\t\t\t\t\tmock.Anything,\n\t\t\t\t).Run(func(\n\t\t\t\t\tst *state.StateDB,\n\t\t\t\t\t_ types.Deposits,\n\t\t\t\t\texecPayloadHeader *types.ExecutionPayloadHeader,\n\t\t\t\t\tgenesisVersion common.Version,\n\t\t\t\t) {\n\t\t\t\t\texpectedGenesisPayload = execPayloadHeader\n\t\t\t\t\texpectedGenesisFork = &types.Fork{\n\t\t\t\t\t\tPreviousVersion: genesisVersion,\n\t\t\t\t\t\tCurrentVersion:  genesisVersion,\n\t\t\t\t\t}\n\t\t\t\t\trequire.NoError(t, st.SetLatestExecutionPayloadHeader(execPayloadHeader))\n\t\t\t\t\trequire.NoError(t, st.SetFork(expectedGenesisFork))\n\t\t\t\t}).Return(nil, nil) // duly process genesis once parsed\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, b *backend.Backend, errLoad error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, errLoad)\n\n\t\t\t\t// Load genesis state and show (at least some) data matches\n\t\t\t\tgenState, genSlot, err := b.StateAndSlotFromHeight(0) // check genesis state is provided\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, math.Slot(0), genSlot)\n\n\t\t\t\tgotGenesisPayload, err := genState.GetLatestExecutionPayloadHeader()\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, expectedGenesisPayload, gotGenesisPayload)\n\n\t\t\t\tgotGenesisFork, err := genState.GetFork()\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, expectedGenesisFork, gotGenesisFork)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"app not ready\",\n\t\t\tsetMockExpectations: func(\n\t\t\t\tcs *coremocks.ConsensusService,\n\t\t\t\t_ *mocks.GenesisStateProcessor,\n\t\t\t) {\n\t\t\t\tt.Helper()\n\n\t\t\t\tcs.EXPECT().IsAppReady().Return(cometbft.ErrAppNotReady) // mark the app as not ready\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, b *backend.Backend, errLoad error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\t// just keep going, it will load later on, as soon as possible\n\t\t\t\trequire.NoError(t, errLoad)\n\n\t\t\t\t_, _, err := b.StateAndSlotFromHeight(0) // check genesis state is provided\n\t\t\t\trequire.ErrorIs(t, err, cometbft.ErrAppNotReady)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"could not check app is ready\",\n\t\t\tsetMockExpectations: func(\n\t\t\t\tcs *coremocks.ConsensusService,\n\t\t\t\t_ *mocks.GenesisStateProcessor,\n\t\t\t) {\n\t\t\t\tt.Helper()\n\n\t\t\t\tcs.EXPECT().IsAppReady().Return(errors.New(\"unknown error\"))\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, _ *backend.Backend, errLoad error) {\n\t\t\t\tt.Helper()\n\t\t\t\trequire.Error(t, errLoad)\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\t// 1 - Build backend\n\t\t\tcs, err := spec.MainnetChainSpec()\n\t\t\trequire.NoError(t, err)\n\n\t\t\tcmtCfg := buildTestCometConfig(t)\n\n\t\t\t_, kvStore, depositStore, err := statetransition.BuildTestStores()\n\t\t\trequire.NoError(t, err)\n\t\t\tsb := storage.NewBackend(\n\t\t\t\tcs, nil, kvStore, depositStore, nil, log.NewNopLogger(), metrics.NewNoOpTelemetrySink(),\n\t\t\t)\n\n\t\t\ttcs := coremocks.NewConsensusService(t)\n\t\t\tsp := mocks.NewGenesisStateProcessor(t)\n\n\t\t\tb := backend.New(sb, sp, cs, cmtCfg, tcs)\n\t\t\tdefer func() {\n\t\t\t\trequire.NoError(t, b.Close())\n\t\t\t}()\n\n\t\t\t// 2- Setup expectations\n\t\t\ttc.setMockExpectations(tcs, sp)\n\n\t\t\t// 3 - Test\n\t\t\terrLoad := b.LoadData(t.Context())\n\n\t\t\t// 4- Checks\n\t\t\ttc.check(t, b, errLoad)\n\t\t})\n\t}\n}\n\n//nolint:lll // adapted genesis from mainnet\nfunc buildTestCometConfig(t *testing.T) *cmtcfg.Config {\n\tt.Helper()\n\n\t// Create a temporary directory for CometBFT config\n\ttmpDir := t.TempDir()\n\tcmtCfg := cmtcfg.DefaultConfig()\n\tcmtCfg.SetRoot(tmpDir)\n\n\t// Create config directory\n\tconfigDir := filepath.Join(tmpDir, \"config\")\n\terr := os.MkdirAll(configDir, 0o755)\n\trequire.NoError(t, err)\n\n\t// Create app genesis with version of Deneb 0x04000000.\n\tappGenesis := genutiltypes.NewAppGenesisWithVersion(\"test-chain\", []byte(`\n\t{\n    \"beacon\": {\n      \"fork_version\": \"0x04000000\",\n      \"deposits\": [],\n      \"execution_payload_header\": {\n        \"parentHash\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        \"feeRecipient\": \"0x0000000000000000000000000000000000000000\",\n        \"stateRoot\": \"0x2aace2f233f1ef6ca13e5fd8feae4cb1b0b580fa56c8ee081ab89d861eaf1515\",\n        \"receiptsRoot\": \"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\n        \"logsBloom\": \"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n        \"prevRandao\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        \"blockNumber\": \"0x0\",\n        \"gasLimit\": \"0x1c9c380\",\n        \"gasUsed\": \"0x0\",\n        \"timestamp\": \"0x678e56e0\",\n        \"extraData\": \"0x\",\n        \"baseFeePerGas\": \"1000000000\",\n        \"blockHash\": \"0xd57819422128da1c44339fc7956662378c17e2213e669b427ac91cd11dfcfb38\",\n        \"transactionsRoot\": \"0x7ffe241ea60187fdb0187bfa22de35d1f9bed7ab061d9401fd47e34a54fbede1\",\n        \"withdrawalsRoot\": \"0x792930bbd5baac43bcc798ee49aa8185ef76bb3b44ba62b91d86ae569e4bb535\",\n        \"blobGasUsed\": \"0x0\",\n        \"excessBlobGas\": \"0x0\"\n      }\n    }\n\t}\n\t`))\n\n\t// Save genesis file to the config directory\n\tgenesisFile := filepath.Join(configDir, \"genesis.json\")\n\terr = appGenesis.SaveAs(genesisFile)\n\trequire.NoError(t, err)\n\n\treturn cmtCfg\n}\n"
  },
  {
    "path": "node-api/backend/getters.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage backend\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"runtime\"\n\n\t\"cosmossdk.io/log\"\n\tcometbft \"github.com/berachain/beacon-kit/consensus/cometbft/service\"\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/encoding\"\n\tdatypes \"github.com/berachain/beacon-kit/da/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tcmttypes \"github.com/cometbft/cometbft/types\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n\t\"github.com/cosmos/cosmos-sdk/version\"\n)\n\n// StateAndSlotFromHeight returns the beacon state at a particular slot using query context,\n// resolving an input height of -1 to the latest slot.\n//\n// This returns the beacon state of the version that was committed to disk at the requested slot,\n// which has the empty state root in the latest block header. Hence, the most recent state and\n// block roots are not updated.\nfunc (b *Backend) StateAndSlotFromHeight(height int64) (ReadOnlyBeaconState, math.Slot, error) {\n\tif height < -1 {\n\t\treturn nil, 0, fmt.Errorf(\"expected height, must be non-negative or -1 to request tip, got %d\", height)\n\t}\n\tif height == 0 {\n\t\tswitch err := b.node.IsAppReady(); {\n\t\tcase err == nil:\n\t\t\t// chain finally ready, time to loading genesis\n\t\t\tif err = b.loadGenesisState(); err != nil {\n\t\t\t\treturn nil, 0, fmt.Errorf(\"failed loading genesis state: %w\", err)\n\t\t\t}\n\t\tcase errors.Is(err, cometbft.ErrAppNotReady):\n\t\t\treturn nil, 0, cometbft.ErrAppNotReady\n\t\tdefault:\n\t\t\treturn nil, 0, fmt.Errorf(\"unable to check whether app is ready: %w\", err)\n\t\t}\n\n\t\tb.muSt.Lock()\n\t\tdefer b.muSt.Unlock()\n\n\t\t// Copy the state to ensure clients potential changes won't pollute the state\n\t\t// Also we make sure to create the copy in a thread-safe way via the muCms mutex.\n\t\tms := b.cms.CacheMultiStore()\n\t\tctx := sdk.NewContext(ms, true, log.NewNopLogger())\n\t\tephemeralGenesisState := b.genesisState.Protect(ctx)\n\t\treturn ephemeralGenesisState, 0, nil\n\t}\n\n\theight = max(0, height) // CreateQueryContext uses 0 to pick latest height.\n\tqueryCtx, err := b.node.CreateQueryContext(height, false)\n\tif err != nil {\n\t\treturn nil, 0, fmt.Errorf(\"CreateQueryContext failed: %w\", err)\n\t}\n\tst := b.sb.StateFromContext(queryCtx)\n\n\tvar slot math.Slot\n\tif height > 0 {\n\t\tslot = math.Slot(height)\n\t} else {\n\t\t// height must be -1, so pick state slot\n\t\tslot, err = st.GetSlot()\n\t\tif err != nil {\n\t\t\treturn st, slot, fmt.Errorf(\"GetSlot failed: %w\", err)\n\t\t}\n\t}\n\treturn st, slot, nil\n}\n\n// GetSlotByBlockRoot retrieves the slot by a block root from the block store.\nfunc (b *Backend) GetSlotByBlockRoot(root common.Root) (math.Slot, error) {\n\treturn b.sb.BlockStore().GetSlotByBlockRoot(root)\n}\n\n// GetSlotByStateRoot retrieves the slot by a state root from the block store.\nfunc (b *Backend) GetSlotByStateRoot(root common.Root) (math.Slot, error) {\n\treturn b.sb.BlockStore().GetSlotByStateRoot(root)\n}\n\n// GetParentSlotByTimestamp retrieves the parent slot by a given timestamp from\n// the block store.\nfunc (b *Backend) GetParentSlotByTimestamp(timestamp math.U64) (math.Slot, error) {\n\treturn b.sb.BlockStore().GetParentSlotByTimestamp(timestamp)\n}\n\n// GetSignatureBySlot retrieves the block signature for a given slot by decoding\n// the SignedBeaconBlock from CometBFT's blockstore.\nfunc (b *Backend) GetSignatureBySlot(slot math.Slot) (crypto.BLSSignature, error) {\n\tblock := b.node.GetBlock(int64(slot.Unwrap())) //#nosec:G115\n\tif block == nil {\n\t\treturn crypto.BLSSignature{}, fmt.Errorf(\"block not found at slot %d\", slot)\n\t}\n\n\t// Extract transactions from CometBFT block\n\ttxs := make([][]byte, len(block.Data.Txs))\n\tfor i, tx := range block.Data.Txs {\n\t\ttxs[i] = tx\n\t}\n\n\tforkVersion := b.cs.ActiveForkVersionForTimestamp(math.U64(block.Header.Time.Unix())) //#nosec:G115\n\tsignedBlock, err := encoding.UnmarshalBeaconBlockFromABCIRequest(txs, 0, forkVersion)\n\tif err != nil {\n\t\treturn crypto.BLSSignature{}, fmt.Errorf(\"failed to unmarshal block at slot %d: %w\", slot, err)\n\t}\n\n\treturn signedBlock.Signature, nil\n}\n\nfunc (b *Backend) GetBlobSidecarsAtSlot(slot math.Slot) (datypes.BlobSidecars, error) {\n\treturn b.sb.AvailabilityStore().GetBlobSidecars(slot)\n}\n\nfunc (b *Backend) GetSyncData() (int64 /*latestHeight*/, int64 /*syncToHeight*/) {\n\treturn b.node.GetSyncData()\n}\n\nfunc (b *Backend) GetVersionData() (\n\tstring, // appName\n\tstring, // cometVersion\n\tstring, // os\n\tstring, // arch\n) {\n\tcometVersionInfo := version.NewInfo() // same used in beacond version command\n\n\tvar (\n\t\tappName      = cometVersionInfo.AppName\n\t\tcometVersion = cometVersionInfo.Version\n\t\tos           = runtime.GOOS\n\t\tarch         = runtime.GOARCH\n\t)\n\n\treturn appName,\n\t\tcometVersion,\n\t\tos,\n\t\tarch\n}\n\n// GetCometBFTBlock returns the CometBFT block at the given height.\nfunc (b *Backend) GetCometBFTBlock(height int64) *cmttypes.Block {\n\treturn b.node.GetBlock(height)\n}\n\n// GetCometBFTSignedHeader returns the CometBFT signed header (header + commit) at the given height.\nfunc (b *Backend) GetCometBFTSignedHeader(height int64) *cmttypes.SignedHeader {\n\treturn b.node.GetSignedHeader(height)\n}\n"
  },
  {
    "path": "node-api/backend/interface.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage backend\n\nimport (\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n)\n\ntype GenesisStateProcessor interface {\n\tInitializeBeaconStateFromEth1(\n\t\tst *statedb.StateDB,\n\t\tdeposits ctypes.Deposits,\n\t\texecPayloadHeader *ctypes.ExecutionPayloadHeader,\n\t\tgenesisVersion common.Version,\n\t) (transition.ValidatorUpdates, error)\n}\n\n// Keep just getters currently used. To be expanded as we increase API endpoints available\ntype ReadOnlyBeaconState interface {\n\tGetGenesisValidatorsRoot() (common.Root, error)\n\tGetFork() (*ctypes.Fork, error)\n\tGetLatestExecutionPayloadHeader() (*ctypes.ExecutionPayloadHeader, error)\n\n\tGetLatestBlockHeader() (*ctypes.BeaconBlockHeader, error)\n\tHashTreeRoot() common.Root\n\n\tGetRandaoMixAtIndex(uint64) (common.Bytes32, error)\n\n\tGetBalances() ([]uint64, error)\n\tGetBalance(math.ValidatorIndex) (math.Gwei, error)\n\tValidatorIndexByPubkey(crypto.BLSPubkey) (math.ValidatorIndex, error)\n\n\tGetValidators() (ctypes.Validators, error)\n\tValidatorByIndex(math.ValidatorIndex) (*ctypes.Validator, error)\n\n\tGetPendingPartialWithdrawals() ([]*ctypes.PendingPartialWithdrawal, error)\n\n\tGetMarshallable() (*ctypes.BeaconState, error)\n}\n"
  },
  {
    "path": "node-api/backend/mocks/genesis_state_processor.mock.go",
    "content": "// Code generated by mockery v2.53.5. DO NOT EDIT.\n\npackage mocks\n\nimport (\n\ttypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tcommon \"github.com/berachain/beacon-kit/primitives/common\"\n\ttransition \"github.com/berachain/beacon-kit/primitives/transition\"\n\tstate \"github.com/berachain/beacon-kit/state-transition/core/state\"\n\tmock \"github.com/stretchr/testify/mock\"\n)\n\n// GenesisStateProcessor is an autogenerated mock type for the GenesisStateProcessor type\ntype GenesisStateProcessor struct {\n\tmock.Mock\n}\n\ntype GenesisStateProcessor_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *GenesisStateProcessor) EXPECT() *GenesisStateProcessor_Expecter {\n\treturn &GenesisStateProcessor_Expecter{mock: &_m.Mock}\n}\n\n// InitializeBeaconStateFromEth1 provides a mock function with given fields: st, deposits, execPayloadHeader, genesisVersion\nfunc (_m *GenesisStateProcessor) InitializeBeaconStateFromEth1(st *state.StateDB, deposits types.Deposits, execPayloadHeader *types.ExecutionPayloadHeader, genesisVersion common.Version) (transition.ValidatorUpdates, error) {\n\tret := _m.Called(st, deposits, execPayloadHeader, genesisVersion)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for InitializeBeaconStateFromEth1\")\n\t}\n\n\tvar r0 transition.ValidatorUpdates\n\tvar r1 error\n\tif rf, ok := ret.Get(0).(func(*state.StateDB, types.Deposits, *types.ExecutionPayloadHeader, common.Version) (transition.ValidatorUpdates, error)); ok {\n\t\treturn rf(st, deposits, execPayloadHeader, genesisVersion)\n\t}\n\tif rf, ok := ret.Get(0).(func(*state.StateDB, types.Deposits, *types.ExecutionPayloadHeader, common.Version) transition.ValidatorUpdates); ok {\n\t\tr0 = rf(st, deposits, execPayloadHeader, genesisVersion)\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(transition.ValidatorUpdates)\n\t\t}\n\t}\n\n\tif rf, ok := ret.Get(1).(func(*state.StateDB, types.Deposits, *types.ExecutionPayloadHeader, common.Version) error); ok {\n\t\tr1 = rf(st, deposits, execPayloadHeader, genesisVersion)\n\t} else {\n\t\tr1 = ret.Error(1)\n\t}\n\n\treturn r0, r1\n}\n\n// GenesisStateProcessor_InitializeBeaconStateFromEth1_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'InitializeBeaconStateFromEth1'\ntype GenesisStateProcessor_InitializeBeaconStateFromEth1_Call struct {\n\t*mock.Call\n}\n\n// InitializeBeaconStateFromEth1 is a helper method to define mock.On call\n//   - st *state.StateDB\n//   - deposits types.Deposits\n//   - execPayloadHeader *types.ExecutionPayloadHeader\n//   - genesisVersion common.Version\nfunc (_e *GenesisStateProcessor_Expecter) InitializeBeaconStateFromEth1(st interface{}, deposits interface{}, execPayloadHeader interface{}, genesisVersion interface{}) *GenesisStateProcessor_InitializeBeaconStateFromEth1_Call {\n\treturn &GenesisStateProcessor_InitializeBeaconStateFromEth1_Call{Call: _e.mock.On(\"InitializeBeaconStateFromEth1\", st, deposits, execPayloadHeader, genesisVersion)}\n}\n\nfunc (_c *GenesisStateProcessor_InitializeBeaconStateFromEth1_Call) Run(run func(st *state.StateDB, deposits types.Deposits, execPayloadHeader *types.ExecutionPayloadHeader, genesisVersion common.Version)) *GenesisStateProcessor_InitializeBeaconStateFromEth1_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(*state.StateDB), args[1].(types.Deposits), args[2].(*types.ExecutionPayloadHeader), args[3].(common.Version))\n\t})\n\treturn _c\n}\n\nfunc (_c *GenesisStateProcessor_InitializeBeaconStateFromEth1_Call) Return(_a0 transition.ValidatorUpdates, _a1 error) *GenesisStateProcessor_InitializeBeaconStateFromEth1_Call {\n\t_c.Call.Return(_a0, _a1)\n\treturn _c\n}\n\nfunc (_c *GenesisStateProcessor_InitializeBeaconStateFromEth1_Call) RunAndReturn(run func(*state.StateDB, types.Deposits, *types.ExecutionPayloadHeader, common.Version) (transition.ValidatorUpdates, error)) *GenesisStateProcessor_InitializeBeaconStateFromEth1_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewGenesisStateProcessor creates a new instance of GenesisStateProcessor. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewGenesisStateProcessor(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *GenesisStateProcessor {\n\tmock := &GenesisStateProcessor{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/backend.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacon\n\nimport (\n\tdatypes \"github.com/berachain/beacon-kit/da/types\"\n\t\"github.com/berachain/beacon-kit/node-api/backend\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// Backend is the interface for backend of the beacon API.\ntype Backend interface {\n\t// Blob related methods\n\tGetSyncData() (int64 /*latestHeight*/, int64 /*syncToHeight*/)\n\tGetBlobSidecarsAtSlot(slot math.Slot) (datypes.BlobSidecars, error)\n\n\t// State loading method, used by most of the handlers\n\t// Height == -1 must be used to require tip state.\n\t// Height == 0 must be used to require Genesis state\n\t// Height > 0 must be used to require state at slot <Height>\n\tStateAndSlotFromHeight(height int64) (backend.ReadOnlyBeaconState, math.Slot, error)\n\n\t// Methods helping mapping block/state/... IDs in requests to heights\n\tGetSlotByBlockRoot(root common.Root) (math.Slot, error)\n\tGetSlotByStateRoot(root common.Root) (math.Slot, error)\n\n\t// GetSignatureBySlot retrieves the block signature for a given slot.\n\tGetSignatureBySlot(slot math.Slot) (crypto.BLSSignature, error)\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/blob_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacon_test\n\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tdatypes \"github.com/berachain/beacon-kit/da/types\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/log/noop\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/beacon\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/beacon/mocks\"\n\tbeacontypes \"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\thandlertypes \"github.com/berachain/beacon-kit/node-api/handlers/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n\t\"github.com/berachain/beacon-kit/node-api/middleware\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/labstack/echo/v4\"\n\t\"github.com/stretchr/testify/mock\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestGetBlobSidecars(t *testing.T) {\n\tt.Parallel()\n\n\tcs, errSpec := spec.MainnetChainSpec()\n\trequire.NoError(t, errSpec)\n\n\ttestSidecars := datypes.BlobSidecars{\n\t\t{\n\t\t\tIndex: 25,\n\t\t\tSignedBeaconBlockHeader: &ctypes.SignedBeaconBlockHeader{\n\t\t\t\tHeader: &ctypes.BeaconBlockHeader{\n\t\t\t\t\tSlot:            math.Slot(987),\n\t\t\t\t\tProposerIndex:   math.ValidatorIndex(2),\n\t\t\t\t\tParentBlockRoot: common.Root{0x1, 0x2},\n\t\t\t\t\tStateRoot:       common.Root{0x3, 0x4},\n\t\t\t\t\tBodyRoot:        common.Root{0x5, 0x6},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\ttestCases := []struct {\n\t\tname                string\n\t\tinputs              func() beacontypes.GetBlobSidecarsRequest\n\t\tsetMockExpectations func(*testing.T, *mocks.Backend)\n\t\tcheck               func(t *testing.T, res any, err error)\n\t}{\n\t\t{\n\t\t\tname: \"success\",\n\t\t\tinputs: func() beacontypes.GetBlobSidecarsRequest {\n\t\t\t\treturn beacontypes.GetBlobSidecarsRequest{\n\t\t\t\t\tBlockIDRequest: handlertypes.BlockIDRequest{\n\t\t\t\t\t\tBlockID: utils.StateIDHead,\n\t\t\t\t\t},\n\t\t\t\t\tIndices: nil,\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(t *testing.T, b *mocks.Backend) {\n\t\t\t\tt.Helper()\n\n\t\t\t\tb.EXPECT().GetSyncData().Return(int64(1234), int64(1234))\n\t\t\t\tb.EXPECT().GetBlobSidecarsAtSlot(mock.Anything).Return(testSidecars, nil)\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, beacontypes.SidecarsResponse{}, res)\n\t\t\t\tsr, _ := res.(beacontypes.SidecarsResponse)\n\n\t\t\t\trequire.Len(t, sr.Data, 1)\n\t\t\t\trequire.Equal(t, beacontypes.SidecarFromConsensus(testSidecars[0]), sr.Data[0])\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\t// setup test\n\t\t\tbackend := mocks.NewBackend(t)\n\t\t\th := beacon.NewHandler(backend, cs, noop.NewLogger[log.Logger]())\n\t\t\te := echo.New()\n\t\t\te.Validator = &middleware.CustomValidator{\n\t\t\t\tValidator: middleware.ConstructValidator(),\n\t\t\t}\n\n\t\t\t// create API inputs\n\t\t\tinput := tc.inputs()\n\t\t\tinputBytes, err := json.Marshal(input) //nolint:musttag //  TODO:fix\n\t\t\trequire.NoError(t, err)\n\t\t\tbody := strings.NewReader(string(inputBytes))\n\t\t\treq := httptest.NewRequest(http.MethodGet, \"/\", body)\n\t\t\treq.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) // otherwise code=415, message=Unsupported Media Type\n\t\t\tc := e.NewContext(req, httptest.NewRecorder())\n\n\t\t\t// set expectations\n\t\t\ttc.setMockExpectations(t, backend)\n\n\t\t\t// test\n\t\t\tres, err := h.GetBlobSidecars(c)\n\n\t\t\t// finally do checks\n\t\t\ttc.check(t, res, err)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/blobs.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacon\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// GetBlobSidecars provides an implementation for the\n// \"/eth/v1/beacon/blob_sidecars/:block_id\" API endpoint.\n//\n//nolint:gocognit // TODO: fix\nfunc (h *Handler) GetBlobSidecars(c handlers.Context) (any, error) {\n\treq, err := utils.BindAndValidate[types.GetBlobSidecarsRequest](\n\t\tc, h.Logger(),\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Map requested blockID to slot\n\tslotID, err := utils.BlockIDToHeight(req.BlockID, h.backend)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar slot math.Slot\n\tif slotID == utils.Head {\n\t\tlatestHeight, _ := h.backend.GetSyncData()\n\t\tif latestHeight < 0 {\n\t\t\treturn nil, errors.New(\"invalid negative block height\")\n\t\t}\n\t\tslot = math.Slot(latestHeight)\n\t} else {\n\t\tslot = math.Slot(slotID) //#nosec: G115 // practically safe\n\t}\n\n\t// Convert indices to uint64.\n\tindices := make([]uint64, len(req.Indices))\n\tfor i, idxS := range req.Indices {\n\t\tvar idx math.U64\n\t\tidx, err = math.U64FromString(idxS)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tindices[i] = idx.Unwrap()\n\t}\n\n\t// Validate the requested slot is within the Data Availability Period.\n\tif !h.cs.WithinDAPeriod(slot, slot) {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"requested slot (%d) is not within Data Availability Period (previous %d epochs)\",\n\t\t\tslotID, h.cs.MinEpochsForBlobsSidecarsRequest(),\n\t\t)\n\t}\n\n\t// Validate request indices.\n\tif uint64(len(indices)) >= h.cs.MaxBlobsPerBlock() {\n\t\treturn nil, errors.New(\"too many indices requested\")\n\t}\n\tfor _, index := range indices {\n\t\tif index >= h.cs.MaxBlobsPerBlock() {\n\t\t\treturn nil, errors.New(\"blob index out of range\")\n\t\t}\n\t}\n\n\tblobSidecars, err := h.backend.GetBlobSidecarsAtSlot(slot)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Create a map of requested indices for O(1) index lookups.\n\tisRequestIndex := make(map[uint64]bool)\n\tfor _, idx := range indices {\n\t\tisRequestIndex[idx] = true\n\t}\n\n\t// Preallocate response slice - if indices specified, size will be len(indices),\n\t// otherwise size will be all sidecars.\n\tresponseCap := len(blobSidecars)\n\tif len(indices) > 0 {\n\t\tresponseCap = len(indices)\n\t}\n\tblobSidecarsResponse := make([]*types.Sidecar, 0, responseCap)\n\n\tfor _, blobSidecar := range blobSidecars {\n\t\t// Skip if indices specified and this index not requested.\n\t\tif len(indices) > 0 && !isRequestIndex[blobSidecar.GetIndex()] {\n\t\t\tcontinue\n\t\t}\n\t\t// Craft and append the blob sidecar serialized data to the response.\n\t\tblobSidecarsResponse = append(blobSidecarsResponse,\n\t\t\ttypes.SidecarFromConsensus(blobSidecar),\n\t\t)\n\t}\n\n\treturn types.SidecarsResponse{\n\t\tData: blobSidecarsResponse,\n\t}, nil\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/block.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacon\n\nimport (\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\tbeacontypes \"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n)\n\nfunc (h *Handler) GetBlockRewards(c handlers.Context) (any, error) {\n\t_, err := utils.BindAndValidate[beacontypes.GetBlockRewardsRequest](\n\t\tc, h.Logger(),\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// TODO: Implement this.\n\trewards := &beacontypes.BlockRewardsData{\n\t\tProposerIndex:     1,\n\t\tTotal:             1,\n\t\tAttestations:      1,\n\t\tSyncAggregate:     1,\n\t\tProposerSlashings: 1,\n\t\tAttesterSlashings: 1,\n\t}\n\treturn beacontypes.NewResponse(rewards), nil\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/genesis.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacon\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\tcometbft \"github.com/berachain/beacon-kit/consensus/cometbft/service\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\tbeacontypes \"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\thandlertypes \"github.com/berachain/beacon-kit/node-api/handlers/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n)\n\nfunc (h *Handler) GetGenesis(handlers.Context) (any, error) {\n\tst, _, err := h.backend.StateAndSlotFromHeight(utils.Genesis)\n\tif err != nil {\n\t\tif errors.Is(err, cometbft.ErrAppNotReady) {\n\t\t\t// chain not ready, like when genesis time is set in the future\n\t\t\treturn nil, handlertypes.ErrNotFound\n\t\t}\n\t\treturn nil, fmt.Errorf(\"failed to get state from genesis: %w\", err)\n\t}\n\n\tgenesisRoot, err := st.GetGenesisValidatorsRoot()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tgenesisFork, err := st.GetFork()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tpayload, err := st.GetLatestExecutionPayloadHeader()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn beacontypes.GenesisResponse{\n\t\tData: beacontypes.GenesisData{\n\t\t\tGenesisTime:           payload.GetTimestamp().Base10(),\n\t\t\tGenesisValidatorsRoot: genesisRoot,\n\t\t\tGenesisForkVersion:    genesisFork.CurrentVersion.String(),\n\t\t},\n\t}, nil\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/genesis_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacon_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\tcorestore \"cosmossdk.io/core/store\"\n\t\"cosmossdk.io/log\"\n\t\"cosmossdk.io/store\"\n\tsdkmetrics \"cosmossdk.io/store/metrics\"\n\tstoretypes \"cosmossdk.io/store/types\"\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tcometbft \"github.com/berachain/beacon-kit/consensus/cometbft/service\"\n\tbeaconlog \"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/log/noop\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/beacon\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/beacon/mocks\"\n\tbeacontypes \"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/types\"\n\t\"github.com/berachain/beacon-kit/node-api/middleware\"\n\t\"github.com/berachain/beacon-kit/node-core/components/metrics\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/state-transition/core/state\"\n\tkvstorage \"github.com/berachain/beacon-kit/storage\"\n\t\"github.com/berachain/beacon-kit/storage/beacondb\"\n\t\"github.com/berachain/beacon-kit/storage/db\"\n\tdbm \"github.com/cosmos/cosmos-db\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n\t\"github.com/labstack/echo/v4\"\n\t\"github.com/stretchr/testify/mock\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestGetGenesis(t *testing.T) {\n\tt.Parallel()\n\n\tcs, errSpec := spec.MainnetChainSpec()\n\trequire.NoError(t, errSpec)\n\n\tvar (\n\t\ttestGenesisRoot        = common.Root{0x10, 0x20, 0x30}\n\t\ttestGenesisForkVersion = common.Version{0xff, 0x11, 0x22, 0x33}\n\t\ttestGenesisTime        = math.U64(123456789)\n\t)\n\n\ttestCases := []struct {\n\t\tname                string\n\t\tsetMockExpectations func(*mocks.Backend)\n\t\tcheck               func(t *testing.T, res any, err error)\n\t}{\n\t\t{\n\t\t\tname: \"success\",\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tst := initTestGenesisState(t, cs)\n\n\t\t\t\trequire.NoError(t, st.SetGenesisValidatorsRoot(testGenesisRoot))\n\t\t\t\trequire.NoError(t, st.SetFork(&ctypes.Fork{\n\t\t\t\t\tPreviousVersion: testGenesisForkVersion,\n\t\t\t\t\tCurrentVersion:  testGenesisForkVersion,\n\t\t\t\t}))\n\t\t\t\trequire.NoError(t, st.SetLatestExecutionPayloadHeader(&ctypes.ExecutionPayloadHeader{\n\t\t\t\t\tVersionable: ctypes.NewVersionable(testGenesisForkVersion),\n\t\t\t\t\tTimestamp:   testGenesisTime,\n\t\t\t\t}))\n\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, 0, nil)\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, beacontypes.GenesisResponse{}, res)\n\t\t\t\tgr, _ := res.(beacontypes.GenesisResponse)\n\n\t\t\t\trequire.Equal(t, testGenesisRoot, gr.Data.GenesisValidatorsRoot)\n\t\t\t\trequire.Equal(t, testGenesisForkVersion.String(), gr.Data.GenesisForkVersion)\n\t\t\t\trequire.Equal(t, testGenesisTime.Base10(), gr.Data.GenesisTime)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"genesis not ready\",\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(nil, 0, cometbft.ErrAppNotReady)\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.ErrorIs(t, err, types.ErrNotFound)\n\t\t\t\trequire.Nil(t, res)\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\t// setup test\n\t\t\tbackend := mocks.NewBackend(t)\n\t\t\th := beacon.NewHandler(backend, cs, noop.NewLogger[beaconlog.Logger]())\n\t\t\te := echo.New()\n\t\t\te.Validator = &middleware.CustomValidator{\n\t\t\t\tValidator: middleware.ConstructValidator(),\n\t\t\t}\n\n\t\t\t// set expectations\n\t\t\ttc.setMockExpectations(backend)\n\n\t\t\t// test\n\t\t\tres, err := h.GetGenesis(nil) // input not relevant for this API\n\n\t\t\t// finally do checks\n\t\t\ttc.check(t, res, err)\n\t\t})\n\t}\n}\n\ntype backendKVStoreService struct {\n\tctx sdk.Context\n}\n\nfunc (kvs *backendKVStoreService) OpenKVStore(context.Context) corestore.KVStore {\n\t//nolint:contextcheck // fine with tests\n\tstore := sdk.UnwrapSDKContext(kvs.ctx).KVStore(testStoreKey)\n\treturn kvstorage.NewKVStore(store)\n}\n\nvar testStoreKey = storetypes.NewKVStoreKey(\"test-genesis\")\n\nfunc initTestGenesisState(t *testing.T, cs chain.Spec) *state.StateDB {\n\tt.Helper()\n\n\tdb, err := db.OpenDB(\"\", dbm.MemDBBackend)\n\trequire.NoError(t, err)\n\n\tvar (\n\t\tnopLog     = log.NewNopLogger()\n\t\tnopMetrics = sdkmetrics.NewNoOpMetrics()\n\t)\n\n\tcms := store.NewCommitMultiStore(db, nopLog, nopMetrics)\n\tcms.MountStoreWithDB(testStoreKey, storetypes.StoreTypeIAVL, nil)\n\trequire.NoError(t, cms.LoadLatestVersion())\n\n\tctx := sdk.NewContext(cms, true, nopLog)\n\tbackendStoreService := &backendKVStoreService{\n\t\tctx: ctx,\n\t}\n\tkvStore := beacondb.New(backendStoreService)\n\n\tsdkCtx := sdk.NewContext(cms.CacheMultiStore(), true, nopLog)\n\treturn state.NewBeaconStateFromDB(\n\t\tkvStore.WithContext(sdkCtx),\n\t\tcs,\n\t\tsdkCtx.Logger(),\n\t\tmetrics.NewNoOpTelemetrySink(),\n\t)\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/handler.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacon\n\nimport (\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n)\n\n// Handler is the handler for the beacon API.\ntype Handler struct {\n\t*handlers.BaseHandler\n\n\tcs      chain.Spec\n\tbackend Backend\n}\n\n// NewHandler creates a new handler for the beacon API.\nfunc NewHandler(backend Backend, cs chain.Spec, logger log.Logger) *Handler {\n\th := &Handler{\n\t\tBaseHandler: handlers.NewBaseHandler(logger),\n\t\tcs:          cs,\n\t\tbackend:     backend,\n\t}\n\tregisterRoutes(h)\n\treturn h\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/header.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacon\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\tstdmath \"math\"\n\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\tbeacontypes \"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\thandlertypes \"github.com/berachain/beacon-kit/node-api/handlers/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\nvar ErrMismatchedSlotAndParentBlock = errors.New(\"slot does not match with parent block\")\n\nfunc (h *Handler) GetBlockHeaders(c handlers.Context) (any, error) {\n\treq, errReq := utils.BindAndValidate[beacontypes.GetBlockHeadersRequest](c, h.Logger())\n\tif errReq != nil {\n\t\treturn nil, errReq\n\t}\n\n\tswitch {\n\tcase len(req.Slot) == 0 && len(req.ParentRoot) == 0:\n\t\t// no parameter specified, pick chain HEAD\n\t\t// by requesting special height -1.\n\t\theight := utils.Head\n\t\treturn h.makeBlockHeaderResponse(height, true /*resultsInList*/)\n\n\tcase len(req.Slot) != 0 && len(req.ParentRoot) == 0:\n\t\tslot, errSlot := math.U64FromString(req.Slot)\n\t\t// errSlot should always be nil since we validated slots in BindAndValidate.\n\t\tif errSlot != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed retrieving slot from input parameters: %w\", errSlot)\n\t\t}\n\t\tif slot > stdmath.MaxInt64 { // appease linters\n\t\t\treturn 0, fmt.Errorf(\"%w: slot %d\", utils.ErrFailedMappingHeightTooHigh, slot)\n\t\t}\n\t\treturn h.makeBlockHeaderResponse(int64(slot), true /*resultsInList*/) //#nosec: G115 // safe\n\n\tcase len(req.Slot) == 0 && len(req.ParentRoot) != 0:\n\t\tparentHeight, errParent := utils.BlockIDToHeight(req.ParentRoot, h.backend)\n\t\tif errParent != nil {\n\t\t\treturn nil, fmt.Errorf(\"%w, failed retrieving parent root with error: %w\", handlertypes.ErrNotFound, errParent)\n\t\t}\n\t\tif parentHeight == utils.Head {\n\t\t\treturn nil, fmt.Errorf(\"%w, requested header of tip's child\", handlertypes.ErrNotFound)\n\t\t}\n\t\theight := parentHeight + 1\n\t\treturn h.makeBlockHeaderResponse(height, true /*resultsInList*/)\n\n\tdefault:\n\t\tvar (\n\t\t\tslot, errSlot         = math.U64FromString(req.Slot)\n\t\t\tparentSlot, errParent = utils.BlockIDToHeight(req.ParentRoot, h.backend)\n\t\t)\n\t\tif err := errors.Join(errSlot, errParent); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif slot > stdmath.MaxInt64 { // appease linters\n\t\t\treturn 0, fmt.Errorf(\"%w: slot %d\", utils.ErrFailedMappingHeightTooHigh, slot)\n\t\t}\n\t\theight := int64(slot) //#nosec: G115 // safe\n\t\tif height != parentSlot+1 {\n\t\t\treturn nil, fmt.Errorf(\"%w: request slot %d, parent block slot %d\", ErrMismatchedSlotAndParentBlock, slot, parentSlot)\n\t\t}\n\t\treturn h.makeBlockHeaderResponse(height, true /*resultsInList*/)\n\t}\n}\n\nfunc (h *Handler) GetBlockHeaderByID(c handlers.Context) (any, error) {\n\treq, err := utils.BindAndValidate[beacontypes.GetBlockHeaderRequest](c, h.Logger())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tslot, err := utils.BlockIDToHeight(req.BlockID, h.backend)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed retrieving slot from block ID %s: %w\", req.BlockID, err)\n\t}\n\treturn h.makeBlockHeaderResponse(slot, false /*resultsInList*/)\n}\n\nfunc (h *Handler) makeBlockHeaderResponse(height int64, resultsInList bool) (any, error) {\n\tst, slot, err := h.backend.StateAndSlotFromHeight(height)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%w: failed to get state from height %d, %s\", handlertypes.ErrNotFound, height, err.Error())\n\t}\n\t// Return after updating the state root in the block header.\n\theader, err := st.GetLatestBlockHeader()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get latest block header: %w\", err)\n\t}\n\theader.SetStateRoot(st.HashTreeRoot())\n\n\t// Retrieve the block signature from the block store. The signature may not be available\n\t// if the block is outside the availability window or if querying genesis.\n\tvar signatureStr string\n\tif slot > 0 {\n\t\tsignature, sigErr := h.backend.GetSignatureBySlot(slot)\n\t\tif sigErr == nil {\n\t\t\tsignatureStr = signature.String()\n\t\t}\n\t}\n\n\t// While an Ethereum node may have multiple blocks per slot, BeaconKit\n\t// will access only one, given single slot finality and the fact that we only\n\t// access finalized blocks in this APIs. Still we may return a list of responses\n\t// to be compliant with API specs https://ethereum.github.io/beacon-APIs/?urls.primaryName=v3.1.0#/Beacon/getBlockHeader\n\theaderResp := beacontypes.BlockHeaderResponse{\n\t\tRoot:      header.GetBodyRoot(),\n\t\tCanonical: true,\n\t\tHeader: &beacontypes.SignedBeaconBlockHeader{\n\t\t\tMessage:   beacontypes.BeaconBlockHeaderFromConsensus(header),\n\t\t\tSignature: signatureStr,\n\t\t},\n\t}\n\n\tif !resultsInList {\n\t\treturn beacontypes.NewResponse(&headerResp), nil\n\t}\n\n\tres := []beacontypes.BlockHeaderResponse{\n\t\theaderResp,\n\t}\n\treturn beacontypes.NewResponse(res), nil\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/header_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacon_test\n\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/log/noop\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/beacon\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/beacon/mocks\"\n\tbeacontypes \"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\thandlertypes \"github.com/berachain/beacon-kit/node-api/handlers/types\"\n\t\"github.com/berachain/beacon-kit/node-api/middleware\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n\t\"github.com/labstack/echo/v4\"\n\t\"github.com/stretchr/testify/mock\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n//nolint:maintidx // multiple test cases\nfunc TestGetBlockHeaders(t *testing.T) {\n\tt.Parallel()\n\n\tcs, errSpec := spec.MainnetChainSpec()\n\trequire.NoError(t, errSpec)\n\n\t// testHeaders to build test cases on top of\n\ttestParentHeader := &ctypes.BeaconBlockHeader{\n\t\tSlot:            math.Slot(10),\n\t\tProposerIndex:   math.ValidatorIndex(1234),\n\t\tParentBlockRoot: common.Root{'p', 'a', 'r', 'e', 'n', 't', 'b', 'l', 'o', 'c', 'k', 'r', 'o', 'o', 't'},\n\t\tStateRoot:       common.Root{'p', 'a', 'r', 'e', 'n', 't', 's', 't', 'a', 't', 'e', 'r', 'o', 'o', 't'},\n\t\tBodyRoot:        common.Root{'p', 'a', 'r', 'e', 'n', 't', 'r', 'o', 'o', 't'},\n\t}\n\ttestHeader := &ctypes.BeaconBlockHeader{\n\t\tSlot:            testParentHeader.Slot + 1,\n\t\tProposerIndex:   math.ValidatorIndex(5678),\n\t\tParentBlockRoot: testParentHeader.BodyRoot,\n\t\tStateRoot:       common.Root{}, // set in test cases\n\t\tBodyRoot:        common.Root{'d', 'u', 'm', 'm', 'y', 'r', 'o', 'o', 't'},\n\t}\n\twrongSlot := testHeader.Slot + 1234\n\terrTestHeaderNotFound := errors.New(\"test header not found error\")\n\n\ttestCases := []struct {\n\t\tname                string\n\t\tinputs              func() beacontypes.GetBlockHeadersRequest\n\t\tsetMockExpectations func(*testing.T, *mocks.Backend) common.Root\n\t\tcheck               func(t *testing.T, expectedStateRoot common.Root, res any, err error)\n\t}{\n\t\t{\n\t\t\tname: \"GetBlockHeaders - success - no query params\",\n\t\t\tinputs: func() beacontypes.GetBlockHeadersRequest {\n\t\t\t\treturn beacontypes.GetBlockHeadersRequest{\n\t\t\t\t\tSlotRequest: beacontypes.SlotRequest{},\n\t\t\t\t\tParentRoot:  \"\",\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(t *testing.T, b *mocks.Backend) common.Root {\n\t\t\t\tt.Helper()\n\n\t\t\t\tst := makeTestState(t, cs)\n\t\t\t\tstateRoot := testDummyState(t, cs, st, testHeader)\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, math.Slot(0), nil)\n\t\t\t\treturn stateRoot\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, expectedStateRoot common.Root, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, beacontypes.GenericResponse{}, res)\n\t\t\t\tgr, _ := res.(beacontypes.GenericResponse)\n\t\t\t\trequire.IsType(t, []beacontypes.BlockHeaderResponse{}, gr.Data)\n\t\t\t\tdata, _ := gr.Data.([]beacontypes.BlockHeaderResponse)\n\t\t\t\trequire.Len(t, data, 1)\n\n\t\t\t\trequire.Equal(t, testHeader.BodyRoot, data[0].Root)\n\t\t\t\texpectedHeader := &beacontypes.BeaconBlockHeader{\n\t\t\t\t\tSlot:          testHeader.Slot.Base10(),\n\t\t\t\t\tProposerIndex: testHeader.ProposerIndex.Base10(),\n\t\t\t\t\tParentRoot:    testHeader.ParentBlockRoot.Hex(),\n\t\t\t\t\tStateRoot:     expectedStateRoot.Hex(),\n\t\t\t\t\tBodyRoot:      testHeader.BodyRoot.Hex(),\n\t\t\t\t}\n\t\t\t\trequire.Equal(t, expectedHeader, data[0].Header.Message)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"GetBlockHeaders - success - slot only\",\n\t\t\tinputs: func() beacontypes.GetBlockHeadersRequest {\n\t\t\t\treturn beacontypes.GetBlockHeadersRequest{\n\t\t\t\t\tSlotRequest: beacontypes.SlotRequest{\n\t\t\t\t\t\tSlot: testHeader.Slot.Base10(),\n\t\t\t\t\t},\n\t\t\t\t\tParentRoot: \"\",\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(t *testing.T, b *mocks.Backend) common.Root {\n\t\t\t\tt.Helper()\n\n\t\t\t\tst := makeTestState(t, cs)\n\t\t\t\tstateRoot := testDummyState(t, cs, st, testHeader)\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, math.Slot(0), nil)\n\t\t\t\treturn stateRoot\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, expectedStateRoot common.Root, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, beacontypes.GenericResponse{}, res)\n\t\t\t\tgr, _ := res.(beacontypes.GenericResponse)\n\t\t\t\trequire.IsType(t, []beacontypes.BlockHeaderResponse{}, gr.Data)\n\t\t\t\tdata, _ := gr.Data.([]beacontypes.BlockHeaderResponse)\n\t\t\t\trequire.Len(t, data, 1)\n\n\t\t\t\trequire.Equal(t, testHeader.BodyRoot, data[0].Root)\n\t\t\t\texpectedHeader := &beacontypes.BeaconBlockHeader{\n\t\t\t\t\tSlot:          testHeader.Slot.Base10(),\n\t\t\t\t\tProposerIndex: testHeader.ProposerIndex.Base10(),\n\t\t\t\t\tParentRoot:    testHeader.ParentBlockRoot.Hex(),\n\t\t\t\t\tStateRoot:     expectedStateRoot.Hex(),\n\t\t\t\t\tBodyRoot:      testHeader.BodyRoot.Hex(),\n\t\t\t\t}\n\t\t\t\trequire.Equal(t, expectedHeader, data[0].Header.Message)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"GetBlockHeaders - failure - invalid slot\",\n\t\t\tinputs: func() beacontypes.GetBlockHeadersRequest {\n\t\t\t\treturn beacontypes.GetBlockHeadersRequest{\n\t\t\t\t\tSlotRequest: beacontypes.SlotRequest{\n\t\t\t\t\t\tSlot: \"AAAA\",\n\t\t\t\t\t},\n\t\t\t\t\tParentRoot: \"\",\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(*testing.T, *mocks.Backend) common.Root {\n\t\t\t\t// nothing to set here, slot is invalid\n\t\t\t\treturn common.Root{}\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, _ common.Root, _ any, err error) {\n\t\t\t\tt.Helper()\n\t\t\t\trequire.ErrorIs(t, err, handlertypes.ErrInvalidRequest)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"GetBlockHeaders - failure - unindexed slot\",\n\t\t\tinputs: func() beacontypes.GetBlockHeadersRequest {\n\t\t\t\treturn beacontypes.GetBlockHeadersRequest{\n\t\t\t\t\tSlotRequest: beacontypes.SlotRequest{\n\t\t\t\t\t\tSlot: testHeader.Slot.Base10(),\n\t\t\t\t\t},\n\t\t\t\t\tParentRoot: \"\",\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(t *testing.T, b *mocks.Backend) common.Root {\n\t\t\t\tt.Helper()\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(nil, math.Slot(0), errTestHeaderNotFound)\n\t\t\t\treturn common.Root{}\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, _ common.Root, _ any, err error) {\n\t\t\t\tt.Helper()\n\t\t\t\t// Implicitly ensuring that 404 error code is returned\n\t\t\t\t// (see responseFromError implementation)\n\t\t\t\trequire.ErrorIs(t, err, handlertypes.ErrNotFound)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"GetBlockHeaders - success - parent root only\",\n\t\t\tinputs: func() beacontypes.GetBlockHeadersRequest {\n\t\t\t\treturn beacontypes.GetBlockHeadersRequest{\n\t\t\t\t\tSlotRequest: beacontypes.SlotRequest{},\n\t\t\t\t\tParentRoot:  testHeader.ParentBlockRoot.Hex(),\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(t *testing.T, b *mocks.Backend) common.Root {\n\t\t\t\tt.Helper()\n\n\t\t\t\tst := makeTestState(t, cs)\n\t\t\t\tstateRoot := testDummyState(t, cs, st, testHeader)\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, math.Slot(0), nil)\n\t\t\t\tb.EXPECT().GetSlotByBlockRoot(testParentHeader.BodyRoot).Return(testParentHeader.Slot, nil)\n\t\t\t\treturn stateRoot\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, expectedStateRoot common.Root, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, beacontypes.GenericResponse{}, res)\n\t\t\t\tgr, _ := res.(beacontypes.GenericResponse)\n\t\t\t\trequire.IsType(t, []beacontypes.BlockHeaderResponse{}, gr.Data)\n\t\t\t\tdata, _ := gr.Data.([]beacontypes.BlockHeaderResponse)\n\t\t\t\trequire.Len(t, data, 1)\n\n\t\t\t\trequire.Equal(t, testHeader.BodyRoot, data[0].Root)\n\t\t\t\texpectedHeader := &beacontypes.BeaconBlockHeader{\n\t\t\t\t\tSlot:          testHeader.Slot.Base10(),\n\t\t\t\t\tProposerIndex: testHeader.ProposerIndex.Base10(),\n\t\t\t\t\tParentRoot:    testHeader.ParentBlockRoot.Hex(),\n\t\t\t\t\tStateRoot:     expectedStateRoot.Hex(),\n\t\t\t\t\tBodyRoot:      testHeader.BodyRoot.Hex(),\n\t\t\t\t}\n\t\t\t\trequire.Equal(t, expectedHeader, data[0].Header.Message)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"GetBlockHeaders - failure - invalid parent root\",\n\t\t\tinputs: func() beacontypes.GetBlockHeadersRequest {\n\t\t\t\treturn beacontypes.GetBlockHeadersRequest{\n\t\t\t\t\tSlotRequest: beacontypes.SlotRequest{},\n\t\t\t\t\tParentRoot:  \"AN-INVALID-HEX\",\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(*testing.T, *mocks.Backend) common.Root {\n\t\t\t\t// nothing to set here, slot is invalid\n\t\t\t\treturn common.Root{}\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, _ common.Root, _ any, err error) {\n\t\t\t\tt.Helper()\n\t\t\t\trequire.ErrorIs(t, err, handlertypes.ErrInvalidRequest)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"GetBlockHeaders - failure - unindexed parent block\",\n\t\t\tinputs: func() beacontypes.GetBlockHeadersRequest {\n\t\t\t\treturn beacontypes.GetBlockHeadersRequest{\n\t\t\t\t\tSlotRequest: beacontypes.SlotRequest{},\n\t\t\t\t\tParentRoot:  testHeader.ParentBlockRoot.Hex(),\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(_ *testing.T, b *mocks.Backend) common.Root {\n\t\t\t\t// Assume parent header is not known\n\t\t\t\tb.EXPECT().GetSlotByBlockRoot(testParentHeader.BodyRoot).Return(0, errTestHeaderNotFound)\n\t\t\t\treturn common.Root{}\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, _ common.Root, _ any, err error) {\n\t\t\t\tt.Helper()\n\t\t\t\t// Implicitly ensuring that 404 error code is returned\n\t\t\t\t// (see responseFromError implementation)\n\t\t\t\trequire.ErrorIs(t, err, handlertypes.ErrNotFound)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"GetBlockHeaders - success - slot and parent root\",\n\t\t\tinputs: func() beacontypes.GetBlockHeadersRequest {\n\t\t\t\treturn beacontypes.GetBlockHeadersRequest{\n\t\t\t\t\tSlotRequest: beacontypes.SlotRequest{\n\t\t\t\t\t\tSlot: testHeader.Slot.Base10(),\n\t\t\t\t\t},\n\t\t\t\t\tParentRoot: testHeader.ParentBlockRoot.Hex(),\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(t *testing.T, b *mocks.Backend) common.Root {\n\t\t\t\tt.Helper()\n\n\t\t\t\tst := makeTestState(t, cs)\n\t\t\t\tstateRoot := testDummyState(t, cs, st, testHeader)\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, math.Slot(0), nil)\n\t\t\t\tb.EXPECT().GetSlotByBlockRoot(testParentHeader.BodyRoot).Return(testParentHeader.Slot, nil)\n\t\t\t\treturn stateRoot\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, expectedStateRoot common.Root, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, beacontypes.GenericResponse{}, res)\n\t\t\t\tgr, _ := res.(beacontypes.GenericResponse)\n\t\t\t\trequire.IsType(t, []beacontypes.BlockHeaderResponse{}, gr.Data)\n\t\t\t\tdata, _ := gr.Data.([]beacontypes.BlockHeaderResponse)\n\t\t\t\trequire.Len(t, data, 1)\n\n\t\t\t\trequire.Equal(t, testHeader.BodyRoot, data[0].Root)\n\t\t\t\texpectedHeader := &beacontypes.BeaconBlockHeader{\n\t\t\t\t\tSlot:          testHeader.Slot.Base10(),\n\t\t\t\t\tProposerIndex: testHeader.ProposerIndex.Base10(),\n\t\t\t\t\tParentRoot:    testHeader.ParentBlockRoot.Hex(),\n\t\t\t\t\tStateRoot:     expectedStateRoot.Hex(),\n\t\t\t\t\tBodyRoot:      testHeader.BodyRoot.Hex(),\n\t\t\t\t}\n\t\t\t\trequire.Equal(t, expectedHeader, data[0].Header.Message)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"GetBlockHeaders - failure - mismatched slot and parent root\",\n\t\t\tinputs: func() beacontypes.GetBlockHeadersRequest {\n\t\t\t\treturn beacontypes.GetBlockHeadersRequest{\n\t\t\t\t\tSlotRequest: beacontypes.SlotRequest{\n\t\t\t\t\t\tSlot: wrongSlot.Base10(),\n\t\t\t\t\t},\n\t\t\t\t\tParentRoot: testHeader.ParentBlockRoot.Hex(),\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(_ *testing.T, b *mocks.Backend) common.Root {\n\t\t\t\tb.EXPECT().GetSlotByBlockRoot(testParentHeader.BodyRoot).Return(testParentHeader.Slot, nil)\n\t\t\t\treturn common.Root{}\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, _ common.Root, _ any, err error) {\n\t\t\t\tt.Helper()\n\t\t\t\trequire.ErrorIs(t, err, beacon.ErrMismatchedSlotAndParentBlock)\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\t// setup test\n\t\t\tbackend := mocks.NewBackend(t)\n\t\t\th := beacon.NewHandler(backend, cs, noop.NewLogger[log.Logger]())\n\t\t\te := echo.New()\n\t\t\te.Validator = &middleware.CustomValidator{\n\t\t\t\tValidator: middleware.ConstructValidator(),\n\t\t\t}\n\n\t\t\t// create API inputs\n\t\t\tinput := tc.inputs()\n\t\t\tinputBytes, err := json.Marshal(input) //nolint:musttag //  TODO:fix\n\t\t\trequire.NoError(t, err)\n\t\t\tbody := strings.NewReader(string(inputBytes))\n\t\t\treq := httptest.NewRequest(http.MethodGet, \"/\", body)\n\t\t\treq.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) // otherwise code=415, message=Unsupported Media Type\n\t\t\tc := e.NewContext(req, httptest.NewRecorder())\n\n\t\t\t// set expectations\n\t\t\texpectedStateRoot := tc.setMockExpectations(t, backend)\n\n\t\t\t// test\n\t\t\tres, err := h.GetBlockHeaders(c)\n\n\t\t\t// finally do checks\n\t\t\ttc.check(t, expectedStateRoot, res, err)\n\t\t})\n\t}\n}\n\nfunc TestGetBlockHeaderByID(t *testing.T) {\n\tt.Parallel()\n\n\tcs, errSpec := spec.MainnetChainSpec()\n\trequire.NoError(t, errSpec)\n\n\t// a test testHeader to build test cases on top of\n\ttestHeader := &ctypes.BeaconBlockHeader{\n\t\tSlot:            math.Slot(1234),\n\t\tProposerIndex:   math.ValidatorIndex(5678),\n\t\tParentBlockRoot: common.Root{'p', 'a', 'r', 'e', 'n', 't', 'b', 'l', 'o', 'c', 'k', 'r', 'o', 'o', 't'},\n\t\tStateRoot:       common.Root{}, // set in test cases\n\t\tBodyRoot:        common.Root{'d', 'u', 'm', 'm', 'y', 'r', 'o', 'o', 't'},\n\t}\n\terrTestHeaderNotFound := errors.New(\"test header not found error\")\n\n\ttestCases := []struct {\n\t\tname                string\n\t\tinputs              func() beacontypes.GetBlockHeaderRequest\n\t\tsetMockExpectations func(*testing.T, *mocks.Backend) common.Root\n\t\tcheck               func(t *testing.T, expectedStateRoot common.Root, res any, err error)\n\t}{\n\t\t{\n\t\t\tname: \"GetBlockHeaderByID - success - id is slot\",\n\t\t\tinputs: func() beacontypes.GetBlockHeaderRequest {\n\t\t\t\treturn beacontypes.GetBlockHeaderRequest{\n\t\t\t\t\tBlockIDRequest: handlertypes.BlockIDRequest{\n\t\t\t\t\t\tBlockID: testHeader.Slot.Base10(),\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(t *testing.T, b *mocks.Backend) common.Root {\n\t\t\t\tt.Helper()\n\n\t\t\t\tst := makeTestState(t, cs)\n\t\t\t\tstateRoot := testDummyState(t, cs, st, testHeader)\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, math.Slot(0), nil)\n\t\t\t\treturn stateRoot\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, expectedStateRoot common.Root, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, beacontypes.GenericResponse{}, res)\n\t\t\t\tgr, _ := res.(beacontypes.GenericResponse)\n\t\t\t\trequire.IsType(t, &beacontypes.BlockHeaderResponse{}, gr.Data)\n\t\t\t\tdata, _ := gr.Data.(*beacontypes.BlockHeaderResponse)\n\n\t\t\t\trequire.Equal(t, testHeader.BodyRoot, data.Root)\n\t\t\t\texpectedHeader := &beacontypes.BeaconBlockHeader{\n\t\t\t\t\tSlot:          testHeader.Slot.Base10(),\n\t\t\t\t\tProposerIndex: testHeader.ProposerIndex.Base10(),\n\t\t\t\t\tParentRoot:    testHeader.ParentBlockRoot.Hex(),\n\t\t\t\t\tStateRoot:     expectedStateRoot.Hex(),\n\t\t\t\t\tBodyRoot:      testHeader.BodyRoot.Hex(),\n\t\t\t\t}\n\t\t\t\trequire.Equal(t, expectedHeader, data.Header.Message)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"GetBlockHeaderByID - failure - invalid slot\",\n\t\t\tinputs: func() beacontypes.GetBlockHeaderRequest {\n\t\t\t\treturn beacontypes.GetBlockHeaderRequest{\n\t\t\t\t\tBlockIDRequest: handlertypes.BlockIDRequest{\n\t\t\t\t\t\tBlockID: \"zzzz\",\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(*testing.T, *mocks.Backend) common.Root {\n\t\t\t\t// nothing to set here, slot is invalid\n\t\t\t\treturn common.Root{}\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, _ common.Root, _ any, err error) {\n\t\t\t\tt.Helper()\n\t\t\t\trequire.ErrorIs(t, err, handlertypes.ErrInvalidRequest)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"GetBlockHeaderByID - failure - unindexed slot\",\n\t\t\tinputs: func() beacontypes.GetBlockHeaderRequest {\n\t\t\t\treturn beacontypes.GetBlockHeaderRequest{\n\t\t\t\t\tBlockIDRequest: handlertypes.BlockIDRequest{\n\t\t\t\t\t\tBlockID: testHeader.Slot.Base10(),\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(t *testing.T, b *mocks.Backend) common.Root {\n\t\t\t\tt.Helper()\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(nil, math.Slot(0), errTestHeaderNotFound)\n\t\t\t\treturn common.Root{}\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, _ common.Root, _ any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\t// Implicitly ensuring that 404 error code is returned\n\t\t\t\t// (see responseFromError implementation)\n\t\t\t\trequire.ErrorIs(t, err, handlertypes.ErrNotFound)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"GetBlockHeaderByID - success - id is block root\",\n\t\t\tinputs: func() beacontypes.GetBlockHeaderRequest {\n\t\t\t\treturn beacontypes.GetBlockHeaderRequest{\n\t\t\t\t\tBlockIDRequest: handlertypes.BlockIDRequest{\n\t\t\t\t\t\tBlockID: testHeader.BodyRoot.Hex(),\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(t *testing.T, b *mocks.Backend) common.Root {\n\t\t\t\tt.Helper()\n\n\t\t\t\tst := makeTestState(t, cs)\n\t\t\t\tstateRoot := testDummyState(t, cs, st, testHeader)\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, math.Slot(0), nil)\n\t\t\t\tb.EXPECT().GetSlotByBlockRoot(testHeader.BodyRoot).Return(testHeader.Slot, nil)\n\t\t\t\treturn stateRoot\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, expectedStateRoot common.Root, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, beacontypes.GenericResponse{}, res)\n\t\t\t\tgr, _ := res.(beacontypes.GenericResponse)\n\t\t\t\trequire.IsType(t, &beacontypes.BlockHeaderResponse{}, gr.Data)\n\t\t\t\tdata, _ := gr.Data.(*beacontypes.BlockHeaderResponse)\n\n\t\t\t\trequire.Equal(t, testHeader.BodyRoot, data.Root)\n\t\t\t\texpectedHeader := &beacontypes.BeaconBlockHeader{\n\t\t\t\t\tSlot:          testHeader.Slot.Base10(),\n\t\t\t\t\tProposerIndex: testHeader.ProposerIndex.Base10(),\n\t\t\t\t\tParentRoot:    testHeader.ParentBlockRoot.Hex(),\n\t\t\t\t\tStateRoot:     expectedStateRoot.Hex(),\n\t\t\t\t\tBodyRoot:      testHeader.BodyRoot.Hex(),\n\t\t\t\t}\n\t\t\t\trequire.Equal(t, expectedHeader, data.Header.Message)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"GetBlockHeaderByID - failure - invalid block root\",\n\t\t\tinputs: func() beacontypes.GetBlockHeaderRequest {\n\t\t\t\treturn beacontypes.GetBlockHeaderRequest{\n\t\t\t\t\tBlockIDRequest: handlertypes.BlockIDRequest{\n\t\t\t\t\t\tBlockID: \"AN-INVALID-HEX\",\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(*testing.T, *mocks.Backend) common.Root {\n\t\t\t\t// nothing to set here, slot is invalid\n\t\t\t\treturn common.Root{}\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, _ common.Root, _ any, err error) {\n\t\t\t\tt.Helper()\n\t\t\t\trequire.ErrorIs(t, err, handlertypes.ErrInvalidRequest)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"GetBlockHeaderByID - failure - unindexed block\",\n\t\t\tinputs: func() beacontypes.GetBlockHeaderRequest {\n\t\t\t\treturn beacontypes.GetBlockHeaderRequest{\n\t\t\t\t\tBlockIDRequest: handlertypes.BlockIDRequest{\n\t\t\t\t\t\tBlockID: testHeader.BodyRoot.Hex(),\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(_ *testing.T, b *mocks.Backend) common.Root {\n\t\t\t\t// Assume parent header is not known\n\t\t\t\tb.EXPECT().GetSlotByBlockRoot(testHeader.BodyRoot).Return(0, errTestHeaderNotFound)\n\t\t\t\treturn common.Root{}\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, _ common.Root, _ any, err error) {\n\t\t\t\tt.Helper()\n\t\t\t\trequire.ErrorIs(t, err, errTestHeaderNotFound)\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\t// setup test\n\t\t\tbackend := mocks.NewBackend(t)\n\t\t\th := beacon.NewHandler(backend, cs, noop.NewLogger[log.Logger]())\n\t\t\te := echo.New()\n\t\t\te.Validator = &middleware.CustomValidator{\n\t\t\t\tValidator: middleware.ConstructValidator(),\n\t\t\t}\n\n\t\t\t// create API inputs\n\t\t\tinput := tc.inputs()\n\t\t\tinputBytes, err := json.Marshal(input) //nolint:musttag //  TODO:fix\n\t\t\trequire.NoError(t, err)\n\t\t\tbody := strings.NewReader(string(inputBytes))\n\t\t\treq := httptest.NewRequest(http.MethodGet, \"/\", body)\n\t\t\treq.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) // otherwise code=415, message=Unsupported Media Type\n\t\t\tc := e.NewContext(req, httptest.NewRecorder())\n\n\t\t\t// set expectations\n\t\t\texpectedStateRoot := tc.setMockExpectations(t, backend)\n\n\t\t\t// test\n\t\t\tres, err := h.GetBlockHeaderByID(c)\n\n\t\t\t// finally do checks\n\t\t\ttc.check(t, expectedStateRoot, res, err)\n\t\t})\n\t}\n}\n\n// TestDummyState sets a few dummy state elements, enough to\n// be able to call HashTreeRoot over the state.\nfunc testDummyState(\n\tt *testing.T,\n\tcs chain.Spec,\n\tst *statedb.StateDB,\n\ttestHeader *ctypes.BeaconBlockHeader,\n) common.Root {\n\tt.Helper()\n\n\tdummyFork := &ctypes.Fork{\n\t\tPreviousVersion: version.Deneb(),\n\t\tCurrentVersion:  version.Electra(),\n\t\tEpoch:           math.Epoch(200),\n\t}\n\trequire.NoError(t, st.SetSlot(1234))\n\trequire.NoError(t, st.SetFork(dummyFork))\n\trequire.NoError(t, st.SetGenesisValidatorsRoot(common.Root{0x01}))\n\trequire.NoError(t, st.SetLatestBlockHeader(testHeader))\n\tfor i := range cs.HistoricalRootsLimit() {\n\t\trequire.NoError(t, st.UpdateBlockRootAtIndex(i, common.Root{}))\n\t\trequire.NoError(t, st.UpdateStateRootAtIndex(i, common.Root{}))\n\t}\n\trequire.NoError(t, st.SetLatestExecutionPayloadHeader(&ctypes.ExecutionPayloadHeader{\n\t\tVersionable: ctypes.NewVersionable(dummyFork.CurrentVersion),\n\t}))\n\trequire.NoError(t, st.SetEth1Data(&ctypes.Eth1Data{}))\n\trequire.NoError(t, st.SetEth1DepositIndex(0))\n\trequire.NoError(t, st.AddValidator(&ctypes.Validator{}))\n\trequire.NoError(t, st.SetBalance(math.ValidatorIndex(0), math.Gwei(0)))\n\tfor i := range cs.EpochsPerHistoricalVector() {\n\t\trequire.NoError(t, st.UpdateRandaoMixAtIndex(i, common.Bytes32{}))\n\t}\n\trequire.NoError(t, st.SetNextWithdrawalIndex(0))\n\trequire.NoError(t, st.SetNextWithdrawalValidatorIndex(math.ValidatorIndex(0)))\n\trequire.NoError(t, st.SetPendingPartialWithdrawals([]*ctypes.PendingPartialWithdrawal{}))\n\n\treturn st.HashTreeRoot()\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/historical.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacon\n\nimport (\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\tbeacontypes \"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n)\n\nfunc (h *Handler) GetStateRoot(c handlers.Context) (any, error) {\n\treq, err := utils.BindAndValidate[beacontypes.GetStateRootRequest](\n\t\tc, h.Logger(),\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tslot, err := utils.StateIDToHeight(req.StateID, h.backend)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tst, _, err := h.backend.StateAndSlotFromHeight(slot)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn beacontypes.NewResponse(beacontypes.RootData{Root: st.HashTreeRoot()}), nil\n}\n\nfunc (h *Handler) GetStateFork(c handlers.Context) (any, error) {\n\treq, err := utils.BindAndValidate[beacontypes.GetStateForkRequest](\n\t\tc, h.Logger(),\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tslot, err := utils.StateIDToHeight(req.StateID, h.backend)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tst, _, err := h.backend.StateAndSlotFromHeight(slot)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfork, err := st.GetFork()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn beacontypes.NewResponse(fork), nil\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/mocks/backend.mock.go",
    "content": "// Code generated by mockery v2.53.5. DO NOT EDIT.\n\npackage mocks\n\nimport (\n\tbackend \"github.com/berachain/beacon-kit/node-api/backend\"\n\n\ttypes \"github.com/berachain/beacon-kit/da/types\"\n\tcommon \"github.com/berachain/beacon-kit/primitives/common\"\n\tcrypto \"github.com/berachain/beacon-kit/primitives/crypto\"\n\tmath \"github.com/berachain/beacon-kit/primitives/math\"\n\tmock \"github.com/stretchr/testify/mock\"\n)\n\n// Backend is an autogenerated mock type for the Backend type\ntype Backend struct {\n\tmock.Mock\n}\n\ntype Backend_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *Backend) EXPECT() *Backend_Expecter {\n\treturn &Backend_Expecter{mock: &_m.Mock}\n}\n\n// GetBlobSidecarsAtSlot provides a mock function with given fields: slot\nfunc (_m *Backend) GetBlobSidecarsAtSlot(slot math.Slot) (types.BlobSidecars, error) {\n\tret := _m.Called(slot)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetBlobSidecarsAtSlot\")\n\t}\n\n\tvar r0 types.BlobSidecars\n\tvar r1 error\n\tif rf, ok := ret.Get(0).(func(math.Slot) (types.BlobSidecars, error)); ok {\n\t\treturn rf(slot)\n\t}\n\tif rf, ok := ret.Get(0).(func(math.Slot) types.BlobSidecars); ok {\n\t\tr0 = rf(slot)\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(types.BlobSidecars)\n\t\t}\n\t}\n\n\tif rf, ok := ret.Get(1).(func(math.Slot) error); ok {\n\t\tr1 = rf(slot)\n\t} else {\n\t\tr1 = ret.Error(1)\n\t}\n\n\treturn r0, r1\n}\n\n// Backend_GetBlobSidecarsAtSlot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBlobSidecarsAtSlot'\ntype Backend_GetBlobSidecarsAtSlot_Call struct {\n\t*mock.Call\n}\n\n// GetBlobSidecarsAtSlot is a helper method to define mock.On call\n//   - slot math.Slot\nfunc (_e *Backend_Expecter) GetBlobSidecarsAtSlot(slot interface{}) *Backend_GetBlobSidecarsAtSlot_Call {\n\treturn &Backend_GetBlobSidecarsAtSlot_Call{Call: _e.mock.On(\"GetBlobSidecarsAtSlot\", slot)}\n}\n\nfunc (_c *Backend_GetBlobSidecarsAtSlot_Call) Run(run func(slot math.Slot)) *Backend_GetBlobSidecarsAtSlot_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(math.Slot))\n\t})\n\treturn _c\n}\n\nfunc (_c *Backend_GetBlobSidecarsAtSlot_Call) Return(_a0 types.BlobSidecars, _a1 error) *Backend_GetBlobSidecarsAtSlot_Call {\n\t_c.Call.Return(_a0, _a1)\n\treturn _c\n}\n\nfunc (_c *Backend_GetBlobSidecarsAtSlot_Call) RunAndReturn(run func(math.Slot) (types.BlobSidecars, error)) *Backend_GetBlobSidecarsAtSlot_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// GetSignatureBySlot provides a mock function with given fields: slot\nfunc (_m *Backend) GetSignatureBySlot(slot math.Slot) (crypto.BLSSignature, error) {\n\tret := _m.Called(slot)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetSignatureBySlot\")\n\t}\n\n\tvar r0 crypto.BLSSignature\n\tvar r1 error\n\tif rf, ok := ret.Get(0).(func(math.Slot) (crypto.BLSSignature, error)); ok {\n\t\treturn rf(slot)\n\t}\n\tif rf, ok := ret.Get(0).(func(math.Slot) crypto.BLSSignature); ok {\n\t\tr0 = rf(slot)\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(crypto.BLSSignature)\n\t\t}\n\t}\n\n\tif rf, ok := ret.Get(1).(func(math.Slot) error); ok {\n\t\tr1 = rf(slot)\n\t} else {\n\t\tr1 = ret.Error(1)\n\t}\n\n\treturn r0, r1\n}\n\n// Backend_GetSignatureBySlot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSignatureBySlot'\ntype Backend_GetSignatureBySlot_Call struct {\n\t*mock.Call\n}\n\n// GetSignatureBySlot is a helper method to define mock.On call\n//   - slot math.Slot\nfunc (_e *Backend_Expecter) GetSignatureBySlot(slot interface{}) *Backend_GetSignatureBySlot_Call {\n\treturn &Backend_GetSignatureBySlot_Call{Call: _e.mock.On(\"GetSignatureBySlot\", slot)}\n}\n\nfunc (_c *Backend_GetSignatureBySlot_Call) Run(run func(slot math.Slot)) *Backend_GetSignatureBySlot_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(math.Slot))\n\t})\n\treturn _c\n}\n\nfunc (_c *Backend_GetSignatureBySlot_Call) Return(_a0 crypto.BLSSignature, _a1 error) *Backend_GetSignatureBySlot_Call {\n\t_c.Call.Return(_a0, _a1)\n\treturn _c\n}\n\nfunc (_c *Backend_GetSignatureBySlot_Call) RunAndReturn(run func(math.Slot) (crypto.BLSSignature, error)) *Backend_GetSignatureBySlot_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// GetSlotByBlockRoot provides a mock function with given fields: root\nfunc (_m *Backend) GetSlotByBlockRoot(root common.Root) (math.Slot, error) {\n\tret := _m.Called(root)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetSlotByBlockRoot\")\n\t}\n\n\tvar r0 math.Slot\n\tvar r1 error\n\tif rf, ok := ret.Get(0).(func(common.Root) (math.Slot, error)); ok {\n\t\treturn rf(root)\n\t}\n\tif rf, ok := ret.Get(0).(func(common.Root) math.Slot); ok {\n\t\tr0 = rf(root)\n\t} else {\n\t\tr0 = ret.Get(0).(math.Slot)\n\t}\n\n\tif rf, ok := ret.Get(1).(func(common.Root) error); ok {\n\t\tr1 = rf(root)\n\t} else {\n\t\tr1 = ret.Error(1)\n\t}\n\n\treturn r0, r1\n}\n\n// Backend_GetSlotByBlockRoot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSlotByBlockRoot'\ntype Backend_GetSlotByBlockRoot_Call struct {\n\t*mock.Call\n}\n\n// GetSlotByBlockRoot is a helper method to define mock.On call\n//   - root common.Root\nfunc (_e *Backend_Expecter) GetSlotByBlockRoot(root interface{}) *Backend_GetSlotByBlockRoot_Call {\n\treturn &Backend_GetSlotByBlockRoot_Call{Call: _e.mock.On(\"GetSlotByBlockRoot\", root)}\n}\n\nfunc (_c *Backend_GetSlotByBlockRoot_Call) Run(run func(root common.Root)) *Backend_GetSlotByBlockRoot_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(common.Root))\n\t})\n\treturn _c\n}\n\nfunc (_c *Backend_GetSlotByBlockRoot_Call) Return(_a0 math.Slot, _a1 error) *Backend_GetSlotByBlockRoot_Call {\n\t_c.Call.Return(_a0, _a1)\n\treturn _c\n}\n\nfunc (_c *Backend_GetSlotByBlockRoot_Call) RunAndReturn(run func(common.Root) (math.Slot, error)) *Backend_GetSlotByBlockRoot_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// GetSlotByStateRoot provides a mock function with given fields: root\nfunc (_m *Backend) GetSlotByStateRoot(root common.Root) (math.Slot, error) {\n\tret := _m.Called(root)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetSlotByStateRoot\")\n\t}\n\n\tvar r0 math.Slot\n\tvar r1 error\n\tif rf, ok := ret.Get(0).(func(common.Root) (math.Slot, error)); ok {\n\t\treturn rf(root)\n\t}\n\tif rf, ok := ret.Get(0).(func(common.Root) math.Slot); ok {\n\t\tr0 = rf(root)\n\t} else {\n\t\tr0 = ret.Get(0).(math.Slot)\n\t}\n\n\tif rf, ok := ret.Get(1).(func(common.Root) error); ok {\n\t\tr1 = rf(root)\n\t} else {\n\t\tr1 = ret.Error(1)\n\t}\n\n\treturn r0, r1\n}\n\n// Backend_GetSlotByStateRoot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSlotByStateRoot'\ntype Backend_GetSlotByStateRoot_Call struct {\n\t*mock.Call\n}\n\n// GetSlotByStateRoot is a helper method to define mock.On call\n//   - root common.Root\nfunc (_e *Backend_Expecter) GetSlotByStateRoot(root interface{}) *Backend_GetSlotByStateRoot_Call {\n\treturn &Backend_GetSlotByStateRoot_Call{Call: _e.mock.On(\"GetSlotByStateRoot\", root)}\n}\n\nfunc (_c *Backend_GetSlotByStateRoot_Call) Run(run func(root common.Root)) *Backend_GetSlotByStateRoot_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(common.Root))\n\t})\n\treturn _c\n}\n\nfunc (_c *Backend_GetSlotByStateRoot_Call) Return(_a0 math.Slot, _a1 error) *Backend_GetSlotByStateRoot_Call {\n\t_c.Call.Return(_a0, _a1)\n\treturn _c\n}\n\nfunc (_c *Backend_GetSlotByStateRoot_Call) RunAndReturn(run func(common.Root) (math.Slot, error)) *Backend_GetSlotByStateRoot_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// GetSyncData provides a mock function with no fields\nfunc (_m *Backend) GetSyncData() (int64, int64) {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetSyncData\")\n\t}\n\n\tvar r0 int64\n\tvar r1 int64\n\tif rf, ok := ret.Get(0).(func() (int64, int64)); ok {\n\t\treturn rf()\n\t}\n\tif rf, ok := ret.Get(0).(func() int64); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tr0 = ret.Get(0).(int64)\n\t}\n\n\tif rf, ok := ret.Get(1).(func() int64); ok {\n\t\tr1 = rf()\n\t} else {\n\t\tr1 = ret.Get(1).(int64)\n\t}\n\n\treturn r0, r1\n}\n\n// Backend_GetSyncData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSyncData'\ntype Backend_GetSyncData_Call struct {\n\t*mock.Call\n}\n\n// GetSyncData is a helper method to define mock.On call\nfunc (_e *Backend_Expecter) GetSyncData() *Backend_GetSyncData_Call {\n\treturn &Backend_GetSyncData_Call{Call: _e.mock.On(\"GetSyncData\")}\n}\n\nfunc (_c *Backend_GetSyncData_Call) Run(run func()) *Backend_GetSyncData_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *Backend_GetSyncData_Call) Return(_a0 int64, _a1 int64) *Backend_GetSyncData_Call {\n\t_c.Call.Return(_a0, _a1)\n\treturn _c\n}\n\nfunc (_c *Backend_GetSyncData_Call) RunAndReturn(run func() (int64, int64)) *Backend_GetSyncData_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// StateAndSlotFromHeight provides a mock function with given fields: height\nfunc (_m *Backend) StateAndSlotFromHeight(height int64) (backend.ReadOnlyBeaconState, math.Slot, error) {\n\tret := _m.Called(height)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for StateAndSlotFromHeight\")\n\t}\n\n\tvar r0 backend.ReadOnlyBeaconState\n\tvar r1 math.Slot\n\tvar r2 error\n\tif rf, ok := ret.Get(0).(func(int64) (backend.ReadOnlyBeaconState, math.Slot, error)); ok {\n\t\treturn rf(height)\n\t}\n\tif rf, ok := ret.Get(0).(func(int64) backend.ReadOnlyBeaconState); ok {\n\t\tr0 = rf(height)\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(backend.ReadOnlyBeaconState)\n\t\t}\n\t}\n\n\tif rf, ok := ret.Get(1).(func(int64) math.Slot); ok {\n\t\tr1 = rf(height)\n\t} else {\n\t\tr1 = ret.Get(1).(math.Slot)\n\t}\n\n\tif rf, ok := ret.Get(2).(func(int64) error); ok {\n\t\tr2 = rf(height)\n\t} else {\n\t\tr2 = ret.Error(2)\n\t}\n\n\treturn r0, r1, r2\n}\n\n// Backend_StateAndSlotFromHeight_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'StateAndSlotFromHeight'\ntype Backend_StateAndSlotFromHeight_Call struct {\n\t*mock.Call\n}\n\n// StateAndSlotFromHeight is a helper method to define mock.On call\n//   - height int64\nfunc (_e *Backend_Expecter) StateAndSlotFromHeight(height interface{}) *Backend_StateAndSlotFromHeight_Call {\n\treturn &Backend_StateAndSlotFromHeight_Call{Call: _e.mock.On(\"StateAndSlotFromHeight\", height)}\n}\n\nfunc (_c *Backend_StateAndSlotFromHeight_Call) Run(run func(height int64)) *Backend_StateAndSlotFromHeight_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(int64))\n\t})\n\treturn _c\n}\n\nfunc (_c *Backend_StateAndSlotFromHeight_Call) Return(_a0 backend.ReadOnlyBeaconState, _a1 math.Slot, _a2 error) *Backend_StateAndSlotFromHeight_Call {\n\t_c.Call.Return(_a0, _a1, _a2)\n\treturn _c\n}\n\nfunc (_c *Backend_StateAndSlotFromHeight_Call) RunAndReturn(run func(int64) (backend.ReadOnlyBeaconState, math.Slot, error)) *Backend_StateAndSlotFromHeight_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewBackend creates a new instance of Backend. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewBackend(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *Backend {\n\tmock := &Backend{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/randao.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacon\n\nimport (\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\tbeacontypes \"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\nfunc (h *Handler) GetRandao(c handlers.Context) (any, error) {\n\treq, err := utils.BindAndValidate[beacontypes.GetRandaoRequest](\n\t\tc,\n\t\th.Logger(),\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Get slot and associated state\n\theight, err := utils.StateIDToHeight(req.StateID, h.backend)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tst, slot, err := h.backend.StateAndSlotFromHeight(height)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"failed to get state from height %d\", height)\n\t}\n\n\t// Get the epoch\n\tvar epoch math.Epoch\n\tif req.Epoch != \"\" {\n\t\tepoch, err = math.U64FromString(req.Epoch)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t} else {\n\t\t// Infer the epoch if not provided.\n\t\tepoch = h.cs.SlotToEpoch(slot)\n\t}\n\n\t// Retrieve the randao\n\tindex := epoch.Unwrap() % h.cs.EpochsPerHistoricalVector()\n\trandao, err := st.GetRandaoMixAtIndex(index)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn beacontypes.NewResponse(randao), nil\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/randao_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacon_test\n\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"strconv\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/log/noop\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/beacon\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/beacon/mocks\"\n\tbeacontypes \"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\thandlertypes \"github.com/berachain/beacon-kit/node-api/handlers/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n\t\"github.com/berachain/beacon-kit/node-api/middleware\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/labstack/echo/v4\"\n\t\"github.com/stretchr/testify/mock\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestGetRandao(t *testing.T) {\n\tt.Parallel()\n\n\tcs, errSpec := spec.MainnetChainSpec()\n\trequire.NoError(t, errSpec)\n\n\tvar (\n\t\ttestSlot  = math.Slot(1234)\n\t\ttestEpoch = cs.SlotToEpoch(testSlot)\n\t\tindex     = testEpoch.Unwrap() % cs.EpochsPerHistoricalVector()\n\t\ttestMix   = common.Bytes32{0x01, 0x02, 0x03}\n\t)\n\n\ttestCases := []struct {\n\t\tname                string\n\t\tinputs              func() beacontypes.GetRandaoRequest\n\t\tsetMockExpectations func(*mocks.Backend)\n\t\tcheck               func(t *testing.T, res any, err error)\n\t}{\n\t\t{\n\t\t\tname: \"randao request - specified epoch\",\n\t\t\tinputs: func() beacontypes.GetRandaoRequest {\n\t\t\t\tstateID := utils.StateIDHead\n\t\t\t\tepoch := strconv.Itoa(int(testEpoch.Unwrap()))\n\t\t\t\treturn beacontypes.GetRandaoRequest{\n\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\tStateID: stateID,\n\t\t\t\t\t},\n\t\t\t\t\tEpochOptionalRequest: beacontypes.EpochOptionalRequest{\n\t\t\t\t\t\tEpoch: epoch,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tst := makeTestState(t, cs)\n\n\t\t\t\trequire.NoError(t, st.UpdateRandaoMixAtIndex(index, testMix))\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, testSlot, nil)\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, beacontypes.GenericResponse{}, res)\n\t\t\t\tgr, _ := res.(beacontypes.GenericResponse)\n\t\t\t\trequire.IsType(t, common.Bytes32{}, gr.Data)\n\t\t\t\tdata, _ := gr.Data.(common.Bytes32)\n\t\t\t\trequire.Equal(t, testMix, data)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"randao request - unspecified epoch\",\n\t\t\tinputs: func() beacontypes.GetRandaoRequest {\n\t\t\t\tstateID := utils.StateIDHead\n\t\t\t\treturn beacontypes.GetRandaoRequest{\n\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\tStateID: stateID,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tst := makeTestState(t, cs)\n\n\t\t\t\trequire.NoError(t, st.UpdateRandaoMixAtIndex(index, testMix))\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, testSlot, nil)\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, beacontypes.GenericResponse{}, res)\n\t\t\t\tgr, _ := res.(beacontypes.GenericResponse)\n\t\t\t\trequire.IsType(t, common.Bytes32{}, gr.Data)\n\t\t\t\tdata, _ := gr.Data.(common.Bytes32)\n\t\t\t\trequire.Equal(t, testMix, data)\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\t// setup test\n\t\t\tbackend := mocks.NewBackend(t)\n\t\t\th := beacon.NewHandler(backend, cs, noop.NewLogger[log.Logger]())\n\t\t\te := echo.New()\n\t\t\te.Validator = &middleware.CustomValidator{\n\t\t\t\tValidator: middleware.ConstructValidator(),\n\t\t\t}\n\n\t\t\t// set expectations\n\t\t\ttc.setMockExpectations(backend)\n\n\t\t\t// create input\n\t\t\tinput := tc.inputs()\n\t\t\tinputBytes, err := json.Marshal(input) //nolint:musttag //  TODO:fix\n\t\t\trequire.NoError(t, err)\n\t\t\tbody := strings.NewReader(string(inputBytes))\n\t\t\treq := httptest.NewRequest(http.MethodGet, \"/\", body)\n\t\t\treq.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) // otherwise code=415, message=Unsupported Media Type\n\t\t\tc := e.NewContext(req, httptest.NewRecorder())\n\n\t\t\t// test\n\t\t\tres, err := h.GetRandao(c)\n\n\t\t\t// check\n\t\t\ttc.check(t, res, err)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/routes.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacon\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n)\n\n//nolint:funlen // routes are long\nfunc registerRoutes(h *Handler) {\n\th.BaseHandler.AddRoutes([]*handlers.Route{\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/genesis\",\n\t\t\tHandler: h.GetGenesis,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/states/:state_id/root\",\n\t\t\tHandler: h.GetStateRoot,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/states/:state_id/fork\",\n\t\t\tHandler: h.GetStateFork,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/states/:state_id/finality_checkpoints\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/states/:state_id/validators\",\n\t\t\tHandler: h.GetStateValidators,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/beacon/states/:state_id/validators\",\n\t\t\tHandler: h.PostStateValidators,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/states/:state_id/validators/:validator_id\",\n\t\t\tHandler: h.GetStateValidator,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/states/:state_id/validator_balances\",\n\t\t\tHandler: h.GetStateValidatorBalances,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/beacon/states/:state_id/validator_balances\",\n\t\t\tHandler: h.PostStateValidatorBalances,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/beacon/states/:state_id/validator_identities\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/states/:state_id/committees\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/states/:state_id/sync_committees\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/states/:state_id/randao\",\n\t\t\tHandler: h.GetRandao,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/states/:state_id/pending_deposits\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/states/:state_id/pending_partial_withdrawals\",\n\t\t\tHandler: h.GetPendingPartialWithdrawals,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/headers\",\n\t\t\tHandler: h.GetBlockHeaders,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/headers/:block_id\",\n\t\t\tHandler: h.GetBlockHeaderByID,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/beacon/blocks/blinded_blocks\",\n\t\t\tHandler: h.Deprecated,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"eth/v2/beacon/blocks/blinded_blocks\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/beacon/blocks\",\n\t\t\tHandler: h.Deprecated,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"eth/v2/beacon/blocks\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"eth/v2/beacon/blocks/:block_id\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/blocks/:block_id/root\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/blocks/:block_id/attestations\",\n\t\t\tHandler: h.Deprecated,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v2/beacon/blocks/:block_id/attestations\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/blob_sidecars/:block_id\",\n\t\t\tHandler: h.GetBlobSidecars,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/beacon/rewards/sync_committee/:block_id\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/deposit_snapshot\",\n\t\t\tHandler: h.Deprecated,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/rewards/blocks/:block_id\",\n\t\t\tHandler: h.GetBlockRewards,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/beacon/rewards/attestations/:epoch\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/blinded_blocks/:block_id\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/light_client/bootstrap/:block_root\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/light_client/updates\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/light_client/finality_update\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/light_client/optimistic_update\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/pool/attestations\",\n\t\t\tHandler: h.Deprecated,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/beacon/pool/attestations\",\n\t\t\tHandler: h.Deprecated,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v2/beacon/pool/attestations\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v2/beacon/pool/attestations\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/pool/attester_slashings\",\n\t\t\tHandler: h.Deprecated,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/beacon/pool/attester_slashings\",\n\t\t\tHandler: h.Deprecated,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v2/beacon/pool/attester_slashings\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v2/beacon/pool/attester_slashings\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/pool/proposer_slashings\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/beacon/pool/proposer_slashings\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/beacon/pool/sync_committees\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/pool/voluntary_exits\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/beacon/pool/voluntary_exits\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/beacon/pool/bls_to_execution_changes\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/beacon/pool/bls_to_execution_changes\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/types/conversions.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\n\t\"github.com/berachain/beacon-kit/cli/utils/parser\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tdatypes \"github.com/berachain/beacon-kit/da/types\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\nfunc BeaconBlockHeaderFromConsensus(h *ctypes.BeaconBlockHeader) *BeaconBlockHeader {\n\treturn &BeaconBlockHeader{\n\t\tSlot:          fmt.Sprintf(\"%d\", h.Slot),\n\t\tProposerIndex: fmt.Sprintf(\"%d\", h.ProposerIndex),\n\t\tParentRoot:    h.ParentBlockRoot.Hex(),\n\t\tStateRoot:     h.StateRoot.Hex(),\n\t\tBodyRoot:      h.BodyRoot.Hex(),\n\t}\n}\n\nfunc SignedBeaconBlockHeaderFromConsensus(h *ctypes.SignedBeaconBlockHeader) *SignedBeaconBlockHeader {\n\treturn &SignedBeaconBlockHeader{\n\t\tMessage:   BeaconBlockHeaderFromConsensus(h.Header),\n\t\tSignature: h.Signature.String(),\n\t}\n}\n\nfunc SidecarFromConsensus(sc *datypes.BlobSidecar) *Sidecar {\n\tproofs := make([]string, len(sc.InclusionProof))\n\tfor i := range sc.InclusionProof {\n\t\tproofs[i] = hex.EncodeBytes(sc.InclusionProof[i][:])\n\t}\n\treturn &Sidecar{\n\t\tIndex:                       strconv.FormatUint(sc.Index, 10),\n\t\tBlob:                        hex.EncodeBytes(sc.Blob[:]),\n\t\tKZGCommitment:               hex.EncodeBytes(sc.KzgCommitment[:]),\n\t\tSignedBlockHeader:           SignedBeaconBlockHeaderFromConsensus(sc.SignedBeaconBlockHeader),\n\t\tKZGProof:                    hex.EncodeBytes(sc.KzgProof[:]),\n\t\tKZGCommitmentInclusionProof: proofs,\n\t}\n}\n\nfunc ValidatorFromConsensus(v *ctypes.Validator) *Validator {\n\treturn &Validator{\n\t\tPublicKey:                  v.GetPubkey().String(),\n\t\tWithdrawalCredentials:      v.GetWithdrawalCredentials().String(),\n\t\tEffectiveBalance:           v.GetEffectiveBalance().Base10(),\n\t\tSlashed:                    v.IsSlashed(),\n\t\tActivationEligibilityEpoch: v.GetActivationEligibilityEpoch().Base10(),\n\t\tActivationEpoch:            v.GetActivationEpoch().Base10(),\n\t\tExitEpoch:                  v.GetExitEpoch().Base10(),\n\t\tWithdrawableEpoch:          v.GetWithdrawableEpoch().Base10(),\n\t}\n}\n\n// useful in UTs\nfunc ValidatorToConsensus(v *Validator) (*ctypes.Validator, error) {\n\tpk, err := parser.ConvertPubkey(v.PublicKey)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed parsing public key: %w\", err)\n\t}\n\twc, err := parser.ConvertWithdrawalCredentials(v.WithdrawalCredentials)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed parsing withdrawals: %w\", err)\n\t}\n\teb, err := math.U64FromString(v.EffectiveBalance)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed parsing effective balance: %w\", err)\n\t}\n\taee, err := math.U64FromString(v.ActivationEligibilityEpoch)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed parsing activation eligibility epoch: %w\", err)\n\t}\n\tae, err := math.U64FromString(v.ActivationEpoch)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed parsing activation epoch: %w\", err)\n\t}\n\tee, err := math.U64FromString(v.ExitEpoch)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed parsing exit epoch: %w\", err)\n\t}\n\twe, err := math.U64FromString(v.WithdrawableEpoch)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed parsing withdrawable epoch: %w\", err)\n\t}\n\treturn &ctypes.Validator{\n\t\tPubkey:                     pk,\n\t\tWithdrawalCredentials:      wc,\n\t\tEffectiveBalance:           eb,\n\t\tSlashed:                    v.Slashed,\n\t\tActivationEligibilityEpoch: aee,\n\t\tActivationEpoch:            ae,\n\t\tExitEpoch:                  ee,\n\t\tWithdrawableEpoch:          we,\n\t}, nil\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/types/request.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/types\"\n)\n\ntype GetGenesisRequest struct{}\n\ntype GetStateRootRequest struct {\n\ttypes.StateIDRequest\n}\n\ntype GetStateRequest struct {\n\ttypes.StateIDRequest\n}\n\ntype GetStateForkRequest struct {\n\ttypes.StateIDRequest\n}\n\ntype GetFinalityCheckpointsRequest struct {\n\ttypes.StateIDRequest\n}\n\ntype GetPendingPartialWithdrawalsRequest struct {\n\ttypes.StateIDRequest\n}\n\ntype GetStateValidatorsRequest struct {\n\ttypes.StateIDRequest\n\tIDs      []string `query:\"id\"     validate:\"dive,validator_id\"`\n\tStatuses []string `query:\"status\" validate:\"dive,validator_status\"`\n}\n\ntype PostStateValidatorsRequest struct {\n\ttypes.StateIDRequest\n\tIDs      []string `json:\"ids\"      validate:\"dive,validator_id\"`\n\tStatuses []string `json:\"statuses\" validate:\"dive,validator_status\"`\n}\n\ntype GetStateValidatorRequest struct {\n\ttypes.StateIDRequest\n\tValidatorID string `param:\"validator_id\" validate:\"required,validator_id\"`\n}\n\ntype GetValidatorBalancesRequest struct {\n\ttypes.StateIDRequest\n\tIDs []string `query:\"id\" validate:\"dive,validator_id\"`\n}\n\ntype PostValidatorBalancesRequest struct {\n\ttypes.StateIDRequest\n\tIDs []string `json:\"-\" validate:\"dive,validator_id\"`\n}\n\ntype GetStateCommitteesRequest struct {\n\ttypes.StateIDRequest\n\tEpochOptionalRequest\n\tCommitteeIndexRequest\n\tSlotRequest\n}\n\ntype GetSyncCommitteesRequest struct {\n\ttypes.StateIDRequest\n\tEpochOptionalRequest\n}\n\ntype GetRandaoRequest struct {\n\ttypes.StateIDRequest\n\tEpochOptionalRequest\n}\n\ntype GetBlockHeadersRequest struct {\n\tSlotRequest\n\n\tParentRoot string `query:\"parent_root\" validate:\"omitempty,hex\"`\n}\n\ntype GetBlockHeaderRequest struct {\n\ttypes.BlockIDRequest\n}\n\ntype PostBlindedBlocksV1Request struct {\n\tEthConsensusVersion string `json:\"eth_consensus_version\" validate:\"required,eth_consensus_version\"`\n}\n\ntype PostBlindedBlocksV2Request struct {\n\tPostBlindedBlocksV1Request\n\tBroadcastValidation string `json:\"broadcast_validation\" validate:\"required,broadcast_validation\"`\n}\n\ntype PostBlocksV1Request struct {\n\tEthConsensusVersion string             `json:\"eth_consensus_version\" validate:\"required,eth_consensus_version\"`\n\tBeaconBlock         ctypes.BeaconBlock `json:\"beacon_block\"`\n}\n\ntype PostBlocksV2Request struct {\n\tPostBlocksV1Request\n\tBroadcastValidation string `json:\"broadcast_validation\" validate:\"required,broadcast_validation\"`\n}\n\ntype GetBlocksRequest struct {\n\ttypes.BlockIDRequest\n}\n\ntype GetBlockRootRequest struct {\n\ttypes.BlockIDRequest\n}\n\ntype GetBlockAttestationsRequest struct {\n\ttypes.BlockIDRequest\n}\n\ntype GetBlobSidecarsRequest struct {\n\ttypes.BlockIDRequest\n\tIndices []string `query:\"indices\" validate:\"dive,numeric\"`\n}\n\ntype PostRewardsSyncCommitteeRequest struct {\n\ttypes.BlockIDRequest\n\tIDs []string `validate:\"dive,validator_id\"`\n}\n\ntype GetDepositTreeSnapshotRequest struct{}\n\ntype GetBlockRewardsRequest struct {\n\ttypes.BlockIDRequest\n}\n\ntype PostAttestationsRewardsRequest struct {\n\tEpochRequest\n\tIDs []string `validate:\"dive,validator_id\"`\n}\n\ntype GetBlindedBlockRequest struct {\n\ttypes.BlockIDRequest\n}\n\ntype EpochOptionalRequest struct {\n\tEpoch string `query:\"epoch\" validate:\"epoch\"`\n}\n\ntype EpochRequest struct {\n\tEpoch string `param:\"epoch\" validate:\"required,epoch\"`\n}\n\ntype CommitteeIndexRequest struct {\n\tCommitteeIndex string `query:\"committee_index\" validate:\"committee_index\"`\n}\n\ntype SlotRequest struct {\n\tSlot string `query:\"slot\" validate:\"slot\"`\n}\n\ntype HeadersRequest struct {\n\tSlotRequest\n\tParentRoot string `query:\"parent_root\" validate:\"hex\"`\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/types/response.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n)\n\ntype GenericResponse struct {\n\tExecutionOptimistic bool `json:\"execution_optimistic\"`\n\tFinalized           bool `json:\"finalized\"`\n\tData                any  `json:\"data\"`\n}\n\n// NewResponse creates a new response with CometBFT's finality guarantees.\nfunc NewResponse(data any) GenericResponse {\n\treturn GenericResponse{\n\t\t// All data is finalized in CometBFT since we only return data for slots up to head\n\t\tFinalized: true,\n\t\t// Never optimistic since we only return finalized data\n\t\tExecutionOptimistic: false,\n\t\tData:                data,\n\t}\n}\n\ntype BlockResponse struct {\n\tVersion string `json:\"version\"`\n\tGenericResponse\n}\n\ntype StateResponse struct {\n\tVersion             string `json:\"version\"`\n\tExecutionOptimistic bool   `json:\"execution_optimistic\"`\n\tFinalized           bool   `json:\"finalized\"`\n\tData                any    `json:\"data\"`\n}\n\ntype BlockHeaderResponse struct {\n\tRoot      common.Root              `json:\"root\"`\n\tCanonical bool                     `json:\"canonical\"`\n\tHeader    *SignedBeaconBlockHeader `json:\"header\"`\n}\n\ntype BeaconBlockHeader struct {\n\tSlot          string `json:\"slot\"`\n\tProposerIndex string `json:\"proposer_index\"`\n\tParentRoot    string `json:\"parent_root\"`\n\tStateRoot     string `json:\"state_root\"`\n\tBodyRoot      string `json:\"body_root\"`\n}\n\ntype SignedBeaconBlockHeader struct {\n\tMessage   *BeaconBlockHeader `json:\"message\"`\n\tSignature string             `json:\"signature\"`\n}\n\ntype GenesisData struct {\n\tGenesisTime           string      `json:\"genesis_time\"`\n\tGenesisValidatorsRoot common.Root `json:\"genesis_validators_root\"`\n\tGenesisForkVersion    string      `json:\"genesis_fork_version\"`\n}\n\n// GenesisResponse is handled with this explicit response type since\n// \"finalized\" and \"execution_optimistic\" are not part of the return value.\n//\n// https://ethereum.github.io/beacon-APIs/#/Beacon/getGenesis\ntype GenesisResponse struct {\n\tData GenesisData `json:\"data\"`\n}\n\ntype RootData struct {\n\tRoot common.Root `json:\"root\"`\n}\n\ntype ValidatorData struct {\n\tValidatorBalanceData\n\tStatus    string     `json:\"status\"`\n\tValidator *Validator `json:\"validator\"`\n}\n\ntype ValidatorBalanceData struct {\n\tIndex   uint64 `json:\"index,string\"`\n\tBalance uint64 `json:\"balance,string\"`\n}\n\n// Validator is the spec representation of the struct.\ntype Validator struct {\n\tPublicKey                  string `json:\"pubkey\"`\n\tWithdrawalCredentials      string `json:\"withdrawal_credentials\"`\n\tEffectiveBalance           string `json:\"effective_balance\"`\n\tSlashed                    bool   `json:\"slashed\"`\n\tActivationEligibilityEpoch string `json:\"activation_eligibility_epoch\"`\n\tActivationEpoch            string `json:\"activation_epoch\"`\n\tExitEpoch                  string `json:\"exit_epoch\"`\n\tWithdrawableEpoch          string `json:\"withdrawable_epoch\"`\n}\n\n//nolint:staticcheck // todo: figure this out.\ntype CommitteeData struct {\n\tIndex      uint64   `json:\"index,string\"`\n\tSlot       uint64   `json:\"slot,string\"`\n\tValidators []uint64 `json:\"validators,string\"`\n}\n\ntype BlockRewardsData struct {\n\tProposerIndex     uint64 `json:\"proposer_index,string\"`\n\tTotal             uint64 `json:\"total,string\"`\n\tAttestations      uint64 `json:\"attestations,string\"`\n\tSyncAggregate     uint64 `json:\"sync_aggregate,string\"`\n\tProposerSlashings uint64 `json:\"proposer_slashings,string\"`\n\tAttesterSlashings uint64 `json:\"attester_slashings,string\"`\n}\n\ntype Sidecar struct {\n\tIndex                       string                   `json:\"index\"`\n\tBlob                        string                   `json:\"blob\"`\n\tKZGCommitment               string                   `json:\"kzg_commitment\"`\n\tKZGProof                    string                   `json:\"kzg_proof\"`\n\tSignedBlockHeader           *SignedBeaconBlockHeader `json:\"signed_block_header\"`\n\tKZGCommitmentInclusionProof []string                 `json:\"kzg_commitment_inclusion_proof\"`\n}\n\ntype SidecarsResponse struct {\n\tData []*Sidecar `json:\"data\"`\n}\n\n// PendingPartialWithdrawalsResponse has a version field to indicate the fork version.\n// https://ethereum.github.io/beacon-APIs/#/Beacon/getPendingPartialWithdrawals\ntype PendingPartialWithdrawalsResponse struct {\n\tVersion string `json:\"version\"`\n\tGenericResponse\n}\n\ntype PendingPartialWithdrawalData struct {\n\tValidatorIndex  uint64 `json:\"validator_index,string\"`\n\tAmount          uint64 `json:\"amount,string\"`\n\tWithdrawalEpoch uint64 `json:\"withdrawal_epoch,string\"`\n}\n\n// NewPendingPartialWithdrawalsResponse creates a typed response with PendingPartialWithdrawal data\nfunc NewPendingPartialWithdrawalsResponse(\n\tforkVersion common.Version,\n\twithdrawals []*PendingPartialWithdrawalData,\n) PendingPartialWithdrawalsResponse {\n\treturn PendingPartialWithdrawalsResponse{\n\t\t// Version is the name of the fork version.\n\t\tVersion:         version.Name(forkVersion),\n\t\tGenericResponse: NewResponse(withdrawals),\n\t}\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/validators.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacon\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t\"cosmossdk.io/collections\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\tbeacontypes \"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\ttypes \"github.com/berachain/beacon-kit/node-api/handlers/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n)\n\nfunc (h *Handler) GetStateValidators(c handlers.Context) (any, error) {\n\treq, err := utils.BindAndValidate[beacontypes.GetStateValidatorsRequest](\n\t\tc, h.Logger(),\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\theight, err := utils.StateIDToHeight(req.StateID, h.backend)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfilteredVals, err := h.FilterValidators(height, req.IDs, req.Statuses)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to filter validators: %w\", err)\n\t}\n\treturn beacontypes.NewResponse(filteredVals), nil\n}\n\nfunc (h *Handler) PostStateValidators(c handlers.Context) (any, error) {\n\treq, err := utils.BindAndValidate[beacontypes.PostStateValidatorsRequest](\n\t\tc, h.Logger(),\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\theight, err := utils.StateIDToHeight(req.StateID, h.backend)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfilteredVals, err := h.FilterValidators(height, req.IDs, req.Statuses)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to filter validators: %w\", err)\n\t}\n\treturn beacontypes.NewResponse(filteredVals), nil\n}\n\nfunc (h *Handler) GetStateValidator(c handlers.Context) (any, error) {\n\treq, err := utils.BindAndValidate[beacontypes.GetStateValidatorRequest](\n\t\tc, h.Logger(),\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\theight, err := utils.StateIDToHeight(req.StateID, h.backend)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvalData, err := h.getValidator(height, req.ValidatorID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn beacontypes.NewResponse(valData), err\n}\n\n// getValidator contains all the logic of the GetStateValidator api\n// that is not related to http stuff. Consider exporting it if needed\nfunc (h *Handler) getValidator(height int64, validatorID string) (*beacontypes.ValidatorData, error) {\n\tst, resolvedSlot, err := h.backend.StateAndSlotFromHeight(height)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get state from height %d: %w\", height, err)\n\t}\n\n\t// retrieve validator data\n\tindex, err := validatorIndexByID(st, validatorID)\n\tif err != nil {\n\t\tif errors.Is(err, collections.ErrNotFound) {\n\t\t\t// this should happen when validatorID is an unknown pub key\n\t\t\treturn nil, fmt.Errorf(\"%s: %w\", err.Error(), types.ErrNotFound)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"failed to get validator index by id %s: %w\", validatorID, err)\n\t}\n\n\tvalidator, err := st.ValidatorByIndex(index)\n\tif err != nil {\n\t\t// this should happen when validatorID is an unknown index\n\t\tif errors.Is(err, collections.ErrNotFound) {\n\t\t\treturn nil, fmt.Errorf(\"%s: %w\", err.Error(), types.ErrNotFound)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"failed to get validator by index %s: %w\", validatorID, err)\n\t}\n\n\tbalance, err := st.GetBalance(index)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"failed to get validator balance for validator pubkey %s and index %d: %w\",\n\t\t\tvalidator.GetPubkey(),\n\t\t\tindex,\n\t\t\terr,\n\t\t)\n\t}\n\tstatus, err := validator.Status(h.cs.SlotToEpoch(resolvedSlot))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get validator status for validator pubkey %s and index %d: %w\", validator.GetPubkey(), index, err)\n\t}\n\treturn &beacontypes.ValidatorData{\n\t\tValidatorBalanceData: beacontypes.ValidatorBalanceData{\n\t\t\tIndex:   index.Unwrap(),\n\t\t\tBalance: balance.Unwrap(),\n\t\t},\n\t\tStatus:    status,\n\t\tValidator: beacontypes.ValidatorFromConsensus(validator),\n\t}, nil\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/validators_balances.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacon\n\nimport (\n\t\"fmt\"\n\n\t\"cosmossdk.io/collections\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/node-api/backend\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\tbeacontypes \"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\nfunc (h *Handler) GetStateValidatorBalances(c handlers.Context) (any, error) {\n\treq, err := utils.BindAndValidate[beacontypes.GetValidatorBalancesRequest](\n\t\tc, h.Logger(),\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\theight, err := utils.StateIDToHeight(req.StateID, h.backend)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tbalances, err := h.getValidatorBalance(height, req.IDs)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn beacontypes.NewResponse(balances), nil\n}\n\nfunc (h *Handler) PostStateValidatorBalances(c handlers.Context) (any, error) {\n\tvar ids []string\n\tif err := c.Bind(&ids); err != nil {\n\t\treturn nil, fmt.Errorf(\"%s: %w\", err.Error(), types.ErrInvalidRequest)\n\t}\n\t// Get state_id from URL path parameter\n\treq := beacontypes.PostValidatorBalancesRequest{\n\t\tStateIDRequest: types.StateIDRequest{StateID: c.Param(\"state_id\")},\n\t\tIDs:            ids,\n\t}\n\n\tif err := c.Validate(&req); err != nil {\n\t\treturn nil, types.ErrInvalidRequest\n\t}\n\n\theight, err := utils.StateIDToHeight(req.StateID, h.backend)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tbalances, err := h.getValidatorBalance(height, req.IDs)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn beacontypes.NewResponse(balances), nil\n}\n\nfunc (h *Handler) getValidatorBalance(height int64, validatorIDs []string) ([]*beacontypes.ValidatorBalanceData, error) {\n\tst, _, err := h.backend.StateAndSlotFromHeight(height)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get state from height %d: %w\", height, err)\n\t}\n\n\t// If no IDs provided, return all validator balances\n\tif len(validatorIDs) == 0 {\n\t\trawBalances, errInBalances := st.GetBalances()\n\t\tif errInBalances != nil {\n\t\t\treturn nil, errInBalances\n\t\t}\n\t\t// Convert []uint64 to []*ValidatorBalanceData as per the API spec\n\t\tbalances := make([]*beacontypes.ValidatorBalanceData, len(rawBalances))\n\t\tfor i, balance := range rawBalances {\n\t\t\tbalances[i] = &beacontypes.ValidatorBalanceData{\n\t\t\t\tIndex:   uint64(i), // #nosec:G115 // Safe as i comes from range loop\n\t\t\t\tBalance: balance,\n\t\t\t}\n\t\t}\n\t\treturn balances, nil\n\t}\n\n\tvar (\n\t\tbalances = make([]*beacontypes.ValidatorBalanceData, 0, len(validatorIDs))\n\t\tindex    math.U64\n\t)\n\tfor _, id := range validatorIDs {\n\t\tindex, err = validatorIndexByID(st, id)\n\t\tswitch {\n\t\tcase err == nil:\n\t\t\t// nothing to do, keep processing\n\t\tcase errors.Is(err, collections.ErrNotFound):\n\t\t\t// If public key as id is not found in the state\n\t\t\t// we simply skip the index.\n\t\t\tcontinue\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"failed to get validator index by id %s: %w\", id, err)\n\t\t}\n\n\t\tvar balance math.U64\n\t\tswitch balance, err = st.GetBalance(index); {\n\t\tcase err == nil:\n\t\t\tbalances = append(balances, &beacontypes.ValidatorBalanceData{\n\t\t\t\tIndex:   index.Unwrap(),\n\t\t\t\tBalance: balance.Unwrap(),\n\t\t\t})\n\t\tcase errors.Is(err, collections.ErrNotFound):\n\t\t\t// if index does not exist and GetBalance returns\n\t\t\t// \"collections: not found\" we simply skip the index.\n\t\t\tcontinue\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"failed to get validator balance for validator index %d: %w\", index, err)\n\t\t}\n\t}\n\treturn balances, nil\n}\n\n// ValidatorIndexByID parses a validator index from a string.\n// The string can be either a validator index or a validator pubkey.\nfunc validatorIndexByID(st backend.ReadOnlyBeaconState, keyOrIndex string) (math.U64, error) {\n\tindex, err := math.U64FromString(keyOrIndex)\n\tif err == nil {\n\t\treturn index, nil\n\t}\n\tvar key crypto.BLSPubkey\n\tif err = key.UnmarshalText([]byte(keyOrIndex)); err != nil {\n\t\treturn math.U64(0), err\n\t}\n\treturn st.ValidatorIndexByPubkey(key)\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/validators_balances_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacon_test\n\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"strconv\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/log/noop\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/beacon\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/beacon/mocks\"\n\tbeacontypes \"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\thandlertypes \"github.com/berachain/beacon-kit/node-api/handlers/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n\t\"github.com/berachain/beacon-kit/node-api/middleware\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/labstack/echo/v4\"\n\t\"github.com/stretchr/testify/mock\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestGetStateValidatorBalances(t *testing.T) {\n\tt.Parallel()\n\n\tcs, errSpec := spec.MainnetChainSpec()\n\trequire.NoError(t, errSpec)\n\n\t// Create some input validators and store them to a readonly state\n\tstateValidators := createStateValidators(cs)\n\n\ttestCases := []struct {\n\t\tname                string\n\t\tinputs              func() (beacontypes.GetValidatorBalancesRequest, beacontypes.PostValidatorBalancesRequest)\n\t\tsetMockExpectations func(*mocks.Backend)\n\t\tcheck               func(t *testing.T, res any, err error)\n\t}{\n\t\t{\n\t\t\tname: \"all validators\",\n\t\t\tinputs: func() (beacontypes.GetValidatorBalancesRequest, beacontypes.PostValidatorBalancesRequest) {\n\t\t\t\tstateID := utils.StateIDHead\n\t\t\t\tIDs := []string(nil)\n\t\t\t\treturn beacontypes.GetValidatorBalancesRequest{\n\t\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\t\tStateID: stateID,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tIDs: IDs,\n\t\t\t\t\t}, beacontypes.PostValidatorBalancesRequest{\n\t\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\t\tStateID: stateID,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tIDs: IDs,\n\t\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tst := makeTestState(t, cs)\n\t\t\t\taddTestValidators(t, stateValidators, st)\n\n\t\t\t\t// slot is not really tested here, we just return zero\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, math.Slot(0), nil)\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, beacontypes.GenericResponse{}, res)\n\t\t\t\tgr, _ := res.(beacontypes.GenericResponse)\n\t\t\t\trequire.IsType(t, []*beacontypes.ValidatorBalanceData{}, gr.Data)\n\t\t\t\tdata, _ := gr.Data.([]*beacontypes.ValidatorBalanceData)\n\n\t\t\t\texpectedBalances := make([]*beacontypes.ValidatorBalanceData, 0, len(stateValidators))\n\t\t\t\tfor _, val := range stateValidators {\n\t\t\t\t\texpectedBalances = append(expectedBalances,\n\t\t\t\t\t\t&beacontypes.ValidatorBalanceData{\n\t\t\t\t\t\t\tIndex:   val.Index,\n\t\t\t\t\t\t\tBalance: val.Balance,\n\t\t\t\t\t\t},\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\trequire.Equal(t, expectedBalances, data)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"single validators\",\n\t\t\tinputs: func() (beacontypes.GetValidatorBalancesRequest, beacontypes.PostValidatorBalancesRequest) {\n\t\t\t\tstateID := utils.StateIDHead\n\t\t\t\tIDs := []string{\n\t\t\t\t\tstateValidators[0].Validator.PublicKey,\n\t\t\t\t\tstateValidators[1].Validator.PublicKey,\n\t\t\t\t}\n\t\t\t\treturn beacontypes.GetValidatorBalancesRequest{\n\t\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\t\tStateID: stateID,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tIDs: IDs,\n\t\t\t\t\t}, beacontypes.PostValidatorBalancesRequest{\n\t\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\t\tStateID: stateID,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tIDs: IDs,\n\t\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tst := makeTestState(t, cs)\n\t\t\t\taddTestValidators(t, stateValidators, st)\n\n\t\t\t\t// slot is not really tested here, we just return zero\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, math.Slot(0), nil)\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, beacontypes.GenericResponse{}, res)\n\t\t\t\tgr, _ := res.(beacontypes.GenericResponse)\n\t\t\t\trequire.IsType(t, []*beacontypes.ValidatorBalanceData{}, gr.Data)\n\t\t\t\tdata, _ := gr.Data.([]*beacontypes.ValidatorBalanceData)\n\n\t\t\t\texpectedBalances := []*beacontypes.ValidatorBalanceData{\n\t\t\t\t\t{\n\t\t\t\t\t\tIndex:   stateValidators[0].Index,\n\t\t\t\t\t\tBalance: stateValidators[0].Balance,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tIndex:   stateValidators[1].Index,\n\t\t\t\t\t\tBalance: stateValidators[1].Balance,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t\trequire.Equal(t, expectedBalances, data)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"mixed know and unknow validators\",\n\t\t\tinputs: func() (beacontypes.GetValidatorBalancesRequest, beacontypes.PostValidatorBalancesRequest) {\n\t\t\t\tstateID := utils.StateIDHead\n\t\t\t\tunknownValPk := bytes.B48{0xff, 0xff}\n\t\t\t\tunknownValIdx := strconv.Itoa(2025)\n\t\t\t\tIDs := []string{\n\t\t\t\t\tunknownValIdx,\n\t\t\t\t\tstateValidators[0].Validator.PublicKey,\n\t\t\t\t\tunknownValPk.String(),\n\t\t\t\t}\n\t\t\t\treturn beacontypes.GetValidatorBalancesRequest{\n\t\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\t\tStateID: stateID,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tIDs: IDs,\n\t\t\t\t\t}, beacontypes.PostValidatorBalancesRequest{\n\t\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\t\tStateID: stateID,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tIDs: IDs,\n\t\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tst := makeTestState(t, cs)\n\t\t\t\taddTestValidators(t, stateValidators, st)\n\n\t\t\t\t// slot is not really tested here, we just return zero\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, math.Slot(0), nil)\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, beacontypes.GenericResponse{}, res)\n\t\t\t\tgr, _ := res.(beacontypes.GenericResponse)\n\t\t\t\trequire.IsType(t, []*beacontypes.ValidatorBalanceData{}, gr.Data)\n\t\t\t\tdata, _ := gr.Data.([]*beacontypes.ValidatorBalanceData)\n\n\t\t\t\texpectedBalances := []*beacontypes.ValidatorBalanceData{\n\t\t\t\t\t{\n\t\t\t\t\t\tIndex:   stateValidators[0].Index,\n\t\t\t\t\t\tBalance: stateValidators[0].Balance,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t\trequire.Equal(t, expectedBalances, data)\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\t// setup test\n\t\t\tbackend := mocks.NewBackend(t)\n\t\t\th := beacon.NewHandler(backend, cs, noop.NewLogger[log.Logger]())\n\t\t\te := echo.New()\n\t\t\te.Validator = &middleware.CustomValidator{\n\t\t\t\tValidator: middleware.ConstructValidator(),\n\t\t\t}\n\n\t\t\t// set expectations\n\t\t\ttc.setMockExpectations(backend)\n\n\t\t\tinputGet, inputPost := tc.inputs()\n\n\t\t\t{ // Test Get method\n\t\t\t\tinputBytes, err := json.Marshal(inputGet) //nolint:musttag //  TODO:fix\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tbody := strings.NewReader(string(inputBytes))\n\t\t\t\treq := httptest.NewRequest(http.MethodGet, \"/\", body)\n\t\t\t\treq.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) // otherwise code=415, message=Unsupported Media Type\n\t\t\t\tc := e.NewContext(req, httptest.NewRecorder())\n\n\t\t\t\t// test Get\n\t\t\t\tres, err := h.GetStateValidatorBalances(c)\n\n\t\t\t\t// check Get\n\t\t\t\ttc.check(t, res, err)\n\t\t\t}\n\n\t\t\t{ // Test Post method\n\t\t\t\t// Marshal only the IDs array for the POST body\n\t\t\t\tinputBytes, err := json.Marshal(inputPost.IDs)\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tbody := strings.NewReader(string(inputBytes))\n\t\t\t\treq := httptest.NewRequest(http.MethodPost, \"/\", body)\n\t\t\t\treq.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) // otherwise code=415, message=Unsupported Media Type\n\t\t\t\tc := e.NewContext(req, httptest.NewRecorder())\n\n\t\t\t\t// Set the state_id as a URL path parameter\n\t\t\t\tc.SetParamNames(\"state_id\")\n\t\t\t\tc.SetParamValues(inputPost.StateID)\n\n\t\t\t\t// test Post\n\t\t\t\tres, err := h.PostStateValidatorBalances(c)\n\n\t\t\t\t// check Post\n\t\t\t\ttc.check(t, res, err)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/validators_filters.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacon\n\nimport (\n\t\"fmt\"\n\t\"slices\"\n\n\tconsensustypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tcometbft \"github.com/berachain/beacon-kit/consensus/cometbft/service\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/node-api/backend\"\n\tbeacontypes \"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\thandlertypes \"github.com/berachain/beacon-kit/node-api/handlers/types\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tsdkerrors \"github.com/cosmos/cosmos-sdk/types/errors\"\n)\n\n// errStatusFilterMismatch is an error for when a validator status does not\n// match the status filter.\nvar errStatusFilterMismatch = errors.New(\"validator status does not match status filter\")\n\n// FilterValidators is a helper function to provide implementation\n// consistency between GetStateValidators and PostStateValidators, since they\n// are intended to behave the same way.\nfunc (h *Handler) FilterValidators(height int64, ids []string, statuses []string) ([]*beacontypes.ValidatorData, error) {\n\tst, resolvedSlot, err := h.backend.StateAndSlotFromHeight(height)\n\tif err != nil {\n\t\tif errors.Is(err, cometbft.ErrAppNotReady) {\n\t\t\t// chain not ready, like when genesis time is set in the future\n\t\t\treturn nil, handlertypes.ErrNotFound\n\t\t}\n\t\tif errors.Is(err, sdkerrors.ErrInvalidHeight) {\n\t\t\t// height requested too high\n\t\t\treturn nil, handlertypes.ErrNotFound\n\t\t}\n\t\treturn nil, fmt.Errorf(\"failed to get state from height %d: %w\", height, err)\n\t}\n\n\tallVals, err := st.GetValidators()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get validators: %w\", err)\n\t}\n\n\t// Parse all IDs and pubkeys once at the start\n\tfilters := parseValidatorIDs(ids)\n\tepoch := h.cs.SlotToEpoch(resolvedSlot)\n\n\treturn filterAndBuildValidatorData(st, allVals, filters, epoch, statuses)\n}\n\ntype validatorFilters struct {\n\tindexes []uint64\n\tpubkeys []crypto.BLSPubkey\n}\n\n// parseID attempts to parse a single ID as either a numeric ID or pubkey\nfunc (f *validatorFilters) parseID(id string) {\n\t// Try parsing as numeric ID first\n\tif index, err := math.U64FromString(id); err == nil {\n\t\tf.indexes = append(f.indexes, index.Unwrap())\n\t\treturn\n\t}\n\n\t// Try parsing as pubkey\n\tvar pubkey crypto.BLSPubkey\n\tif err := pubkey.UnmarshalText([]byte(id)); err == nil {\n\t\tf.pubkeys = append(f.pubkeys, pubkey)\n\t}\n\t// We can skip errors here, since they should not happen.\n\t// We do validate these ids in ValidateValidatorID.\n}\n\n// parseValidatorIDs parses a slice of string IDs into numeric IDs and pubkeys\nfunc parseValidatorIDs(ids []string) *validatorFilters {\n\tfilters := &validatorFilters{\n\t\tindexes: make([]uint64, 0, len(ids)),\n\t\tpubkeys: make([]crypto.BLSPubkey, 0, len(ids)),\n\t}\n\n\tfor _, id := range ids {\n\t\tfilters.parseID(id)\n\t}\n\n\treturn filters\n}\n\n// filterAndBuildValidatorData processes all validators and builds their data based on filters\nfunc filterAndBuildValidatorData(\n\tst backend.ReadOnlyBeaconState,\n\tvalidators []*consensustypes.Validator,\n\tfilters *validatorFilters,\n\tepoch math.Epoch,\n\tstatuses []string,\n) ([]*beacontypes.ValidatorData, error) {\n\tvalidatorData := make([]*beacontypes.ValidatorData, 0, len(validators))\n\n\tfor _, validator := range validators {\n\t\tindex, err := st.ValidatorIndexByPubkey(validator.GetPubkey())\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrapf(err, \"failed to get validator index by pubkey %s\", validator.GetPubkey())\n\t\t}\n\n\t\tif !matchesFilters(validator, index, filters) {\n\t\t\tcontinue\n\t\t}\n\n\t\tdata, err := buildValidatorData(st, validator, index, epoch, statuses)\n\t\tswitch {\n\t\tcase err == nil:\n\t\t\tvalidatorData = append(validatorData, data)\n\t\tcase errors.Is(err, errStatusFilterMismatch):\n\t\t\tcontinue\n\t\tdefault:\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn validatorData, nil\n}\n\n// matchesFilters checks if a validator matches the filters.\nfunc matchesFilters(validator *consensustypes.Validator, index math.U64, filters *validatorFilters) bool {\n\t// If no filters, accept all validators\n\tif len(filters.indexes) == 0 && len(filters.pubkeys) == 0 {\n\t\treturn true\n\t}\n\n\t// Check numeric IDs\n\tif len(filters.indexes) > 0 && matchesIndex(index, filters.indexes) {\n\t\treturn true\n\t}\n\n\t// Check pubkeys\n\tif len(filters.pubkeys) > 0 && matchesPubkey(validator, filters.pubkeys) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc matchesPubkey(validator *consensustypes.Validator, parsedPubkeys []crypto.BLSPubkey) bool {\n\tvalidatorPubkey := validator.GetPubkey()\n\treturn slices.Contains(parsedPubkeys, validatorPubkey)\n}\n\nfunc matchesIndex(index math.U64, ids []uint64) bool {\n\treturn slices.Contains(ids, index.Unwrap())\n}\n\nfunc matchesStatusFilter(status string, statuses []string) bool {\n\treturn len(statuses) == 0 || slices.Contains(statuses, status)\n}\n\nfunc buildValidatorData(\n\tst backend.ReadOnlyBeaconState,\n\tvalidator *consensustypes.Validator,\n\tindex math.U64,\n\tepoch math.Epoch,\n\tstatuses []string,\n) (*beacontypes.ValidatorData, error) {\n\tstatus, err := validator.Status(epoch)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"failed to get validator status for validator pubkey %s and index %d\", validator.GetPubkey(), index)\n\t}\n\n\tif !matchesStatusFilter(status, statuses) {\n\t\treturn nil, errStatusFilterMismatch\n\t}\n\n\tbalance, err := st.GetBalance(index)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"failed to get validator balance for validator pubkey %s and index %d\", validator.GetPubkey(), index)\n\t}\n\n\treturn &beacontypes.ValidatorData{\n\t\tValidatorBalanceData: beacontypes.ValidatorBalanceData{\n\t\t\tIndex:   index.Unwrap(),\n\t\t\tBalance: balance.Unwrap(),\n\t\t},\n\t\tStatus:    status,\n\t\tValidator: beacontypes.ValidatorFromConsensus(validator),\n\t}, nil\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/validators_filters_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacon_test\n\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"strconv\"\n\t\"strings\"\n\t\"testing\"\n\n\tcosmoslog \"cosmossdk.io/log\"\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tcometbft \"github.com/berachain/beacon-kit/consensus/cometbft/service\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/log/noop\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/beacon\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/beacon/mocks\"\n\tbeacontypes \"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\thandlertypes \"github.com/berachain/beacon-kit/node-api/handlers/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n\t\"github.com/berachain/beacon-kit/node-api/middleware\"\n\t\"github.com/berachain/beacon-kit/node-core/components/metrics\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n\tstatetransition \"github.com/berachain/beacon-kit/testing/state-transition\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n\tsdkerrors \"github.com/cosmos/cosmos-sdk/types/errors\"\n\t\"github.com/labstack/echo/v4\"\n\t\"github.com/stretchr/testify/mock\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n//nolint:maintidx // Testing multiple scenarios for Get and Post api in parallel\nfunc TestFilterValidators(t *testing.T) {\n\tt.Parallel()\n\n\tcs, errSpec := spec.MainnetChainSpec()\n\trequire.NoError(t, errSpec)\n\n\t// Create some input validators and store them to a readonly state\n\tstateValidators := createStateValidators(cs)\n\n\ttestCases := []struct {\n\t\tname                string\n\t\tinputs              func() (beacontypes.GetStateValidatorsRequest, beacontypes.PostStateValidatorsRequest)\n\t\tsetMockExpectations func(*mocks.Backend)\n\t\tcheck               func(t *testing.T, res any, err error)\n\t}{\n\t\t{\n\t\t\tname: \"all validators\",\n\t\t\tinputs: func() (beacontypes.GetStateValidatorsRequest, beacontypes.PostStateValidatorsRequest) {\n\t\t\t\tstateID := utils.StateIDHead\n\t\t\t\treturn beacontypes.GetStateValidatorsRequest{\n\t\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\t\tStateID: stateID,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, beacontypes.PostStateValidatorsRequest{\n\t\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\t\tStateID: stateID,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tst := makeTestState(t, cs)\n\t\t\t\taddTestValidators(t, stateValidators, st)\n\n\t\t\t\t// slot is not really tested here, we just return zero\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, math.Slot(0), nil)\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, beacontypes.GenericResponse{}, res)\n\t\t\t\tgr, _ := res.(beacontypes.GenericResponse)\n\t\t\t\trequire.IsType(t, []*beacontypes.ValidatorData{}, gr.Data)\n\t\t\t\tdata, _ := gr.Data.([]*beacontypes.ValidatorData)\n\n\t\t\t\trequire.Len(t, data, len(stateValidators))\n\t\t\t\tfor i := range data {\n\t\t\t\t\trequire.Equal(t, stateValidators[i], data[i], \"index %d\", i)\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"some validators by indexes\",\n\t\t\tinputs: func() (beacontypes.GetStateValidatorsRequest, beacontypes.PostStateValidatorsRequest) {\n\t\t\t\tstateID := utils.StateIDHead\n\t\t\t\tIDs := []string{\"1\", \"3\"}\n\t\t\t\treturn beacontypes.GetStateValidatorsRequest{\n\t\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\t\tStateID: stateID,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tIDs:      IDs,\n\t\t\t\t\t\tStatuses: nil,\n\t\t\t\t\t}, beacontypes.PostStateValidatorsRequest{\n\t\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\t\tStateID: utils.StateIDHead,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tIDs:      IDs,\n\t\t\t\t\t\tStatuses: nil,\n\t\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tst := makeTestState(t, cs)\n\t\t\t\taddTestValidators(t, stateValidators, st)\n\n\t\t\t\t// slot is not really tested here, we just return zero\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, math.Slot(0), nil)\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, beacontypes.GenericResponse{}, res)\n\t\t\t\tgr, _ := res.(beacontypes.GenericResponse)\n\t\t\t\trequire.IsType(t, []*beacontypes.ValidatorData{}, gr.Data)\n\t\t\t\tdata, _ := gr.Data.([]*beacontypes.ValidatorData)\n\n\t\t\t\texpectedRes := []*beacontypes.ValidatorData{\n\t\t\t\t\tstateValidators[1],\n\t\t\t\t\tstateValidators[3],\n\t\t\t\t}\n\t\t\t\trequire.Len(t, data, len(expectedRes))\n\t\t\t\tfor i := range data {\n\t\t\t\t\trequire.Equal(t, expectedRes[i], data[i], \"index %d\", i)\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"some validators by pub keys\",\n\t\t\tinputs: func() (beacontypes.GetStateValidatorsRequest, beacontypes.PostStateValidatorsRequest) {\n\t\t\t\tstateID := utils.StateIDHead\n\t\t\t\tIDs := []string{\n\t\t\t\t\tstateValidators[2].Validator.PublicKey,\n\t\t\t\t\tstateValidators[4].Validator.PublicKey,\n\t\t\t\t}\n\t\t\t\treturn beacontypes.GetStateValidatorsRequest{\n\t\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\t\tStateID: stateID,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tIDs: IDs,\n\t\t\t\t\t}, beacontypes.PostStateValidatorsRequest{\n\t\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\t\tStateID: utils.StateIDHead,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tIDs: IDs,\n\t\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tst := makeTestState(t, cs)\n\t\t\t\taddTestValidators(t, stateValidators, st)\n\n\t\t\t\t// slot is not really tested here, we just return zero\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, math.Slot(0), nil)\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, beacontypes.GenericResponse{}, res)\n\t\t\t\tgr, _ := res.(beacontypes.GenericResponse)\n\t\t\t\trequire.IsType(t, []*beacontypes.ValidatorData{}, gr.Data)\n\t\t\t\tdata, _ := gr.Data.([]*beacontypes.ValidatorData)\n\n\t\t\t\texpectedRes := []*beacontypes.ValidatorData{\n\t\t\t\t\tstateValidators[2],\n\t\t\t\t\tstateValidators[4],\n\t\t\t\t}\n\t\t\t\trequire.Len(t, data, len(expectedRes))\n\t\t\t\tfor i := range data {\n\t\t\t\t\trequire.Equal(t, expectedRes[i], data[i], \"index %d\", i)\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"some validators by status\",\n\t\t\tinputs: func() (beacontypes.GetStateValidatorsRequest, beacontypes.PostStateValidatorsRequest) {\n\t\t\t\tstateID := utils.StateIDHead\n\t\t\t\tstatuses := []string{\n\t\t\t\t\tconstants.ValidatorStatusActiveOngoing,\n\t\t\t\t\tconstants.ValidatorStatusActiveSlashed,\n\t\t\t\t\tconstants.ValidatorStatusActiveExiting,\n\t\t\t\t}\n\t\t\t\treturn beacontypes.GetStateValidatorsRequest{\n\t\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\t\tStateID: stateID,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tStatuses: statuses,\n\t\t\t\t\t}, beacontypes.PostStateValidatorsRequest{\n\t\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\t\tStateID: stateID,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tStatuses: statuses,\n\t\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tst := makeTestState(t, cs)\n\t\t\t\taddTestValidators(t, stateValidators, st)\n\n\t\t\t\t// slot is not really tested here, we just return zero\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, math.Slot(0), nil)\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, beacontypes.GenericResponse{}, res)\n\t\t\t\tgr, _ := res.(beacontypes.GenericResponse)\n\t\t\t\trequire.IsType(t, []*beacontypes.ValidatorData{}, gr.Data)\n\t\t\t\tdata, _ := gr.Data.([]*beacontypes.ValidatorData)\n\n\t\t\t\texpectedRes := []*beacontypes.ValidatorData{\n\t\t\t\t\tstateValidators[2],\n\t\t\t\t\tstateValidators[3],\n\t\t\t\t\tstateValidators[4],\n\t\t\t\t}\n\n\t\t\t\trequire.Len(t, data, len(expectedRes))\n\t\t\t\tfor i := range data {\n\t\t\t\t\trequire.Equal(t, expectedRes[i], data[i], \"index %d\", i)\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"chain not ready\",\n\t\t\tinputs: func() (beacontypes.GetStateValidatorsRequest, beacontypes.PostStateValidatorsRequest) {\n\t\t\t\tstateID := utils.StateIDHead\n\t\t\t\treturn beacontypes.GetStateValidatorsRequest{\n\t\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\t\tStateID: stateID,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, beacontypes.PostStateValidatorsRequest{\n\t\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\t\tStateID: stateID,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\t// cometbft.ErrAppNotReady is the error flag returned when\n\t\t\t\t// genesis has not yet been processed and chain is not ready.\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(nil, math.Slot(0), cometbft.ErrAppNotReady)\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\t// handlertypes.ErrNotFound is the error flag used to return 404 error code\n\t\t\t\trequire.ErrorIs(t, err, handlertypes.ErrNotFound)\n\t\t\t\trequire.Nil(t, res)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"height requested too high\",\n\t\t\tinputs: func() (beacontypes.GetStateValidatorsRequest, beacontypes.PostStateValidatorsRequest) {\n\t\t\t\tunknownStateID := strconv.Itoa(2025)\n\t\t\t\treturn beacontypes.GetStateValidatorsRequest{\n\t\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\t\tStateID: unknownStateID,\n\t\t\t\t\t\t},\n\t\t\t\t\t}, beacontypes.PostStateValidatorsRequest{\n\t\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\t\tStateID: unknownStateID,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\t// sdkerrors.ErrInvalidHeight is the error flag returned when\n\t\t\t\t// requested height is not in the state.\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(nil, math.Slot(0), sdkerrors.ErrInvalidHeight)\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\t// handlertypes.ErrNotFound is the error flag used to return 404 error code\n\t\t\t\trequire.ErrorIs(t, err, handlertypes.ErrNotFound)\n\t\t\t\trequire.Nil(t, res)\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\t// setup test\n\t\t\tbackend := mocks.NewBackend(t)\n\t\t\th := beacon.NewHandler(backend, cs, noop.NewLogger[log.Logger]())\n\t\t\te := echo.New()\n\t\t\te.Validator = &middleware.CustomValidator{\n\t\t\t\tValidator: middleware.ConstructValidator(),\n\t\t\t}\n\n\t\t\t// set expectations\n\t\t\ttc.setMockExpectations(backend)\n\n\t\t\tinputGet, inputPost := tc.inputs()\n\n\t\t\t{ // Test Get method\n\t\t\t\tinputBytes, err := json.Marshal(inputGet) //nolint:musttag //  TODO:fix\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tbody := strings.NewReader(string(inputBytes))\n\t\t\t\treq := httptest.NewRequest(http.MethodGet, \"/\", body)\n\t\t\t\treq.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) // otherwise code=415, message=Unsupported Media Type\n\t\t\t\tc := e.NewContext(req, httptest.NewRecorder())\n\n\t\t\t\t// test Get\n\t\t\t\tres, err := h.GetStateValidators(c)\n\n\t\t\t\t// check Get\n\t\t\t\ttc.check(t, res, err)\n\t\t\t}\n\n\t\t\t{ // Test Post method\n\t\t\t\t// create Post inputs\n\t\t\t\tinputBytes, err := json.Marshal(inputPost) //nolint:musttag //  TODO:fix\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\tbody := strings.NewReader(string(inputBytes))\n\t\t\t\treq := httptest.NewRequest(http.MethodPost, \"/\", body)\n\t\t\t\treq.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) // otherwise code=415, message=Unsupported Media Type\n\t\t\t\tc := e.NewContext(req, httptest.NewRecorder())\n\n\t\t\t\t// test Post\n\t\t\t\tres, err := h.PostStateValidators(c)\n\n\t\t\t\t// check Post\n\t\t\t\ttc.check(t, res, err)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc createStateValidators(cs chain.Spec) []*beacontypes.ValidatorData {\n\treturn []*beacontypes.ValidatorData{\n\t\t{\n\t\t\tValidatorBalanceData: beacontypes.ValidatorBalanceData{\n\t\t\t\tIndex:   0,\n\t\t\t\tBalance: cs.MaxEffectiveBalance().Unwrap(),\n\t\t\t},\n\t\t\tStatus: constants.ValidatorStatusPendingInitialized,\n\t\t\tValidator: beacontypes.ValidatorFromConsensus(\n\t\t\t\t&ctypes.Validator{\n\t\t\t\t\tPubkey:                     [48]byte{0x01},\n\t\t\t\t\tWithdrawalCredentials:      [32]byte{0x02},\n\t\t\t\t\tEffectiveBalance:           cs.MaxEffectiveBalance(),\n\t\t\t\t\tSlashed:                    false,\n\t\t\t\t\tActivationEligibilityEpoch: constants.FarFutureEpoch,\n\t\t\t\t\tActivationEpoch:            constants.FarFutureEpoch,\n\t\t\t\t\tExitEpoch:                  constants.FarFutureEpoch,\n\t\t\t\t\tWithdrawableEpoch:          constants.FarFutureEpoch,\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tValidatorBalanceData: beacontypes.ValidatorBalanceData{\n\t\t\t\tIndex:   1,\n\t\t\t\tBalance: cs.MaxEffectiveBalance().Unwrap() * 3 / 4,\n\t\t\t},\n\t\t\tStatus: constants.ValidatorStatusPendingQueued,\n\t\t\tValidator: beacontypes.ValidatorFromConsensus(\n\t\t\t\t&ctypes.Validator{\n\t\t\t\t\tPubkey:                     [48]byte{0x03},\n\t\t\t\t\tWithdrawalCredentials:      [32]byte{0x04},\n\t\t\t\t\tEffectiveBalance:           cs.MaxEffectiveBalance() / 2,\n\t\t\t\t\tSlashed:                    false,\n\t\t\t\t\tActivationEligibilityEpoch: math.Epoch(0),\n\t\t\t\t\tActivationEpoch:            constants.FarFutureEpoch,\n\t\t\t\t\tExitEpoch:                  constants.FarFutureEpoch,\n\t\t\t\t\tWithdrawableEpoch:          constants.FarFutureEpoch,\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tValidatorBalanceData: beacontypes.ValidatorBalanceData{\n\t\t\t\tIndex:   2,\n\t\t\t\tBalance: cs.MaxEffectiveBalance().Unwrap() / 4,\n\t\t\t},\n\t\t\tStatus: constants.ValidatorStatusActiveOngoing,\n\t\t\tValidator: beacontypes.ValidatorFromConsensus(\n\t\t\t\t&ctypes.Validator{\n\t\t\t\t\tPubkey:                     [48]byte{0x05},\n\t\t\t\t\tWithdrawalCredentials:      [32]byte{0x06},\n\t\t\t\t\tEffectiveBalance:           cs.MaxEffectiveBalance() / 3,\n\t\t\t\t\tSlashed:                    false,\n\t\t\t\t\tActivationEligibilityEpoch: math.Epoch(0),\n\t\t\t\t\tActivationEpoch:            math.Epoch(0),\n\t\t\t\t\tExitEpoch:                  constants.FarFutureEpoch,\n\t\t\t\t\tWithdrawableEpoch:          constants.FarFutureEpoch,\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tValidatorBalanceData: beacontypes.ValidatorBalanceData{\n\t\t\t\tIndex:   3,\n\t\t\t\tBalance: cs.MaxEffectiveBalance().Unwrap() / 4,\n\t\t\t},\n\t\t\tStatus: constants.ValidatorStatusActiveSlashed,\n\t\t\tValidator: beacontypes.ValidatorFromConsensus(\n\t\t\t\t&ctypes.Validator{\n\t\t\t\t\tPubkey:                     [48]byte{0x15},\n\t\t\t\t\tWithdrawalCredentials:      [32]byte{0x16},\n\t\t\t\t\tEffectiveBalance:           cs.MaxEffectiveBalance() / 3,\n\t\t\t\t\tSlashed:                    true,\n\t\t\t\t\tActivationEligibilityEpoch: math.Epoch(0),\n\t\t\t\t\tActivationEpoch:            math.Epoch(0),\n\t\t\t\t\tExitEpoch:                  math.Epoch(5),\n\t\t\t\t\tWithdrawableEpoch:          constants.FarFutureEpoch,\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tValidatorBalanceData: beacontypes.ValidatorBalanceData{\n\t\t\t\tIndex:   4,\n\t\t\t\tBalance: cs.MaxEffectiveBalance().Unwrap() / 4,\n\t\t\t},\n\t\t\tStatus: constants.ValidatorStatusActiveExiting,\n\t\t\tValidator: beacontypes.ValidatorFromConsensus(\n\t\t\t\t&ctypes.Validator{\n\t\t\t\t\tPubkey:                     [48]byte{0x17},\n\t\t\t\t\tWithdrawalCredentials:      [32]byte{0x18},\n\t\t\t\t\tEffectiveBalance:           cs.MaxEffectiveBalance() / 3,\n\t\t\t\t\tSlashed:                    false,\n\t\t\t\t\tActivationEligibilityEpoch: math.Epoch(0),\n\t\t\t\t\tActivationEpoch:            math.Epoch(0),\n\t\t\t\t\tExitEpoch:                  math.Epoch(5),\n\t\t\t\t\tWithdrawableEpoch:          constants.FarFutureEpoch,\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tValidatorBalanceData: beacontypes.ValidatorBalanceData{\n\t\t\t\tIndex:   5,\n\t\t\t\tBalance: cs.MaxEffectiveBalance().Unwrap() / 2,\n\t\t\t},\n\t\t\tStatus: constants.ValidatorStatusExitedUnslashed,\n\t\t\tValidator: beacontypes.ValidatorFromConsensus(\n\t\t\t\t&ctypes.Validator{\n\t\t\t\t\tPubkey:                     [48]byte{0x07},\n\t\t\t\t\tWithdrawalCredentials:      [32]byte{0x08},\n\t\t\t\t\tEffectiveBalance:           cs.MaxEffectiveBalance() / 4,\n\t\t\t\t\tSlashed:                    false,\n\t\t\t\t\tActivationEligibilityEpoch: math.Epoch(0),\n\t\t\t\t\tActivationEpoch:            math.Epoch(0),\n\t\t\t\t\tExitEpoch:                  math.Epoch(0),\n\t\t\t\t\tWithdrawableEpoch:          constants.FarFutureEpoch,\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tValidatorBalanceData: beacontypes.ValidatorBalanceData{\n\t\t\t\tIndex:   6,\n\t\t\t\tBalance: cs.MaxEffectiveBalance().Unwrap() / 2,\n\t\t\t},\n\t\t\tStatus: constants.ValidatorStatusExitedSlashed,\n\t\t\tValidator: beacontypes.ValidatorFromConsensus(\n\t\t\t\t&ctypes.Validator{\n\t\t\t\t\tPubkey:                     [48]byte{0x27},\n\t\t\t\t\tWithdrawalCredentials:      [32]byte{0x28},\n\t\t\t\t\tEffectiveBalance:           cs.MaxEffectiveBalance() / 4,\n\t\t\t\t\tSlashed:                    true,\n\t\t\t\t\tActivationEligibilityEpoch: math.Epoch(0),\n\t\t\t\t\tActivationEpoch:            math.Epoch(0),\n\t\t\t\t\tExitEpoch:                  math.Epoch(0),\n\t\t\t\t\tWithdrawableEpoch:          constants.FarFutureEpoch,\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tValidatorBalanceData: beacontypes.ValidatorBalanceData{\n\t\t\t\tIndex:   7,\n\t\t\t\tBalance: cs.MinActivationBalance().Unwrap() - cs.EffectiveBalanceIncrement().Unwrap(),\n\t\t\t},\n\t\t\tStatus: constants.ValidatorStatusWithdrawalPossible,\n\t\t\tValidator: beacontypes.ValidatorFromConsensus(\n\t\t\t\t&ctypes.Validator{\n\t\t\t\t\tPubkey:                     [48]byte{0x09},\n\t\t\t\t\tWithdrawalCredentials:      [32]byte{0x10},\n\t\t\t\t\tEffectiveBalance:           cs.MaxEffectiveBalance() / 5,\n\t\t\t\t\tSlashed:                    false,\n\t\t\t\t\tActivationEligibilityEpoch: math.Epoch(0),\n\t\t\t\t\tActivationEpoch:            math.Epoch(0),\n\t\t\t\t\tExitEpoch:                  math.Epoch(0),\n\t\t\t\t\tWithdrawableEpoch:          math.Epoch(0),\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tValidatorBalanceData: beacontypes.ValidatorBalanceData{\n\t\t\t\tIndex:   8,\n\t\t\t\tBalance: 0,\n\t\t\t},\n\t\t\tStatus: constants.ValidatorStatusWithdrawalPossible,\n\t\t\tValidator: beacontypes.ValidatorFromConsensus(\n\t\t\t\t&ctypes.Validator{\n\t\t\t\t\tPubkey:                     [48]byte{0x39},\n\t\t\t\t\tWithdrawalCredentials:      [32]byte{0x40},\n\t\t\t\t\tEffectiveBalance:           cs.MaxEffectiveBalance() / 5,\n\t\t\t\t\tSlashed:                    false,\n\t\t\t\t\tActivationEligibilityEpoch: math.Epoch(0),\n\t\t\t\t\tActivationEpoch:            math.Epoch(0),\n\t\t\t\t\tExitEpoch:                  math.Epoch(0),\n\t\t\t\t\tWithdrawableEpoch:          math.Epoch(0),\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t}\n}\n\nfunc addTestValidators(t *testing.T, stateValidators []*beacontypes.ValidatorData, st *statedb.StateDB) {\n\tt.Helper()\n\n\tfor _, in := range stateValidators {\n\t\tval, errVal := beacontypes.ValidatorToConsensus(in.Validator)\n\t\trequire.NoError(t, errVal)\n\t\trequire.NoError(t, st.AddValidator(val))\n\n\t\trequire.NoError(t, st.SetBalance(math.ValidatorIndex(in.Index), math.Gwei(in.Balance)))\n\t}\n}\n\nfunc makeTestState(t *testing.T, cs chain.Spec) *statedb.StateDB {\n\tt.Helper()\n\n\tcms, kvStore, _, errSt := statetransition.BuildTestStores()\n\trequire.NoError(t, errSt)\n\tsdkCtx := sdk.NewContext(cms.CacheMultiStore(), true, cosmoslog.NewNopLogger())\n\tst := statedb.NewBeaconStateFromDB(\n\t\tkvStore.WithContext(sdkCtx), cs, sdkCtx.Logger(), metrics.NewNoOpTelemetrySink(),\n\t)\n\treturn st\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/validators_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacon_test\n\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"strconv\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/log/noop\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/beacon\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/beacon/mocks\"\n\tbeacontypes \"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\thandlertypes \"github.com/berachain/beacon-kit/node-api/handlers/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n\t\"github.com/berachain/beacon-kit/node-api/middleware\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/labstack/echo/v4\"\n\t\"github.com/stretchr/testify/mock\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestGetValidator(t *testing.T) {\n\tt.Parallel()\n\n\tcs, errSpec := spec.MainnetChainSpec()\n\trequire.NoError(t, errSpec)\n\n\t// Create some input validators and store them to a readonly state\n\tstateValidators := createStateValidators(cs)\n\n\ttestCases := []struct {\n\t\tname                string\n\t\tinputs              func() beacontypes.GetStateValidatorRequest\n\t\tsetMockExpectations func(*mocks.Backend)\n\t\tcheck               func(t *testing.T, res any, err error)\n\t}{\n\t\t{\n\t\t\tname: \"get existing validator\",\n\t\t\tinputs: func() beacontypes.GetStateValidatorRequest {\n\t\t\t\treturn beacontypes.GetStateValidatorRequest{\n\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\tStateID: utils.StateIDHead,\n\t\t\t\t\t},\n\t\t\t\t\tValidatorID: stateValidators[0].Validator.PublicKey,\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tst := makeTestState(t, cs)\n\t\t\t\taddTestValidators(t, stateValidators, st)\n\n\t\t\t\t// slot is not really tested here, we just return zero\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, math.Slot(0), nil)\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, beacontypes.GenericResponse{}, res)\n\t\t\t\tgr, _ := res.(beacontypes.GenericResponse)\n\t\t\t\trequire.IsType(t, &beacontypes.ValidatorData{}, gr.Data)\n\t\t\t\tdata, _ := gr.Data.(*beacontypes.ValidatorData)\n\n\t\t\t\trequire.Equal(t, stateValidators[0], data)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"get unknown validator - 1\",\n\t\t\tinputs: func() beacontypes.GetStateValidatorRequest {\n\t\t\t\tunknownValIdx := strconv.Itoa(2025)\n\t\t\t\treturn beacontypes.GetStateValidatorRequest{\n\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\tStateID: utils.StateIDHead,\n\t\t\t\t\t},\n\t\t\t\t\tValidatorID: unknownValIdx,\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tst := makeTestState(t, cs)\n\t\t\t\taddTestValidators(t, stateValidators, st)\n\n\t\t\t\t// slot is not really tested here, we just return zero\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, math.Slot(0), nil)\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\t\t\t\trequire.ErrorIs(t, err, handlertypes.ErrNotFound)\n\t\t\t\trequire.Nil(t, res)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"get unknown validator - 2\",\n\t\t\tinputs: func() beacontypes.GetStateValidatorRequest {\n\t\t\t\tunknownValPk := bytes.B48{0xff, 0xff}\n\t\t\t\treturn beacontypes.GetStateValidatorRequest{\n\t\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\t\tStateID: utils.StateIDHead,\n\t\t\t\t\t},\n\t\t\t\t\tValidatorID: unknownValPk.String(),\n\t\t\t\t}\n\t\t\t},\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tst := makeTestState(t, cs)\n\t\t\t\taddTestValidators(t, stateValidators, st)\n\n\t\t\t\t// slot is not really tested here, we just return zero\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, math.Slot(0), nil)\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\t\t\t\trequire.ErrorIs(t, err, handlertypes.ErrNotFound)\n\t\t\t\trequire.Nil(t, res)\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\t// setup test\n\t\t\tbackend := mocks.NewBackend(t)\n\t\t\th := beacon.NewHandler(backend, cs, noop.NewLogger[log.Logger]())\n\t\t\te := echo.New()\n\t\t\te.Validator = &middleware.CustomValidator{\n\t\t\t\tValidator: middleware.ConstructValidator(),\n\t\t\t}\n\n\t\t\t// create API inputs\n\t\t\tinput := tc.inputs()\n\t\t\tinputBytes, err := json.Marshal(input) //nolint:musttag //  TODO:fix\n\t\t\trequire.NoError(t, err)\n\t\t\tbody := strings.NewReader(string(inputBytes))\n\t\t\treq := httptest.NewRequest(http.MethodGet, \"/\", body)\n\t\t\treq.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) // otherwise code=415, message=Unsupported Media Type\n\t\t\tc := e.NewContext(req, httptest.NewRecorder())\n\n\t\t\t// set expectations\n\t\t\ttc.setMockExpectations(backend)\n\n\t\t\t// test\n\t\t\tres, err := h.GetStateValidator(c)\n\n\t\t\t// finally do checks\n\t\t\ttc.check(t, res, err)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/withdrawal.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacon\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\tbeacontypes \"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\thandlertypes \"github.com/berachain/beacon-kit/node-api/handlers/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n)\n\nfunc (h *Handler) GetPendingPartialWithdrawals(c handlers.Context) (any, error) {\n\treq, err := utils.BindAndValidate[beacontypes.GetPendingPartialWithdrawalsRequest](\n\t\tc, h.Logger(),\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Load state for the requested state ID\n\theight, err := utils.StateIDToHeight(req.StateID, h.backend)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tst, _, err := h.backend.StateAndSlotFromHeight(height)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Check withdrawal are active\n\tforkVersion, err := st.GetFork()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif version.IsBefore(forkVersion.CurrentVersion, version.Electra()) {\n\t\treturn nil, fmt.Errorf(\"%w: Electra fork not active yet\", handlertypes.ErrInvalidRequest)\n\t}\n\n\t// Retrieve and return withdrawals\n\tcTypePartialWithdrawals, err := st.GetPendingPartialWithdrawals()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get pending partial withdrawals from state: %w\", err)\n\t}\n\n\tpartialWithdrawals := make([]*beacontypes.PendingPartialWithdrawalData, len(cTypePartialWithdrawals))\n\tfor i, cTypeWithdrawal := range cTypePartialWithdrawals {\n\t\tpartialWithdrawals[i] = &beacontypes.PendingPartialWithdrawalData{\n\t\t\tValidatorIndex:  cTypeWithdrawal.ValidatorIndex.Unwrap(),\n\t\t\tAmount:          cTypeWithdrawal.Amount.Unwrap(),\n\t\t\tWithdrawalEpoch: cTypeWithdrawal.WithdrawableEpoch.Unwrap(),\n\t\t}\n\t}\n\n\treturn beacontypes.NewPendingPartialWithdrawalsResponse(\n\t\tforkVersion.CurrentVersion,\n\t\tpartialWithdrawals,\n\t), nil\n}\n"
  },
  {
    "path": "node-api/handlers/beacon/withdrawal_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacon_test\n\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/log/noop\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/beacon\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/beacon/mocks\"\n\tbeacontypes \"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\thandlertypes \"github.com/berachain/beacon-kit/node-api/handlers/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n\t\"github.com/berachain/beacon-kit/node-api/middleware\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/labstack/echo/v4\"\n\t\"github.com/stretchr/testify/mock\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestGetPendingPartialWithdrawals(t *testing.T) {\n\tt.Parallel()\n\n\tcs, errSpec := spec.MainnetChainSpec()\n\trequire.NoError(t, errSpec)\n\n\tpreElectraFork := &ctypes.Fork{\n\t\tPreviousVersion: version.Capella(),\n\t\tCurrentVersion:  version.Deneb(),\n\t\tEpoch:           math.Epoch(200),\n\t}\n\telectraFork := &ctypes.Fork{\n\t\tPreviousVersion: version.Deneb(),\n\t\tCurrentVersion:  version.Electra(),\n\t\tEpoch:           math.Epoch(200),\n\t}\n\ttestPendingPartialWithdrawals := []*ctypes.PendingPartialWithdrawal{\n\t\t{\n\t\t\tValidatorIndex:    0,\n\t\t\tAmount:            math.Gwei(1_000_000),\n\t\t\tWithdrawableEpoch: math.Epoch(1),\n\t\t},\n\t\t{\n\t\t\tValidatorIndex:    1,\n\t\t\tAmount:            math.Gwei(999_999_999),\n\t\t\tWithdrawableEpoch: math.Epoch(2),\n\t\t},\n\t}\n\n\ttestCases := []struct {\n\t\tname                string\n\t\tsetMockExpectations func(*mocks.Backend)\n\t\tcheck               func(t *testing.T, res any, err error)\n\t}{\n\t\t{\n\t\t\tname: \"post-Electra withdrawal requests present\",\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tst := makeTestState(t, cs)\n\n\t\t\t\trequire.NoError(t, st.SetFork(electraFork))\n\t\t\t\trequire.NoError(t, st.SetPendingPartialWithdrawals(testPendingPartialWithdrawals))\n\n\t\t\t\t// slot is not really tested here, we just return zero\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, math.Slot(0), nil)\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, beacontypes.PendingPartialWithdrawalsResponse{}, res)\n\t\t\t\tresp, _ := res.(beacontypes.PendingPartialWithdrawalsResponse)\n\n\t\t\t\trequire.Equal(t, version.Name(electraFork.CurrentVersion), resp.Version)\n\n\t\t\t\trequire.IsType(t, []*beacontypes.PendingPartialWithdrawalData{}, resp.GenericResponse.Data)\n\t\t\t\tdata, _ := resp.GenericResponse.Data.([]*beacontypes.PendingPartialWithdrawalData)\n\n\t\t\t\trequire.Len(t, data, len(testPendingPartialWithdrawals))\n\t\t\t\tfor i, w := range testPendingPartialWithdrawals {\n\t\t\t\t\trequire.Equal(t, math.ValidatorIndex(data[i].ValidatorIndex), w.ValidatorIndex)\n\t\t\t\t\trequire.Equal(t, math.Gwei(data[i].Amount), w.Amount)\n\t\t\t\t\trequire.Equal(t, math.Epoch(data[i].WithdrawalEpoch), w.WithdrawableEpoch)\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"post-Electra withdrawal no requests\",\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tst := makeTestState(t, cs)\n\n\t\t\t\trequire.NoError(t, st.SetFork(electraFork))\n\t\t\t\trequire.NoError(t, st.SetPendingPartialWithdrawals(nil))\n\n\t\t\t\t// slot is not really tested here, we just return zero\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, math.Slot(0), nil)\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, beacontypes.PendingPartialWithdrawalsResponse{}, res)\n\t\t\t\tresp, _ := res.(beacontypes.PendingPartialWithdrawalsResponse)\n\n\t\t\t\trequire.Equal(t, version.Name(electraFork.CurrentVersion), resp.Version)\n\n\t\t\t\trequire.IsType(t, []*beacontypes.PendingPartialWithdrawalData{}, resp.GenericResponse.Data)\n\t\t\t\tdata, _ := resp.GenericResponse.Data.([]*beacontypes.PendingPartialWithdrawalData)\n\n\t\t\t\trequire.Empty(t, data)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"pre-Electra - error\",\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tst := makeTestState(t, cs)\n\n\t\t\t\trequire.NoError(t, st.SetFork(preElectraFork))\n\n\t\t\t\t// slot is not really tested here, we just return zero\n\t\t\t\tb.EXPECT().StateAndSlotFromHeight(mock.Anything).Return(st, math.Slot(0), nil)\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.ErrorIs(t, err, handlertypes.ErrInvalidRequest)\n\t\t\t\trequire.Nil(t, res)\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\t// setup test\n\t\t\tbackend := mocks.NewBackend(t)\n\t\t\th := beacon.NewHandler(backend, cs, noop.NewLogger[log.Logger]())\n\t\t\te := echo.New()\n\t\t\te.Validator = &middleware.CustomValidator{\n\t\t\t\tValidator: middleware.ConstructValidator(),\n\t\t\t}\n\n\t\t\t// set expectations\n\t\t\ttc.setMockExpectations(backend)\n\n\t\t\t// create input\n\t\t\tinput := beacontypes.GetPendingPartialWithdrawalsRequest{\n\t\t\t\tStateIDRequest: handlertypes.StateIDRequest{\n\t\t\t\t\tStateID: utils.StateIDGenesis,\n\t\t\t\t},\n\t\t\t}\n\t\t\tinputBytes, err := json.Marshal(input) //nolint:musttag //  TODO:fix\n\t\t\trequire.NoError(t, err)\n\t\t\tbody := strings.NewReader(string(inputBytes))\n\t\t\treq := httptest.NewRequest(http.MethodGet, \"/\", body)\n\t\t\treq.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON) // otherwise code=415, message=Unsupported Media Type\n\t\t\tc := e.NewContext(req, httptest.NewRecorder())\n\n\t\t\t// test\n\t\t\tres, err := h.GetPendingPartialWithdrawals(c)\n\n\t\t\t// check\n\t\t\ttc.check(t, res, err)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "node-api/handlers/builder/handler.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage builder\n\nimport (\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n)\n\ntype Handler struct {\n\t*handlers.BaseHandler\n\tlogger log.Logger\n}\n\nfunc NewHandler(logger log.Logger) *Handler {\n\th := &Handler{\n\t\tBaseHandler: handlers.NewBaseHandler(logger),\n\t\tlogger:      logger,\n\t}\n\tregisterRoutes(h)\n\treturn h\n}\n"
  },
  {
    "path": "node-api/handlers/builder/routes.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage builder\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n)\n\nfunc registerRoutes(h *Handler) {\n\th.BaseHandler.AddRoutes([]*handlers.Route{\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/builder/states/:state_id/expected_withdrawals\",\n\t\t\tHandler: h.Deprecated,\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "node-api/handlers/cometbft/backend.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage cometbft\n\nimport (\n\tcmttypes \"github.com/cometbft/cometbft/types\"\n)\n\n// Backend is the interface for the CometBFT API backend.\ntype Backend interface {\n\t// GetCometBFTBlock returns the CometBFT block at the given height.\n\tGetCometBFTBlock(height int64) *cmttypes.Block\n\t// GetCometBFTSignedHeader returns the CometBFT signed header (header + commit) at the given height.\n\tGetCometBFTSignedHeader(height int64) *cmttypes.SignedHeader\n}\n"
  },
  {
    "path": "node-api/handlers/cometbft/block.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage cometbft\n\nimport (\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n)\n\n// GetBlock returns the CometBFT block at the specified height.\n// GET /cometbft/v1/block/:height\nfunc (h *Handler) GetBlock(c handlers.Context) (any, error) {\n\treq, err := utils.BindAndValidate[HeightRequest](c, h.Logger())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tblock := h.backend.GetCometBFTBlock(req.Height)\n\tif block == nil {\n\t\treturn nil, errors.Wrapf(types.ErrNotFound, \"block not found at height %d\", req.Height)\n\t}\n\n\treturn Response{Data: block}, nil\n}\n"
  },
  {
    "path": "node-api/handlers/cometbft/cometbft_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage cometbft_test\n\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/log/noop\"\n\tcometbftapi \"github.com/berachain/beacon-kit/node-api/handlers/cometbft\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/cometbft/mocks\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/types\"\n\t\"github.com/berachain/beacon-kit/node-api/middleware\"\n\tcmtversion \"github.com/cometbft/cometbft/api/cometbft/version/v1\"\n\tcmttypes \"github.com/cometbft/cometbft/types\"\n\t\"github.com/labstack/echo/v4\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestGetBlock(t *testing.T) {\n\tt.Parallel()\n\n\ttestTime := time.Date(2024, 1, 26, 12, 0, 0, 0, time.UTC)\n\ttestBlock := &cmttypes.Block{\n\t\tHeader: cmttypes.Header{\n\t\t\tVersion: cmtversion.Consensus{Block: 11, App: 0},\n\t\t\tChainID: \"test-chain\",\n\t\t\tHeight:  100,\n\t\t\tTime:    testTime,\n\t\t\tLastBlockID: cmttypes.BlockID{\n\t\t\t\tHash: []byte(\"prev-block-hash\"),\n\t\t\t\tPartSetHeader: cmttypes.PartSetHeader{\n\t\t\t\t\tTotal: 1,\n\t\t\t\t\tHash:  []byte(\"part-set-hash\"),\n\t\t\t\t},\n\t\t\t},\n\t\t\tLastCommitHash:     []byte(\"last-commit-hash\"),\n\t\t\tDataHash:           []byte(\"data-hash\"),\n\t\t\tValidatorsHash:     []byte(\"validators-hash\"),\n\t\t\tNextValidatorsHash: []byte(\"next-validators-hash\"),\n\t\t\tConsensusHash:      []byte(\"consensus-hash\"),\n\t\t\tAppHash:            []byte(\"app-hash\"),\n\t\t\tLastResultsHash:    []byte(\"last-results-hash\"),\n\t\t\tEvidenceHash:       []byte(\"evidence-hash\"),\n\t\t\tProposerAddress:    []byte(\"proposer-address\"),\n\t\t},\n\t\tData: cmttypes.Data{\n\t\t\tTxs: []cmttypes.Tx{\n\t\t\t\t[]byte(\"transaction-1\"),\n\t\t\t\t[]byte(\"transaction-2\"),\n\t\t\t},\n\t\t},\n\t\tEvidence: cmttypes.EvidenceData{\n\t\t\tEvidence: []cmttypes.Evidence{},\n\t\t},\n\t\tLastCommit: &cmttypes.Commit{\n\t\t\tHeight: 99,\n\t\t\tRound:  0,\n\t\t\tBlockID: cmttypes.BlockID{\n\t\t\t\tHash: []byte(\"prev-block-hash\"),\n\t\t\t\tPartSetHeader: cmttypes.PartSetHeader{\n\t\t\t\t\tTotal: 1,\n\t\t\t\t\tHash:  []byte(\"part-set-hash\"),\n\t\t\t\t},\n\t\t\t},\n\t\t\tSignatures: []cmttypes.CommitSig{\n\t\t\t\t{\n\t\t\t\t\tBlockIDFlag:      cmttypes.BlockIDFlagCommit,\n\t\t\t\t\tValidatorAddress: []byte(\"validator-1\"),\n\t\t\t\t\tTimestamp:        testTime,\n\t\t\t\t\tSignature:        []byte(\"signature-1\"),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\ttestCases := []struct {\n\t\tname                string\n\t\theight              string\n\t\tsetMockExpectations func(*mocks.Backend)\n\t\tcheck               func(t *testing.T, res any, err error)\n\t}{\n\t\t{\n\t\t\tname:   \"success\",\n\t\t\theight: \"100\",\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tb.EXPECT().GetCometBFTBlock(int64(100)).Return(testBlock).Once()\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\n\t\t\t\trespJSON, err := json.Marshal(res)\n\t\t\t\trequire.NoError(t, err)\n\n\t\t\t\tvar response cometbftapi.Response\n\t\t\t\terr = json.Unmarshal(respJSON, &response)\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, response.Data)\n\n\t\t\t\tdataJSON, err := json.Marshal(response.Data)\n\t\t\t\trequire.NoError(t, err)\n\n\t\t\t\tvar blockData cmttypes.Block\n\t\t\t\terr = json.Unmarshal(dataJSON, &blockData)\n\t\t\t\trequire.NoError(t, err)\n\n\t\t\t\trequire.Equal(t, \"test-chain\", blockData.Header.ChainID)\n\t\t\t\trequire.Equal(t, int64(100), blockData.Header.Height)\n\t\t\t\trequire.Len(t, blockData.Data.Txs, 2)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"not found\",\n\t\t\theight: \"999999\",\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tb.EXPECT().GetCometBFTBlock(int64(999999)).Return(nil).Once()\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\t\t\t\trequire.Error(t, err)\n\t\t\t\trequire.ErrorIs(t, err, types.ErrNotFound)\n\t\t\t\trequire.Contains(t, err.Error(), \"block not found\")\n\t\t\t\trequire.Nil(t, res)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:                \"invalid height - non-numeric\",\n\t\t\theight:              \"abc\",\n\t\t\tsetMockExpectations: func(_ *mocks.Backend) {},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\t\t\t\trequire.Error(t, err)\n\t\t\t\trequire.Contains(t, err.Error(), \"failed to bind request\")\n\t\t\t\trequire.Nil(t, res)\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tbackend := mocks.NewBackend(t)\n\t\t\th := cometbftapi.NewHandler(backend, noop.NewLogger[log.Logger]())\n\t\t\te := echo.New()\n\t\t\te.Validator = &middleware.CustomValidator{\n\t\t\t\tValidator: middleware.ConstructValidator(),\n\t\t\t}\n\n\t\t\ttc.setMockExpectations(backend)\n\n\t\t\treq := httptest.NewRequest(http.MethodGet, \"/cometbft/v1/block/\"+tc.height, nil)\n\t\t\trec := httptest.NewRecorder()\n\t\t\tc := e.NewContext(req, rec)\n\t\t\tc.SetParamNames(\"height\")\n\t\t\tc.SetParamValues(tc.height)\n\n\t\t\tresult, err := h.GetBlock(c)\n\n\t\t\ttc.check(t, result, err)\n\t\t})\n\t}\n}\n\nfunc TestGetSignedHeader(t *testing.T) {\n\tt.Parallel()\n\n\ttestTime := time.Date(2024, 1, 26, 12, 0, 0, 0, time.UTC)\n\ttestSignedHeader := &cmttypes.SignedHeader{\n\t\tHeader: &cmttypes.Header{\n\t\t\tVersion:         cmtversion.Consensus{Block: 11, App: 0},\n\t\t\tChainID:         \"test-chain\",\n\t\t\tHeight:          100,\n\t\t\tTime:            testTime,\n\t\t\tProposerAddress: []byte(\"proposer-address\"),\n\t\t\tLastBlockID: cmttypes.BlockID{\n\t\t\t\tHash: []byte(\"prev-block-hash\"),\n\t\t\t\tPartSetHeader: cmttypes.PartSetHeader{\n\t\t\t\t\tTotal: 1,\n\t\t\t\t\tHash:  []byte(\"part-set-hash\"),\n\t\t\t\t},\n\t\t\t},\n\t\t\tLastCommitHash:     []byte(\"last-commit-hash\"),\n\t\t\tDataHash:           []byte(\"data-hash\"),\n\t\t\tValidatorsHash:     []byte(\"validators-hash\"),\n\t\t\tNextValidatorsHash: []byte(\"next-validators-hash\"),\n\t\t\tConsensusHash:      []byte(\"consensus-hash\"),\n\t\t\tAppHash:            []byte(\"app-hash\"),\n\t\t\tLastResultsHash:    []byte(\"last-results-hash\"),\n\t\t\tEvidenceHash:       []byte(\"evidence-hash\"),\n\t\t},\n\t\tCommit: &cmttypes.Commit{\n\t\t\tHeight: 100,\n\t\t\tRound:  0,\n\t\t\tBlockID: cmttypes.BlockID{\n\t\t\t\tHash: []byte(\"block-hash\"),\n\t\t\t\tPartSetHeader: cmttypes.PartSetHeader{\n\t\t\t\t\tTotal: 1,\n\t\t\t\t\tHash:  []byte(\"part-set-hash\"),\n\t\t\t\t},\n\t\t\t},\n\t\t\tSignatures: []cmttypes.CommitSig{\n\t\t\t\t{\n\t\t\t\t\tBlockIDFlag:      cmttypes.BlockIDFlagCommit,\n\t\t\t\t\tValidatorAddress: []byte(\"validator-1\"),\n\t\t\t\t\tTimestamp:        testTime,\n\t\t\t\t\tSignature:        []byte(\"signature-1\"),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tBlockIDFlag:      cmttypes.BlockIDFlagCommit,\n\t\t\t\t\tValidatorAddress: []byte(\"validator-2\"),\n\t\t\t\t\tTimestamp:        testTime.Add(time.Millisecond * 100),\n\t\t\t\t\tSignature:        []byte(\"signature-2\"),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\ttestCases := []struct {\n\t\tname                string\n\t\theight              string\n\t\tsetMockExpectations func(*mocks.Backend)\n\t\tcheck               func(t *testing.T, res any, err error)\n\t}{\n\t\t{\n\t\t\tname:   \"success\",\n\t\t\theight: \"100\",\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tb.EXPECT().GetCometBFTSignedHeader(int64(100)).Return(testSignedHeader).Once()\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\n\t\t\t\trespJSON, err := json.Marshal(res)\n\t\t\t\trequire.NoError(t, err)\n\n\t\t\t\tvar response cometbftapi.Response\n\t\t\t\terr = json.Unmarshal(respJSON, &response)\n\t\t\t\trequire.NoError(t, err)\n\n\t\t\t\tdataJSON, err := json.Marshal(response.Data)\n\t\t\t\trequire.NoError(t, err)\n\n\t\t\t\tvar signedHeaderData cmttypes.SignedHeader\n\t\t\t\terr = json.Unmarshal(dataJSON, &signedHeaderData)\n\t\t\t\trequire.NoError(t, err)\n\n\t\t\t\trequire.Equal(t, \"test-chain\", signedHeaderData.Header.ChainID)\n\t\t\t\trequire.Equal(t, int64(100), signedHeaderData.Header.Height)\n\t\t\t\trequire.Equal(t, int64(100), signedHeaderData.Commit.Height)\n\t\t\t\trequire.Equal(t, int32(0), signedHeaderData.Commit.Round)\n\t\t\t\trequire.Len(t, signedHeaderData.Commit.Signatures, 2)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"not found\",\n\t\t\theight: \"999999\",\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tb.EXPECT().GetCometBFTSignedHeader(int64(999999)).Return(nil).Once()\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\t\t\t\trequire.Error(t, err)\n\t\t\t\trequire.ErrorIs(t, err, types.ErrNotFound)\n\t\t\t\trequire.Contains(t, err.Error(), \"signed header not found\")\n\t\t\t\trequire.Nil(t, res)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:                \"invalid height - non-numeric\",\n\t\t\theight:              \"abc\",\n\t\t\tsetMockExpectations: func(_ *mocks.Backend) {},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\t\t\t\trequire.Error(t, err)\n\t\t\t\trequire.Contains(t, err.Error(), \"failed to bind request\")\n\t\t\t\trequire.Nil(t, res)\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tbackend := mocks.NewBackend(t)\n\t\t\th := cometbftapi.NewHandler(backend, noop.NewLogger[log.Logger]())\n\t\t\te := echo.New()\n\t\t\te.Validator = &middleware.CustomValidator{\n\t\t\t\tValidator: middleware.ConstructValidator(),\n\t\t\t}\n\n\t\t\ttc.setMockExpectations(backend)\n\n\t\t\treq := httptest.NewRequest(http.MethodGet, \"/cometbft/v1/signed_header/\"+tc.height, nil)\n\t\t\trec := httptest.NewRecorder()\n\t\t\tc := e.NewContext(req, rec)\n\t\t\tc.SetParamNames(\"height\")\n\t\t\tc.SetParamValues(tc.height)\n\n\t\t\tresult, err := h.GetSignedHeader(c)\n\n\t\t\ttc.check(t, result, err)\n\t\t})\n\t}\n}\n\nfunc TestGetBlock_FieldConversion(t *testing.T) {\n\tt.Parallel()\n\n\ttestTime := time.Date(2024, 1, 26, 12, 0, 0, 123456789, time.UTC)\n\tblock := &cmttypes.Block{\n\t\tHeader: cmttypes.Header{\n\t\t\tVersion:         cmtversion.Consensus{Block: 11, App: 1},\n\t\t\tChainID:         \"test-chain-123\",\n\t\t\tHeight:          12345,\n\t\t\tTime:            testTime,\n\t\t\tProposerAddress: []byte(\"proposer\"),\n\t\t},\n\t\tData: cmttypes.Data{\n\t\t\tTxs: []cmttypes.Tx{[]byte(\"tx1\"), []byte(\"tx2\"), []byte(\"tx3\")},\n\t\t},\n\t\tEvidence: cmttypes.EvidenceData{\n\t\t\tEvidence: []cmttypes.Evidence{},\n\t\t},\n\t}\n\n\tbackend := mocks.NewBackend(t)\n\th := cometbftapi.NewHandler(backend, noop.NewLogger[log.Logger]())\n\te := echo.New()\n\te.Validator = &middleware.CustomValidator{\n\t\tValidator: middleware.ConstructValidator(),\n\t}\n\n\tbackend.EXPECT().GetCometBFTBlock(int64(12345)).Return(block).Once()\n\n\treq := httptest.NewRequest(http.MethodGet, \"/cometbft/v1/block/12345\", nil)\n\trec := httptest.NewRecorder()\n\tc := e.NewContext(req, rec)\n\tc.SetParamNames(\"height\")\n\tc.SetParamValues(\"12345\")\n\n\tresult, err := h.GetBlock(c)\n\trequire.NoError(t, err)\n\n\trespJSON, err := json.Marshal(result)\n\trequire.NoError(t, err)\n\n\tvar response cometbftapi.Response\n\terr = json.Unmarshal(respJSON, &response)\n\trequire.NoError(t, err)\n\n\tdataJSON, err := json.Marshal(response.Data)\n\trequire.NoError(t, err)\n\n\tvar blockData cmttypes.Block\n\terr = json.Unmarshal(dataJSON, &blockData)\n\trequire.NoError(t, err)\n\n\trequire.Equal(t, \"test-chain-123\", blockData.Header.ChainID)\n\trequire.Equal(t, int64(12345), blockData.Header.Height)\n\trequire.Equal(t, uint64(11), blockData.Header.Version.Block)\n\trequire.Equal(t, uint64(1), blockData.Header.Version.App)\n\trequire.Len(t, blockData.Data.Txs, 3)\n}\n\nfunc TestGetSignedHeader_MultipleSignatures(t *testing.T) {\n\tt.Parallel()\n\n\ttestTime := time.Date(2024, 1, 26, 12, 0, 0, 0, time.UTC)\n\tsignedHeader := &cmttypes.SignedHeader{\n\t\tHeader: &cmttypes.Header{\n\t\t\tVersion:         cmtversion.Consensus{Block: 11, App: 0},\n\t\t\tChainID:         \"test-chain\",\n\t\t\tHeight:          100,\n\t\t\tTime:            testTime,\n\t\t\tProposerAddress: []byte(\"proposer\"),\n\t\t},\n\t\tCommit: &cmttypes.Commit{\n\t\t\tHeight: 100,\n\t\t\tRound:  2,\n\t\t\tBlockID: cmttypes.BlockID{\n\t\t\t\tHash: []byte(\"block-hash\"),\n\t\t\t},\n\t\t\tSignatures: []cmttypes.CommitSig{\n\t\t\t\t{\n\t\t\t\t\tBlockIDFlag:      cmttypes.BlockIDFlagCommit,\n\t\t\t\t\tValidatorAddress: []byte(\"val1\"),\n\t\t\t\t\tTimestamp:        testTime,\n\t\t\t\t\tSignature:        []byte(\"sig1\"),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tBlockIDFlag:      cmttypes.BlockIDFlagAbsent,\n\t\t\t\t\tValidatorAddress: []byte(\"val2\"),\n\t\t\t\t\tTimestamp:        testTime,\n\t\t\t\t\tSignature:        nil,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tBlockIDFlag:      cmttypes.BlockIDFlagNil,\n\t\t\t\t\tValidatorAddress: []byte(\"val3\"),\n\t\t\t\t\tTimestamp:        testTime,\n\t\t\t\t\tSignature:        []byte(\"sig3\"),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tbackend := mocks.NewBackend(t)\n\th := cometbftapi.NewHandler(backend, noop.NewLogger[log.Logger]())\n\te := echo.New()\n\te.Validator = &middleware.CustomValidator{\n\t\tValidator: middleware.ConstructValidator(),\n\t}\n\n\tbackend.EXPECT().GetCometBFTSignedHeader(int64(100)).Return(signedHeader).Once()\n\n\treq := httptest.NewRequest(http.MethodGet, \"/cometbft/v1/signed_header/100\", nil)\n\trec := httptest.NewRecorder()\n\tc := e.NewContext(req, rec)\n\tc.SetParamNames(\"height\")\n\tc.SetParamValues(\"100\")\n\n\tresult, err := h.GetSignedHeader(c)\n\trequire.NoError(t, err)\n\n\trespJSON, err := json.Marshal(result)\n\trequire.NoError(t, err)\n\n\tvar response cometbftapi.Response\n\terr = json.Unmarshal(respJSON, &response)\n\trequire.NoError(t, err)\n\n\tdataJSON, err := json.Marshal(response.Data)\n\trequire.NoError(t, err)\n\n\tvar signedHeaderData cmttypes.SignedHeader\n\terr = json.Unmarshal(dataJSON, &signedHeaderData)\n\trequire.NoError(t, err)\n\n\trequire.Equal(t, \"test-chain\", signedHeaderData.Header.ChainID)\n\trequire.Equal(t, int64(100), signedHeaderData.Header.Height)\n\trequire.Equal(t, int32(2), signedHeaderData.Commit.Round)\n\trequire.Len(t, signedHeaderData.Commit.Signatures, 3)\n\n\trequire.Equal(t, cmttypes.BlockIDFlagCommit, signedHeaderData.Commit.Signatures[0].BlockIDFlag)\n\trequire.Equal(t, cmttypes.BlockIDFlagAbsent, signedHeaderData.Commit.Signatures[1].BlockIDFlag)\n\trequire.Equal(t, cmttypes.BlockIDFlagNil, signedHeaderData.Commit.Signatures[2].BlockIDFlag)\n}\n"
  },
  {
    "path": "node-api/handlers/cometbft/handler.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage cometbft\n\nimport (\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n)\n\n// Handler is the handler for the CometBFT API.\ntype Handler struct {\n\t*handlers.BaseHandler\n\n\tbackend Backend\n}\n\n// NewHandler creates a new handler for the CometBFT API.\nfunc NewHandler(backend Backend, logger log.Logger) *Handler {\n\th := &Handler{\n\t\tBaseHandler: handlers.NewBaseHandler(logger),\n\t\tbackend:     backend,\n\t}\n\tregisterRoutes(h)\n\treturn h\n}\n"
  },
  {
    "path": "node-api/handlers/cometbft/mocks/backend.mock.go",
    "content": "// Code generated by mockery v2.53.5. DO NOT EDIT.\n\npackage mocks\n\nimport (\n\tcometbfttypes \"github.com/cometbft/cometbft/types\"\n\n\tmock \"github.com/stretchr/testify/mock\"\n)\n\n// Backend is an autogenerated mock type for the Backend type\ntype Backend struct {\n\tmock.Mock\n}\n\ntype Backend_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *Backend) EXPECT() *Backend_Expecter {\n\treturn &Backend_Expecter{mock: &_m.Mock}\n}\n\n// GetCometBFTBlock provides a mock function with given fields: height\nfunc (_m *Backend) GetCometBFTBlock(height int64) *cometbfttypes.Block {\n\tret := _m.Called(height)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetCometBFTBlock\")\n\t}\n\n\tvar r0 *cometbfttypes.Block\n\tif rf, ok := ret.Get(0).(func(int64) *cometbfttypes.Block); ok {\n\t\tr0 = rf(height)\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(*cometbfttypes.Block)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// Backend_GetCometBFTBlock_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCometBFTBlock'\ntype Backend_GetCometBFTBlock_Call struct {\n\t*mock.Call\n}\n\n// GetCometBFTBlock is a helper method to define mock.On call\n//   - height int64\nfunc (_e *Backend_Expecter) GetCometBFTBlock(height interface{}) *Backend_GetCometBFTBlock_Call {\n\treturn &Backend_GetCometBFTBlock_Call{Call: _e.mock.On(\"GetCometBFTBlock\", height)}\n}\n\nfunc (_c *Backend_GetCometBFTBlock_Call) Run(run func(height int64)) *Backend_GetCometBFTBlock_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(int64))\n\t})\n\treturn _c\n}\n\nfunc (_c *Backend_GetCometBFTBlock_Call) Return(_a0 *cometbfttypes.Block) *Backend_GetCometBFTBlock_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *Backend_GetCometBFTBlock_Call) RunAndReturn(run func(int64) *cometbfttypes.Block) *Backend_GetCometBFTBlock_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// GetCometBFTSignedHeader provides a mock function with given fields: height\nfunc (_m *Backend) GetCometBFTSignedHeader(height int64) *cometbfttypes.SignedHeader {\n\tret := _m.Called(height)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetCometBFTSignedHeader\")\n\t}\n\n\tvar r0 *cometbfttypes.SignedHeader\n\tif rf, ok := ret.Get(0).(func(int64) *cometbfttypes.SignedHeader); ok {\n\t\tr0 = rf(height)\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(*cometbfttypes.SignedHeader)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// Backend_GetCometBFTSignedHeader_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCometBFTSignedHeader'\ntype Backend_GetCometBFTSignedHeader_Call struct {\n\t*mock.Call\n}\n\n// GetCometBFTSignedHeader is a helper method to define mock.On call\n//   - height int64\nfunc (_e *Backend_Expecter) GetCometBFTSignedHeader(height interface{}) *Backend_GetCometBFTSignedHeader_Call {\n\treturn &Backend_GetCometBFTSignedHeader_Call{Call: _e.mock.On(\"GetCometBFTSignedHeader\", height)}\n}\n\nfunc (_c *Backend_GetCometBFTSignedHeader_Call) Run(run func(height int64)) *Backend_GetCometBFTSignedHeader_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(int64))\n\t})\n\treturn _c\n}\n\nfunc (_c *Backend_GetCometBFTSignedHeader_Call) Return(_a0 *cometbfttypes.SignedHeader) *Backend_GetCometBFTSignedHeader_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *Backend_GetCometBFTSignedHeader_Call) RunAndReturn(run func(int64) *cometbfttypes.SignedHeader) *Backend_GetCometBFTSignedHeader_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewBackend creates a new instance of Backend. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewBackend(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *Backend {\n\tmock := &Backend{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "node-api/handlers/cometbft/routes.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage cometbft\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n)\n\nfunc registerRoutes(h *Handler) {\n\th.BaseHandler.AddRoutes([]*handlers.Route{\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/cometbft/v1/block/:height\",\n\t\t\tHandler: h.GetBlock,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/cometbft/v1/signed_header/:height\",\n\t\t\tHandler: h.GetSignedHeader,\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "node-api/handlers/cometbft/signed_header.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage cometbft\n\nimport (\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n)\n\n// GetSignedHeader returns the CometBFT signed header (header + commit) at the specified height.\n// GET /cometbft/v1/signed_header/:height\nfunc (h *Handler) GetSignedHeader(c handlers.Context) (any, error) {\n\treq, err := utils.BindAndValidate[HeightRequest](c, h.Logger())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tsignedHeader := h.backend.GetCometBFTSignedHeader(req.Height)\n\tif signedHeader == nil {\n\t\treturn nil, errors.Wrapf(types.ErrNotFound, \"signed header not found at height %d\", req.Height)\n\t}\n\n\treturn Response{Data: signedHeader}, nil\n}\n"
  },
  {
    "path": "node-api/handlers/cometbft/types.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage cometbft\n\n// HeightRequest is a request type for CometBFT endpoints that accept a height parameter.\ntype HeightRequest struct {\n\tHeight int64 `param:\"height\" validate:\"required,numeric\"`\n}\n\n// Response wraps CometBFT data in a standard response envelope.\ntype Response struct {\n\tData any `json:\"data\"`\n}\n"
  },
  {
    "path": "node-api/handlers/config/handler.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage config\n\nimport (\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n)\n\ntype Handler struct {\n\t*handlers.BaseHandler\n\n\tcs chain.Spec\n}\n\nfunc NewHandler(cs chain.Spec, logger log.Logger) *Handler {\n\th := &Handler{\n\t\tBaseHandler: handlers.NewBaseHandler(logger),\n\t\tcs:          cs,\n\t}\n\tregisterRoutes(h)\n\treturn h\n}\n"
  },
  {
    "path": "node-api/handlers/config/routes.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage config\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n)\n\nfunc registerRoutes(h *Handler) {\n\th.BaseHandler.AddRoutes([]*handlers.Route{\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/config/fork_schedule\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/config/spec\",\n\t\t\tHandler: h.GetSpec,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/config/deposit_contract\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "node-api/handlers/config/spec.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage config\n\nimport (\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/config/types\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// InactivityPenaltyQuotientPlaceholder is a placeholder value for the inactivity penalty quotient.\nconst InactivityPenaltyQuotientPlaceholder = \"0\"\n\n// GetSpec returns the spec of the beacon chain.\nfunc (h *Handler) GetSpec(handlers.Context) (any, error) {\n\treturn types.SpecResponse{Data: types.SpecData{\n\t\tDepositContractAddress: h.cs.DepositContractAddress().String(),\n\n\t\t// Network ID is same as eth1 chain ID.\n\t\tDepositNetworkID: math.U64(h.cs.DepositEth1ChainID()).Base10(),\n\n\t\tDomainAggregateAndProof: h.cs.DomainTypeAggregateAndProof().String(),\n\n\t\t// Currently these are placeholders, will be replaced with the correct values for our\n\t\t// versions like Deneb, Deneb1 etc once we implement slashing for inactivity.\n\t\tInactivityPenaltyQuotient:       InactivityPenaltyQuotientPlaceholder,\n\t\tInactivityPenaltyQuotientAltair: InactivityPenaltyQuotientPlaceholder,\n\t}}, nil\n}\n"
  },
  {
    "path": "node-api/handlers/config/types/response.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\ntype SpecResponse struct {\n\tData SpecData `json:\"data\"`\n}\n\ntype SpecData struct {\n\tDepositContractAddress          string `json:\"DEPOSIT_CONTRACT_ADDRESS\"`\n\tDepositNetworkID                string `json:\"DEPOSIT_NETWORK_ID\"`\n\tDomainAggregateAndProof         string `json:\"DOMAIN_AGGREGATE_AND_PROOF\"`\n\tInactivityPenaltyQuotient       string `json:\"INACTIVITY_PENALTY_QUOTIENT\"`\n\tInactivityPenaltyQuotientAltair string `json:\"INACTIVITY_PENALTY_QUOTIENT_ALTAIR\"`\n}\n"
  },
  {
    "path": "node-api/handlers/debug/backend.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage debug\n\nimport (\n\t\"github.com/berachain/beacon-kit/node-api/backend\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// Backend is the interface for backend of the debug API.\ntype Backend interface {\n\tGetSlotByStateRoot(root common.Root) (math.Slot, error)\n\tStateAndSlotFromHeight(height int64) (backend.ReadOnlyBeaconState, math.Slot, error)\n}\n"
  },
  {
    "path": "node-api/handlers/debug/handler.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage debug\n\nimport (\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n)\n\n// Handler is the handler for the beacon API.\ntype Handler struct {\n\t*handlers.BaseHandler\n\tbackend Backend\n}\n\n// NewHandler creates a new handler for the beacon API.\nfunc NewHandler(backend Backend, logger log.Logger) *Handler {\n\th := &Handler{\n\t\tBaseHandler: handlers.NewBaseHandler(logger),\n\t\tbackend:     backend,\n\t}\n\tregisterRoutes(h)\n\treturn h\n}\n"
  },
  {
    "path": "node-api/handlers/debug/routes.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage debug\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n)\n\nfunc registerRoutes(h *Handler) {\n\th.BaseHandler.AddRoutes([]*handlers.Route{\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v2/debug/beacon/states/:state_id\",\n\t\t\tHandler: h.GetState,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v2/debug/beacon/heads\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/debug/fork_choice\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "node-api/handlers/debug/state.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage debug\n\nimport (\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\tbeacontypes \"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n)\n\nfunc (h *Handler) GetState(c handlers.Context) (any, error) {\n\treq, err := utils.BindAndValidate[beacontypes.GetStateRequest](\n\t\tc, h.Logger(),\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\theight, err := utils.StateIDToHeight(req.StateID, h.backend)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Get the raw state at the given slot.\n\tstate, _, err := h.backend.StateAndSlotFromHeight(height)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tbeaconState, err := state.GetMarshallable()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Get the fork version from the state.\n\tfork, err := state.GetFork()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn beacontypes.StateResponse{\n\t\t// All data is finalized in CometBFT since we only return data for slots up to head\n\t\tFinalized: true,\n\t\t// Never optimistic since we only return finalized data\n\t\tExecutionOptimistic: false,\n\n\t\tVersion: version.Name(fork.CurrentVersion),\n\t\tData:    beaconState,\n\t}, nil\n}\n"
  },
  {
    "path": "node-api/handlers/error.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage handlers\n\nimport \"fmt\"\n\n// HTTPError represents an HTTP error response.\ntype HTTPError struct {\n\tCode    int    `json:\"code\"`\n\tMessage string `json:\"message\"`\n}\n\n// NewHTTPError creates a new HTTPError with a formatted message.\nfunc NewHTTPError(code int, message string, args ...any) *HTTPError {\n\treturn &HTTPError{\n\t\tCode:    code,\n\t\tMessage: fmt.Sprintf(message, args...),\n\t}\n}\n\n// Error implements the error interface.\nfunc (e *HTTPError) Error() string {\n\treturn e.Message\n}\n\n// StatusCode returns the HTTP status code.\nfunc (e *HTTPError) StatusCode() int {\n\treturn e.Code\n}\n"
  },
  {
    "path": "node-api/handlers/events/handler.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage events\n\nimport (\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n)\n\ntype Handler struct {\n\t*handlers.BaseHandler\n}\n\nfunc NewHandler(logger log.Logger) *Handler {\n\th := &Handler{\n\t\tBaseHandler: handlers.NewBaseHandler(logger),\n\t}\n\tregisterRoutes(h)\n\treturn h\n}\n"
  },
  {
    "path": "node-api/handlers/events/routes.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage events\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n)\n\nfunc registerRoutes(h *Handler) {\n\th.BaseHandler.AddRoutes([]*handlers.Route{\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/events\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "node-api/handlers/handlers.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage handlers\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/log\"\n)\n\n// BaseHandler is a base handler for all handlers. It abstracts the route set\n// and logger from the handler.\ntype BaseHandler struct {\n\troutes *RouteSet\n\tlogger log.Logger\n}\n\n// NewBaseHandler initializes a new base handler with the given routes and\n// logger.\nfunc NewBaseHandler(logger log.Logger) *BaseHandler {\n\treturn &BaseHandler{\n\t\troutes: &RouteSet{\n\t\t\tRoutes: make([]*Route, 0), // Must be set via AddRoutes,\n\t\t},\n\t\tlogger: logger,\n\t}\n}\n\n// NotImplemented is the handler for API endpoints that are defined in the Ethereum Beacon Node API\n// spec, but not yet implemented.\nfunc (b *BaseHandler) NotImplemented(c Context) (any, error) {\n\tendpoint := c.Request().URL.Path\n\treturn nil, fmt.Errorf(\"endpoint %s is not yet implemented\", endpoint)\n}\n\n// Deprecated handles deprecated API endpoints that are no longer supported according to the\n// Ethereum Beacon Node API spec.\nfunc (b *BaseHandler) Deprecated(c Context) (any, error) {\n\tendpoint := c.Request().URL.Path\n\treturn nil, fmt.Errorf(\"endpoint %s is deprecated\", endpoint)\n}\n\n// RouteSet returns the route set for the base handler.\nfunc (b *BaseHandler) RouteSet() *RouteSet {\n\treturn b.routes\n}\n\n// Logger is used to access the logger for the base handler.\nfunc (b *BaseHandler) Logger() log.Logger {\n\treturn b.logger\n}\n\n// AddRoutes adds the given slice of routes to the base handler.\nfunc (b *BaseHandler) AddRoutes(routes []*Route) {\n\tb.routes.Routes = append(b.routes.Routes, routes...)\n}\n"
  },
  {
    "path": "node-api/handlers/node/backend.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2024, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage node\n\ntype Backend interface {\n\tGetSyncData() (latestHeight int64, syncToHeight int64)\n\tGetVersionData() (\n\t\tappName,\n\t\tversion,\n\t\tos,\n\t\tarch string,\n\t)\n}\n"
  },
  {
    "path": "node-api/handlers/node/handler.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage node\n\nimport (\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n)\n\ntype Handler struct {\n\t*handlers.BaseHandler\n\n\tbackend Backend\n}\n\nfunc NewHandler(b Backend, logger log.Logger) *Handler {\n\th := &Handler{\n\t\tBaseHandler: handlers.NewBaseHandler(logger),\n\t\tbackend:     b,\n\t}\n\tregisterRoutes(h)\n\treturn h\n}\n"
  },
  {
    "path": "node-api/handlers/node/mocks/backend.mock.go",
    "content": "// Code generated by mockery v2.53.5. DO NOT EDIT.\n\npackage mocks\n\nimport mock \"github.com/stretchr/testify/mock\"\n\n// Backend is an autogenerated mock type for the Backend type\ntype Backend struct {\n\tmock.Mock\n}\n\ntype Backend_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *Backend) EXPECT() *Backend_Expecter {\n\treturn &Backend_Expecter{mock: &_m.Mock}\n}\n\n// GetSyncData provides a mock function with no fields\nfunc (_m *Backend) GetSyncData() (int64, int64) {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetSyncData\")\n\t}\n\n\tvar r0 int64\n\tvar r1 int64\n\tif rf, ok := ret.Get(0).(func() (int64, int64)); ok {\n\t\treturn rf()\n\t}\n\tif rf, ok := ret.Get(0).(func() int64); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tr0 = ret.Get(0).(int64)\n\t}\n\n\tif rf, ok := ret.Get(1).(func() int64); ok {\n\t\tr1 = rf()\n\t} else {\n\t\tr1 = ret.Get(1).(int64)\n\t}\n\n\treturn r0, r1\n}\n\n// Backend_GetSyncData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSyncData'\ntype Backend_GetSyncData_Call struct {\n\t*mock.Call\n}\n\n// GetSyncData is a helper method to define mock.On call\nfunc (_e *Backend_Expecter) GetSyncData() *Backend_GetSyncData_Call {\n\treturn &Backend_GetSyncData_Call{Call: _e.mock.On(\"GetSyncData\")}\n}\n\nfunc (_c *Backend_GetSyncData_Call) Run(run func()) *Backend_GetSyncData_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *Backend_GetSyncData_Call) Return(latestHeight int64, syncToHeight int64) *Backend_GetSyncData_Call {\n\t_c.Call.Return(latestHeight, syncToHeight)\n\treturn _c\n}\n\nfunc (_c *Backend_GetSyncData_Call) RunAndReturn(run func() (int64, int64)) *Backend_GetSyncData_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// GetVersionData provides a mock function with no fields\nfunc (_m *Backend) GetVersionData() (string, string, string, string) {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetVersionData\")\n\t}\n\n\tvar r0 string\n\tvar r1 string\n\tvar r2 string\n\tvar r3 string\n\tif rf, ok := ret.Get(0).(func() (string, string, string, string)); ok {\n\t\treturn rf()\n\t}\n\tif rf, ok := ret.Get(0).(func() string); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tr0 = ret.Get(0).(string)\n\t}\n\n\tif rf, ok := ret.Get(1).(func() string); ok {\n\t\tr1 = rf()\n\t} else {\n\t\tr1 = ret.Get(1).(string)\n\t}\n\n\tif rf, ok := ret.Get(2).(func() string); ok {\n\t\tr2 = rf()\n\t} else {\n\t\tr2 = ret.Get(2).(string)\n\t}\n\n\tif rf, ok := ret.Get(3).(func() string); ok {\n\t\tr3 = rf()\n\t} else {\n\t\tr3 = ret.Get(3).(string)\n\t}\n\n\treturn r0, r1, r2, r3\n}\n\n// Backend_GetVersionData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetVersionData'\ntype Backend_GetVersionData_Call struct {\n\t*mock.Call\n}\n\n// GetVersionData is a helper method to define mock.On call\nfunc (_e *Backend_Expecter) GetVersionData() *Backend_GetVersionData_Call {\n\treturn &Backend_GetVersionData_Call{Call: _e.mock.On(\"GetVersionData\")}\n}\n\nfunc (_c *Backend_GetVersionData_Call) Run(run func()) *Backend_GetVersionData_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *Backend_GetVersionData_Call) Return(appName string, version string, os string, arch string) *Backend_GetVersionData_Call {\n\t_c.Call.Return(appName, version, os, arch)\n\treturn _c\n}\n\nfunc (_c *Backend_GetVersionData_Call) RunAndReturn(run func() (string, string, string, string)) *Backend_GetVersionData_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewBackend creates a new instance of Backend. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewBackend(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *Backend {\n\tmock := &Backend{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "node-api/handlers/node/node.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage node\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/node/types\"\n)\n\n// Syncing returns the syncing status of the beacon node.\nfunc (h *Handler) Syncing(handlers.Context) (any, error) {\n\tlatestHeight, syncingToHeight := h.backend.GetSyncData()\n\tsyncDistance := syncingToHeight - latestHeight\n\tresponse := &types.SyncingData{\n\t\tHeadSlot:     latestHeight,\n\t\tSyncDistance: syncDistance,\n\n\t\t// BeaconKit has two operation modes: syncing from genesis\n\t\t// and normal operations. Every block finalized is verified\n\t\t// by the EL so for every purpose IsSyncing is equivalent to syncDistance > 0\n\t\tIsSyncing: syncDistance > 0,\n\n\t\t// BeaconKit always verifies blocks payload, whether\n\t\t// it is syncing or it's in normal operation mode.\n\t\t// So IsOptimistic is always false\n\t\tIsOptimistic: false,\n\n\t\t// BeaconKit fails to verify and finalize blocks if\n\t\t// the EL is not reachable, resulting in a panic state.\n\t\t// TODO: consider exposing the EL state here\n\t\tELOffline: false,\n\t}\n\n\treturn types.Wrap(response), nil\n}\n\n// Note: version comes from git describe (via the build process)\n// Git describe usually returns string like <v1.2.3-14-g2414721>, which can be understood as follow:\n// - v1.2.3 → the most recent tag reachable from this commit\n// - 14 → number of commits since that tag\n// - g2414721 → the abbreviated commit hash, **with a leading g**.\n// That g stands for “git”. It’s a prefix Git uses to distinguish the commit hash from other possible identifiers.\nfunc (h *Handler) Version(handlers.Context) (any, error) {\n\tappName, version, os, arch := h.backend.GetVersionData()\n\tr := &types.VersionData{\n\t\tVersion: fmt.Sprintf(\"%s/%s (%s %s)\",\n\t\t\tappName,\n\t\t\tversion,\n\t\t\tos,\n\t\t\tarch,\n\t\t),\n\t}\n\n\treturn types.Wrap(r), nil\n}\n"
  },
  {
    "path": "node-api/handlers/node/node_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage node_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/log/noop\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/node\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/node/mocks\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/node/types\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestNodeSyncing(t *testing.T) {\n\tt.Parallel()\n\n\ttestCases := []struct {\n\t\tname                string\n\t\tsetMockExpectations func(*mocks.Backend)\n\t\tcheck               func(t *testing.T, res any, err error)\n\t}{\n\t\t{\n\t\t\tname: \"syncing\",\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tlatestHeight := int64(2025)\n\t\t\t\tsyncToHeight := int64(2026)\n\t\t\t\tb.EXPECT().GetSyncData().Return(latestHeight, syncToHeight).Once()\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, types.DataResponse{}, res)\n\t\t\t\tdr, _ := res.(types.DataResponse)\n\t\t\t\trequire.IsType(t, &types.SyncingData{}, dr.Data)\n\t\t\t\tdata, _ := dr.Data.(*types.SyncingData)\n\n\t\t\t\tlatestHeight := int64(2025) // duplicated from setMockExpectations\n\t\t\t\tsyncToHeight := int64(2026) // duplicated from setMockExpectations\n\n\t\t\t\trequire.Equal(t, latestHeight, data.HeadSlot)\n\t\t\t\trequire.Equal(t, syncToHeight-latestHeight, data.SyncDistance)\n\t\t\t\trequire.True(t, data.IsSyncing)\n\t\t\t\trequire.False(t, data.IsOptimistic)\n\t\t\t\trequire.False(t, data.ELOffline)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"normal operations mode\",\n\t\t\tsetMockExpectations: func(b *mocks.Backend) {\n\t\t\t\tlatestHeight := int64(1492)\n\t\t\t\tsyncToHeight := int64(1492)\n\t\t\t\tb.EXPECT().GetSyncData().Return(latestHeight, syncToHeight).Once()\n\t\t\t},\n\t\t\tcheck: func(t *testing.T, res any, err error) {\n\t\t\t\tt.Helper()\n\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.NotNil(t, res)\n\t\t\t\trequire.IsType(t, types.DataResponse{}, res)\n\t\t\t\tdr, _ := res.(types.DataResponse)\n\t\t\t\trequire.IsType(t, &types.SyncingData{}, dr.Data)\n\t\t\t\tdata, _ := dr.Data.(*types.SyncingData)\n\n\t\t\t\tlatestHeight := int64(1492) // duplicated from setMockExpectations\n\t\t\t\tsyncToHeight := int64(1492) // duplicated from setMockExpectations\n\n\t\t\t\trequire.Equal(t, latestHeight, data.HeadSlot)\n\t\t\t\trequire.Equal(t, syncToHeight-latestHeight, data.SyncDistance)\n\t\t\t\trequire.False(t, data.IsSyncing)\n\t\t\t\trequire.False(t, data.IsOptimistic)\n\t\t\t\trequire.False(t, data.ELOffline)\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\t// setup test\n\t\t\tbackend := mocks.NewBackend(t)\n\t\t\th := node.NewHandler(backend, noop.NewLogger[log.Logger]())\n\n\t\t\ttc.setMockExpectations(backend)\n\n\t\t\t// test\n\t\t\tres, err := h.Syncing(nil) // input does not matter here\n\n\t\t\ttc.check(t, res, err)\n\t\t})\n\t}\n}\n\nfunc TestNodeVersion(t *testing.T) {\n\tt.Parallel()\n\n\t// setup test\n\tbackend := mocks.NewBackend(t)\n\th := node.NewHandler(backend, noop.NewLogger[log.Logger]())\n\n\tvar (\n\t\tappName = \"testing-beacond\"\n\t\tversion = \"x.x.x-rc-14-gebeee824a\"\n\t\tos      = \"theOs\"\n\t\tarch    = \"theArch\"\n\t)\n\tbackend.EXPECT().GetVersionData().Return(appName, version, os, arch).Once()\n\n\t// test\n\tres, err := h.Version(nil) // input does not matter here\n\n\t// checks\n\trequire.NoError(t, err)\n\trequire.NotNil(t, res)\n\trequire.IsType(t, types.DataResponse{}, res)\n\tdr, _ := res.(types.DataResponse)\n\trequire.IsType(t, &types.VersionData{}, dr.Data)\n\tdata, _ := dr.Data.(*types.VersionData)\n\n\trequire.Contains(t, data.Version, appName)\n\trequire.Contains(t, data.Version, version)\n\trequire.Contains(t, data.Version, os)\n\trequire.Contains(t, data.Version, arch)\n}\n"
  },
  {
    "path": "node-api/handlers/node/routes.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage node\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n)\n\nfunc registerRoutes(h *Handler) {\n\th.BaseHandler.AddRoutes([]*handlers.Route{\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/node/identity\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/node/peers\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/node/peers/:peer_id\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/node/peer_count\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/node/version\",\n\t\t\tHandler: h.Version,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/node/syncing\",\n\t\t\tHandler: h.Syncing,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/node/health\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "node-api/handlers/node/types/response.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"encoding/json\"\n\t\"strconv\"\n)\n\ntype DataResponse struct {\n\tData any `json:\"data\"`\n}\n\nfunc Wrap(data any) DataResponse {\n\treturn DataResponse{\n\t\tData: data,\n\t}\n}\n\ntype VersionData struct {\n\tVersion string `json:\"version\"`\n}\n\ntype SyncingData struct {\n\tHeadSlot     int64 `json:\"head_slot\"`\n\tSyncDistance int64 `json:\"sync_distance\"`\n\tIsSyncing    bool  `json:\"is_syncing\"`\n\tIsOptimistic bool  `json:\"is_optimistic\"`\n\tELOffline    bool  `json:\"el_offline\"`\n}\n\ntype syncingJSON struct {\n\tHeadSlot     string `json:\"head_slot\"`\n\tSyncDistance string `json:\"sync_distance\"`\n\tIsSyncing    bool   `json:\"is_syncing\"`\n\tIsOptimistic bool   `json:\"is_optimistic\"`\n\tELOffline    bool   `json:\"el_offline\"`\n}\n\nfunc (s *SyncingData) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(syncingJSON{\n\t\tHeadSlot:     strconv.FormatInt(s.HeadSlot, 10),\n\t\tSyncDistance: strconv.FormatInt(s.SyncDistance, 10),\n\t\tIsSyncing:    s.IsSyncing,\n\t\tIsOptimistic: s.IsOptimistic,\n\t\tELOffline:    s.ELOffline,\n\t})\n}\n"
  },
  {
    "path": "node-api/handlers/proof/backend.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage proof\n\nimport (\n\t\"github.com/berachain/beacon-kit/node-api/backend\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// Backend is the interface for backend of the proof API.\ntype Backend interface {\n\tStateBackend\n\tGetParentSlotByTimestamp(timestamp math.U64) (math.Slot, error)\n}\n\ntype StateBackend interface {\n\tStateAndSlotFromHeight(height int64) (backend.ReadOnlyBeaconState, math.Slot, error)\n}\n"
  },
  {
    "path": "node-api/handlers/proof/block_proposer.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage proof\n\nimport (\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/proof/merkle\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/proof/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n)\n\n// GetBlockProposer returns the block proposer pubkey for the given timestamp\n// id along with a merkle proof that can be verified against the beacon block\n// root. It also returns the merkle proof of the proposer index.\nfunc (h *Handler) GetBlockProposer(c handlers.Context) (any, error) {\n\tparams, err := utils.BindAndValidate[types.BlockProposerRequest](c, h.Logger())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tslot, beaconState, blockHeader, err := h.resolveTimestampID(params.TimestampID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\th.Logger().Info(\"Generating block proposer proofs\", \"slot\", slot)\n\n\t// Generate the proof (along with the \"correct\" beacon block root to verify against) for the\n\t// proposer validator's pubkey.\n\tbsm, err := beaconState.GetMarshallable()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpubkeyProof, beaconBlockRoot, err := merkle.ProveProposerPubkeyInBlock(blockHeader, bsm)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Generate the proof for the proposer index.\n\tproposerIndexProof, _, err := merkle.ProveProposerIndexInBlock(blockHeader)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Get the pubkey of the proposer validator.\n\tproposerValidator, err := beaconState.ValidatorByIndex(blockHeader.GetProposerIndex())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn types.BlockProposerResponse{\n\t\tBeaconBlockHeader:    blockHeader,\n\t\tBeaconBlockRoot:      beaconBlockRoot,\n\t\tValidatorPubkey:      proposerValidator.GetPubkey(),\n\t\tValidatorPubkeyProof: pubkeyProof,\n\t\tProposerIndexProof:   proposerIndexProof,\n\t}, nil\n}\n"
  },
  {
    "path": "node-api/handlers/proof/handler.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage proof\n\nimport (\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/node-api/backend\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// Handler is the handler for the proof API.\ntype Handler struct {\n\t*handlers.BaseHandler\n\tbackend Backend\n}\n\n// NewHandler creates a new handler for the proof API.\nfunc NewHandler(backend Backend, logger log.Logger) *Handler {\n\th := &Handler{\n\t\tBaseHandler: handlers.NewBaseHandler(logger),\n\t\tbackend:     backend,\n\t}\n\tregisterRoutes(h)\n\treturn h\n}\n\n// Get the slot from the given input of timestamp id, beacon state, and beacon\n// block header for the resolved slot.\nfunc (h *Handler) resolveTimestampID(timestampID string) (\n\tmath.Slot, backend.ReadOnlyBeaconState, *ctypes.BeaconBlockHeader, error,\n) {\n\tvar (\n\t\tbeaconState backend.ReadOnlyBeaconState\n\t\tblockHeader *ctypes.BeaconBlockHeader\n\t\tslot        math.Slot\n\t)\n\n\theight, err := utils.TimestampIDToParentHeight(timestampID, h.backend)\n\tif err != nil {\n\t\treturn 0, beaconState, blockHeader, err\n\t}\n\n\tbeaconState, slot, err = h.backend.StateAndSlotFromHeight(height)\n\tif err != nil {\n\t\treturn 0, beaconState, blockHeader, err\n\t}\n\n\t// Return after updating the state root in the block header.\n\tblockHeader, err = beaconState.GetLatestBlockHeader()\n\tif err != nil {\n\t\treturn 0, beaconState, blockHeader, err\n\t}\n\tblockHeader.SetStateRoot(beaconState.HashTreeRoot())\n\n\treturn slot, beaconState, blockHeader, nil\n}\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/beacon_state.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle\n\nimport (\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/merkle\"\n)\n\n// ProveBeaconStateInBlock generates a proof for the beacon state in the\n// beacon block. It uses the fastssz library to generate the proof.\nfunc ProveBeaconStateInBlock(\n\tbbh *ctypes.BeaconBlockHeader, verifyProof bool,\n) ([]common.Root, error) {\n\tblockProofTree, err := bbh.GetTree()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tstateInBlockProof, err := blockProofTree.Prove(StateGIndexBlock)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tproof := make([]common.Root, len(stateInBlockProof.Hashes))\n\tfor i, hash := range stateInBlockProof.Hashes {\n\t\tproof[i] = common.NewRootFromBytes(hash)\n\t}\n\n\tif verifyProof {\n\t\tif err = verifyBeaconStateInBlock(\n\t\t\tbbh, proof, common.NewRootFromBytes(stateInBlockProof.Leaf),\n\t\t); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn proof, nil\n}\n\n// verifyBeaconStateInBlock verifies the beacon state proof in the block.\n//\n// TODO: verifying the proof is not absolutely necessary.\nfunc verifyBeaconStateInBlock(\n\tbbh *ctypes.BeaconBlockHeader, proof []common.Root, leaf common.Root,\n) error {\n\tbeaconRoot := bbh.HashTreeRoot()\n\tif !merkle.VerifyProof(beaconRoot, leaf, StateGIndexBlock, proof) {\n\t\treturn errors.Wrapf(\n\t\t\terrors.New(\"beacon stateproof failed to verify against beacon root\"),\n\t\t\t\"beacon root: 0x%s\", beaconRoot,\n\t\t)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/beacon_state_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/proof/merkle\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// TestProveBeaconStateInBlock tests the ProveBeaconStateInBlock function and\n// that the generated proof correctly verifies.\nfunc TestProveBeaconStateInBlock(t *testing.T) {\n\tt.Parallel()\n\tbbh := &types.BeaconBlockHeader{}\n\n\ttestCases := []struct {\n\t\tname              string\n\t\tslot              math.Slot\n\t\tproposerIndex     math.ValidatorIndex\n\t\tparentBlockRoot   common.Root\n\t\tbodyRoot          common.Root\n\t\tstateRoot         common.Root\n\t\texpectedProofFile string\n\t}{\n\t\t{\n\t\t\tname:              \"Empty block with non-empty state root\",\n\t\t\tstateRoot:         common.Root{1, 2, 3, 4, 5, 6, 7, 8, 9},\n\t\t\texpectedProofFile: \"empty_state_proof.json\",\n\t\t},\n\t\t{\n\t\t\tname:              \"Non-empty block with empty state root\",\n\t\t\tslot:              4,\n\t\t\tproposerIndex:     5,\n\t\t\tparentBlockRoot:   common.Root{1, 2, 3, 4, 5, 6, 7, 8, 9},\n\t\t\tbodyRoot:          common.Root{9, 8, 7, 6, 5, 4, 3, 2, 1},\n\t\t\texpectedProofFile: \"non_empty_state_proof.json\",\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tbbh.SetSlot(tc.slot)\n\t\t\tbbh.SetProposerIndex(tc.proposerIndex)\n\t\t\tbbh.SetParentBlockRoot(tc.parentBlockRoot)\n\t\t\tbbh.SetBodyRoot(tc.bodyRoot)\n\t\t\tbbh.SetStateRoot(tc.stateRoot)\n\n\t\t\tproof, err := merkle.ProveBeaconStateInBlock(bbh, true)\n\t\t\trequire.NoError(t, err)\n\t\t\texpectedProof := ReadProofFromFile(t, tc.expectedProofFile)\n\t\t\trequire.Equal(t, expectedProof, proof)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/generalized_indexes.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n)\n\nconst (\n\t// ProposerIndexGIndexBlock is the generalized index of the proposer index in the beacon block.\n\t// This value remains consistent for all Deneb and Electra forks.\n\tProposerIndexGIndexBlock = 9\n\n\t// StateGIndexBlock is the generalized index of the beacon state in the beacon block. This\n\t// value remains consistent for all Deneb and Electra forks.\n\tStateGIndexBlock = 11\n\n\t// ZeroValidatorPubkeyGIndexDenebState is the generalized index of the 0\n\t// validator's pubkey in the beacon state in the Deneb forks. To get the\n\t// GIndex of the pubkey of validator at index n, the formula is:\n\t// GIndex = ZeroValidatorPubkeyGIndexDenebState + (ValidatorPubkeyGIndexOffset * n)\n\tZeroValidatorPubkeyGIndexDenebState = 439804651110400\n\n\t// ZeroValidatorPubkeyGIndexDenebBlock is the generalized index of the 0\n\t// validator's pubkey in the beacon block in the Deneb forks. This is\n\t// calculated by concatenating the (ZeroValidatorPubkeyGIndexDenebState, StateGIndexBlock)\n\t// GIndices. To get the GIndex of the pubkey of validator at index n, the formula is:\n\t// GIndex = ZeroValidatorPubkeyGIndexDenebBlock + (ValidatorPubkeyGIndexOffset * n)\n\tZeroValidatorPubkeyGIndexDenebBlock = 3254554418216960\n\n\t// ValidatorGIndexOffset is the offset of a validator's GIndex.\n\tValidatorGIndexOffset = 8\n\n\t// ZeroValidatorPubkeyGIndexElectraState is the generalized index of the 0\n\t// validator's pubkey in the beacon state in the Electra forks. To get the\n\t// GIndex of the pubkey of validator at index n, the formula is:\n\t// GIndex = ZeroValidatorPubkeyGIndexElectraState + (ValidatorPubkeyGIndexOffset * n)\n\tZeroValidatorPubkeyGIndexElectraState = 721279627821056\n\n\t// ZeroValidatorPubkeyGIndexElectraBlock is the generalized index of the 0\n\t// validator's pubkey in the beacon block in the Electra forks. This is\n\t// calculated by concatenating the (ZeroValidatorPubkeyGIndexElectraState, StateGIndexBlock)\n\t// GIndices. To get the GIndex of the pubkey of validator at index n, the formula is:\n\t// GIndex = ZeroValidatorPubkeyGIndexElectraBlock + (ValidatorPubkeyGIndexOffset * n)\n\tZeroValidatorPubkeyGIndexElectraBlock = 6350779162034176\n\n\t// ZeroValidatoCredentialsGIndexElectraState is the generalized index of the 0\n\t// validator's withdrawal credentials in the beacon state in the Electra forks. To get the\n\t// GIndex of the withdrawal credentials of validator at index n, the formula is:\n\t// GIndex = ZeroValidatorCredentialsGIndexElectraState + (ValidatorGIndexOffset * n)\n\tZeroValidatorCredentialsGIndexElectraState = 721279627821057\n\n\t// ZeroValidatorCredentialsGIndexElectraBlock is the generalized index of the 0\n\t// validator's withdrawal credentials in the beacon block in the Electra forks. This is\n\t// calculated by concatenating the (ZeroValidatorCredentialsGIndexElectraState, StateGIndexBlock)\n\t// GIndices. To get the GIndex of the withdrawal credentials of validator at index n, the formula is:\n\t// GIndex = ZeroValidatorCredentialsGIndexElectraBlock + (ValidatorGIndexOffset * n)\n\tZeroValidatorCredentialsGIndexElectraBlock = 6350779162034177\n\n\t// ZeroValidatorBalanceGIndexElectraState is the generalized index of the 0-3\n\t// validators' balances in the beacon state in the Electra forks. Balances are\n\t// packed 4 per leaf (uint64 values, 32 bytes per leaf). To get the GIndex of\n\t// the balance of validator at index n, the formula is:\n\t// GIndex = ZeroValidatorBalanceGIndexElectraState + (n / 4)\n\tZeroValidatorBalanceGIndexElectraState = 23089744183296\n\n\t// ZeroValidatorBalanceGIndexElectraBlock is the generalized index of the 0-3\n\t// validators' balances in the beacon block in the Electra forks. This is\n\t// calculated by concatenating the (ZeroValidatorBalanceGIndexElectraState, StateGIndexBlock)\n\t// GIndices. To get the GIndex of the balance of validator at index n, the formula is:\n\t// GIndex = ZeroValidatorBalanceGIndexElectraBlock + (n / 4)\n\tZeroValidatorBalanceGIndexElectraBlock = 199011604627456\n\n\t// BalancesPerLeaf is the number of validator balances packed into a single leaf.\n\tBalancesPerLeaf = 4\n)\n\n// GetZeroValidatorPubkeyGIndexState determines the generalized index of the 0\n// validator's pubkey in the beacon state based on the fork version.\nfunc GetZeroValidatorPubkeyGIndexState(forkVersion common.Version) (int, error) {\n\tif version.EqualsOrIsAfter(forkVersion, version.Electra()) {\n\t\treturn ZeroValidatorPubkeyGIndexElectraState, nil\n\t} else if version.EqualsOrIsAfter(forkVersion, version.Deneb()) {\n\t\treturn ZeroValidatorPubkeyGIndexDenebState, nil\n\t}\n\treturn 0, fmt.Errorf(\"unsupported fork version: %s\", forkVersion)\n}\n\n// GetZeroValidatorPubkeyGIndexBlock determines the generalized index of the 0\n// validator's pubkey in the beacon block based on the fork version.\nfunc GetZeroValidatorPubkeyGIndexBlock(forkVersion common.Version) (uint64, error) {\n\tif version.EqualsOrIsAfter(forkVersion, version.Electra()) {\n\t\treturn ZeroValidatorPubkeyGIndexElectraBlock, nil\n\t} else if version.EqualsOrIsAfter(forkVersion, version.Deneb()) {\n\t\treturn ZeroValidatorPubkeyGIndexDenebBlock, nil\n\t}\n\treturn 0, fmt.Errorf(\"unsupported fork version: %s\", forkVersion)\n}\n\n// GetZeroValidatorCredentialsGIndexState determines the generalized\n// index of the 0-th validator's withdrawal credentials in the beacon state\n// based on the fork version.\nfunc GetZeroValidatorCredentialsGIndexState(forkVersion common.Version) (int, error) {\n\tif version.EqualsOrIsAfter(forkVersion, version.Electra()) {\n\t\treturn ZeroValidatorCredentialsGIndexElectraState, nil\n\t}\n\treturn 0, fmt.Errorf(\"unsupported fork version: %s\", forkVersion)\n}\n\n// GetZeroValidatorCredentialsGIndexBlock determines the generalized\n// index of the 0-th validator's withdrawal credentials in the beacon block\n// based on the fork version.\nfunc GetZeroValidatorCredentialsGIndexBlock(forkVersion common.Version) (uint64, error) {\n\tif version.EqualsOrIsAfter(forkVersion, version.Electra()) {\n\t\treturn ZeroValidatorCredentialsGIndexElectraBlock, nil\n\t}\n\treturn 0, fmt.Errorf(\"unsupported fork version: %s\", forkVersion)\n}\n\n// GetZeroValidatorBalanceGIndexState determines the generalized\n// index of the 0-3 validators' balances in the beacon state\n// based on the fork version.\nfunc GetZeroValidatorBalanceGIndexState(forkVersion common.Version) (int, error) {\n\tif version.EqualsOrIsAfter(forkVersion, version.Electra()) {\n\t\treturn ZeroValidatorBalanceGIndexElectraState, nil\n\t}\n\treturn 0, fmt.Errorf(\"unsupported fork version: %s\", forkVersion)\n}\n\n// GetZeroValidatorBalanceGIndexBlock determines the generalized\n// index of the 0-3 validators' balances in the beacon block\n// based on the fork version.\nfunc GetZeroValidatorBalanceGIndexBlock(forkVersion common.Version) (uint64, error) {\n\tif version.EqualsOrIsAfter(forkVersion, version.Electra()) {\n\t\treturn ZeroValidatorBalanceGIndexElectraBlock, nil\n\t}\n\treturn 0, fmt.Errorf(\"unsupported fork version: %s\", forkVersion)\n}\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/generalized_indexes_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle_test\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/node-api/handlers/proof/merkle\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz/schema\"\n\tmlib \"github.com/berachain/beacon-kit/primitives/merkle\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nvar (\n\tbeaconStateFieldsDeneb = []*schema.Field{\n\t\tschema.NewField(\"GenesisValidatorsRoot\", schema.B32()),\n\t\tschema.NewField(\"Slot\", schema.U64()),\n\t\tschema.NewField(\"Fork\", schema.DefineContainer(\n\t\t\tschema.NewField(\"PreviousVersion\", schema.B4()),\n\t\t\tschema.NewField(\"CurrentVersion\", schema.B4()),\n\t\t\tschema.NewField(\"Epoch\", schema.U64()),\n\t\t)),\n\t\tschema.NewField(\"LatestBlockHeader\", schema.DefineContainer(\n\t\t\tschema.NewField(\"Slot\", schema.U64()),\n\t\t\tschema.NewField(\"ProposerIndex\", schema.U64()),\n\t\t\tschema.NewField(\"ParentBlockRoot\", schema.B32()),\n\t\t\tschema.NewField(\"StateRoot\", schema.B32()),\n\t\t\tschema.NewField(\"BodyRoot\", schema.B32()),\n\t\t)),\n\t\tschema.NewField(\"BlockRoots\", schema.DefineList(schema.B32(), 8192)),\n\t\tschema.NewField(\"StateRoots\", schema.DefineList(schema.B32(), 8192)),\n\t\tschema.NewField(\"Eth1Data\", schema.DefineContainer(\n\t\t\tschema.NewField(\"DepositRoot\", schema.B32()),\n\t\t\tschema.NewField(\"DepositCount\", schema.U64()),\n\t\t\tschema.NewField(\"BlockHash\", schema.B32()),\n\t\t)),\n\t\tschema.NewField(\"Eth1DepositIndex\", schema.U64()),\n\t\tschema.NewField(\"LatestExecutionPayloadHeader\", schema.DefineContainer(\n\t\t\tschema.NewField(\"ParentHash\", schema.B32()),\n\t\t\tschema.NewField(\"FeeRecipient\", schema.B20()),\n\t\t\tschema.NewField(\"StateRoot\", schema.B32()),\n\t\t\tschema.NewField(\"ReceiptsRoot\", schema.B32()),\n\t\t\tschema.NewField(\"LogsBloom\", schema.B256()),\n\t\t\tschema.NewField(\"Random\", schema.B32()),\n\t\t\tschema.NewField(\"Number\", schema.U64()),\n\t\t\tschema.NewField(\"GasLimit\", schema.U64()),\n\t\t\tschema.NewField(\"GasUsed\", schema.U64()),\n\t\t\tschema.NewField(\"Timestamp\", schema.U64()),\n\t\t\tschema.NewField(\"ExtraData\", schema.DefineByteList(32)),\n\t\t\tschema.NewField(\"BaseFeePerGas\", schema.U256()),\n\t\t\tschema.NewField(\"BlockHash\", schema.B32()),\n\t\t\tschema.NewField(\"TransactionsRoot\", schema.B32()),\n\t\t\tschema.NewField(\"WithdrawalsRoot\", schema.B32()),\n\t\t\tschema.NewField(\"BlobGasUsed\", schema.U64()),\n\t\t\tschema.NewField(\"ExcessBlobGas\", schema.U64()),\n\t\t)),\n\t\tschema.NewField(\"Validators\", schema.DefineList(schema.DefineContainer(\n\t\t\tschema.NewField(\"Pubkey\", schema.B48()),\n\t\t\tschema.NewField(\"WithdrawalCredentials\", schema.B32()),\n\t\t\tschema.NewField(\"EffectiveBalance\", schema.U64()),\n\t\t\tschema.NewField(\"Slashed\", schema.Bool()),\n\t\t\tschema.NewField(\"ActivationEligibilityEpoch\", schema.U64()),\n\t\t\tschema.NewField(\"ActivationEpoch\", schema.U64()),\n\t\t\tschema.NewField(\"ExitEpoch\", schema.U64()),\n\t\t\tschema.NewField(\"WithdrawableEpoch\", schema.U64()),\n\t\t), constants.ValidatorsRegistryLimit)),\n\t\tschema.NewField(\n\t\t\t\"Balances\", schema.DefineList(schema.U64(), constants.ValidatorsRegistryLimit),\n\t\t),\n\t\tschema.NewField(\"RandaoMixes\", schema.DefineList(schema.B32(), 65536)),\n\t\tschema.NewField(\"NextWithdrawalIndex\", schema.U64()),\n\t\tschema.NewField(\"NextWithdrawalValidatorIndex\", schema.U64()),\n\t\tschema.NewField(\n\t\t\t\"Slashings\", schema.DefineList(schema.U64(), constants.ValidatorsRegistryLimit),\n\t\t),\n\t\tschema.NewField(\"TotalSlashing\", schema.U64()),\n\t}\n\n\tadditionalBeaconStateFieldsElectra = []*schema.Field{\n\t\tschema.NewField(\"PendingPartialWithdrawals\", schema.DefineList(schema.DefineContainer(\n\t\t\tschema.NewField(\"ValidatorIndex\", schema.U64()),\n\t\t\tschema.NewField(\"Amount\", schema.U64()),\n\t\t\tschema.NewField(\"WithdrawableEpoch\", schema.U64()),\n\t\t), constants.PendingPartialWithdrawalsLimit)),\n\t}\n\n\t// beaconStateSchemaDeneb is the schema for the BeaconState struct in the Deneb forks.\n\tbeaconStateSchemaDeneb = schema.DefineContainer(beaconStateFieldsDeneb...)\n\n\t// beaconStateSchemaElectra is the schema for the BeaconState struct in the Electra forks.\n\tbeaconStateSchemaElectra = schema.DefineContainer(\n\t\tappend(beaconStateFieldsDeneb, additionalBeaconStateFieldsElectra...)...,\n\t)\n)\n\nvar (\n\t// beaconHeaderSchemaDeneb is the schema for the BeaconBlockHeader in the Deneb forks, with the\n\t// SSZ expansion of StateRoot to use the BeaconState.\n\tbeaconHeaderSchemaDeneb = schema.DefineContainer(\n\t\tschema.NewField(\"Slot\", schema.U64()),\n\t\tschema.NewField(\"ProposerIndex\", schema.U64()),\n\t\tschema.NewField(\"ParentRoot\", schema.B32()),\n\t\tschema.NewField(\"State\", beaconStateSchemaDeneb),\n\t\tschema.NewField(\"BodyRoot\", schema.B32()),\n\t)\n\n\t// beaconHeaderSchemaElectra is the schema for the BeaconBlockHeader in the Electra forks, with\n\t// the SSZ expansion of StateRoot to use the BeaconState.\n\tbeaconHeaderSchemaElectra = schema.DefineContainer(\n\t\tschema.NewField(\"Slot\", schema.U64()),\n\t\tschema.NewField(\"ProposerIndex\", schema.U64()),\n\t\tschema.NewField(\"ParentRoot\", schema.B32()),\n\t\tschema.NewField(\"State\", beaconStateSchemaElectra),\n\t\tschema.NewField(\"BodyRoot\", schema.B32()),\n\t)\n)\n\n// TestGIndexProposerIndex tests the generalized index of the proposer\n// index in the beacon block.\nfunc TestGIndexProposerIndex(t *testing.T) {\n\tt.Parallel()\n\n\t// Deneb forks.\n\t_, proposerIndexGIndexBlock, _, err := mlib.ObjectPath(\n\t\t\"ProposerIndex\",\n\t).GetGeneralizedIndex(beaconHeaderSchemaDeneb)\n\trequire.NoError(t, err)\n\trequire.Equal(\n\t\tt,\n\t\tmerkle.ProposerIndexGIndexBlock,\n\t\tint(proposerIndexGIndexBlock),\n\t)\n\n\t// Electra forks.\n\t_, proposerIndexGIndexBlockElectra, _, err := mlib.ObjectPath(\n\t\t\"ProposerIndex\",\n\t).GetGeneralizedIndex(beaconHeaderSchemaElectra)\n\trequire.NoError(t, err)\n\trequire.Equal(t,\n\t\tmerkle.ProposerIndexGIndexBlock,\n\t\tint(proposerIndexGIndexBlockElectra),\n\t)\n}\n\n// TestGIndicesValidatorPubkeyDeneb tests the generalized indices used by\n// beacon state proofs for validator pubkeys on the Deneb forks.\nfunc TestGIndicesValidatorPubkeyDeneb(t *testing.T) {\n\tt.Parallel()\n\n\t// GIndex of state in the block.\n\t_, stateGIndexBlock, _, err := mlib.ObjectPath(\n\t\t\"State\",\n\t).GetGeneralizedIndex(beaconHeaderSchemaDeneb)\n\trequire.NoError(t, err)\n\trequire.Equal(t, merkle.StateGIndexBlock, int(stateGIndexBlock))\n\n\t// GIndex of the 0 validator's pubkey in the state.\n\t_, zeroValidatorPubkeyGIndexState, _, err := mlib.ObjectPath(\n\t\t\"Validators/0/Pubkey\",\n\t).GetGeneralizedIndex(beaconStateSchemaDeneb)\n\trequire.NoError(t, err)\n\trequire.Equal(t,\n\t\tmerkle.ZeroValidatorPubkeyGIndexDenebState,\n\t\tint(zeroValidatorPubkeyGIndexState),\n\t)\n\n\t// GIndex of the 0 validator's pubkey in the block.\n\t_, zeroValidatorPubkeyGIndexBlock, _, err := mlib.ObjectPath(\n\t\t\"State/Validators/0/Pubkey\",\n\t).GetGeneralizedIndex(beaconHeaderSchemaDeneb)\n\trequire.NoError(t, err)\n\trequire.Equal(t,\n\t\tmerkle.ZeroValidatorPubkeyGIndexDenebBlock,\n\t\tint(zeroValidatorPubkeyGIndexBlock),\n\t)\n\n\t// Concatenation is consistent.\n\tconcatValidatorPubkeyStateToBlock := mlib.GeneralizedIndices{\n\t\tmlib.GeneralizedIndex(stateGIndexBlock),\n\t\tmlib.GeneralizedIndex(zeroValidatorPubkeyGIndexState),\n\t}.Concat()\n\trequire.Equal(t,\n\t\tzeroValidatorPubkeyGIndexBlock,\n\t\tuint64(concatValidatorPubkeyStateToBlock),\n\t)\n\n\t// GIndex offset of the next validator's pubkey.\n\t_, oneValidatorPubkeyGIndexState, _, err := mlib.ObjectPath(\n\t\t\"Validators/1/Pubkey\",\n\t).GetGeneralizedIndex(beaconStateSchemaDeneb)\n\trequire.NoError(t, err)\n\trequire.Equal(t,\n\t\tmerkle.ValidatorGIndexOffset,\n\t\tint(oneValidatorPubkeyGIndexState-zeroValidatorPubkeyGIndexState),\n\t)\n}\n\n// TestGIndicesValidatorPubkeyElectra tests the generalized indices used by\n// beacon state proofs for validator pubkeys on the Electra forks.\nfunc TestGIndicesValidatorPubkeyElectra(t *testing.T) {\n\tt.Parallel()\n\n\t// GIndex of state in the block.\n\t_, stateGIndexBlock, _, err := mlib.ObjectPath(\n\t\t\"State\",\n\t).GetGeneralizedIndex(beaconHeaderSchemaElectra)\n\trequire.NoError(t, err)\n\trequire.Equal(t, merkle.StateGIndexBlock, int(stateGIndexBlock))\n\n\t// GIndex of the 0 validator's pubkey in the state.\n\t_, zeroValidatorPubkeyGIndexState, _, err := mlib.ObjectPath(\n\t\t\"Validators/0/Pubkey\",\n\t).GetGeneralizedIndex(beaconStateSchemaElectra)\n\trequire.NoError(t, err)\n\trequire.Equal(t,\n\t\tmerkle.ZeroValidatorPubkeyGIndexElectraState,\n\t\tint(zeroValidatorPubkeyGIndexState),\n\t)\n\n\t// GIndex of the 0 validator's pubkey in the block.\n\t_, zeroValidatorPubkeyGIndexBlock, _, err := mlib.ObjectPath(\n\t\t\"State/Validators/0/Pubkey\",\n\t).GetGeneralizedIndex(beaconHeaderSchemaElectra)\n\trequire.NoError(t, err)\n\trequire.Equal(t,\n\t\tmerkle.ZeroValidatorPubkeyGIndexElectraBlock,\n\t\tint(zeroValidatorPubkeyGIndexBlock),\n\t)\n\n\t// Concatenation is consistent.\n\tconcatValidatorPubkeyStateToBlock := mlib.GeneralizedIndices{\n\t\tmlib.GeneralizedIndex(stateGIndexBlock),\n\t\tmlib.GeneralizedIndex(zeroValidatorPubkeyGIndexState),\n\t}.Concat()\n\trequire.Equal(t,\n\t\tzeroValidatorPubkeyGIndexBlock,\n\t\tuint64(concatValidatorPubkeyStateToBlock),\n\t)\n\n\t// GIndex offset of the next validator's pubkey.\n\t_, oneValidatorPubkeyGIndexState, _, err := mlib.ObjectPath(\n\t\t\"Validators/1/Pubkey\",\n\t).GetGeneralizedIndex(beaconStateSchemaElectra)\n\trequire.NoError(t, err)\n\trequire.Equal(t,\n\t\tmerkle.ValidatorGIndexOffset,\n\t\tint(oneValidatorPubkeyGIndexState-zeroValidatorPubkeyGIndexState),\n\t)\n}\n\nfunc TestValidatorWithdrawalCredentialsGIndexElectra(t *testing.T) {\n\tt.Parallel()\n\n\t// GIndex of the 0 validator's withdrawal credentials in the state.\n\t_, zeroValidatorWithdrawalCredentialsGIndexState, _, err := mlib.ObjectPath(\n\t\t\"Validators/0/WithdrawalCredentials\",\n\t).GetGeneralizedIndex(beaconStateSchemaElectra)\n\trequire.NoError(t, err)\n\trequire.Equal(t,\n\t\tmerkle.ZeroValidatorCredentialsGIndexElectraState,\n\t\tint(zeroValidatorWithdrawalCredentialsGIndexState),\n\t)\n\n\t// GIndex of the 0 validator's withdrawal credentials in the block.\n\t_, zeroValidatorWithdrawalCredentialsGIndexBlock, _, err := mlib.ObjectPath(\n\t\t\"State/Validators/0/WithdrawalCredentials\",\n\t).GetGeneralizedIndex(beaconHeaderSchemaElectra)\n\trequire.NoError(t, err)\n\trequire.Equal(t,\n\t\tmerkle.ZeroValidatorCredentialsGIndexElectraBlock,\n\t\tint(zeroValidatorWithdrawalCredentialsGIndexBlock),\n\t)\n\n\t// Concatenation is consistent.\n\tconcatValidatorWithdrawalCredentialsStateToBlock := mlib.GeneralizedIndices{\n\t\tmlib.GeneralizedIndex(merkle.StateGIndexBlock),\n\t\tmlib.GeneralizedIndex(zeroValidatorWithdrawalCredentialsGIndexState),\n\t}.Concat()\n\trequire.Equal(t,\n\t\tzeroValidatorWithdrawalCredentialsGIndexBlock,\n\t\tuint64(concatValidatorWithdrawalCredentialsStateToBlock),\n\t)\n\n\t// GIndex offset of the next validator's withdrawal credentials.\n\t_, oneValidatorWithdrawalCredentialsGIndexState, _, err := mlib.ObjectPath(\n\t\t\"Validators/1/WithdrawalCredentials\",\n\t).GetGeneralizedIndex(beaconStateSchemaElectra)\n\trequire.NoError(t, err)\n\trequire.Equal(t,\n\t\tmerkle.ValidatorGIndexOffset,\n\t\tint(oneValidatorWithdrawalCredentialsGIndexState-zeroValidatorWithdrawalCredentialsGIndexState),\n\t)\n}\n\nfunc TestValidatorBalanceGIndexElectra(t *testing.T) {\n\tt.Parallel()\n\n\t// GIndex of the 0 validator's balance in the state.\n\t_, zeroValidatorBalanceGIndexState, _, err := mlib.ObjectPath(\n\t\t\"Balances/0\",\n\t).GetGeneralizedIndex(beaconStateSchemaElectra)\n\trequire.NoError(t, err)\n\trequire.Equal(t,\n\t\tmerkle.ZeroValidatorBalanceGIndexElectraState,\n\t\tint(zeroValidatorBalanceGIndexState),\n\t)\n\n\t// GIndex of the 0 validator's balance in the block.\n\t_, zeroValidatorBalanceGIndexBlock, _, err := mlib.ObjectPath(\n\t\t\"State/Balances/0\",\n\t).GetGeneralizedIndex(beaconHeaderSchemaElectra)\n\trequire.NoError(t, err)\n\trequire.Equal(t,\n\t\tmerkle.ZeroValidatorBalanceGIndexElectraBlock,\n\t\tint(zeroValidatorBalanceGIndexBlock),\n\t)\n\n\t// Concatenation is consistent.\n\tconcatValidatorBalanceStateToBlock := mlib.GeneralizedIndices{\n\t\tmlib.GeneralizedIndex(merkle.StateGIndexBlock),\n\t\tmlib.GeneralizedIndex(zeroValidatorBalanceGIndexState),\n\t}.Concat()\n\trequire.Equal(t,\n\t\tzeroValidatorBalanceGIndexBlock,\n\t\tuint64(concatValidatorBalanceStateToBlock),\n\t)\n\n\t// Verify that balances 0-3 share the same GIndex (packed in same leaf)\n\tfor i := range merkle.BalancesPerLeaf {\n\t\tpath := fmt.Sprintf(\"Balances/%d\", i)\n\t\t_, balanceGIndex, _, gIndexErr := mlib.ObjectPath(path).GetGeneralizedIndex(beaconStateSchemaElectra)\n\t\trequire.NoError(t, gIndexErr)\n\t\trequire.Equal(t, zeroValidatorBalanceGIndexState, balanceGIndex)\n\t}\n\n\t// GIndex offset of the next validator's balance.\n\t// Balances are packed 4 per leaf (uint64 values, 32 bytes per leaf)\n\tbalance4Path := fmt.Sprintf(\"Balances/%d\", merkle.BalancesPerLeaf)\n\t_, balanceGIndex4, _, err := mlib.ObjectPath(balance4Path).GetGeneralizedIndex(beaconStateSchemaElectra)\n\trequire.NoError(t, err)\n\trequire.Equal(t, 1, int(balanceGIndex4-zeroValidatorBalanceGIndexState))\n\tbalance8Path := fmt.Sprintf(\"Balances/%d\", merkle.BalancesPerLeaf*2)\n\t_, balanceGIndex8, _, err := mlib.ObjectPath(balance8Path).GetGeneralizedIndex(beaconStateSchemaElectra)\n\trequire.NoError(t, err)\n\trequire.Equal(t, 1, int(balanceGIndex8-balanceGIndex4))\n}\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/merkle_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle_test\n\nimport (\n\t\"encoding/json\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// ReadProofFromFile reads a proof from a JSON file in the testdata directory.\nfunc ReadProofFromFile(t *testing.T, filename string) []common.Root {\n\tt.Helper()\n\tpath := filepath.Join(\"testdata\", filename)\n\tdata, err := os.ReadFile(path)\n\trequire.NoError(t, err)\n\n\tvar proof []common.Root\n\terr = json.Unmarshal(data, &proof)\n\trequire.NoError(t, err)\n\n\treturn proof\n}\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/mock/beacon_state.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage mock\n\nimport (\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n)\n\n// NewBeaconStateWith creates a new mock beacon state with only the given fork version,\n// slot, validators, execution number, and execution fee recipient populated.\nfunc NewBeaconStateWith(\n\tslot math.Slot,\n\tvals types.Validators,\n\texecutionNumber math.U64,\n\texecutionFeeRecipient common.ExecutionAddress,\n\tforkVersion common.Version,\n) *types.BeaconState {\n\t// If no validators are provided, create an empty slice.\n\tif len(vals) == 0 {\n\t\tvals = make(types.Validators, 0)\n\t}\n\n\t// Create an empty execution payload header with the given execution number and fee recipient.\n\texecPayloadHeader := types.NewEmptyExecutionPayloadHeaderWithVersion(forkVersion)\n\texecPayloadHeader.Number = executionNumber\n\texecPayloadHeader.FeeRecipient = executionFeeRecipient\n\n\tbsm := types.NewEmptyBeaconStateWithVersion(forkVersion)\n\tbsm.Slot = slot\n\tbsm.GenesisValidatorsRoot = common.Root{}\n\tbsm.Fork = &types.Fork{}\n\tbsm.LatestBlockHeader = types.NewEmptyBeaconBlockHeader()\n\tbsm.BlockRoots = []common.Root{}\n\tbsm.StateRoots = []common.Root{}\n\tbsm.LatestExecutionPayloadHeader = execPayloadHeader\n\tbsm.Eth1Data = &types.Eth1Data{}\n\tbsm.Eth1DepositIndex = 0\n\tbsm.Validators = vals\n\tbsm.Balances = []uint64{}\n\tbsm.RandaoMixes = []common.Bytes32{}\n\tbsm.NextWithdrawalIndex = 0\n\tbsm.NextWithdrawalValidatorIndex = 0\n\tbsm.Slashings = []math.Gwei{}\n\tbsm.TotalSlashing = 0\n\tif version.EqualsOrIsAfter(bsm.GetForkVersion(), version.Electra()) {\n\t\tbsm.PendingPartialWithdrawals = []*types.PendingPartialWithdrawal{}\n\t}\n\n\treturn bsm\n}\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/proposer_index.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle\n\nimport (\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/merkle\"\n)\n\n// ProveProposerIndexInBlock generates a proof for the proposer index in the\n// beacon block. The proof is then verified against the beacon block root as a\n// sanity check. Returns the proof along with the beacon block root. It uses\n// the fastssz library to generate the proof.\nfunc ProveProposerIndexInBlock(\n\tbbh *ctypes.BeaconBlockHeader,\n) ([]common.Root, common.Root, error) {\n\tblockProofTree, err := bbh.GetTree()\n\tif err != nil {\n\t\treturn nil, common.Root{}, err\n\t}\n\n\tproposerIndexProof, err := blockProofTree.Prove(ProposerIndexGIndexBlock)\n\tif err != nil {\n\t\treturn nil, common.Root{}, err\n\t}\n\n\tproof := make([]common.Root, len(proposerIndexProof.Hashes))\n\tfor i, hash := range proposerIndexProof.Hashes {\n\t\tproof[i] = common.NewRootFromBytes(hash)\n\t}\n\n\tbeaconRoot, err := verifyProposerIndexInBlock(\n\t\tbbh, proof, common.NewRootFromBytes(proposerIndexProof.Leaf),\n\t)\n\tif err != nil {\n\t\treturn nil, common.Root{}, err\n\t}\n\n\treturn proof, beaconRoot, nil\n}\n\n// verifyProposerIndexInBlock verifies the proposer index proof in the block.\n//\n// TODO: verifying the proof is not absolutely necessary.\nfunc verifyProposerIndexInBlock(\n\tbbh *ctypes.BeaconBlockHeader, proof []common.Root, leaf common.Root,\n) (common.Root, error) {\n\tbeaconRoot := bbh.HashTreeRoot()\n\tif !merkle.VerifyProof(beaconRoot, leaf, ProposerIndexGIndexBlock, proof) {\n\t\treturn common.Root{}, errors.Wrapf(\n\t\t\terrors.New(\"proposer index proof failed to verify against beacon root\"),\n\t\t\t\"beacon root: 0x%s\", beaconRoot,\n\t\t)\n\t}\n\n\treturn beaconRoot, nil\n}\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/proposer_index_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/proof/merkle\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// TestBlockProposerIndexProof tests the ProveProposerIndexInBlock function\n// and that the generated proof correctly verifies.\nfunc TestBlockProposerIndexProof(t *testing.T) {\n\tt.Parallel()\n\ttestCases := []struct {\n\t\tname              string\n\t\tslot              math.Slot\n\t\tproposerIndex     math.ValidatorIndex\n\t\tparentBlockRoot   common.Root\n\t\tstateRoot         common.Root\n\t\tbodyRoot          common.Root\n\t\texpectedProofFile string\n\t}{\n\t\t{\n\t\t\tname:              \"1 Validator Set\",\n\t\t\tslot:              69,\n\t\t\tproposerIndex:     0,\n\t\t\tparentBlockRoot:   common.Root{1, 2, 3},\n\t\t\tstateRoot:         common.Root{4, 5, 6},\n\t\t\tbodyRoot:          common.Root{7, 8, 9},\n\t\t\texpectedProofFile: \"one_validator_proposer_index_proof.json\",\n\t\t},\n\t\t{\n\t\t\tname:              \"Many Validator Set\",\n\t\t\tslot:              420,\n\t\t\tproposerIndex:     69,\n\t\t\tparentBlockRoot:   common.Root{1, 2, 3},\n\t\t\tstateRoot:         common.Root{4, 5, 6},\n\t\t\tbodyRoot:          common.Root{7, 8, 9},\n\t\t\texpectedProofFile: \"many_validators_proposer_index_proof.json\",\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tbbh := types.NewBeaconBlockHeader(\n\t\t\t\ttc.slot,\n\t\t\t\ttc.proposerIndex,\n\t\t\t\ttc.parentBlockRoot,\n\t\t\t\ttc.stateRoot,\n\t\t\t\ttc.bodyRoot,\n\t\t\t)\n\n\t\t\tproof, beaconRoot, err := merkle.ProveProposerIndexInBlock(bbh)\n\t\t\trequire.NoError(t, err)\n\n\t\t\trequire.Equal(t, bbh.HashTreeRoot(), beaconRoot)\n\n\t\t\texpectedProof := ReadProofFromFile(t, tc.expectedProofFile)\n\t\t\trequire.Equal(t, expectedProof, proof)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/testdata/empty_state_proof.json",
    "content": "[\n  \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n  \"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b\",\n  \"0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71\"\n]\n  "
  },
  {
    "path": "node-api/handlers/proof/merkle/testdata/many_validators_proposer_index_proof.json",
    "content": "[\n  \"0xa401000000000000000000000000000000000000000000000000000000000000\",\n  \"0x5ca6b806bfaf4c5c16be71ea6ee96e4e05b172144c1e6c2eb5646535896a30ac\",\n  \"0xfbfd75335009f40216a1ca7e1e9306e76194a2cebd6f7f9e88ea5a471d86b5f9\"\n]\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/testdata/many_validators_proposer_pubkey_proof_deneb.json",
    "content": "[\n  \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n  \"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b\",\n  \"0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71\",\n  \"0xfa324a462bcb0f10c24c9e17c326a4e0ebad204feced523eccaf346c686f06ee\",\n  \"0x4b71985b48d4d27159fb953494feef9e7eeba75f5acd2d03b1c306a186d0537c\",\n  \"0x11740281865e8d784f81fc4de65e85e38a6aadd4983586ffeff99d326439a834\",\n  \"0xb5d7f6be4d62c17c85aad66691b3c8a8ab3efe4305c5c4d09a58c4fce699b191\",\n  \"0xcba76b0fd6edcfd2c74f6020fa3a249f27f07d0c96237d5826f5c5dddf87d2fc\",\n  \"0x02460b6ea65b13017a2b5dcd11e5b615b12da48e980ac55b1bc1fbbd7bde8d63\",\n  \"0x5d91c749461f080b40700a41b1468944bb58fa69ffe0c24af202cefb903b9f6f\",\n  \"0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c\",\n  \"0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193\",\n  \"0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1\",\n  \"0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b\",\n  \"0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220\",\n  \"0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f\",\n  \"0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e\",\n  \"0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784\",\n  \"0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb\",\n  \"0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb\",\n  \"0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab\",\n  \"0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4\",\n  \"0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f\",\n  \"0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa\",\n  \"0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c\",\n  \"0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167\",\n  \"0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7\",\n  \"0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0\",\n  \"0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544\",\n  \"0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765\",\n  \"0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4\",\n  \"0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1\",\n  \"0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636\",\n  \"0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c\",\n  \"0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7\",\n  \"0xc6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff\",\n  \"0x1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc5\",\n  \"0x2f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d\",\n  \"0x328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362c\",\n  \"0xbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c327\",\n  \"0x55d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a74\",\n  \"0xf7210d4f8e7e1039790e7bf4efa207555a10a6db1dd4b95da313aaa88b88fe76\",\n  \"0xad21b516cbc645ffe34ab5de1c8aef8cd4e7f8d2b51e8e1456adc7563cda206f\",\n  \"0x6400000000000000000000000000000000000000000000000000000000000000\",\n  \"0x54b4b8b897929a1ede97d29e9551d610229f22c1a59d186d95aed203333b4e5e\",\n  \"0x4019708b8a442b0e6fc88b6531e2420811d4833db8e862d75a65501695afed1c\",\n  \"0x1b8afbf6f0034f939f0cfc6e3b03362631bdce35a43b65cbb8f732fa08373b69\",\n  \"0x70ccdae9a06cda39d93eba92e2692bec147a29ef7e31ad9f4bebb347792d9204\",\n  \"0x0102030405060000000000000000000000000000000000000000000000000000\",\n  \"0xe38c573641a369b49f1e77043562c3b6b3932c2cce7fcd4d71d494b4b8d08012\",\n  \"0xa3df0acb0b3d50f9b7f569ffb440f3a5891a2723a35bd825d6cf271298e616b6\"\n]\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/testdata/many_validators_proposer_pubkey_proof_electra.json",
    "content": "[\n  \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n  \"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b\",\n  \"0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71\",\n  \"0xfa324a462bcb0f10c24c9e17c326a4e0ebad204feced523eccaf346c686f06ee\",\n  \"0x4b71985b48d4d27159fb953494feef9e7eeba75f5acd2d03b1c306a186d0537c\",\n  \"0x11740281865e8d784f81fc4de65e85e38a6aadd4983586ffeff99d326439a834\",\n  \"0xb5d7f6be4d62c17c85aad66691b3c8a8ab3efe4305c5c4d09a58c4fce699b191\",\n  \"0xcba76b0fd6edcfd2c74f6020fa3a249f27f07d0c96237d5826f5c5dddf87d2fc\",\n  \"0x02460b6ea65b13017a2b5dcd11e5b615b12da48e980ac55b1bc1fbbd7bde8d63\",\n  \"0x5d91c749461f080b40700a41b1468944bb58fa69ffe0c24af202cefb903b9f6f\",\n  \"0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c\",\n  \"0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193\",\n  \"0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1\",\n  \"0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b\",\n  \"0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220\",\n  \"0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f\",\n  \"0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e\",\n  \"0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784\",\n  \"0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb\",\n  \"0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb\",\n  \"0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab\",\n  \"0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4\",\n  \"0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f\",\n  \"0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa\",\n  \"0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c\",\n  \"0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167\",\n  \"0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7\",\n  \"0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0\",\n  \"0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544\",\n  \"0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765\",\n  \"0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4\",\n  \"0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1\",\n  \"0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636\",\n  \"0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c\",\n  \"0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7\",\n  \"0xc6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff\",\n  \"0x1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc5\",\n  \"0x2f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d\",\n  \"0x328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362c\",\n  \"0xbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c327\",\n  \"0x55d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a74\",\n  \"0xf7210d4f8e7e1039790e7bf4efa207555a10a6db1dd4b95da313aaa88b88fe76\",\n  \"0xad21b516cbc645ffe34ab5de1c8aef8cd4e7f8d2b51e8e1456adc7563cda206f\",\n  \"0x6400000000000000000000000000000000000000000000000000000000000000\",\n  \"0x54b4b8b897929a1ede97d29e9551d610229f22c1a59d186d95aed203333b4e5e\",\n  \"0x4019708b8a442b0e6fc88b6531e2420811d4833db8e862d75a65501695afed1c\",\n  \"0x1b8afbf6f0034f939f0cfc6e3b03362631bdce35a43b65cbb8f732fa08373b69\",\n  \"0x70ccdae9a06cda39d93eba92e2692bec147a29ef7e31ad9f4bebb347792d9204\",\n  \"0x58f6c4a556e87b8de03a64800211685b11e4e6e05e001b65d5f0a588e4985be3\",\n  \"0x0102030405060000000000000000000000000000000000000000000000000000\",\n  \"0xe38c573641a369b49f1e77043562c3b6b3932c2cce7fcd4d71d494b4b8d08012\",\n  \"0xa3df0acb0b3d50f9b7f569ffb440f3a5891a2723a35bd825d6cf271298e616b6\"\n]\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/testdata/many_validators_validator_balance_proof.json",
    "content": "[\n  \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n  \"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b\",\n  \"0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71\",\n  \"0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c\",\n  \"0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c\",\n  \"0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30\",\n  \"0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1\",\n  \"0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c\",\n  \"0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193\",\n  \"0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1\",\n  \"0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b\",\n  \"0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220\",\n  \"0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f\",\n  \"0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e\",\n  \"0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784\",\n  \"0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb\",\n  \"0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb\",\n  \"0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab\",\n  \"0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4\",\n  \"0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f\",\n  \"0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa\",\n  \"0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c\",\n  \"0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167\",\n  \"0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7\",\n  \"0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0\",\n  \"0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544\",\n  \"0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765\",\n  \"0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4\",\n  \"0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1\",\n  \"0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636\",\n  \"0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c\",\n  \"0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7\",\n  \"0xc6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff\",\n  \"0x1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc5\",\n  \"0x2f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d\",\n  \"0x328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362c\",\n  \"0xbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c327\",\n  \"0x55d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a74\",\n  \"0x6400000000000000000000000000000000000000000000000000000000000000\",\n  \"0x6080a24df6cb76f31cacdf4419ac9bf0ac092087f40ec93f10c4608f967ca23a\",\n  \"0xdb4261da1f55277e8d739af87ee3f2757b11de49e3021abcafe2d73ae3dd5ad1\",\n  \"0x1b8afbf6f0034f939f0cfc6e3b03362631bdce35a43b65cbb8f732fa08373b69\",\n  \"0x70ccdae9a06cda39d93eba92e2692bec147a29ef7e31ad9f4bebb347792d9204\",\n  \"0x58f6c4a556e87b8de03a64800211685b11e4e6e05e001b65d5f0a588e4985be3\",\n  \"0x0102030405060000000000000000000000000000000000000000000000000000\",\n  \"0xe38c573641a369b49f1e77043562c3b6b3932c2cce7fcd4d71d494b4b8d08012\",\n  \"0xa3df0acb0b3d50f9b7f569ffb440f3a5891a2723a35bd825d6cf271298e616b6\"\n]\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/testdata/many_validators_validator_credentials_proof.json",
    "content": "[\n  \"0xbbd454dfd62ecc85d24a755a14cd5019ddfc64043d0ffd0e2efd23fdec124e30\",\n  \"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b\",\n  \"0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71\",\n  \"0xfa324a462bcb0f10c24c9e17c326a4e0ebad204feced523eccaf346c686f06ee\",\n  \"0x4b71985b48d4d27159fb953494feef9e7eeba75f5acd2d03b1c306a186d0537c\",\n  \"0x11740281865e8d784f81fc4de65e85e38a6aadd4983586ffeff99d326439a834\",\n  \"0xb5d7f6be4d62c17c85aad66691b3c8a8ab3efe4305c5c4d09a58c4fce699b191\",\n  \"0xcba76b0fd6edcfd2c74f6020fa3a249f27f07d0c96237d5826f5c5dddf87d2fc\",\n  \"0x02460b6ea65b13017a2b5dcd11e5b615b12da48e980ac55b1bc1fbbd7bde8d63\",\n  \"0x5d91c749461f080b40700a41b1468944bb58fa69ffe0c24af202cefb903b9f6f\",\n  \"0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c\",\n  \"0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193\",\n  \"0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1\",\n  \"0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b\",\n  \"0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220\",\n  \"0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f\",\n  \"0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e\",\n  \"0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784\",\n  \"0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb\",\n  \"0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb\",\n  \"0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab\",\n  \"0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4\",\n  \"0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f\",\n  \"0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa\",\n  \"0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c\",\n  \"0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167\",\n  \"0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7\",\n  \"0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0\",\n  \"0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544\",\n  \"0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765\",\n  \"0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4\",\n  \"0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1\",\n  \"0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636\",\n  \"0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c\",\n  \"0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7\",\n  \"0xc6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff\",\n  \"0x1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc5\",\n  \"0x2f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d\",\n  \"0x328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362c\",\n  \"0xbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c327\",\n  \"0x55d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a74\",\n  \"0xf7210d4f8e7e1039790e7bf4efa207555a10a6db1dd4b95da313aaa88b88fe76\",\n  \"0xad21b516cbc645ffe34ab5de1c8aef8cd4e7f8d2b51e8e1456adc7563cda206f\",\n  \"0x6400000000000000000000000000000000000000000000000000000000000000\",\n  \"0x54b4b8b897929a1ede97d29e9551d610229f22c1a59d186d95aed203333b4e5e\",\n  \"0x4019708b8a442b0e6fc88b6531e2420811d4833db8e862d75a65501695afed1c\",\n  \"0x1b8afbf6f0034f939f0cfc6e3b03362631bdce35a43b65cbb8f732fa08373b69\",\n  \"0x70ccdae9a06cda39d93eba92e2692bec147a29ef7e31ad9f4bebb347792d9204\",\n  \"0x58f6c4a556e87b8de03a64800211685b11e4e6e05e001b65d5f0a588e4985be3\",\n  \"0x0102030405060000000000000000000000000000000000000000000000000000\",\n  \"0xe38c573641a369b49f1e77043562c3b6b3932c2cce7fcd4d71d494b4b8d08012\",\n  \"0xa3df0acb0b3d50f9b7f569ffb440f3a5891a2723a35bd825d6cf271298e616b6\"\n]\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/testdata/non_empty_state_proof.json",
    "content": "[\n  \"0x0102030405060708090000000000000000000000000000000000000000000000\",\n  \"0xbd50456d5ad175ae99a1612a53ca229124b65d3eaabd9ff9c7ab979a385cf6b3\",\n  \"0x2137a0ff622bd6e30728bc64e7deed6ea418596c772143e232cfea9d88babd58\"\n]\n  "
  },
  {
    "path": "node-api/handlers/proof/merkle/testdata/one_validator_proposer_index_proof.json",
    "content": "[\n  \"0x4500000000000000000000000000000000000000000000000000000000000000\",\n  \"0x5ca6b806bfaf4c5c16be71ea6ee96e4e05b172144c1e6c2eb5646535896a30ac\",\n  \"0xfbfd75335009f40216a1ca7e1e9306e76194a2cebd6f7f9e88ea5a471d86b5f9\"\n]\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/testdata/one_validator_proposer_pubkey_proof_deneb.json",
    "content": "[\n  \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n  \"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b\",\n  \"0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71\",\n  \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n  \"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b\",\n  \"0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71\",\n  \"0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c\",\n  \"0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c\",\n  \"0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30\",\n  \"0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1\",\n  \"0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c\",\n  \"0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193\",\n  \"0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1\",\n  \"0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b\",\n  \"0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220\",\n  \"0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f\",\n  \"0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e\",\n  \"0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784\",\n  \"0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb\",\n  \"0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb\",\n  \"0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab\",\n  \"0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4\",\n  \"0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f\",\n  \"0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa\",\n  \"0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c\",\n  \"0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167\",\n  \"0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7\",\n  \"0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0\",\n  \"0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544\",\n  \"0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765\",\n  \"0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4\",\n  \"0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1\",\n  \"0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636\",\n  \"0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c\",\n  \"0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7\",\n  \"0xc6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff\",\n  \"0x1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc5\",\n  \"0x2f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d\",\n  \"0x328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362c\",\n  \"0xbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c327\",\n  \"0x55d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a74\",\n  \"0xf7210d4f8e7e1039790e7bf4efa207555a10a6db1dd4b95da313aaa88b88fe76\",\n  \"0xad21b516cbc645ffe34ab5de1c8aef8cd4e7f8d2b51e8e1456adc7563cda206f\",\n  \"0x0100000000000000000000000000000000000000000000000000000000000000\",\n  \"0x54b4b8b897929a1ede97d29e9551d610229f22c1a59d186d95aed203333b4e5e\",\n  \"0x4019708b8a442b0e6fc88b6531e2420811d4833db8e862d75a65501695afed1c\",\n  \"0x1b8afbf6f0034f939f0cfc6e3b03362631bdce35a43b65cbb8f732fa08373b69\",\n  \"0xda5a83fdae2974416e891f268f5d29d45f071bb414304bdff46aaaa07a7403cb\",\n  \"0x0102030000000000000000000000000000000000000000000000000000000000\",\n  \"0xd6e497b816c27a31acd5d9f3ed670639fef7842fee51f044dfbfb6319c760a5f\",\n  \"0x7b85fe2a9afab51dcca12b224e10bf25e6cb1cb99ac5d24be8a55fac862b6c90\"\n]\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/testdata/one_validator_proposer_pubkey_proof_electra.json",
    "content": "[\n  \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n  \"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b\",\n  \"0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71\",\n  \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n  \"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b\",\n  \"0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71\",\n  \"0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c\",\n  \"0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c\",\n  \"0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30\",\n  \"0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1\",\n  \"0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c\",\n  \"0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193\",\n  \"0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1\",\n  \"0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b\",\n  \"0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220\",\n  \"0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f\",\n  \"0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e\",\n  \"0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784\",\n  \"0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb\",\n  \"0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb\",\n  \"0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab\",\n  \"0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4\",\n  \"0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f\",\n  \"0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa\",\n  \"0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c\",\n  \"0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167\",\n  \"0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7\",\n  \"0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0\",\n  \"0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544\",\n  \"0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765\",\n  \"0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4\",\n  \"0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1\",\n  \"0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636\",\n  \"0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c\",\n  \"0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7\",\n  \"0xc6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff\",\n  \"0x1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc5\",\n  \"0x2f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d\",\n  \"0x328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362c\",\n  \"0xbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c327\",\n  \"0x55d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a74\",\n  \"0xf7210d4f8e7e1039790e7bf4efa207555a10a6db1dd4b95da313aaa88b88fe76\",\n  \"0xad21b516cbc645ffe34ab5de1c8aef8cd4e7f8d2b51e8e1456adc7563cda206f\",\n  \"0x0100000000000000000000000000000000000000000000000000000000000000\",\n  \"0x54b4b8b897929a1ede97d29e9551d610229f22c1a59d186d95aed203333b4e5e\",\n  \"0x4019708b8a442b0e6fc88b6531e2420811d4833db8e862d75a65501695afed1c\",\n  \"0x1b8afbf6f0034f939f0cfc6e3b03362631bdce35a43b65cbb8f732fa08373b69\",\n  \"0xda5a83fdae2974416e891f268f5d29d45f071bb414304bdff46aaaa07a7403cb\",\n  \"0x58f6c4a556e87b8de03a64800211685b11e4e6e05e001b65d5f0a588e4985be3\",\n  \"0x0102030000000000000000000000000000000000000000000000000000000000\",\n  \"0xd6e497b816c27a31acd5d9f3ed670639fef7842fee51f044dfbfb6319c760a5f\",\n  \"0x7b85fe2a9afab51dcca12b224e10bf25e6cb1cb99ac5d24be8a55fac862b6c90\"\n]\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/testdata/one_validator_validator_balance_proof.json",
    "content": "[\n  \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n  \"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b\",\n  \"0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71\",\n  \"0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c\",\n  \"0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c\",\n  \"0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30\",\n  \"0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1\",\n  \"0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c\",\n  \"0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193\",\n  \"0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1\",\n  \"0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b\",\n  \"0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220\",\n  \"0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f\",\n  \"0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e\",\n  \"0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784\",\n  \"0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb\",\n  \"0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb\",\n  \"0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab\",\n  \"0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4\",\n  \"0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f\",\n  \"0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa\",\n  \"0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c\",\n  \"0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167\",\n  \"0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7\",\n  \"0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0\",\n  \"0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544\",\n  \"0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765\",\n  \"0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4\",\n  \"0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1\",\n  \"0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636\",\n  \"0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c\",\n  \"0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7\",\n  \"0xc6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff\",\n  \"0x1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc5\",\n  \"0x2f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d\",\n  \"0x328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362c\",\n  \"0xbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c327\",\n  \"0x55d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a74\",\n  \"0x0100000000000000000000000000000000000000000000000000000000000000\",\n  \"0x6080a24df6cb76f31cacdf4419ac9bf0ac092087f40ec93f10c4608f967ca23a\",\n  \"0xd8fa0aadb22a3b0fbc808b72568e1ee6a4e189a09f5caf344277c96e6fa474fd\",\n  \"0x1b8afbf6f0034f939f0cfc6e3b03362631bdce35a43b65cbb8f732fa08373b69\",\n  \"0xda5a83fdae2974416e891f268f5d29d45f071bb414304bdff46aaaa07a7403cb\",\n  \"0x58f6c4a556e87b8de03a64800211685b11e4e6e05e001b65d5f0a588e4985be3\",\n  \"0x0102030000000000000000000000000000000000000000000000000000000000\",\n  \"0xd6e497b816c27a31acd5d9f3ed670639fef7842fee51f044dfbfb6319c760a5f\",\n  \"0x7b85fe2a9afab51dcca12b224e10bf25e6cb1cb99ac5d24be8a55fac862b6c90\"\n]\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/testdata/one_validator_validator_credentials_proof.json",
    "content": "[\n  \"0x292f7782a5d9c4cc3c0d5b5dcdbaeba0f07736ff8ad2f68c57e2dcd832f444f1\",\n  \"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b\",\n  \"0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71\",\n  \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n  \"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b\",\n  \"0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71\",\n  \"0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c\",\n  \"0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c\",\n  \"0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30\",\n  \"0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1\",\n  \"0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c\",\n  \"0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193\",\n  \"0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1\",\n  \"0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b\",\n  \"0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220\",\n  \"0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f\",\n  \"0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e\",\n  \"0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784\",\n  \"0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb\",\n  \"0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb\",\n  \"0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab\",\n  \"0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4\",\n  \"0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f\",\n  \"0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa\",\n  \"0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c\",\n  \"0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167\",\n  \"0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7\",\n  \"0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0\",\n  \"0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544\",\n  \"0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765\",\n  \"0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4\",\n  \"0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1\",\n  \"0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636\",\n  \"0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c\",\n  \"0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7\",\n  \"0xc6f67e02e6e4e1bdefb994c6098953f34636ba2b6ca20a4721d2b26a886722ff\",\n  \"0x1c9a7e5ff1cf48b4ad1582d3f4e4a1004f3b20d8c5a2b71387a4254ad933ebc5\",\n  \"0x2f075ae229646b6f6aed19a5e372cf295081401eb893ff599b3f9acc0c0d3e7d\",\n  \"0x328921deb59612076801e8cd61592107b5c67c79b846595cc6320c395b46362c\",\n  \"0xbfb909fdb236ad2411b4e4883810a074b840464689986c3f8a8091827e17c327\",\n  \"0x55d8fb3687ba3ba49f342c77f5a1f89bec83d811446e1a467139213d640b6a74\",\n  \"0xf7210d4f8e7e1039790e7bf4efa207555a10a6db1dd4b95da313aaa88b88fe76\",\n  \"0xad21b516cbc645ffe34ab5de1c8aef8cd4e7f8d2b51e8e1456adc7563cda206f\",\n  \"0x0100000000000000000000000000000000000000000000000000000000000000\",\n  \"0x54b4b8b897929a1ede97d29e9551d610229f22c1a59d186d95aed203333b4e5e\",\n  \"0x4019708b8a442b0e6fc88b6531e2420811d4833db8e862d75a65501695afed1c\",\n  \"0x1b8afbf6f0034f939f0cfc6e3b03362631bdce35a43b65cbb8f732fa08373b69\",\n  \"0xda5a83fdae2974416e891f268f5d29d45f071bb414304bdff46aaaa07a7403cb\",\n  \"0x58f6c4a556e87b8de03a64800211685b11e4e6e05e001b65d5f0a588e4985be3\",\n  \"0x0102030000000000000000000000000000000000000000000000000000000000\",\n  \"0xd6e497b816c27a31acd5d9f3ed670639fef7842fee51f044dfbfb6319c760a5f\",\n  \"0x7b85fe2a9afab51dcca12b224e10bf25e6cb1cb99ac5d24be8a55fac862b6c90\"\n]\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/validator_balance.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle\n\nimport (\n\t\"fmt\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/proof/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/merkle\"\n\t\"github.com/pkg/errors\"\n)\n\n// bytesPerBalance is the number of bytes in a single balance (uint64).\nconst bytesPerBalance uint64 = 8\n\n// ProveBalanceInState generates a proof for a validator's balance in the beacon state.\nfunc ProveBalanceInState(\n\tforkVersion common.Version,\n\tbsm types.BeaconStateMarshallable,\n\tvalidatorIndex math.U64,\n) ([]common.Root, common.Root, error) {\n\tstateProofTree, err := bsm.GetTree()\n\tif err != nil {\n\t\treturn nil, common.Root{}, err\n\t}\n\n\t// Determine the starting generalized index for the 0-th validator's\n\t// balance for this fork.\n\tzeroBalanceGIndexState, err := GetZeroValidatorBalanceGIndexState(forkVersion)\n\tif err != nil {\n\t\treturn nil, common.Root{}, err\n\t}\n\n\t// Since balances are packed 4 per leaf, calculate the leaf offset\n\tleafOffset := validatorIndex / BalancesPerLeaf\n\n\t// Calculate the generalized index for the target validator's balance leaf.\n\t// The offset multiplication is bounded by the number of validators, so\n\t// converting to int is safe on 64-bit architectures.\n\tgIndex := zeroBalanceGIndexState + int(leafOffset) // #nosec G115\n\n\tbalanceProof, err := stateProofTree.Prove(gIndex)\n\tif err != nil {\n\t\treturn nil, common.Root{}, err\n\t}\n\n\tproof := make([]common.Root, len(balanceProof.Hashes))\n\tfor i, hash := range balanceProof.Hashes {\n\t\tproof[i] = common.NewRootFromBytes(hash)\n\t}\n\n\t// The leaf contains 4 packed uint64 balances\n\treturn proof, common.NewRootFromBytes(balanceProof.Leaf), nil\n}\n\n// ProveBalanceInBlock generates a proof for a validator's balance in the beacon block.\n// Returns the proof, the leaf containing the packed balances, and the beacon block root.\nfunc ProveBalanceInBlock(\n\tvalidatorIndex math.U64,\n\tbbh *ctypes.BeaconBlockHeader,\n\tbsm types.BeaconStateMarshallable,\n\tallBalances []uint64,\n) ([]common.Root, common.Root, common.Root, error) {\n\tforkVersion := bsm.GetForkVersion()\n\n\t// 1. Proof inside the state.\n\tbalanceInStateProof, leaf, err := ProveBalanceInState(\n\t\tforkVersion, bsm, validatorIndex,\n\t)\n\tif err != nil {\n\t\treturn nil, common.Root{}, common.Root{}, err\n\t}\n\n\t// 2. Build the balance leaf and assert that it matches the proof's leaf.\n\tbuiltLeaf := buildBalanceLeaf(allBalances, validatorIndex)\n\tif !leaf.Equals(builtLeaf) {\n\t\treturn nil, common.Root{}, common.Root{}, fmt.Errorf(\n\t\t\t\"balance leaf mismatch -- proof tree leaf: 0x%s, built leaf: 0x%s\", leaf, builtLeaf,\n\t\t)\n\t}\n\n\t// 3. Proof of the state inside the block.\n\tstateInBlockProof, err := ProveBeaconStateInBlock(bbh, false)\n\tif err != nil {\n\t\treturn nil, common.Root{}, common.Root{}, err\n\t}\n\n\t// 4. Combine proofs: state-level hashes come first, followed by block-level\n\t// hashes (same order as ProveProposerPubkeyInBlock).\n\t//\n\t//nolint:gocritic // ok.\n\tcombinedProof := append(balanceInStateProof, stateInBlockProof...)\n\n\t// 5. Verify the combined proof against the beacon block root.\n\t// Since balances are packed 4 per leaf, calculate the leaf offset.\n\tleafOffset := validatorIndex / BalancesPerLeaf\n\tbeaconRoot, err := verifyBalanceInBlock(\n\t\tforkVersion, bbh, leafOffset.Unwrap(), combinedProof, leaf,\n\t)\n\tif err != nil {\n\t\treturn nil, common.Root{}, common.Root{}, err\n\t}\n\n\treturn combinedProof, leaf, beaconRoot, nil\n}\n\n// buildBalanceLeaf constructs the 32-byte leaf containing the packed balances\n// for the group of validators that includes `validatorIndex`. Balances are\n// packed 4 per leaf (little-endian uint64s).\nfunc buildBalanceLeaf(allBalances []uint64, validatorIndex math.U64) common.Root {\n\tvar leafBytes common.Root\n\n\t// Determine which leaf the validator belongs to and the starting index in\n\t// the balances slice.\n\tleafIndex := validatorIndex / BalancesPerLeaf\n\tstartIdx := leafIndex * BalancesPerLeaf\n\n\t// Pack up to 4 balances (little-endian) into the 32-byte array.\n\tfor i := range uint64(BalancesPerLeaf) {\n\t\tidx := startIdx.Unwrap() + i\n\t\tif idx >= uint64(len(allBalances)) {\n\t\t\tbreak\n\t\t}\n\t\tbal := allBalances[idx]\n\t\tfor j := range bytesPerBalance {\n\t\t\tleafBytes[i*bytesPerBalance+j] = byte(bal >> (j * bytesPerBalance)) // #nosec G115 -- intentional byte extraction from uint64.\n\t\t}\n\t}\n\n\treturn leafBytes\n}\n\n// verifyBalanceInBlock verifies the provided Merkle proof of a\n// validator's balance inside the beacon block and returns the\n// beacon block root that the proof was verified against.\n//\n// NOTE: Proof verification is not strictly necessary for operation, but we do\n// it as a sanity check to avoid propagating malformed proofs downstream.\nfunc verifyBalanceInBlock(\n\tforkVersion common.Version,\n\tbbh *ctypes.BeaconBlockHeader,\n\tbalanceOffset uint64,\n\tproof []common.Root,\n\tleaf common.Root,\n) (common.Root, error) {\n\tzeroBalanceGIndexBlock, err := GetZeroValidatorBalanceGIndexBlock(forkVersion)\n\tif err != nil {\n\t\treturn common.Root{}, err\n\t}\n\n\tbeaconRoot := bbh.HashTreeRoot()\n\tif !merkle.VerifyProof(\n\t\tbeaconRoot,\n\t\tleaf,\n\t\tzeroBalanceGIndexBlock+balanceOffset,\n\t\tproof,\n\t) {\n\t\treturn common.Root{}, errors.Wrapf(\n\t\t\terrors.New(\"balance proof failed to verify against beacon root\"),\n\t\t\t\"beacon root: 0x%s\", beaconRoot,\n\t\t)\n\t}\n\n\treturn beaconRoot, nil\n}\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/validator_balance_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle_test\n\nimport (\n\t\"testing\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/proof/merkle\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/proof/merkle/mock\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// TestValidatorBalanceProof_Comparison tests the balance function\n// and that the generated proof matches the expected proof.\nfunc TestValidatorBalanceProof_Comparison(t *testing.T) {\n\tt.Parallel()\n\ttestCases := []struct {\n\t\tname              string\n\t\tforkVersion       common.Version\n\t\tnumValidators     int\n\t\tslot              math.Slot\n\t\tvalIndex          math.ValidatorIndex\n\t\tparentBlockRoot   common.Root\n\t\tbodyRoot          common.Root\n\t\tbalance           uint64\n\t\texpectedProofFile string\n\t}{\n\t\t{\n\t\t\tname:              \"1 Validator Set\",\n\t\t\tforkVersion:       version.Electra(),\n\t\t\tnumValidators:     1,\n\t\t\tslot:              4,\n\t\t\tvalIndex:          0,\n\t\t\tparentBlockRoot:   common.Root{1, 2, 3},\n\t\t\tbodyRoot:          common.Root{3, 2, 1},\n\t\t\tbalance:           1000000000000000000,\n\t\t\texpectedProofFile: \"one_validator_validator_balance_proof.json\",\n\t\t},\n\t\t{\n\t\t\tname:              \"Many Validator Set\",\n\t\t\tforkVersion:       version.Electra(),\n\t\t\tnumValidators:     100,\n\t\t\tslot:              5,\n\t\t\tvalIndex:          95,\n\t\t\tparentBlockRoot:   common.Root{1, 2, 3, 4, 5, 6},\n\t\t\tbodyRoot:          common.Root{3, 2, 1, 9, 8, 7},\n\t\t\tbalance:           2000000000000000000,\n\t\t\texpectedProofFile: \"many_validators_validator_balance_proof.json\",\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tvals := make(ctypes.Validators, tc.numValidators)\n\t\t\tfor i := range vals {\n\t\t\t\tvals[i] = &ctypes.Validator{}\n\t\t\t}\n\n\t\t\tbs := mock.NewBeaconStateWith(\n\t\t\t\ttc.slot, vals, 0, common.ExecutionAddress{}, tc.forkVersion,\n\t\t\t)\n\n\t\t\tbs.Balances = make([]uint64, tc.numValidators)\n\t\t\tbs.Balances[tc.valIndex] = tc.balance\n\n\t\t\tbbh := ctypes.NewBeaconBlockHeader(\n\t\t\t\ttc.slot,\n\t\t\t\ttc.valIndex,\n\t\t\t\ttc.parentBlockRoot,\n\t\t\t\tbs.HashTreeRoot(),\n\t\t\t\ttc.bodyRoot,\n\t\t\t)\n\n\t\t\tproof, _, _, err := merkle.ProveBalanceInBlock(tc.valIndex, bbh, bs, bs.Balances)\n\t\t\trequire.NoError(t, err)\n\t\t\texpectedProof := ReadProofFromFile(t, tc.expectedProofFile)\n\t\t\trequire.Equal(t, expectedProof, proof)\n\t\t})\n\t}\n}\n\nfunc TestValidatorBalanceProof(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname            string\n\t\tnumValidators   int\n\t\tvalidatorIndex  math.U64\n\t\tfork            common.Version\n\t\tslot            math.Slot\n\t\tparentBlockRoot common.Root\n\t\tbodyRoot        common.Root\n\t}{\n\t\t{\n\t\t\tname:            \"Single Validator Balance - Electra\",\n\t\t\tnumValidators:   1,\n\t\t\tvalidatorIndex:  0,\n\t\t\tfork:            version.Electra(),\n\t\t\tslot:            4,\n\t\t\tparentBlockRoot: common.Root{1, 2, 3},\n\t\t\tbodyRoot:        common.Root{3, 2, 1},\n\t\t},\n\t\t{\n\t\t\tname:            \"Multiple Validators Balance - First Leaf - Electra\",\n\t\t\tnumValidators:   10,\n\t\t\tvalidatorIndex:  2, // Within first leaf (0-3)\n\t\t\tfork:            version.Electra(),\n\t\t\tslot:            5,\n\t\t\tparentBlockRoot: common.Root{1, 2, 3, 4},\n\t\t\tbodyRoot:        common.Root{4, 3, 2, 1},\n\t\t},\n\t\t{\n\t\t\tname:            \"Multiple Validators Balance - Second Leaf - Electra\",\n\t\t\tnumValidators:   10,\n\t\t\tvalidatorIndex:  5, // In second leaf (4-7)\n\t\t\tfork:            version.Electra(),\n\t\t\tslot:            6,\n\t\t\tparentBlockRoot: common.Root{1, 2, 3, 4, 5},\n\t\t\tbodyRoot:        common.Root{5, 4, 3, 2, 1},\n\t\t},\n\t\t{\n\t\t\tname:            \"Many Validators Balance - Electra\",\n\t\t\tnumValidators:   100,\n\t\t\tvalidatorIndex:  47, // Tests a validator in a later leaf\n\t\t\tfork:            version.Electra(),\n\t\t\tslot:            7,\n\t\t\tparentBlockRoot: common.Root{1, 2, 3, 4, 5, 6},\n\t\t\tbodyRoot:        common.Root{6, 5, 4, 3, 2, 1},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t// Create validators\n\t\t\tvals := make(ctypes.Validators, tt.numValidators)\n\t\t\tfor i := range tt.numValidators {\n\t\t\t\tvals[i] = &ctypes.Validator{}\n\t\t\t}\n\n\t\t\t// Create beacon state with validators\n\t\t\tbs := mock.NewBeaconStateWith(\n\t\t\t\ttt.slot, vals, 0, common.ExecutionAddress{}, tt.fork,\n\t\t\t)\n\n\t\t\t// Set balances manually since the mock doesn't set them\n\t\t\tbs.Balances = make([]uint64, tt.numValidators)\n\t\t\tfor i := range tt.numValidators {\n\t\t\t\tbs.Balances[i] = uint64(32000000000 + i*1000000000) // 32 ETH + i ETH\n\t\t\t}\n\n\t\t\t// Create beacon block header\n\t\t\tbbh := ctypes.NewBeaconBlockHeader(\n\t\t\t\ttt.slot,\n\t\t\t\t0, // proposer index\n\t\t\t\ttt.parentBlockRoot,\n\t\t\t\tbs.HashTreeRoot(),\n\t\t\t\ttt.bodyRoot,\n\t\t\t)\n\n\t\t\t// Generate the proof\n\t\t\tproof, _, beaconRoot, err := merkle.ProveBalanceInBlock(\n\t\t\t\ttt.validatorIndex,\n\t\t\t\tbbh,\n\t\t\t\tbs,\n\t\t\t\tbs.Balances,\n\t\t\t)\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.NotEmpty(t, proof)\n\t\t\trequire.NotEqual(t, [32]byte{}, beaconRoot)\n\n\t\t\t// Verify the proof is valid (this is done internally in ProveBalanceInBlock)\n\t\t\t// but we can double-check the returned beacon root matches\n\t\t\texpectedRoot := bbh.HashTreeRoot()\n\t\t\trequire.Equal(t, expectedRoot, beaconRoot)\n\t\t})\n\t}\n}\n\nfunc TestValidatorBalanceProofEdgeCases(t *testing.T) {\n\tt.Parallel()\n\n\t// Test with validators at leaf boundaries\n\tnumValidators := 17 // This gives us 5 leaves (0-3, 4-7, 8-11, 12-15, 16)\n\n\tvals := make(ctypes.Validators, numValidators)\n\tfor i := range numValidators {\n\t\tvals[i] = &ctypes.Validator{}\n\t}\n\n\tbs := mock.NewBeaconStateWith(\n\t\t10, vals, 0, common.ExecutionAddress{}, version.Electra(),\n\t)\n\n\t// Set balances\n\tbs.Balances = make([]uint64, numValidators)\n\tfor i := range numValidators {\n\t\tbs.Balances[i] = uint64(32000000000)\n\t}\n\n\tbbh := ctypes.NewBeaconBlockHeader(\n\t\t10,\n\t\t0, // proposer index\n\t\tcommon.Root{1, 2, 3},\n\t\tbs.HashTreeRoot(),\n\t\tcommon.Root{3, 2, 1},\n\t)\n\n\t// Test validators at different positions within leaves\n\ttestCases := []struct {\n\t\tname           string\n\t\tvalidatorIndex math.U64\n\t\tleafIndex      uint64\n\t\tpositionInLeaf uint64\n\t}{\n\t\t{\"First in first leaf\", 0, 0, 0},\n\t\t{\"Last in first leaf\", 3, 0, 3},\n\t\t{\"First in second leaf\", 4, 1, 0},\n\t\t{\"Last in second leaf\", 7, 1, 3},\n\t\t{\"First in last partial leaf\", 16, 4, 0},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tproof, _, beaconRoot, err := merkle.ProveBalanceInBlock(\n\t\t\t\ttc.validatorIndex,\n\t\t\t\tbbh,\n\t\t\t\tbs,\n\t\t\t\tbs.Balances,\n\t\t\t)\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.NotEmpty(t, proof)\n\t\t\trequire.NotEqual(t, [32]byte{}, beaconRoot)\n\n\t\t\t// Verify the leaf index calculation\n\t\t\tcalculatedLeafIndex := tc.validatorIndex / 4\n\t\t\trequire.Equal(t, tc.leafIndex, calculatedLeafIndex.Unwrap())\n\n\t\t\t// Verify position within leaf\n\t\t\tpositionInLeaf := tc.validatorIndex % 4\n\t\t\trequire.Equal(t, tc.positionInLeaf, positionInLeaf.Unwrap())\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/validator_credentials.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle\n\nimport (\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/proof/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/merkle\"\n)\n\n// ProveWithdrawalCredentialsInState generates a proof for a validator's\n// withdrawal credentials in the beacon state. The validatorOffset must be\n// computed as (ValidatorWithdrawalCredentialsGIndexOffset * validatorIndex).\nfunc ProveWithdrawalCredentialsInState(\n\tforkVersion common.Version,\n\tbsm types.BeaconStateMarshallable,\n\tvalidatorOffset math.U64,\n) ([]common.Root, common.Root, error) {\n\tstateProofTree, err := bsm.GetTree()\n\tif err != nil {\n\t\treturn nil, common.Root{}, err\n\t}\n\n\t// Determine the starting generalized index for the 0-th validator's\n\t// withdrawal credentials for this fork.\n\tzeroWithdrawalGIndexState, err := GetZeroValidatorCredentialsGIndexState(forkVersion)\n\tif err != nil {\n\t\treturn nil, common.Root{}, err\n\t}\n\n\t// Calculate the generalized index for the target validator. The offset\n\t// multiplication is bounded by (2^40-1)*8 < 2^43 < 2^63, so converting to\n\t// int is safe on 64-bit architectures.\n\tgIndex := zeroWithdrawalGIndexState + int(validatorOffset) // #nosec G115\n\n\twithdrawalProof, err := stateProofTree.Prove(gIndex)\n\tif err != nil {\n\t\treturn nil, common.Root{}, err\n\t}\n\n\tproof := make([]common.Root, len(withdrawalProof.Hashes))\n\tfor i, hash := range withdrawalProof.Hashes {\n\t\tproof[i] = common.NewRootFromBytes(hash)\n\t}\n\treturn proof, common.NewRootFromBytes(withdrawalProof.Leaf), nil\n}\n\n// ProveWithdrawalCredentialsInBlock generates a proof for a validator's\n// withdrawal credentials in the beacon block. The proof is verified against\n// the beacon block root as a sanity check and the \"correct\" beacon block root\n// is returned alongside the proof.\nfunc ProveWithdrawalCredentialsInBlock(\n\tvalidatorIndex math.U64,\n\tbbh *ctypes.BeaconBlockHeader,\n\tbsm types.BeaconStateMarshallable,\n) ([]common.Root, common.Root, error) {\n\tforkVersion := bsm.GetForkVersion()\n\n\t// Calculate the validator-specific offset.\n\tvalidatorOffset := ValidatorGIndexOffset * validatorIndex\n\n\t// 1. Proof inside the state.\n\twithdrawalInStateProof, leaf, err := ProveWithdrawalCredentialsInState(\n\t\tforkVersion, bsm, validatorOffset,\n\t)\n\tif err != nil {\n\t\treturn nil, common.Root{}, err\n\t}\n\n\t// 2. Proof of the state inside the block.\n\tstateInBlockProof, err := ProveBeaconStateInBlock(bbh, false)\n\tif err != nil {\n\t\treturn nil, common.Root{}, err\n\t}\n\n\t// 3. Combine proofs: state-level hashes come first, followed by block-level\n\t// hashes (same order as ProveProposerPubkeyInBlock).\n\t//\n\t//nolint:gocritic // ok.\n\tcombinedProof := append(withdrawalInStateProof, stateInBlockProof...)\n\n\t// 4. Verify the combined proof against the beacon block root.\n\tbeaconRoot, err := verifyWithdrawalCredentialsInBlock(\n\t\tforkVersion, bbh, validatorOffset, combinedProof, leaf,\n\t)\n\tif err != nil {\n\t\treturn nil, common.Root{}, err\n\t}\n\n\treturn combinedProof, beaconRoot, nil\n}\n\n// verifyWithdrawalCredentialsInBlock verifies the provided Merkle proof of a\n// validator's withdrawal credentials inside the beacon block and returns the\n// beacon block root that the proof was verified against.\n//\n// NOTE: Proof verification is not strictly necessary for operation, but we do\n// it as a sanity check to avoid propagating malformed proofs downstream.\nfunc verifyWithdrawalCredentialsInBlock(\n\tforkVersion common.Version,\n\tbbh *ctypes.BeaconBlockHeader,\n\tvalidatorOffset math.U64,\n\tproof []common.Root,\n\tleaf common.Root,\n) (common.Root, error) {\n\tzeroWithdrawalGIndexBlock, err := GetZeroValidatorCredentialsGIndexBlock(forkVersion)\n\tif err != nil {\n\t\treturn common.Root{}, err\n\t}\n\n\tbeaconRoot := bbh.HashTreeRoot()\n\tif !merkle.VerifyProof(\n\t\tbeaconRoot,\n\t\tleaf,\n\t\tzeroWithdrawalGIndexBlock+validatorOffset.Unwrap(),\n\t\tproof,\n\t) {\n\t\treturn common.Root{}, errors.Wrapf(\n\t\t\terrors.New(\"withdrawal credentials proof failed to verify against beacon root\"),\n\t\t\t\"beacon root: 0x%s\", beaconRoot,\n\t\t)\n\t}\n\n\treturn beaconRoot, nil\n}\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/validator_credentials_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/proof/merkle\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/proof/merkle/mock\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// TestValidatorCredentialsProof tests the ProveWithdrawalCredentialsInBlock function\n// and that the generated proof correctly verifies.\nfunc TestValidatorCredentialsProof(t *testing.T) {\n\tt.Parallel()\n\ttestCases := []struct {\n\t\tname              string\n\t\tforkVersion       common.Version\n\t\tnumValidators     int\n\t\tslot              math.Slot\n\t\tvalIndex          math.ValidatorIndex\n\t\tparentBlockRoot   common.Root\n\t\tbodyRoot          common.Root\n\t\tpubKey            crypto.BLSPubkey\n\t\twithdrawalAddress common.ExecutionAddress\n\t\texpectedProofFile string\n\t}{\n\t\t{\n\t\t\tname:              \"1 Validator Set\",\n\t\t\tforkVersion:       version.Electra(),\n\t\t\tnumValidators:     1,\n\t\t\tslot:              4,\n\t\t\tvalIndex:          0,\n\t\t\tparentBlockRoot:   common.Root{1, 2, 3},\n\t\t\tbodyRoot:          common.Root{3, 2, 1},\n\t\t\tpubKey:            [48]byte{9, 8, 7, 6, 5, 4, 3, 2, 1},\n\t\t\twithdrawalAddress: common.ExecutionAddress{1, 2, 3},\n\t\t\texpectedProofFile: \"one_validator_validator_credentials_proof.json\",\n\t\t},\n\t\t{\n\t\t\tname:              \"Many Validator Set\",\n\t\t\tforkVersion:       version.Electra(),\n\t\t\tnumValidators:     100,\n\t\t\tslot:              5,\n\t\t\tvalIndex:          95,\n\t\t\tparentBlockRoot:   common.Root{1, 2, 3, 4, 5, 6},\n\t\t\tbodyRoot:          common.Root{3, 2, 1, 9, 8, 7},\n\t\t\tpubKey:            [48]byte{9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2},\n\t\t\twithdrawalAddress: common.ExecutionAddress{1, 2, 3},\n\t\t\texpectedProofFile: \"many_validators_validator_credentials_proof.json\",\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tvals := make(types.Validators, tc.numValidators)\n\t\t\tfor i := range vals {\n\t\t\t\tvals[i] = &types.Validator{}\n\t\t\t}\n\t\t\tvals[tc.valIndex] = &types.Validator{\n\t\t\t\tPubkey:                tc.pubKey,\n\t\t\t\tWithdrawalCredentials: types.NewCredentialsFromExecutionAddress(tc.withdrawalAddress),\n\t\t\t}\n\n\t\t\tbs := mock.NewBeaconStateWith(\n\t\t\t\ttc.slot, vals, 0, common.ExecutionAddress{}, tc.forkVersion,\n\t\t\t)\n\n\t\t\tbbh := types.NewBeaconBlockHeader(\n\t\t\t\ttc.slot,\n\t\t\t\ttc.valIndex,\n\t\t\t\ttc.parentBlockRoot,\n\t\t\t\tbs.HashTreeRoot(),\n\t\t\t\ttc.bodyRoot,\n\t\t\t)\n\n\t\t\tproof, _, err := merkle.ProveWithdrawalCredentialsInBlock(\n\t\t\t\ttc.valIndex, bbh, bs,\n\t\t\t)\n\t\t\trequire.NoError(t, err)\n\t\t\texpectedProof := ReadProofFromFile(t, tc.expectedProofFile)\n\t\t\trequire.Equal(t, expectedProof, proof)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/validator_pubkey.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle\n\nimport (\n\t\"fmt\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/proof/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/merkle\"\n)\n\n// ProveProposerPubkeyInBlock generates a proof for the proposer pubkey in the\n// beacon block.\nfunc ProveProposerPubkeyInBlock(\n\tbbh *ctypes.BeaconBlockHeader,\n\tbsm types.BeaconStateMarshallable,\n) ([]common.Root, common.Root, error) {\n\treturn ProveValidatorPubkeyInBlock(bbh.GetProposerIndex(), bbh, bsm)\n}\n\n// ProveValidatorPubkeyInBlock generates a proof for a validator's pubkey in the\n// beacon block. The proof is verified against the beacon block root as a sanity\n// check and the beacon block root is returned alongside the proof.\nfunc ProveValidatorPubkeyInBlock(\n\tvalidatorIndex math.U64,\n\tbbh *ctypes.BeaconBlockHeader,\n\tbsm types.BeaconStateMarshallable,\n) ([]common.Root, common.Root, error) {\n\tforkVersion := bsm.GetForkVersion()\n\n\t// Calculate the validator-specific offset.\n\tvalidatorOffset := ValidatorGIndexOffset * validatorIndex\n\n\t// 1. Proof inside the state.\n\tpubkeyInStateProof, leaf, err := ProveValidatorPubkeyInState(\n\t\tforkVersion, bsm, validatorOffset,\n\t)\n\tif err != nil {\n\t\treturn nil, common.Root{}, err\n\t}\n\n\t// 2. Proof of the state inside the block.\n\tstateInBlockProof, err := ProveBeaconStateInBlock(bbh, false)\n\tif err != nil {\n\t\treturn nil, common.Root{}, err\n\t}\n\n\t// 3. Combine proofs: state-level hashes come first, followed by block-level hashes.\n\t//\n\t//nolint:gocritic // ok.\n\tcombinedProof := append(pubkeyInStateProof, stateInBlockProof...)\n\n\t// 4. Verify the combined proof against the beacon block root.\n\tbeaconRoot, err := verifyPubkeyInBlock(\n\t\tforkVersion, bbh, validatorOffset, combinedProof, leaf,\n\t)\n\tif err != nil {\n\t\treturn nil, common.Root{}, err\n\t}\n\n\treturn combinedProof, beaconRoot, nil\n}\n\n// ProveValidatorPubkeyInState generates a proof for a validator's pubkey\n// in the beacon state. The validatorOffset must be computed as\n// (ValidatorGIndexOffset * validatorIndex).\nfunc ProveValidatorPubkeyInState(\n\tforkVersion common.Version,\n\tbsm types.BeaconStateMarshallable,\n\tvalidatorOffset math.U64,\n) ([]common.Root, common.Root, error) {\n\tstateProofTree, err := bsm.GetTree()\n\tif err != nil {\n\t\treturn nil, common.Root{}, err\n\t}\n\n\t// Determine the correct gIndex based on the fork version.\n\tgIndex := int(validatorOffset) // #nosec G115 -- max validator offset is 8 * (2^40 - 1).\n\tzeroValidatorPubkeyGIndexState, err := GetZeroValidatorPubkeyGIndexState(forkVersion)\n\tif err != nil {\n\t\treturn nil, common.Root{}, err\n\t}\n\tgIndex += zeroValidatorPubkeyGIndexState\n\n\tvalPubkeyInStateProof, err := stateProofTree.Prove(gIndex)\n\tif err != nil {\n\t\treturn nil, common.Root{}, err\n\t}\n\n\tproof := make([]common.Root, len(valPubkeyInStateProof.Hashes))\n\tfor i, hash := range valPubkeyInStateProof.Hashes {\n\t\tproof[i] = common.NewRootFromBytes(hash)\n\t}\n\treturn proof, common.NewRootFromBytes(valPubkeyInStateProof.Leaf), nil\n}\n\n// verifyPubkeyInBlock verifies the validator pubkey in the beacon block,\n// returning the beacon block root used to verify against.\n//\n// TODO: verifying the proof is not absolutely necessary.\nfunc verifyPubkeyInBlock(\n\tforkVersion common.Version,\n\tbbh *ctypes.BeaconBlockHeader,\n\tvalOffset math.U64,\n\tproof []common.Root,\n\tleaf common.Root,\n) (common.Root, error) {\n\tzeroValidatorPubkeyGIndexBlock, err := GetZeroValidatorPubkeyGIndexBlock(forkVersion)\n\tif err != nil {\n\t\treturn common.Root{}, err\n\t}\n\n\tbeaconRoot := bbh.HashTreeRoot()\n\tif !merkle.VerifyProof(\n\t\tbeaconRoot, leaf, zeroValidatorPubkeyGIndexBlock+valOffset.Unwrap(), proof,\n\t) {\n\t\treturn common.Root{}, fmt.Errorf(\n\t\t\t\"proposer pubkey proof failed to verify against beacon root: %s\", beaconRoot,\n\t\t)\n\t}\n\n\treturn beaconRoot, nil\n}\n"
  },
  {
    "path": "node-api/handlers/proof/merkle/validator_pubkey_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/proof/merkle\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/proof/merkle/mock\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// TestValidatorPubkeyProof tests the ProveValidatorPubkeyInBlock function\n// and that the generated proof correctly verifies.\nfunc TestValidatorPubkeyProof(t *testing.T) {\n\tt.Parallel()\n\ttestCases := []struct {\n\t\tname              string\n\t\tforkVersion       common.Version\n\t\tnumValidators     int\n\t\tslot              math.Slot\n\t\tproposerIndex     math.ValidatorIndex\n\t\tparentBlockRoot   common.Root\n\t\tbodyRoot          common.Root\n\t\tpubKey            crypto.BLSPubkey\n\t\texpectedProofFile string\n\t}{\n\t\t{\n\t\t\tname:              \"1 Validator Set - Deneb\",\n\t\t\tforkVersion:       version.Deneb(),\n\t\t\tnumValidators:     1,\n\t\t\tslot:              4,\n\t\t\tproposerIndex:     0,\n\t\t\tparentBlockRoot:   common.Root{1, 2, 3},\n\t\t\tbodyRoot:          common.Root{3, 2, 1},\n\t\t\tpubKey:            [48]byte{9, 8, 7, 6, 5, 4, 3, 2, 1},\n\t\t\texpectedProofFile: \"one_validator_proposer_pubkey_proof_deneb.json\",\n\t\t},\n\t\t{\n\t\t\tname:              \"Many Validator Set - Deneb\",\n\t\t\tforkVersion:       version.Deneb(),\n\t\t\tnumValidators:     100,\n\t\t\tslot:              5,\n\t\t\tproposerIndex:     95,\n\t\t\tparentBlockRoot:   common.Root{1, 2, 3, 4, 5, 6},\n\t\t\tbodyRoot:          common.Root{3, 2, 1, 9, 8, 7},\n\t\t\tpubKey:            [48]byte{9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2},\n\t\t\texpectedProofFile: \"many_validators_proposer_pubkey_proof_deneb.json\",\n\t\t},\n\t\t{\n\t\t\tname:              \"1 Validator Set - Electra\",\n\t\t\tforkVersion:       version.Electra(),\n\t\t\tnumValidators:     1,\n\t\t\tslot:              4,\n\t\t\tproposerIndex:     0,\n\t\t\tparentBlockRoot:   common.Root{1, 2, 3},\n\t\t\tbodyRoot:          common.Root{3, 2, 1},\n\t\t\tpubKey:            [48]byte{9, 8, 7, 6, 5, 4, 3, 2, 1},\n\t\t\texpectedProofFile: \"one_validator_proposer_pubkey_proof_electra.json\",\n\t\t},\n\t\t{\n\t\t\tname:              \"Many Validator Set - Electra\",\n\t\t\tforkVersion:       version.Electra(),\n\t\t\tnumValidators:     100,\n\t\t\tslot:              5,\n\t\t\tproposerIndex:     95,\n\t\t\tparentBlockRoot:   common.Root{1, 2, 3, 4, 5, 6},\n\t\t\tbodyRoot:          common.Root{3, 2, 1, 9, 8, 7},\n\t\t\tpubKey:            [48]byte{9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2},\n\t\t\texpectedProofFile: \"many_validators_proposer_pubkey_proof_electra.json\",\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tvals := make(types.Validators, tc.numValidators)\n\t\t\tfor i := range vals {\n\t\t\t\tvals[i] = &types.Validator{}\n\t\t\t}\n\t\t\tvals[tc.proposerIndex] = &types.Validator{Pubkey: tc.pubKey}\n\n\t\t\tbs := mock.NewBeaconStateWith(\n\t\t\t\ttc.slot, vals, 0, common.ExecutionAddress{}, tc.forkVersion,\n\t\t\t)\n\n\t\t\tbbh := types.NewBeaconBlockHeader(\n\t\t\t\ttc.slot,\n\t\t\t\ttc.proposerIndex,\n\t\t\t\ttc.parentBlockRoot,\n\t\t\t\tbs.HashTreeRoot(),\n\t\t\t\ttc.bodyRoot,\n\t\t\t)\n\n\t\t\t// Use the proposer pubkey helper function to prove validator pubkey of block proposer.\n\t\t\tproof, _, err := merkle.ProveProposerPubkeyInBlock(bbh, bs)\n\t\t\trequire.NoError(t, err)\n\t\t\texpectedProof := ReadProofFromFile(t, tc.expectedProofFile)\n\t\t\trequire.Equal(t, expectedProof, proof)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "node-api/handlers/proof/routes.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage proof\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n)\n\nfunc registerRoutes(h *Handler) {\n\th.BaseHandler.AddRoutes([]*handlers.Route{\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"bkit/v1/proof/block_proposer/:timestamp_id\",\n\t\t\tHandler: h.GetBlockProposer,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"bkit/v1/proof/validator_pubkey/:timestamp_id/:validator_index\",\n\t\t\tHandler: h.GetValidatorPubkey,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"bkit/v1/proof/validator_credentials/:timestamp_id/:validator_index\",\n\t\t\tHandler: h.GetValidatorCredentials,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"bkit/v1/proof/validator_balance/:timestamp_id/:validator_index\",\n\t\t\tHandler: h.GetValidatorBalance,\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "node-api/handlers/proof/types/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\tfastssz \"github.com/ferranbt/fastssz\"\n)\n\n// BeaconStateMarshallable is the interface for a beacon state that can be\n// marshalled or hash tree rooted.\ntype BeaconStateMarshallable interface {\n\tconstraints.Versionable\n\t// GetTree is kept for FastSSZ compatibility.\n\tGetTree() (*fastssz.Node, error)\n}\n"
  },
  {
    "path": "node-api/handlers/proof/types/request.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport \"github.com/berachain/beacon-kit/node-api/handlers/types\"\n\n// BlockProposerRequest is the request for the\n// `/proof/block_proposer/{timestamp_id}` endpoint.\ntype BlockProposerRequest struct {\n\ttypes.TimestampIDRequest\n}\n\n// ValidatorIndexRequest is a request that uses timestamp_id and validator_index.\ntype ValidatorIndexRequest struct {\n\ttypes.TimestampIDRequest\n\tValidatorIndex string `param:\"validator_index\" validate:\"required,numeric\"`\n}\n\n// ValidatorCredentialsRequest is the request for the\n// `/proof/validator_credentials/{timestamp_id}/{validator_index}` endpoint.\ntype ValidatorCredentialsRequest = ValidatorIndexRequest\n\n// ValidatorBalanceRequest is the request for the\n// `/proof/validator_balance/{timestamp_id}/{validator_index}` endpoint.\ntype ValidatorBalanceRequest = ValidatorIndexRequest\n\n// ValidatorPubkeyRequest is the request for the\n// `/proof/validator_pubkey/{timestamp_id}/{validator_index}` endpoint.\ntype ValidatorPubkeyRequest = ValidatorIndexRequest\n"
  },
  {
    "path": "node-api/handlers/proof/types/response.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// BlockProposerResponse is the response for the\n// `/proof/block_proposer/{timestamp_id}` endpoint.\ntype BlockProposerResponse struct {\n\t// BeaconBlockHeader is the block header of which the hash tree root is the\n\t// beacon block root to verify against.\n\tBeaconBlockHeader *ctypes.BeaconBlockHeader `json:\"beacon_block_header\"`\n\n\t// BeaconBlockRoot is the beacon block root for this slot.\n\tBeaconBlockRoot common.Root `json:\"beacon_block_root\"`\n\n\t// ValidatorPubkey is the pubkey of the block proposer.\n\tValidatorPubkey crypto.BLSPubkey `json:\"validator_pubkey\"`\n\n\t// ValidatorPubkeyProof can be verified against the beacon block root. Use\n\t// a Generalized Index of `z + (8 * ValidatorIndex)`, where z is the\n\t// Generalized Index of the 0 validator pubkey in the beacon block. In\n\t// the Deneb fork, z is 3254554418216960.\n\tValidatorPubkeyProof []common.Root `json:\"validator_pubkey_proof\"`\n\n\t// ProposerIndexProof can be verified against the beacon block root. Use\n\t// a Generalized Index of 9 in the Deneb fork.\n\tProposerIndexProof []common.Root `json:\"proposer_index_proof\"`\n}\n\n// ValidatorWithdrawalCredentialsResponse is the response for the\n// `/proof/validator_withdrawal_credentials/{timestamp_id}/{validator_index}` endpoint.\ntype ValidatorWithdrawalCredentialsResponse struct {\n\t// BeaconBlockHeader is the block header of which the hash tree root is the\n\t// beacon block root to verify against.\n\tBeaconBlockHeader *ctypes.BeaconBlockHeader `json:\"beacon_block_header\"`\n\n\t// BeaconBlockRoot is the beacon block root for this slot.\n\tBeaconBlockRoot common.Root `json:\"beacon_block_root\"`\n\n\t// WithdrawalCredentials are the credentials of the requested validator.\n\tValidatorWithdrawalCredentials ctypes.WithdrawalCredentials `json:\"validator_withdrawal_credentials\"`\n\n\t// WithdrawalCredentialsProof can be verified against the beacon block root.\n\t// Use a Generalized Index of `z + (8 * ValidatorIndex)`, where z is the\n\t// Generalized Index of the 0 validator withdrawal credentials in the beacon\n\t// block. In the Electra fork, z is 6350779162034177.\n\tWithdrawalCredentialsProof []common.Root `json:\"withdrawal_credentials_proof\"`\n}\n\n// ValidatorBalanceResponse is the response for the\n// `/proof/validator_balance/{timestamp_id}/{validator_index}` endpoint.\ntype ValidatorBalanceResponse struct {\n\t// BeaconBlockHeader is the block header of which the hash tree root is the\n\t// beacon block root to verify against.\n\tBeaconBlockHeader *ctypes.BeaconBlockHeader `json:\"beacon_block_header\"`\n\n\t// BeaconBlockRoot is the beacon block root for this slot.\n\tBeaconBlockRoot common.Root `json:\"beacon_block_root\"`\n\n\t// ValidatorBalance is the balance of the requested validator.\n\tValidatorBalance math.Gwei `json:\"validator_balance\"`\n\n\t// BalanceLeaf is the leaf containing the validator's balance along with up\n\t// to 3 other validators' balances (packed 4 per leaf).\n\tBalanceLeaf common.Root `json:\"balance_leaf\"`\n\n\t// BalanceProof can be verified against the beacon block root.\n\t// Use a Generalized Index of `z + (1 * (ValidatorIndex / 4))`, where z is the\n\t// Generalized Index of the 0-3 validators' balances in the beacon block.\n\t// In the Electra fork, z is 199011604627456.\n\tBalanceProof []common.Root `json:\"balance_proof\"`\n}\n\n// ValidatorPubkeyResponse is the response for the\n// `/proof/validator_pubkey/{timestamp_id}/{validator_index}` endpoint.\ntype ValidatorPubkeyResponse struct {\n\t// BeaconBlockHeader is the block header of which the hash tree root is the\n\t// beacon block root to verify against.\n\tBeaconBlockHeader *ctypes.BeaconBlockHeader `json:\"beacon_block_header\"`\n\n\t// BeaconBlockRoot is the beacon block root for this slot.\n\tBeaconBlockRoot common.Root `json:\"beacon_block_root\"`\n\n\t// ValidatorPubkey is the pubkey of the requested validator.\n\tValidatorPubkey crypto.BLSPubkey `json:\"validator_pubkey\"`\n\n\t// ValidatorPubkeyProof can be verified against the beacon block root. Use\n\t// a Generalized Index of `z + (8 * ValidatorIndex)`, where z is the\n\t// Generalized Index of the 0 validator pubkey in the beacon block. In\n\t// the Deneb fork, z is 3254554418216960; in the Electra fork, z is\n\t// 6350779162034176.\n\tValidatorPubkeyProof []common.Root `json:\"validator_pubkey_proof\"`\n}\n"
  },
  {
    "path": "node-api/handlers/proof/validator_balance.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage proof\n\nimport (\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/proof/merkle\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/proof/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// GetValidatorBalance returns the balance of a validator along with a\n// Merkle proof that can be verified against the beacon block root.\nfunc (h *Handler) GetValidatorBalance(c handlers.Context) (any, error) {\n\tparams, err := utils.BindAndValidate[types.ValidatorBalanceRequest](c, h.Logger())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Validator index is provided as a string path parameter; convert to math.U64.\n\tvalidatorIndex, err := math.U64FromString(params.ValidatorIndex)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tslot, beaconState, blockHeader, err := h.resolveTimestampID(params.TimestampID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\th.Logger().Info(\n\t\t\"Generating balance proof\", \"slot\", slot, \"validator_index\", validatorIndex,\n\t)\n\n\t// Generate proof for balance in the block.\n\tbsm, err := beaconState.GetMarshallable()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Fetch all balances from state and construct the balance leaf using the\n\t// helper in the merkle package.\n\tallBalances, err := beaconState.GetBalances()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tbalanceProof, balanceLeaf, beaconBlockRoot, err := merkle.ProveBalanceInBlock(\n\t\tvalidatorIndex, blockHeader, bsm, allBalances,\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Fetch the balance to include in the response.\n\tbalance, err := beaconState.GetBalance(validatorIndex)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn types.ValidatorBalanceResponse{\n\t\tBeaconBlockHeader: blockHeader,\n\t\tBeaconBlockRoot:   beaconBlockRoot,\n\t\tValidatorBalance:  balance,\n\t\tBalanceLeaf:       balanceLeaf,\n\t\tBalanceProof:      balanceProof,\n\t}, nil\n}\n"
  },
  {
    "path": "node-api/handlers/proof/validator_credentials.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//nolint:dupl // False positive detected.\npackage proof\n\nimport (\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/proof/merkle\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/proof/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// GetValidatorCredentials returns the withdrawal credentials of a validator along with a\n// Merkle proof that can be verified against the beacon block root.\nfunc (h *Handler) GetValidatorCredentials(c handlers.Context) (any, error) {\n\tparams, err := utils.BindAndValidate[types.ValidatorCredentialsRequest](c, h.Logger())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Validator index is provided as a string path parameter; convert to math.U64.\n\tvalidatorIndex, err := math.U64FromString(params.ValidatorIndex)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tslot, beaconState, blockHeader, err := h.resolveTimestampID(params.TimestampID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\th.Logger().Info(\n\t\t\"Generating withdrawal credential proof\", \"slot\", slot, \"validator_index\", validatorIndex,\n\t)\n\n\t// Generate proof for withdrawal credentials in the block.\n\tbsm, err := beaconState.GetMarshallable()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcredsProof, beaconBlockRoot, err := merkle.ProveWithdrawalCredentialsInBlock(\n\t\tvalidatorIndex, blockHeader, bsm,\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Fetch the validator to get the withdrawal credentials to include in the response.\n\tvalidator, err := beaconState.ValidatorByIndex(validatorIndex)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn types.ValidatorWithdrawalCredentialsResponse{\n\t\tBeaconBlockHeader:              blockHeader,\n\t\tBeaconBlockRoot:                beaconBlockRoot,\n\t\tValidatorWithdrawalCredentials: validator.GetWithdrawalCredentials(),\n\t\tWithdrawalCredentialsProof:     credsProof,\n\t}, nil\n}\n"
  },
  {
    "path": "node-api/handlers/proof/validator_pubkey.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//nolint:dupl // False positive detected.\npackage proof\n\nimport (\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/proof/merkle\"\n\tptypes \"github.com/berachain/beacon-kit/node-api/handlers/proof/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// GetValidatorPubkey returns the pubkey of a validator along with a\n// Merkle proof that can be verified against the beacon block root.\nfunc (h *Handler) GetValidatorPubkey(c handlers.Context) (any, error) {\n\tparams, err := utils.BindAndValidate[ptypes.ValidatorPubkeyRequest](c, h.Logger())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Validator index is provided as a string path parameter; convert to math.U64.\n\tvalidatorIndex, err := math.U64FromString(params.ValidatorIndex)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tslot, beaconState, blockHeader, err := h.resolveTimestampID(params.TimestampID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\th.Logger().Info(\n\t\t\"Generating validator pubkey proof\", \"slot\", slot, \"validator_index\", validatorIndex,\n\t)\n\n\t// Generate proof for validator pubkey in the block.\n\tbsm, err := beaconState.GetMarshallable()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tpubkeyProof, beaconBlockRoot, err := merkle.ProveValidatorPubkeyInBlock(\n\t\tvalidatorIndex, blockHeader, bsm,\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Fetch the validator to include the pubkey in the response.\n\tvalidator, err := beaconState.ValidatorByIndex(validatorIndex)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn ptypes.ValidatorPubkeyResponse{\n\t\tBeaconBlockHeader:    blockHeader,\n\t\tBeaconBlockRoot:      beaconBlockRoot,\n\t\tValidatorPubkey:      validator.GetPubkey(),\n\t\tValidatorPubkeyProof: pubkeyProof,\n\t}, nil\n}\n"
  },
  {
    "path": "node-api/handlers/routes.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage handlers\n\nimport (\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/labstack/echo/v4\"\n)\n\ntype Context = echo.Context\n\n// handlerFn enforces a signature for all handler functions.\ntype handlerFn func(c Context) (any, error)\n\n// Route is a route for the node API.\ntype Route struct {\n\tMethod  string\n\tPath    string\n\tHandler handlerFn\n}\n\n// DecorateWithLogs adds logging to the route's handler function as soon as\n// a request is received and when a response is ready.\nfunc (r *Route) DecorateWithLogs(logger log.Logger) {\n\thandler := r.Handler\n\tr.Handler = func(ctx Context) (any, error) {\n\t\tlogger.Info(\"received request\", \"method\", r.Method, \"path\", r.Path)\n\t\tres, err := handler(ctx)\n\t\tif err != nil {\n\t\t\tlogger.Error(\"error handling request\", \"error\", err)\n\t\t}\n\t\tlogger.Info(\"request handled\")\n\t\treturn res, err\n\t}\n}\n\n// RouteSet is a set of routes for the node API.\ntype RouteSet struct {\n\tBasePath string\n\tRoutes   []*Route\n}\n\n// NewRouteSet creates a new route set.\nfunc NewRouteSet(basePath string, routes ...*Route) *RouteSet {\n\treturn &RouteSet{\n\t\tBasePath: basePath,\n\t\tRoutes:   routes,\n\t}\n}\n"
  },
  {
    "path": "node-api/handlers/types/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport \"errors\"\n\nvar (\n\tErrNotFound       = errors.New(\"not found\")\n\tErrNotImplemented = errors.New(\"not implemented\")\n\tErrInvalidRequest = errors.New(\"invalid request\")\n)\n"
  },
  {
    "path": "node-api/handlers/types/request.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\ntype StateIDRequest struct {\n\tStateID string `param:\"state_id\" validate:\"required,state_id\"`\n}\n\ntype BlockIDRequest struct {\n\tBlockID string `param:\"block_id\" validate:\"required,block_id\"`\n}\n\ntype TimestampIDRequest struct {\n\tTimestampID string `param:\"timestamp_id\" validate:\"required,timestamp_id\"`\n}\n"
  },
  {
    "path": "node-api/handlers/utils/constants.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage utils\n\nconst (\n\tStateIDGenesis    = \"genesis\"\n\tStateIDFinalized  = \"finalized\"\n\tStateIDJustified  = \"justified\"\n\tStateIDHead       = \"head\"\n\tTimestampIDPrefix = \"t\"\n)\n\nconst (\n\tHead    int64 = -1\n\tGenesis int64 = 0\n)\n"
  },
  {
    "path": "node-api/handlers/utils/context.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage utils\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/types\"\n)\n\n// BindAndValidate binds the request to the context and validates it.\nfunc BindAndValidate[RequestT any](c handlers.Context, logger log.Logger) (RequestT, error) {\n\tvar req RequestT\n\tif err := c.Bind(&req); err != nil {\n\t\treturn req, fmt.Errorf(\"%w: failed to bind request: %s\", types.ErrInvalidRequest, err.Error())\n\t}\n\tif err := c.Validate(&req); err != nil {\n\t\treturn req, fmt.Errorf(\"%w: failed to validate request: %s\", types.ErrInvalidRequest, err.Error())\n\t}\n\tlogger.Info(\"Request validation successful\", \"params\", req)\n\treturn req, nil\n}\n"
  },
  {
    "path": "node-api/handlers/utils/mappings.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage utils\n\nimport (\n\t\"fmt\"\n\tstdmath \"math\"\n\t\"strings\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\nvar (\n\tErrNoSlotForStateRoot         = errors.New(\"slot not found at state root\")\n\tErrFailedMappingHeightTooHigh = errors.New(\"failed mapping height too high\")\n)\n\n// TODO: define unique types for each of the query-able IDs (state & block from\n// spec, execution unique to beacon-kit). For each type define validation\n// functions and resolvers to slot number.\n\n// StateIDToHeight returns a slot from the state ID.\n//\n// NOTE: Right now, `stateID` only supports querying by \"head\" (all of \"head\",\n// \"finalized\", \"justified\" are the same), \"genesis\", and <slot>.\nfunc StateIDToHeight[StorageBackendT interface {\n\tGetSlotByStateRoot(root common.Root) (math.Slot, error)\n}](stateID string, storage StorageBackendT) (int64, error) {\n\tif slot, err := stateIDToHeight(stateID); err == nil {\n\t\treturn slot, nil\n\t}\n\n\t// We assume that the state ID is a state hash.\n\troot, err := common.NewRootFromHex(stateID)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tslot, err := storage.GetSlotByStateRoot(root)\n\tif err != nil {\n\t\treturn 0, ErrNoSlotForStateRoot\n\t}\n\tif slot > stdmath.MaxInt64 { // appease linters\n\t\treturn 0, fmt.Errorf(\"%w: slot %d\", ErrFailedMappingHeightTooHigh, slot)\n\t}\n\treturn int64(slot), nil //#nosec: G115 // practically safe\n}\n\n// BlockIDToHeight returns a height from the block ID.\n//\n// NOTE: `blockID` shares the same semantics as `stateID`, with the modification\n// of being able to query by beacon <blockRoot> instead of <stateRoot>.\nfunc BlockIDToHeight[StorageBackendT interface {\n\tGetSlotByBlockRoot(root common.Root) (math.Slot, error)\n}](blockID string, storage StorageBackendT) (int64, error) {\n\tif slot, err := stateIDToHeight(blockID); err == nil {\n\t\treturn slot, nil\n\t}\n\n\t// We assume that the block ID is a block hash.\n\troot, err := common.NewRootFromHex(blockID)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tslot, err := storage.GetSlotByBlockRoot(root)\n\tif slot > stdmath.MaxInt64 { // appease linters\n\t\treturn 0, fmt.Errorf(\"%w: slot %d\", ErrFailedMappingHeightTooHigh, slot)\n\t}\n\treturn int64(slot), err //#nosec: G115 // practically safe\n}\n\n// TimestampIDToParentHeight returns the parent slot corresponding to the\n// timestamp ID.\n//\n// NOTE: `timestampID` shares the same semantics as `stateID`, with the\n// modification of being able to query by next block's <timestamp> instead of\n// the current block's <stateRoot>.\n//\n// The <timestamp> must be prefixed by the 't', followed by the timestamp\n// in decimal UNIX notation. For example 't1728681738' corresponds to the slot\n// which has the next block with a timestamp of 1728681738. Providing just the\n// string '1728681738' (without the prefix 't') will query for the beacon block\n// for slot 1728681738.\nfunc TimestampIDToParentHeight[StorageBackendT interface {\n\tGetParentSlotByTimestamp(timestamp math.U64) (math.Slot, error)\n}](timestampID string, storage StorageBackendT) (int64, error) {\n\tif !IsTimestampIDPrefix(timestampID) {\n\t\treturn stateIDToHeight(timestampID)\n\t}\n\n\t// Parse the timestamp from the timestampID.\n\ttimestamp, err := math.U64FromString(timestampID[1:])\n\tif err != nil {\n\t\treturn 0, errors.Wrapf(\n\t\t\terr, \"failed to parse timestamp from timestampID: %s\", timestampID,\n\t\t)\n\t}\n\tslot, err := storage.GetParentSlotByTimestamp(timestamp)\n\tif slot > stdmath.MaxInt64 { // appease linters\n\t\treturn 0, fmt.Errorf(\"%w: slot %d\", ErrFailedMappingHeightTooHigh, slot)\n\t}\n\treturn int64(slot), err //#nosec: G115 // practically safe\n}\n\n// IsTimestampIDPrefix checks if the given timestampID is prefixed with the\n// correct prefix 't'.\nfunc IsTimestampIDPrefix(timestampID string) bool {\n\treturn strings.HasPrefix(timestampID, TimestampIDPrefix)\n}\n\n// stateIDToHeight returns a slot number from the given state ID.\n// Returns -1 if chain tip is requested\n// Returns 0 if genesis is requested\n// Returns a positive integer if any chain slot is requested\nfunc stateIDToHeight(id string) (int64, error) {\n\tswitch id {\n\tcase StateIDFinalized, StateIDJustified, StateIDHead:\n\t\treturn Head, nil\n\tcase StateIDGenesis:\n\t\treturn Genesis, nil\n\tdefault:\n\t\tslot, err := math.U64FromString(id)\n\t\tif err != nil {\n\t\t\treturn 0, errors.Wrapf(err, \"failed mapping stateID %q to slot\", id)\n\t\t}\n\t\tif slot > stdmath.MaxInt64 { // appease linters\n\t\t\treturn 0, fmt.Errorf(\"%w: slot %d\", ErrFailedMappingHeightTooHigh, slot)\n\t\t}\n\t\treturn int64(slot), nil //#nosec: G115 // practically safe\n\t}\n}\n"
  },
  {
    "path": "node-api/handlers/validator/handler.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage validator\n\nimport (\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n)\n\ntype Handler struct {\n\t*handlers.BaseHandler\n}\n\nfunc NewHandler(logger log.Logger) *Handler {\n\th := &Handler{\n\t\tBaseHandler: handlers.NewBaseHandler(logger),\n\t}\n\tregisterRoutes(h)\n\treturn h\n}\n"
  },
  {
    "path": "node-api/handlers/validator/routes.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage validator\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n)\n\nfunc registerRoutes(h *Handler) {\n\th.BaseHandler.AddRoutes([]*handlers.Route{\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/validator/duties/attester/:epoch\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/validator/duties/proposer/:epoch\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/validator/duties/sync/:epoch\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v3/validator/blocks/:slot\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/validator/attestation_data\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/validator/aggregate_attestation\",\n\t\t\tHandler: h.Deprecated,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v2/validator/aggregate_attestation\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/validator/aggregate_and_proofs\",\n\t\t\tHandler: h.Deprecated,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v2/validator/aggregate_and_proofs\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/validator/beacon_committee_subscriptions\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/validator/sync_committee_subscriptions\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/validator/beacon_committee_selections\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodGet,\n\t\t\tPath:    \"/eth/v1/validator/sync_committee_contribution\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/validator/contribution_and_proofs\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/validator/prepare_beacon_proposer\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/validator/register_validator\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t\t{\n\t\t\tMethod:  http.MethodPost,\n\t\t\tPath:    \"/eth/v1/validator/liveness/:epoch\",\n\t\t\tHandler: h.NotImplemented,\n\t\t},\n\t})\n}\n"
  },
  {
    "path": "node-api/middleware/middleware.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage middleware\n\nimport (\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\t\"github.com/labstack/echo/v4\"\n\t\"github.com/labstack/echo/v4/middleware\"\n)\n\n// Middleware is an implementation of the API engine interface using Echo.\ntype Middleware struct {\n\t*echo.Echo\n\tlogger log.Logger\n}\n\n// NewDefaultMiddleware returns a new default Echo Engine instance.\nfunc NewDefaultMiddleware(logger log.Logger) *Middleware {\n\tengine := echo.New()\n\tengine.Use(middleware.CORSWithConfig(\n\t\tmiddleware.DefaultCORSConfig,\n\t))\n\tengine.Validator = &CustomValidator{\n\t\tValidator: ConstructValidator(),\n\t}\n\tengine.HideBanner = true\n\treturn &Middleware{\n\t\tEcho:   engine,\n\t\tlogger: logger,\n\t}\n}\n\n// Run starts the Echo engine at the given address.\nfunc (e *Middleware) Run(addr string) error {\n\treturn e.Echo.Start(addr)\n}\n\n// RegisterRoutes registers the given route set with the Echo engine.\nfunc (e *Middleware) RegisterRoutes(hs *handlers.RouteSet) {\n\tgroup := e.Group(hs.BasePath)\n\tfor _, route := range hs.Routes {\n\t\troute.DecorateWithLogs(e.logger)\n\t\tgroup.Add(\n\t\t\troute.Method,\n\t\t\troute.Path,\n\t\t\tresponseMiddleware(route),\n\t\t)\n\t}\n}\n"
  },
  {
    "path": "node-api/middleware/request.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage middleware\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/go-playground/validator/v10\"\n\t\"github.com/labstack/echo/v4\"\n)\n\n// TODO: these validators need to be un-janked to 1) not use `FieldLevel` for\n// repeated `.Field().String()` calls and 2) strongly type the allowed IDs,\n// putting validation logic on each type.\n\n// CustomValidator is a custom validator for the API.\ntype CustomValidator struct {\n\tValidator *validator.Validate\n}\n\n// Validate validates the given interface.\nfunc (cv *CustomValidator) Validate(i interface{}) error {\n\tif err := cv.Validator.Struct(i); err != nil {\n\t\tvar validationErrors validator.ValidationErrors\n\t\thasValidationErrors := errors.As(err, &validationErrors)\n\t\tif !hasValidationErrors || len(validationErrors) == 0 {\n\t\t\treturn nil\n\t\t}\n\t\tfirstError := validationErrors[0]\n\t\tfield := firstError.Field()\n\t\tvalue := firstError.Value()\n\t\treturn echo.NewHTTPError(http.StatusBadRequest,\n\t\t\tfmt.Sprintf(\"Invalid %s: %s\", field, value))\n\t}\n\treturn nil\n}\n\nfunc ConstructValidator() *validator.Validate {\n\tvalidators := map[string](func(fl validator.FieldLevel) bool){\n\t\t\"state_id\":         ValidateStateID,\n\t\t\"block_id\":         ValidateBlockID,\n\t\t\"timestamp_id\":     ValidateTimestampID,\n\t\t\"validator_id\":     ValidateValidatorID,\n\t\t\"epoch\":            ValidateUint64,\n\t\t\"slot\":             ValidateUint64,\n\t\t\"validator_status\": ValidateValidatorStatus,\n\t\t\"hex\":              ValidateHex,\n\t}\n\tvalidate := validator.New()\n\tfor tag, fn := range validators {\n\t\terr := validate.RegisterValidation(tag, fn)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}\n\treturn validate\n}\n\nfunc ValidateStateID(fl validator.FieldLevel) bool {\n\tallowedValues := map[string]bool{\n\t\t\"head\":      true,\n\t\t\"genesis\":   true,\n\t\t\"finalized\": true,\n\t\t\"justified\": true,\n\t}\n\treturn validateStateBlockIDs(fl.Field().String(), allowedValues)\n}\n\nfunc ValidateBlockID(fl validator.FieldLevel) bool {\n\tallowedValues := map[string]bool{\n\t\t\"head\":      true,\n\t\t\"genesis\":   true,\n\t\t\"finalized\": true,\n\t}\n\treturn validateStateBlockIDs(fl.Field().String(), allowedValues)\n}\n\nfunc ValidateTimestampID(fl validator.FieldLevel) bool {\n\tallowedValues := map[string]bool{\n\t\tutils.StateIDHead:      true,\n\t\tutils.StateIDGenesis:   true,\n\t\tutils.StateIDFinalized: true,\n\t\tutils.StateIDJustified: true,\n\t}\n\n\tvalue := fl.Field().String()\n\tif utils.IsTimestampIDPrefix(value) {\n\t\treturn ValidateUint64Dec(value[1:])\n\t}\n\n\treturn validateStateBlockIDs(value, allowedValues)\n}\n\nfunc ValidateUint64Dec(value string) bool {\n\tif value == \"\" {\n\t\treturn true\n\t}\n\t_, err := math.U64FromString(value)\n\treturn err == nil\n}\n\nfunc ValidateUint64(fl validator.FieldLevel) bool {\n\treturn ValidateUint64Dec(fl.Field().String())\n}\n\n// ValidateValidatorID checks if the provided field is a valid\n// validator identifier. It validates against a hex-encoded public key\n// or a numeric validator index.\nfunc ValidateValidatorID(fl validator.FieldLevel) bool {\n\tvar key crypto.BLSPubkey\n\terr := key.UnmarshalText([]byte(fl.Field().String()))\n\tif err == nil {\n\t\treturn true\n\t}\n\tif ValidateUint64(fl) {\n\t\treturn true\n\t}\n\treturn false\n}\n\n// ValidateRoot checks if the provided field is a valid root.\n// It validates against a 32 byte hex-encoded root with \"0x\" prefix.\nfunc ValidateRoot(value string) bool {\n\t_, err := common.NewRootFromHex(value)\n\treturn err == nil\n}\n\nfunc ValidateValidatorStatus(fl validator.FieldLevel) bool {\n\t// Eth Beacon Node API specs: https://hackmd.io/ofFJ5gOmQpu1jjHilHbdQQ\n\tallowedStatuses := map[string]bool{\n\t\tconstants.ValidatorStatusActiveExiting:      true,\n\t\tconstants.ValidatorStatusActiveOngoing:      true,\n\t\tconstants.ValidatorStatusActiveSlashed:      true,\n\t\tconstants.ValidatorStatusExitedSlashed:      true,\n\t\tconstants.ValidatorStatusExitedUnslashed:    true,\n\t\tconstants.ValidatorStatusPendingInitialized: true,\n\t\tconstants.ValidatorStatusPendingQueued:      true,\n\t\tconstants.ValidatorStatusWithdrawalDone:     true,\n\t\tconstants.ValidatorStatusWithdrawalPossible: true,\n\t}\n\treturn validateAllowedStrings(fl.Field().String(), allowedStatuses)\n}\n\nfunc validateAllowedStrings(\n\tvalue string,\n\tallowedValues map[string]bool,\n) bool {\n\tif value == \"\" {\n\t\treturn true\n\t}\n\treturn allowedValues[value]\n}\n\nfunc validateStateBlockIDs(value string, allowedValues map[string]bool) bool {\n\t// Check if value is one of the allowed values\n\tif validateAllowedStrings(value, allowedValues) {\n\t\treturn true\n\t}\n\t// Check if value is a slot (unsigned 64-bit integer)\n\tif ValidateUint64Dec(value) {\n\t\treturn true\n\t}\n\t// Check if value is a hex-encoded 32 byte root with \"0x\" prefix\n\tif ValidateRoot(value) {\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc ValidateHex(fl validator.FieldLevel) bool {\n\t_, err := hex.IsValidHex(fl.Field().String())\n\treturn err == nil\n}\n"
  },
  {
    "path": "node-api/middleware/response.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage middleware\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/types\"\n\t\"github.com/labstack/echo/v4\"\n)\n\n// ErrorResponse is a response that is returned when an error occurs.\ntype ErrorResponse struct {\n\tCode    int    `json:\"code\"`\n\tMessage string `json:\"message\"`\n}\n\n// responseMiddleware is a middleware that converts errors to an HTTP status\n// code and response.\nfunc responseMiddleware(handler *handlers.Route) echo.HandlerFunc {\n\treturn func(c handlers.Context) error {\n\t\tdata, err := handler.Handler(c)\n\t\tcode, response := responseFromError(data, err)\n\t\treturn c.JSON(code, response)\n\t}\n}\n\n// responseFromError converts an error to an HTTP status code and response. If\n// the error is nil, the response is returned as is.\nfunc responseFromError(data any, err error) (int, any) {\n\tswitch {\n\tcase err == nil:\n\t\treturn http.StatusOK, data\n\tcase errors.Is(err, types.ErrNotFound):\n\t\treturn http.StatusNotFound, ErrorResponse{\n\t\t\tCode:    http.StatusNotFound,\n\t\t\tMessage: err.Error(),\n\t\t}\n\tcase errors.Is(err, types.ErrInvalidRequest):\n\t\treturn http.StatusBadRequest, ErrorResponse{\n\t\t\tCode:    http.StatusBadRequest,\n\t\t\tMessage: err.Error(),\n\t\t}\n\tcase errors.Is(err, types.ErrNotImplemented):\n\t\treturn http.StatusNotImplemented, ErrorResponse{\n\t\t\tCode:    http.StatusNotImplemented,\n\t\t\tMessage: err.Error(),\n\t\t}\n\tdefault:\n\t\treturn http.StatusInternalServerError, ErrorResponse{\n\t\t\tCode:    http.StatusInternalServerError,\n\t\t\tMessage: err.Error(),\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "node-api/server/config.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage server\n\nconst (\n\tdefaultAddress = \"127.0.0.1:3500\"\n)\n\n// Config is the configuration for the node API server.\ntype Config struct {\n\t// Enabled is the flag to enable the node API server.\n\tEnabled bool `mapstructure:\"enabled\"`\n\t// Address is the address to bind the node API server to.\n\tAddress string `mapstructure:\"address\"`\n\t// Logging is the flag to enable API logging.\n\tLogging bool `mapstructure:\"logging\"`\n}\n\n// DefaultConfig returns the default configuration for the node API server.\nfunc DefaultConfig() Config {\n\treturn Config{\n\t\tEnabled: false,\n\t\tAddress: defaultAddress,\n\t\tLogging: false,\n\t}\n}\n"
  },
  {
    "path": "node-api/server/server.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage server\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/log/noop\"\n\t\"github.com/berachain/beacon-kit/node-api/backend\"\n\tbeaconapi \"github.com/berachain/beacon-kit/node-api/handlers/beacon\"\n\tbuilderapi \"github.com/berachain/beacon-kit/node-api/handlers/builder\"\n\tcometbftapi \"github.com/berachain/beacon-kit/node-api/handlers/cometbft\"\n\tconfigapi \"github.com/berachain/beacon-kit/node-api/handlers/config\"\n\tdebugapi \"github.com/berachain/beacon-kit/node-api/handlers/debug\"\n\teventsapi \"github.com/berachain/beacon-kit/node-api/handlers/events\"\n\tnodeapi \"github.com/berachain/beacon-kit/node-api/handlers/node\"\n\tproofapi \"github.com/berachain/beacon-kit/node-api/handlers/proof\"\n\t\"github.com/berachain/beacon-kit/node-api/middleware\"\n\t\"github.com/berachain/beacon-kit/node-core/components/storage\"\n\t\"github.com/berachain/beacon-kit/node-core/types\"\n\t\"github.com/berachain/beacon-kit/state-transition/core\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n)\n\n// Server is the API Server service.\ntype Server struct {\n\tconfig     Config\n\tlogger     log.Logger\n\tmiddleware *middleware.Middleware\n\n\tb *backend.Backend\n\t// exposed via getter for some tests.\n\t// TODO: consider extending this to other handlers\n\tbeaconHandler *beaconapi.Handler\n}\n\n// New initializes a new API Server with the given config, engine, and logger.\n// It will inject a noop logger into the API handlers and engine if logging is\n// disabled.\nfunc New(\n\tconfig Config,\n\tlogger log.Logger,\n\n\t// attributes to build handlers backend\n\tstorageBackend *storage.Backend,\n\tsp *core.StateProcessor,\n\tcs chain.Spec,\n\tcmtCfg *cmtcfg.Config,\n\n\t// consensusService allows apis to access node state\n\t// and carry out all sorts of queries, including hystorical ones\n\tconsensusService types.ConsensusService,\n) *Server {\n\tapiLogger := logger\n\tif !config.Logging {\n\t\tapiLogger = noop.NewLogger[log.Logger]()\n\t}\n\n\tmware := middleware.NewDefaultMiddleware(apiLogger)\n\n\t// instantiate handlers and register their routes in the middleware\n\tb := backend.New(storageBackend, sp, cs, cmtCfg, consensusService)\n\tbeaconHandler := beaconapi.NewHandler(b, cs, apiLogger)\n\tmware.RegisterRoutes(beaconHandler.RouteSet())\n\tmware.RegisterRoutes(builderapi.NewHandler(apiLogger).RouteSet())\n\tmware.RegisterRoutes(cometbftapi.NewHandler(b, apiLogger).RouteSet())\n\tmware.RegisterRoutes(configapi.NewHandler(cs, apiLogger).RouteSet())\n\tmware.RegisterRoutes(debugapi.NewHandler(b, apiLogger).RouteSet())\n\tmware.RegisterRoutes(eventsapi.NewHandler(apiLogger).RouteSet())\n\tmware.RegisterRoutes(nodeapi.NewHandler(b, apiLogger).RouteSet())\n\tmware.RegisterRoutes(proofapi.NewHandler(b, apiLogger).RouteSet())\n\n\treturn &Server{\n\t\tconfig:        config,\n\t\tlogger:        logger,\n\t\tmiddleware:    mware,\n\t\tb:             b,\n\t\tbeaconHandler: beaconHandler,\n\t}\n}\n\n// Start starts the API Server at the configured address.\nfunc (s *Server) Start(ctx context.Context) error {\n\tif !s.config.Enabled {\n\t\treturn nil\n\t}\n\n\t// pre-load and cache all relevant node-api backend data\n\tif err := s.b.LoadData(ctx); err != nil {\n\t\treturn fmt.Errorf(\"failed loading api backend data: %w\", err)\n\t}\n\n\tgo s.start(ctx)\n\treturn nil\n}\n\nfunc (s *Server) start(ctx context.Context) {\n\terrCh := make(chan error)\n\tgo func() {\n\t\terrCh <- s.middleware.Run(s.config.Address)\n\t}()\n\tfor {\n\t\tselect {\n\t\tcase err := <-errCh:\n\t\t\ts.logger.Error(err.Error())\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (s *Server) Stop() error {\n\treturn s.b.Close()\n}\n\n// Name returns the name of the API server service.\nfunc (s *Server) Name() string {\n\treturn \"node-api-server\"\n}\n\nfunc (s *Server) GetBeaconHandler() *beaconapi.Handler {\n\treturn s.beaconHandler\n}\n"
  },
  {
    "path": "node-core/builder/baseapp_options.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage builder\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"cosmossdk.io/store\"\n\tstoretypes \"cosmossdk.io/store/types\"\n\tserver \"github.com/berachain/beacon-kit/cli/commands/server\"\n\t\"github.com/berachain/beacon-kit/config\"\n\tcometbft \"github.com/berachain/beacon-kit/consensus/cometbft/service\"\n\t\"github.com/cosmos/cosmos-sdk/client/flags\"\n\tgenutiltypes \"github.com/cosmos/cosmos-sdk/x/genutil/types\"\n\t\"github.com/spf13/cast\"\n)\n\n// This file contains Options that extend our default Service options to be\n// called by cosmos when building the app.\n// TODO: refactor into consensus_options for serverv2 migration.\n\n// DefaultServiceOptions returns the default Service options provided by the\n// Cosmos SDK.\nfunc DefaultServiceOptions(\n\tappOpts config.AppOptions,\n) []func(*cometbft.Service) {\n\tvar cache storetypes.MultiStorePersistentCache\n\n\tif cast.ToBool(appOpts.Get(server.FlagInterBlockCache)) {\n\t\tcache = store.NewCommitKVStoreCacheManager()\n\t}\n\n\tpruningOpts, err := server.GetPruningOptionsFromFlags(appOpts)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// get chainID, possibly falling back to genesis if flag is not set\n\tchainID := cast.ToString(appOpts.Get(flags.FlagChainID))\n\tif chainID == \"\" {\n\t\tchainID, err = loadChainIDFromGenesis(appOpts)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}\n\n\treturn []func(*cometbft.Service){\n\t\tcometbft.SetPruning(pruningOpts),\n\t\tcometbft.SetMinRetainBlocks(\n\t\t\tcast.ToUint64(appOpts.Get(server.FlagMinRetainBlocks)),\n\t\t),\n\t\tcometbft.SetInterBlockCache(cache),\n\t\tcometbft.SetIAVLCacheSize(\n\t\t\tcast.ToInt(appOpts.Get(server.FlagIAVLCacheSize)),\n\t\t),\n\t\tcometbft.SetIAVLDisableFastNode(\n\t\t\t// default to true\n\t\t\ttrue,\n\t\t),\n\t\tcometbft.SetChainID(chainID),\n\t}\n}\n\nfunc loadChainIDFromGenesis(appOpts config.AppOptions) (string, error) {\n\tvar (\n\t\thomeDir = cast.ToString(appOpts.Get(flags.FlagHome))\n\t\t// TODO: This is quite inflexible and demands a genesis.json file name and directory\n\t\tfp = filepath.Join(homeDir, \"config\", \"genesis.json\")\n\t)\n\n\tf, err := os.Open(filepath.Clean(fp))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tchainID, err := genutiltypes.ParseChainIDFromGenesis(f)\n\tif err != nil {\n\t\treturn \"\",\n\t\t\terrors.Join(\n\t\t\t\tf.Close(),\n\t\t\t\tfmt.Errorf(\n\t\t\t\t\t\"failed to parse chain-id from genesis file: %w\",\n\t\t\t\t\terr,\n\t\t\t\t),\n\t\t\t)\n\t}\n\treturn chainID, f.Close()\n}\n"
  },
  {
    "path": "node-core/builder/builder.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage builder\n\nimport (\n\t\"io\"\n\n\t\"cosmossdk.io/depinject\"\n\tservertypes \"github.com/berachain/beacon-kit/cli/commands/server/types\"\n\t\"github.com/berachain/beacon-kit/config\"\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/node-core/types\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\tdbm \"github.com/cosmos/cosmos-db\"\n)\n\n// NodeBuilder is a construction helper for creating nodes that implement\n// the types.NodeI interface.\n// TODO: #Make nodebuilder build a node. Currently this is just a builder for\n// the AppCreator function, which is eventually called by cosmos to build a\n// node.\ntype NodeBuilder struct {\n\t// components is a list of components to provide.\n\tcomponents []any\n}\n\n// New returns a new NodeBuilder.\nfunc New(opts ...Opt) *NodeBuilder {\n\tnb := &NodeBuilder{}\n\tfor _, opt := range opts {\n\t\topt(nb)\n\t}\n\treturn nb\n}\n\n// Build uses the node builder options and runtime parameters to\n// build a new instance of the node.\n// It is necessary to adhere to the types.AppCreator[T] interface.\nfunc (nb *NodeBuilder) Build(\n\tlogger *phuslu.Logger,\n\tdb dbm.DB,\n\t_ io.Writer,\n\tcmtCfg *cmtcfg.Config,\n\tappOpts servertypes.AppOptions,\n) types.Node {\n\t// variables to hold the components needed to set up BeaconApp\n\tvar (\n\t\tbeaconNode types.Node\n\t\tcmtService types.ConsensusService\n\t\tconfig     *config.Config\n\t)\n\n\tchainSpec, err := spec.Create(appOpts)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// build all node components using depinject\n\tif err = depinject.Inject(\n\t\tdepinject.Configs(\n\t\t\tdepinject.Provide(\n\t\t\t\tnb.components...,\n\t\t\t),\n\t\t\tdepinject.Supply(\n\t\t\t\tappOpts,\n\t\t\t\tlogger,\n\t\t\t\tdb,\n\t\t\t\tcmtCfg,\n\t\t\t\tchainSpec,\n\t\t\t),\n\t\t),\n\t\t&beaconNode,\n\t\t&cmtService,\n\t\t&config,\n\t); err != nil {\n\t\tpanic(err)\n\t}\n\tif config == nil {\n\t\tpanic(\"config is nil\")\n\t}\n\n\tlogger.WithConfig(config.GetLogger())\n\treturn beaconNode\n}\n"
  },
  {
    "path": "node-core/builder/options.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage builder\n\n// Opt is a type that defines a function that modifies NodeBuilder.\ntype Opt func(*NodeBuilder)\n\n// WithComponents is a function that sets the components for the NodeBuilder.\nfunc WithComponents(components []any) Opt {\n\treturn func(nb *NodeBuilder) {\n\t\tnb.components = components\n\t}\n}\n"
  },
  {
    "path": "node-core/components/api.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/config\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/node-api/server\"\n\t\"github.com/berachain/beacon-kit/node-core/components/storage\"\n\t\"github.com/berachain/beacon-kit/node-core/types\"\n\t\"github.com/berachain/beacon-kit/state-transition/core\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n)\n\ntype NodeAPIServerInput struct {\n\tdepinject.In\n\n\tConfig           *config.Config\n\tLogger           *phuslu.Logger\n\tChainSpec        chain.Spec\n\tStorageBackend   *storage.Backend\n\tStateProcessor   *core.StateProcessor\n\tCometConfig      *cmtcfg.Config\n\tConsensusService types.ConsensusService\n}\n\nfunc ProvideNodeAPIServer(in NodeAPIServerInput) *server.Server {\n\tin.Logger.AddKeyValColor(\n\t\t\"service\",\n\t\t\"node-api-server\",\n\t\tlog.Blue,\n\t)\n\treturn server.New(\n\t\tin.Config.NodeAPI,\n\t\tin.Logger.With(\"service\", \"node-api-server\"),\n\t\tin.StorageBackend,\n\t\tin.StateProcessor,\n\t\tin.ChainSpec,\n\t\tin.CometConfig,\n\t\tin.ConsensusService,\n\t)\n}\n"
  },
  {
    "path": "node-core/components/attributes_factory.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/config\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/payload/attributes\"\n)\n\ntype AttributesFactoryInput struct {\n\tdepinject.In\n\n\tChainSpec chain.Spec\n\tConfig    *config.Config\n\tLogger    *phuslu.Logger\n}\n\n// ProvideAttributesFactory provides an AttributesFactory for the client.\nfunc ProvideAttributesFactory(in AttributesFactoryInput) (*attributes.Factory, error) {\n\treturn attributes.NewAttributesFactory(\n\t\tin.ChainSpec,\n\t\tin.Logger,\n\t\tin.Config.PayloadBuilder.SuggestedFeeRecipient,\n\t), nil\n}\n"
  },
  {
    "path": "node-core/components/availability_store.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/config\"\n\tdastore \"github.com/berachain/beacon-kit/da/store\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/storage/filedb\"\n\t\"github.com/cosmos/cosmos-sdk/client/flags\"\n\t\"github.com/spf13/cast\"\n)\n\n// AvailabilityStoreInput is the input for the ProviderAvailabilityStore\n// function for the depinject framework.\ntype AvailabilityStoreInput struct {\n\tdepinject.In\n\tAppOpts config.AppOptions\n\tLogger  *phuslu.Logger\n}\n\n// ProvideAvailabilityStore provides the availability store.\nfunc ProvideAvailabilityStore(in AvailabilityStoreInput) (*dastore.Store, error) {\n\tvar (\n\t\trootDir  = cast.ToString(in.AppOpts.Get(flags.FlagHome))\n\t\tblobsDir = filepath.Join(rootDir, \"data\", \"blobs\")\n\t)\n\n\treturn dastore.New(\n\t\tfiledb.NewRangeDB(\n\t\t\tfiledb.NewDB(\n\t\t\t\tfiledb.WithRootDirectory(blobsDir),\n\t\t\t\tfiledb.WithFileExtension(\"ssz\"),\n\t\t\t\tfiledb.WithDirectoryPermissions(os.ModePerm),\n\t\t\t\tfiledb.WithLogger(in.Logger),\n\t\t\t),\n\t\t),\n\t\tin.Logger.With(\"service\", \"da-store\"),\n\t), nil\n}\n"
  },
  {
    "path": "node-core/components/backend.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\tdastore \"github.com/berachain/beacon-kit/da/store\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/node-core/components/metrics\"\n\t\"github.com/berachain/beacon-kit/node-core/components/storage\"\n\t\"github.com/berachain/beacon-kit/storage/beacondb\"\n\t\"github.com/berachain/beacon-kit/storage/block\"\n\t\"github.com/berachain/beacon-kit/storage/deposit\"\n)\n\n// StorageBackendInput is the input for the ProvideStorageBackend function.\ntype StorageBackendInput struct {\n\tdepinject.In\n\tAvailabilityStore *dastore.Store\n\tBlockStore        *block.KVStore[*types.BeaconBlock]\n\tChainSpec         chain.Spec\n\tDepositStore      deposit.StoreManager\n\tBeaconStore       *beacondb.KVStore\n\tLogger            *phuslu.Logger\n\tTelemetrySink     *metrics.TelemetrySink\n}\n\n// ProvideStorageBackend is the depinject provider that returns a beacon storage\n// backend.\nfunc ProvideStorageBackend(\n\tin StorageBackendInput,\n) *storage.Backend {\n\treturn storage.NewBackend(\n\t\tin.ChainSpec,\n\t\tin.AvailabilityStore,\n\t\tin.BeaconStore,\n\t\tin.DepositStore,\n\t\tin.BlockStore,\n\t\tin.Logger.With(\"service\", \"storage-backend\"),\n\t\tin.TelemetrySink,\n\t)\n}\n"
  },
  {
    "path": "node-core/components/blobs.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/cli/flags\"\n\t\"github.com/berachain/beacon-kit/config\"\n\tdablob \"github.com/berachain/beacon-kit/da/blob\"\n\t\"github.com/berachain/beacon-kit/da/kzg\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/node-core/components/metrics\"\n\tgokzg4844 \"github.com/crate-crypto/go-kzg-4844\"\n\t\"github.com/spf13/cast\"\n)\n\n// BlobProofVerifierInput is the input for the\n// dep inject framework.\ntype BlobProofVerifierInput struct {\n\tdepinject.In\n\n\tAppOpts          config.AppOptions\n\tJSONTrustedSetup *gokzg4844.JSONTrustedSetup\n}\n\n// ProvideBlobProofVerifier is a function that provides the module to the\n// application.\nfunc ProvideBlobProofVerifier(\n\tin BlobProofVerifierInput,\n) (kzg.BlobProofVerifier, error) {\n\treturn kzg.NewBlobProofVerifier(\n\t\tcast.ToString(in.AppOpts.Get(flags.KZGImplementation)),\n\t\tin.JSONTrustedSetup,\n\t)\n}\n\n// BlobProcessorIn is the input for the BlobProcessor.\ntype BlobProcessorIn struct {\n\tdepinject.In\n\n\tBlobProofVerifier kzg.BlobProofVerifier\n\tLogger            *phuslu.Logger\n\tTelemetrySink     *metrics.TelemetrySink\n}\n\n// ProvideBlobProcessor is a function that provides the BlobProcessor to the\n// depinject framework.\nfunc ProvideBlobProcessor(in BlobProcessorIn) *dablob.Processor {\n\treturn dablob.NewProcessor(\n\t\tin.Logger.With(\"service\", \"blob-processor\"),\n\t\tin.BlobProofVerifier,\n\t\tin.TelemetrySink,\n\t)\n}\n"
  },
  {
    "path": "node-core/components/block_store.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/config\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/storage/block\"\n)\n\n// BlockStoreInput is the input for the dep inject framework.\ntype BlockStoreInput struct {\n\tdepinject.In\n\n\tConfig *config.Config\n\tLogger *phuslu.Logger\n}\n\n// ProvideBlockStore is a function that provides the module to the\n// application.\nfunc ProvideBlockStore(in BlockStoreInput) (*block.KVStore[*ctypes.BeaconBlock], error) {\n\treturn block.NewStore[*ctypes.BeaconBlock](\n\t\tin.Logger.With(\"service\", \"block-store\"),\n\t\tin.Config.BlockStoreService.AvailabilityWindow,\n\t), nil\n}\n"
  },
  {
    "path": "node-core/components/chain_service.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/beacon/blockchain\"\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/execution/deposit\"\n\t\"github.com/berachain/beacon-kit/execution/engine\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/node-core/components/metrics\"\n\t\"github.com/berachain/beacon-kit/node-core/components/storage\"\n)\n\n// ChainServiceInput is the input for the chain service provider.\ntype ChainServiceInput struct {\n\tdepinject.In\n\n\tChainSpec             chain.Spec\n\tExecutionEngine       *engine.Engine\n\tLocalBuilder          LocalBuilder\n\tLogger                *phuslu.Logger\n\tStateProcessor        StateProcessor\n\tStorageBackend        *storage.Backend\n\tBlobProcessor         BlobProcessor\n\tTelemetrySink         *metrics.TelemetrySink\n\tBeaconDepositContract deposit.Contract\n}\n\n// ProvideChainService is a depinject provider for the blockchain service.\nfunc ProvideChainService(in ChainServiceInput) *blockchain.Service {\n\treturn blockchain.NewService(\n\t\tin.StorageBackend,\n\t\tin.BlobProcessor,\n\t\tin.BeaconDepositContract,\n\t\tin.Logger.With(\"service\", \"blockchain\"),\n\t\tin.ChainSpec,\n\t\tin.ExecutionEngine,\n\t\tin.LocalBuilder,\n\t\tin.StateProcessor,\n\t\tin.TelemetrySink,\n\t)\n}\n"
  },
  {
    "path": "node-core/components/cometbft_service.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"github.com/berachain/beacon-kit/beacon/blockchain\"\n\t\"github.com/berachain/beacon-kit/beacon/validator\"\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/config\"\n\tcometbft \"github.com/berachain/beacon-kit/consensus/cometbft/service\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/node-core/builder\"\n\t\"github.com/berachain/beacon-kit/node-core/components/metrics\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\tdbm \"github.com/cosmos/cosmos-db\"\n)\n\n// ProvideCometBFTService provides the CometBFT service component.\nfunc ProvideCometBFTService(\n\tlogger *phuslu.Logger,\n\tblockchain blockchain.BlockchainI,\n\tblockBuilder validator.BlockBuilderI,\n\tdb dbm.DB,\n\tcs chain.Spec,\n\tcmtCfg *cmtcfg.Config,\n\tappOpts config.AppOptions,\n\ttelemetrySink *metrics.TelemetrySink,\n) *cometbft.Service {\n\treturn cometbft.NewService(\n\t\tlogger,\n\t\tdb,\n\t\tblockchain,\n\t\tblockBuilder,\n\t\tcs,\n\t\tcmtCfg,\n\t\ttelemetrySink,\n\t\tbuilder.DefaultServiceOptions(appOpts)...,\n\t)\n}\n"
  },
  {
    "path": "node-core/components/config.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/config\"\n)\n\n// ConfigInput is the input for the dependency injection framework.\ntype ConfigInput struct {\n\tdepinject.In\n\tAppOpts config.AppOptions\n}\n\n// ProvideConfig is a function that provides the BeaconConfig to the\n// application.\nfunc ProvideConfig(in ConfigInput) (*config.Config, error) {\n\t// AppOpts is not populated when called from CLI\n\t// Read the directory\n\treturn config.ReadConfigFromAppOpts(in.AppOpts)\n}\n"
  },
  {
    "path": "node-core/components/config_server.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"errors\"\n\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/config\"\n\tsdkconfig \"github.com/berachain/beacon-kit/config/config\"\n\t\"github.com/mitchellh/mapstructure\"\n\t\"github.com/spf13/viper\"\n)\n\n// ServerConfigInput is the input for the dependency injection framework.\ntype ServerConfigInput struct {\n\tdepinject.In\n\tAppOpts config.AppOptions\n}\n\n// ProvideConfig is a function that provides the BeaconConfig to the\n// application.\nfunc ProvideServerConfig(in ConfigInput) (*sdkconfig.Config, error) {\n\tv, ok := in.AppOpts.(*viper.Viper)\n\tif !ok {\n\t\treturn nil, errors.New(\"invalid application options type\")\n\t}\n\n\tcfg := sdkconfig.Config{}\n\tif err := v.Unmarshal(&cfg,\n\t\tviper.DecodeHook(mapstructure.ComposeDecodeHookFunc(\n\t\t\tmapstructure.StringToTimeDurationHookFunc(),\n\t\t\tmapstructure.StringToSliceHookFunc(\",\"),\n\t\t))); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &cfg, nil\n}\n"
  },
  {
    "path": "node-core/components/deposit_contract.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/execution/client\"\n\t\"github.com/berachain/beacon-kit/execution/deposit\"\n)\n\n// DepositContractInput is the input for the deposit contract\n// for the dep inject framework.\ntype DepositContractInput struct {\n\tdepinject.In\n\tChainSpec    chain.Spec\n\tEngineClient *client.EngineClient\n}\n\n// ProvideDepositContract provides a deposit contract through the\n// dep inject framework.\nfunc ProvideDepositContract(\n\tin DepositContractInput,\n) (*deposit.WrappedDepositContract, error) {\n\t// Build the deposit contract.\n\treturn deposit.NewWrappedDepositContract(\n\t\tin.ChainSpec.DepositContractAddress(),\n\t\tin.EngineClient,\n\t)\n}\n"
  },
  {
    "path": "node-core/components/deposit_store.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"path/filepath\"\n\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/config\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/storage/deposit\"\n\tdbm \"github.com/cosmos/cosmos-db\"\n\t\"github.com/cosmos/cosmos-sdk/client/flags\"\n\t\"github.com/spf13/cast\"\n)\n\n// DepositStoreInput is the input for the dep inject framework.\ntype DepositStoreInput struct {\n\tdepinject.In\n\tLogger  *phuslu.Logger\n\tAppOpts config.AppOptions\n}\n\n// ProvideDepositStore is a function that provides the module to the\n// application.\nfunc ProvideDepositStore(in DepositStoreInput) (deposit.StoreManager, error) {\n\tvar (\n\t\trootDir = cast.ToString(in.AppOpts.Get(flags.FlagHome))\n\t\tdataDir = filepath.Join(rootDir, \"data\")\n\t\tnameV1  = \"deposits\"\n\t)\n\n\tdbV1, err := dbm.NewDB(nameV1, dbm.PebbleDBBackend, dataDir)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn deposit.NewStore(\n\t\tdbV1,\n\t\tin.Logger.With(\"service\", \"deposit-store\"),\n\t), nil\n}\n"
  },
  {
    "path": "node-core/components/engine.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"math/big\"\n\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/config\"\n\t\"github.com/berachain/beacon-kit/execution/client\"\n\t\"github.com/berachain/beacon-kit/execution/engine\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/node-core/components/metrics\"\n\t\"github.com/berachain/beacon-kit/primitives/net/jwt\"\n)\n\n// EngineClientInputs is the input for the EngineClient.\ntype EngineClientInputs struct {\n\tdepinject.In\n\tChainSpec chain.Spec\n\tConfig    *config.Config\n\t// TODO: this feels like a hood way to handle it.\n\tJWTSecret     *jwt.Secret `optional:\"true\"`\n\tLogger        *phuslu.Logger\n\tTelemetrySink *metrics.TelemetrySink\n}\n\n// ProvideEngineClient creates a new EngineClient.\nfunc ProvideEngineClient(in EngineClientInputs) *client.EngineClient {\n\treturn client.New(\n\t\tin.Config.GetEngine(),\n\t\tin.Logger.With(\"service\", \"engine.client\"),\n\t\tin.JWTSecret,\n\t\tin.TelemetrySink,\n\t\tnew(big.Int).SetUint64(in.ChainSpec.DepositEth1ChainID()),\n\t)\n}\n\n// EngineClientInputs is the input for the EngineClient.\ntype ExecutionEngineInputs struct {\n\tdepinject.In\n\tEngineClient  *client.EngineClient\n\tLogger        *phuslu.Logger\n\tTelemetrySink *metrics.TelemetrySink\n}\n\n// ProvideExecutionEngine provides the execution engine to the depinject\n// framework.\nfunc ProvideExecutionEngine(in ExecutionEngineInputs) *engine.Engine {\n\treturn engine.New(\n\t\tin.EngineClient,\n\t\tin.Logger.With(\"service\", \"execution-engine\"),\n\t\tin.TelemetrySink,\n\t)\n}\n"
  },
  {
    "path": "node-core/components/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"context\"\n\n\t\"github.com/berachain/beacon-kit/chain\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tdastore \"github.com/berachain/beacon-kit/da/store\"\n\tdatypes \"github.com/berachain/beacon-kit/da/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/node-api/backend\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\t\"github.com/berachain/beacon-kit/payload/builder\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n\t\"github.com/berachain/beacon-kit/state-transition/core\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n\t\"github.com/berachain/beacon-kit/storage/block\"\n\t\"github.com/berachain/beacon-kit/storage/deposit\"\n)\n\ntype (\n\t// AttributesFactory is the interface for the attributes factory.\n\tAttributesFactory interface {\n\t\tBuildPayloadAttributes(\n\t\t\ttimestamp math.U64,\n\t\t\tpayloadWithdrawals engineprimitives.Withdrawals,\n\t\t\tprevRandao common.Bytes32,\n\t\t\tprevHeadRoot common.Root,\n\t\t\tparentProposerPubkey *crypto.BLSPubkey,\n\t\t) (*engineprimitives.PayloadAttributes, error)\n\t}\n\n\t// BlobProcessor is the interface for the blobs processor.\n\tBlobProcessor interface {\n\t\t// ProcessSidecars processes the blobs and ensures they match the local\n\t\t// state.\n\t\tProcessSidecars(\n\t\t\tavs *dastore.Store,\n\t\t\tsidecars datypes.BlobSidecars,\n\t\t) error\n\t\t// VerifySidecars verifies the blobs and ensures they match the local\n\t\t// state.\n\t\tVerifySidecars(\n\t\t\tctx context.Context,\n\t\t\tsidecars datypes.BlobSidecars,\n\t\t\tblkHeader *ctypes.BeaconBlockHeader,\n\t\t\tkzgCommitments eip4844.KZGCommitments[common.ExecutionHash],\n\t\t) error\n\t}\n\n\t// LocalBuilder is the interface for the builder service.\n\tLocalBuilder interface {\n\t\t// Enabled returns true if the local builder is enabled.\n\t\tEnabled() bool\n\t\t// RequestPayloadAsync requests a new payload for the given slot.\n\t\tRequestPayloadAsync(\n\t\t\tctx context.Context,\n\t\t\tr *builder.RequestPayloadData,\n\t\t) (*engineprimitives.PayloadID, common.Version, error)\n\t\t// RetrievePayload retrieves the payload for the given slot and parentBlockRoot.\n\t\t// If returned error is nil, payload is guaranteed to have expectedForkVersion version.\n\t\tRetrievePayload(\n\t\t\tctx context.Context,\n\t\t\tslot math.Slot,\n\t\t\tparentBlockRoot common.Root,\n\t\t\texpectedForkVersion common.Version,\n\t\t) (ctypes.BuiltExecutionPayloadEnv, error)\n\t\t// RequestPayloadSync requests a payload for the given slot and\n\t\t// blocks until the payload is delivered.\n\t\tRequestPayloadSync(\n\t\t\tctx context.Context,\n\t\t\tr *builder.RequestPayloadData,\n\t\t) (ctypes.BuiltExecutionPayloadEnv, error)\n\t\tCacheLatestVerifiedPayload(\n\t\t\tlatestEnvelopeSlot math.Slot,\n\t\t\tlatestEnvelope ctypes.BuiltExecutionPayloadEnv,\n\t\t)\n\t}\n\n\t// \t// PayloadAttributes is the interface for the payload attributes.\n\t// PayloadAttributes[T any, WithdrawalT any] interface {\n\t// \tengineprimitives.PayloadAttributer\n\t// \t// New creates a new payload attributes instance.\n\t// \tNew(\n\t// \t\tuint32,\n\t// \t\tuint64,\n\t// \t\tcommon.Bytes32,\n\t// \t\tcommon.ExecutionAddress,\n\t// \t\t[]WithdrawalT,\n\t// \t\tcommon.Root,\n\t// \t) (T, error)\n\t// }.\n\n\t// StateProcessor defines the interface for processing the state.\n\tStateProcessor interface {\n\t\t// InitializeBeaconStateFromEth1 initializes the premined beacon\n\t\t// state\n\t\t// from the eth1 deposits.\n\t\tInitializeBeaconStateFromEth1(\n\t\t\t*statedb.StateDB,\n\t\t\tctypes.Deposits,\n\t\t\t*ctypes.ExecutionPayloadHeader,\n\t\t\tcommon.Version,\n\t\t) (transition.ValidatorUpdates, error)\n\t\t// ProcessFork prepares the state for the fork version at the given timestamp.\n\t\tProcessFork(\n\t\t\tst *statedb.StateDB, timestamp math.U64, logUpgrade bool,\n\t\t) error\n\t\t// ProcessSlot processes the slot.\n\t\tProcessSlots(\n\t\t\tst *statedb.StateDB, slot math.Slot,\n\t\t) (transition.ValidatorUpdates, error)\n\t\t// Transition performs the core state transition.\n\t\tTransition(\n\t\t\tctx core.ReadOnlyContext,\n\t\t\tst *statedb.StateDB,\n\t\t\tblk *ctypes.BeaconBlock,\n\t\t) (transition.ValidatorUpdates, error)\n\t\tGetSignatureVerifierFn(st *statedb.StateDB) (\n\t\t\tfunc(blk *ctypes.BeaconBlock, signature crypto.BLSSignature) error,\n\t\t\terror,\n\t\t)\n\t}\n\n\tSidecarFactory interface {\n\t\t// BuildSidecars builds sidecars for a given block and blobs bundle.\n\t\tBuildSidecars(\n\t\t\tsignedBlk *ctypes.SignedBeaconBlock,\n\t\t\tblobs engineprimitives.BlobsBundle,\n\t\t) (datypes.BlobSidecars, error)\n\t}\n\n\t// StorageBackend defines an interface for accessing various storage\n\t// components required by the beacon node.\n\tStorageBackend interface {\n\t\tAvailabilityStore() *dastore.Store\n\t\tBlockStore() *block.KVStore[*ctypes.BeaconBlock]\n\t\tDepositStore() deposit.StoreManager\n\t\t// StateFromContext retrieves the beacon state from the given context.\n\t\tStateFromContext(context.Context) *statedb.StateDB\n\t}\n\n\t// \t// TelemetrySink is an interface for sending metrics to a telemetry\n\t// backend.\n\t// \tTelemetrySink interface {\n\t// \t\t// MeasureSince measures the time since the given time.\n\t// \t\tMeasureSince(key string, start time.Time, args ...string)\n\t// \t}\n\n\t// \t// Validator represents an interface for a validator with generic type\n\t// \t// ValidatorT.\n\t// \tValidator[\n\t// \t\tValidatorT any,\n\t// \t\tWithdrawalCredentialsT any,\n\t// \t] interface {\n\t// \t\tconstraints.Empty[ValidatorT]\n\t// \t\tconstraints.SSZMarshallableRootable\n\t// \t\tSizeSSZ() uint32\n\t// \t\t// New creates a new validator with the given parameters.\n\t// \t\tNew(\n\t// \t\t\tpubkey crypto.BLSPubkey,\n\t// \t\t\twithdrawalCredentials WithdrawalCredentialsT,\n\t// \t\t\tamount math.Gwei,\n\t// \t\t\teffectiveBalanceIncrement math.Gwei,\n\t// \t\t\tmaxEffectiveBalance math.Gwei,\n\t// \t\t) ValidatorT\n\t// \t\t// IsSlashed returns true if the validator is slashed.\n\t// \t\tIsSlashed() bool\n\t// \t\t// IsActive checks if the validator is active at the given epoch.\n\t// \t\tIsActive(epoch math.Epoch) bool\n\t// \t\t// GetPubkey returns the public key of the validator.\n\t// \t\tGetPubkey() crypto.BLSPubkey\n\t// \t\t// GetEffectiveBalance returns the effective balance of the validator\n\t// in\n\t// \t\t// Gwei.\n\t// \t\tGetEffectiveBalance() math.Gwei\n\t// \t\t// SetEffectiveBalance sets the effective balance of the validator in\n\t// \t\t// Gwei.\n\t// \t\tSetEffectiveBalance(math.Gwei)\n\t// \t\t// GetWithdrawableEpoch returns the epoch when the validator can\n\t// \t\t// withdraw.\n\t// \t\tGetWithdrawableEpoch() math.Epoch\n\t// \t\t// GetWithdrawalCredentials returns the withdrawal credentials of the\n\t// \t\t// validator.\n\t// \t\tGetWithdrawalCredentials() WithdrawalCredentialsT\n\t// \t\t// IsFullyWithdrawable checks if the validator is fully withdrawable\n\t// \t\t// given a\n\t// \t\t// certain Gwei amount and epoch.\n\t// \t\tIsFullyWithdrawable(amount math.Gwei, epoch math.Epoch) bool\n\t// \t\t// IsPartiallyWithdrawable checks if the validator is partially\n\t// \t\t// withdrawable\n\t// \t\t// given two Gwei amounts.\n\t// \t\tIsPartiallyWithdrawable(amount1 math.Gwei, amount2 math.Gwei) bool\n\t// \t}\n\n\t// \tValidators[ValidatorT any] interface {\n\t// \t\t~[]ValidatorT\n\t// \t\tHashTreeRoot() common.Root\n\t// \t}\n\n\t// Withdrawal is the interface for a withdrawal.\n\tWithdrawal[T any] interface {\n\t\tNew(\n\t\t\tindex math.U64,\n\t\t\tvalidatorIndex math.ValidatorIndex,\n\t\t\taddress common.ExecutionAddress,\n\t\t\tamount math.Gwei,\n\t\t) T\n\t\t// Equals returns true if the withdrawal is equal to the other.\n\t\tEquals(T) bool\n\t\t// GetAmount returns the amount of the withdrawal.\n\t\tGetAmount() math.Gwei\n\t\t// GetIndex returns the public key of the validator.\n\t\tGetIndex() math.U64\n\t\t// GetValidatorIndex returns the index of the validator.\n\t\tGetValidatorIndex() math.ValidatorIndex\n\t\t// GetAddress returns the address of the withdrawal.\n\t\tGetAddress() common.ExecutionAddress\n\t}\n\n\t// // WithdrawalCredentials represents an interface for withdrawal\n\t// credentials.\n\t//\n\t//\tWithdrawalCredentials interface {\n\t//\t\t~[32]byte\n\t//\t\t// ToExecutionAddress converts the withdrawal credentials to an\n\t//\t\t// execution\n\t//\t\t// address.\n\t//\t\tToExecutionAddress() (common.ExecutionAddress, error)\n\t//\t}\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                BeaconState                                 */\n/* -------------------------------------------------------------------------- */\n\ntype (\n\t// BeaconStore is the interface for the beacon store.\n\tBeaconStore[\n\t\tT any,\n\t] interface {\n\t\t// Context returns the context of the key-value store.\n\t\tContext() context.Context\n\t\t// WithContext returns a new key-value store with the given context.\n\t\tWithContext(\n\t\t\tctx context.Context,\n\t\t) T\n\t\t// Copy returns a copy of the key-value store.\n\t\tCopy(context.Context) T\n\t\t// GetLatestExecutionPayloadHeader retrieves the latest execution\n\t\t// payload\n\t\t// header.\n\t\tGetLatestExecutionPayloadHeader() (*ctypes.ExecutionPayloadHeader, error)\n\t\t// SetLatestExecutionPayloadHeader sets the latest execution payload\n\t\t// header.\n\t\tSetLatestExecutionPayloadHeader(payloadHeader *ctypes.ExecutionPayloadHeader) error\n\t\t// GetEth1DepositIndex retrieves the eth1 deposit index.\n\t\tGetEth1DepositIndex() (uint64, error)\n\t\t// SetEth1DepositIndex sets the eth1 deposit index.\n\t\tSetEth1DepositIndex(\n\t\t\tindex uint64,\n\t\t) error\n\t\t// GetBalance retrieves the balance of a validator.\n\t\tGetBalance(idx math.ValidatorIndex) (math.Gwei, error)\n\t\t// SetBalance sets the balance of a validator.\n\t\tSetBalance(idx math.ValidatorIndex, balance math.Gwei) error\n\t\t// GetSlot retrieves the current slot.\n\t\tGetSlot() (math.Slot, error)\n\t\t// SetSlot sets the current slot.\n\t\tSetSlot(slot math.Slot) error\n\t\t// GetFork retrieves the fork.\n\t\tGetFork() (*ctypes.Fork, error)\n\t\t// SetFork sets the fork.\n\t\tSetFork(fork *ctypes.Fork) error\n\t\t// GetGenesisValidatorsRoot retrieves the genesis validators root.\n\t\tGetGenesisValidatorsRoot() (common.Root, error)\n\t\t// SetGenesisValidatorsRoot sets the genesis validators root.\n\t\tSetGenesisValidatorsRoot(root common.Root) error\n\t\t// GetLatestBlockHeader retrieves the latest block header.\n\t\tGetLatestBlockHeader() (*ctypes.BeaconBlockHeader, error)\n\t\t// SetLatestBlockHeader sets the latest block header.\n\t\tSetLatestBlockHeader(header *ctypes.BeaconBlockHeader) error\n\t\t// GetBlockRootAtIndex retrieves the block root at the given index.\n\t\tGetBlockRootAtIndex(index uint64) (common.Root, error)\n\t\t// StateRootAtIndex retrieves the state root at the given index.\n\t\tStateRootAtIndex(index uint64) (common.Root, error)\n\t\t// GetEth1Data retrieves the eth1 data.\n\t\tGetEth1Data() (*ctypes.Eth1Data, error)\n\t\t// SetEth1Data sets the eth1 data.\n\t\tSetEth1Data(data *ctypes.Eth1Data) error\n\t\t// GetValidators retrieves all validators.\n\t\tGetValidators() (ctypes.Validators, error)\n\t\t// GetBalances retrieves all balances.\n\t\tGetBalances() ([]uint64, error)\n\t\t// GetNextWithdrawalIndex retrieves the next withdrawal index.\n\t\tGetNextWithdrawalIndex() (uint64, error)\n\t\t// SetNextWithdrawalIndex sets the next withdrawal index.\n\t\tSetNextWithdrawalIndex(index uint64) error\n\t\t// GetNextWithdrawalValidatorIndex retrieves the next withdrawal\n\t\t// validator\n\t\t// index.\n\t\tGetNextWithdrawalValidatorIndex() (math.ValidatorIndex, error)\n\t\t// SetNextWithdrawalValidatorIndex sets the next withdrawal validator\n\t\t// index.\n\t\tSetNextWithdrawalValidatorIndex(index math.ValidatorIndex) error\n\t\t// GetTotalSlashing retrieves the total slashing.\n\t\tGetTotalSlashing() (math.Gwei, error)\n\t\t// SetTotalSlashing sets the total slashing.\n\t\tSetTotalSlashing(total math.Gwei) error\n\t\t// GetRandaoMixAtIndex retrieves the randao mix at the given index.\n\t\tGetRandaoMixAtIndex(index uint64) (common.Bytes32, error)\n\t\t// GetSlashings retrieves all slashings.\n\t\tGetSlashings() ([]math.Gwei, error)\n\t\t// SetSlashingAtIndex sets the slashing at the given index.\n\t\tSetSlashingAtIndex(index uint64, amount math.Gwei) error\n\t\t// GetSlashingAtIndex retrieves the slashing at the given index.\n\t\tGetSlashingAtIndex(index uint64) (math.Gwei, error)\n\t\t// GetTotalValidators retrieves the total validators.\n\t\tGetTotalValidators() (uint64, error)\n\t\t// ValidatorByIndex retrieves the validator at the given index.\n\t\tValidatorByIndex(index math.ValidatorIndex) (*ctypes.Validator, error)\n\t\t// UpdateBlockRootAtIndex updates the block root at the given index.\n\t\tUpdateBlockRootAtIndex(index uint64, root common.Root) error\n\t\t// UpdateStateRootAtIndex updates the state root at the given index.\n\t\tUpdateStateRootAtIndex(index uint64, root common.Root) error\n\t\t// UpdateRandaoMixAtIndex updates the randao mix at the given index.\n\t\tUpdateRandaoMixAtIndex(index uint64, mix common.Bytes32) error\n\t\t// UpdateValidatorAtIndex updates the validator at the given index.\n\t\tUpdateValidatorAtIndex(\n\t\t\tindex math.ValidatorIndex,\n\t\t\tvalidator *ctypes.Validator,\n\t\t) error\n\t\t// ValidatorIndexByPubkey retrieves the validator index by the given\n\t\t// pubkey.\n\t\tValidatorIndexByPubkey(\n\t\t\tpubkey crypto.BLSPubkey,\n\t\t) (math.ValidatorIndex, error)\n\t\t// AddValidator adds a validator.\n\t\tAddValidator(val *ctypes.Validator) error\n\t\t// ValidatorIndexByCometBFTAddress retrieves the validator index by the\n\t\t// given comet BFT address.\n\t\tValidatorIndexByCometBFTAddress(\n\t\t\tcometBFTAddress []byte,\n\t\t) (math.ValidatorIndex, error)\n\t}\n\n\t// ReadOnlyBeaconState is the interface for a read-only beacon state.\n\tReadOnlyBeaconState interface {\n\t\tReadOnlyEth1Data\n\t\tReadOnlyRandaoMixes\n\t\tReadOnlyStateRoots\n\t\tReadOnlyValidators\n\t\tReadOnlyWithdrawals\n\n\t\t// GetBalances retrieves all balances.\n\t\tGetBalances() ([]uint64, error)\n\t\tGetBalance(math.ValidatorIndex) (math.Gwei, error)\n\t\tGetSlot() (math.Slot, error)\n\t\tGetFork() (*ctypes.Fork, error)\n\t\tGetGenesisValidatorsRoot() (common.Root, error)\n\t\tGetBlockRootAtIndex(uint64) (common.Root, error)\n\t\tGetLatestBlockHeader() (*ctypes.BeaconBlockHeader, error)\n\t\tGetValidators() (ctypes.Validators, error)\n\t\tGetSlashingAtIndex(uint64) (math.Gwei, error)\n\t\tGetTotalSlashing() (math.Gwei, error)\n\t\tGetNextWithdrawalIndex() (uint64, error)\n\t\tGetNextWithdrawalValidatorIndex() (math.ValidatorIndex, error)\n\t\tGetTotalValidators() (math.U64, error)\n\t\tValidatorIndexByCometBFTAddress(\n\t\t\tcometBFTAddress []byte,\n\t\t) (math.ValidatorIndex, error)\n\t}\n\n\t// WriteOnlyBeaconState is the interface for a write-only beacon state.\n\tWriteOnlyBeaconState interface {\n\t\tWriteOnlyEth1Data\n\t\tWriteOnlyRandaoMixes\n\t\tWriteOnlyStateRoots\n\t\tWriteOnlyValidators\n\n\t\tSetGenesisValidatorsRoot(root common.Root) error\n\t\tSetFork(*ctypes.Fork) error\n\t\tSetSlot(math.Slot) error\n\t\tUpdateBlockRootAtIndex(uint64, common.Root) error\n\t\tSetLatestBlockHeader(*ctypes.BeaconBlockHeader) error\n\t\tIncreaseBalance(math.ValidatorIndex, math.Gwei) error\n\t\tDecreaseBalance(math.ValidatorIndex, math.Gwei) error\n\t\tSetNextWithdrawalIndex(uint64) error\n\t\tSetNextWithdrawalValidatorIndex(math.ValidatorIndex) error\n\t\tSetTotalSlashing(math.Gwei) error\n\t}\n\n\t// WriteOnlyStateRoots defines a struct which only has write access to state\n\t// roots methods.\n\tWriteOnlyStateRoots interface {\n\t\tUpdateStateRootAtIndex(uint64, common.Root) error\n\t}\n\n\t// ReadOnlyStateRoots defines a struct which only has read access to state\n\t// roots\n\t// methods.\n\tReadOnlyStateRoots interface {\n\t\tStateRootAtIndex(uint64) (common.Root, error)\n\t}\n\n\t// WriteOnlyRandaoMixes defines a struct which only has write access to\n\t// randao\n\t// mixes methods.\n\tWriteOnlyRandaoMixes interface {\n\t\tUpdateRandaoMixAtIndex(uint64, common.Bytes32) error\n\t}\n\n\t// ReadOnlyRandaoMixes defines a struct which only has read access to randao\n\t// mixes methods.\n\tReadOnlyRandaoMixes interface {\n\t\tGetRandaoMixAtIndex(uint64) (common.Bytes32, error)\n\t}\n\n\t// WriteOnlyValidators has write access to validator methods.\n\tWriteOnlyValidators interface {\n\t\tUpdateValidatorAtIndex(\n\t\t\tmath.ValidatorIndex,\n\t\t\t*ctypes.Validator,\n\t\t) error\n\n\t\tAddValidator(*ctypes.Validator) error\n\t}\n\n\t// ReadOnlyValidators has read access to validator methods.\n\tReadOnlyValidators interface {\n\t\tValidatorIndexByPubkey(\n\t\t\tcrypto.BLSPubkey,\n\t\t) (math.ValidatorIndex, error)\n\n\t\tValidatorByIndex(\n\t\t\tmath.ValidatorIndex,\n\t\t) (*ctypes.Validator, error)\n\t}\n\n\t// WriteOnlyEth1Data has write access to eth1 data.\n\tWriteOnlyEth1Data interface {\n\t\tSetEth1Data(*ctypes.Eth1Data) error\n\t\tSetEth1DepositIndex(uint64) error\n\t\tSetLatestExecutionPayloadHeader(*ctypes.ExecutionPayloadHeader) error\n\t}\n\n\t// ReadOnlyEth1Data has read access to eth1 data.\n\tReadOnlyEth1Data interface {\n\t\tGetEth1Data() (*ctypes.Eth1Data, error)\n\t\tGetEth1DepositIndex() (uint64, error)\n\t\tGetLatestExecutionPayloadHeader() (*ctypes.ExecutionPayloadHeader, error)\n\t}\n\n\t// ReadOnlyWithdrawals only has read access to withdrawal methods.\n\tReadOnlyWithdrawals interface {\n\t\tEVMInflationWithdrawal(math.Slot) *engineprimitives.Withdrawal\n\t}\n)\n\n// /* --------------------------------------------------------------------------\n// */ /*                                  NodeAPI\n//    */ /*\n// -------------------------------------------------------------------------- */\n\ntype (\n\tNodeAPIContext interface {\n\t\tBind(any) error\n\t\tValidate(any) error\n\t}\n\n\tNodeAPIBackend interface {\n\t\tGetSlotByBlockRoot(root common.Root) (math.Slot, error)\n\t\tGetSlotByStateRoot(root common.Root) (math.Slot, error)\n\t\tGetParentSlotByTimestamp(timestamp math.U64) (math.Slot, error)\n\n\t\tNodeAPIBeaconBackend\n\t\tNodeAPIProofBackend\n\t\tNodeAPINodeBackend\n\t\tNodeAPIConfigBackend\n\t}\n\n\t// NodeAPIBeaconBackend is the interface for backend of the beacon API.\n\tNodeAPIBeaconBackend interface {\n\t\tGenesisBackend\n\t\tBlockBackend\n\t\tStateBackend\n\t\t// GetSlotByBlockRoot retrieves the slot by a given root from the store.\n\t\tGetSlotByBlockRoot(root common.Root) (math.Slot, error)\n\t\t// GetSlotByStateRoot retrieves the slot by a given root from the store.\n\t\tGetSlotByStateRoot(root common.Root) (math.Slot, error)\n\t}\n\n\t// NodeAPIConfigBackend is the interface for backend of the config API.\n\tNodeAPIConfigBackend interface {\n\t\tSpec() (chain.Spec, error)\n\t}\n\n\t// NodeAPIProofBackend is the interface for backend of the proof API.\n\tNodeAPIProofBackend interface {\n\t\tBlockBackend\n\t\tStateBackend\n\t\tGetParentSlotByTimestamp(timestamp math.U64) (math.Slot, error)\n\t}\n\n\tNodeAPINodeBackend interface {\n\t\tGetSyncData() (latestHeight int64, syncToHeight int64)\n\t\tGetVersionData() (\n\t\t\tappName,\n\t\t\tversion,\n\t\t\tos,\n\t\t\tarch string,\n\t\t)\n\t}\n\n\tGenesisBackend interface {\n\t\tGenesisValidatorsRoot() (common.Root, error)\n\t\tGenesisForkVersion() (common.Version, error)\n\t\tGenesisTime() (math.U64, error)\n\t}\n\n\tBlockBackend interface {\n\t\tBlockRootAtSlot(slot math.Slot) (common.Root, error)\n\t\tBlockRewardsAtSlot(slot math.Slot) (*types.BlockRewardsData, error)\n\t\tBlockHeaderAtSlot(slot math.Slot) (*ctypes.BeaconBlockHeader, error)\n\t}\n\n\tStateBackend interface {\n\t\tStateAndSlotFromHeight(height int64) (backend.ReadOnlyBeaconState, math.Slot, error)\n\t}\n)\n"
  },
  {
    "path": "node-core/components/jwt_secret.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/cli/flags\"\n\t\"github.com/berachain/beacon-kit/config\"\n\t\"github.com/berachain/beacon-kit/primitives/net/jwt\"\n\t\"github.com/spf13/afero\"\n\t\"github.com/spf13/cast\"\n)\n\n// JWTSecretInput is the input for the dep inject framework.\ntype JWTSecretInput struct {\n\tdepinject.In\n\tAppOpts config.AppOptions\n}\n\n// ProvideJWTSecret is a function that provides the module to the application.\nfunc ProvideJWTSecret(in JWTSecretInput) (*jwt.Secret, error) {\n\treturn LoadJWTFromFile(cast.ToString(in.AppOpts.Get(flags.JWTSecretPath)))\n}\n\n// LoadJWTFromFile reads the JWT secret from a file and returns it.\nfunc LoadJWTFromFile(filePath string) (*jwt.Secret, error) {\n\tdata, err := afero.ReadFile(afero.NewOsFs(), filePath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed reading path '%s', err: %w\", filePath, err)\n\t}\n\treturn jwt.NewFromHex(strings.TrimSpace(string(data)))\n}\n"
  },
  {
    "path": "node-core/components/metrics/sink.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage metrics\n\nimport (\n\t\"time\"\n\n\t\"github.com/cosmos/cosmos-sdk/telemetry\"\n\t\"github.com/hashicorp/go-metrics\"\n)\n\ntype TelemetrySink struct{}\n\n// NewTelemetrySink creates a new TelemetrySink.\nfunc NewTelemetrySink() TelemetrySink {\n\treturn TelemetrySink{}\n}\n\n// IncrementCounter increments a counter metric identified by the provided\n// keys.\nfunc (TelemetrySink) IncrementCounter(key string, args ...string) {\n\ttelemetry.IncrCounterWithLabels([]string{key}, 1, argsToLabels(args...))\n}\n\n// SetGauge sets a gauge metric to the specified value, identified by the\n// provided keys.\nfunc (TelemetrySink) SetGauge(key string, value int64, args ...string) {\n\ttelemetry.SetGaugeWithLabels(\n\t\t[]string{key},\n\t\tfloat32(value),\n\t\targsToLabels(args...),\n\t)\n}\n\n// MeasureSince measures the time since the provided start time and records\n// the duration in a metric identified by the provided key.\nfunc (TelemetrySink) MeasureSince(key string, start time.Time, args ...string) {\n\tif !telemetry.IsTelemetryEnabled() {\n\t\treturn\n\t}\n\n\t// TODO: Make PR to SDK, currently this will not have any globalLabels.\n\tmetrics.MeasureSinceWithLabels(\n\t\t[]string{key},\n\t\tstart.UTC(),\n\t\targsToLabels(args...),\n\t)\n}\n\n// argsToLabels converts a list of key-value pairs to a list of metrics labels.\n//\n//nolint:mnd // its okay.\nfunc argsToLabels(args ...string) []metrics.Label {\n\tlabels := make([]metrics.Label, len(args)/2)\n\tfor i := 0; i < len(args); i += 2 {\n\t\tlabels[i/2] = metrics.Label{\n\t\t\tName:  args[i],\n\t\t\tValue: args[i+1],\n\t\t}\n\t}\n\treturn labels\n}\n\n// NoOpTelemetrySink is a no-op implementation of the TelemetrySink interface.\ntype NoOpTelemetrySink struct{}\n\n// NewNoOpTelemetrySink creates a new NoOpTelemetrySink.\nfunc NewNoOpTelemetrySink() NoOpTelemetrySink {\n\treturn NoOpTelemetrySink{}\n}\n\n// IncrementCounter is a no-op implementation of the TelemetrySink interface.\nfunc (NoOpTelemetrySink) IncrementCounter(string, ...string) {}\n\n// SetGauge is a no-op implementation of the TelemetrySink interface.\nfunc (NoOpTelemetrySink) SetGauge(string, int64, ...string) {}\n\n// MeasureSince is a no-op implementation of the TelemetrySink interface.\nfunc (NoOpTelemetrySink) MeasureSince(string, time.Time, ...string) {}\n"
  },
  {
    "path": "node-core/components/node.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/config\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/node-core/node\"\n\tservice \"github.com/berachain/beacon-kit/node-core/services/registry\"\n\t\"github.com/berachain/beacon-kit/node-core/types\"\n)\n\ntype ProvideNodeInputs struct {\n\tdepinject.In\n\n\tConfig   *config.Config\n\tRegistry *service.Registry\n\tLogger   *phuslu.Logger\n}\n\n// ProvideNode returns a new node with the given options.\nfunc ProvideNode(in ProvideNodeInputs) types.Node {\n\treturn node.New[types.Node](in.Config.ShutdownTimeout, in.Registry, in.Logger)\n}\n"
  },
  {
    "path": "node-core/components/payload_builder.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/config\"\n\t\"github.com/berachain/beacon-kit/execution/engine\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\tpayloadbuilder \"github.com/berachain/beacon-kit/payload/builder\"\n\t\"github.com/berachain/beacon-kit/payload/cache\"\n)\n\n// LocalBuilderInput is an input for the dep inject framework.\ntype LocalBuilderInput struct {\n\tdepinject.In\n\tAttributesFactory AttributesFactory\n\tCfg               *config.Config\n\tChainSpec         chain.Spec\n\tExecutionEngine   *engine.Engine\n\tLogger            *phuslu.Logger\n}\n\n// ProvideLocalBuilder provides a local payload builder for the\n// depinject framework.\nfunc ProvideLocalBuilder(in LocalBuilderInput) *payloadbuilder.PayloadBuilder {\n\treturn payloadbuilder.New(\n\t\t&in.Cfg.PayloadBuilder,\n\t\tin.ChainSpec,\n\t\tin.Logger.With(\"service\", \"payload-builder\"),\n\t\tin.ExecutionEngine,\n\t\tcache.NewPayloadIDCache(),\n\t\tin.AttributesFactory,\n\t)\n}\n"
  },
  {
    "path": "node-core/components/reporting_service.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/execution/client\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/node-core/components/metrics\"\n\t\"github.com/berachain/beacon-kit/node-core/services/version\"\n\tsdkversion \"github.com/cosmos/cosmos-sdk/version\"\n)\n\ntype ReportingServiceInput struct {\n\tdepinject.In\n\tLogger        *phuslu.Logger\n\tTelemetrySink *metrics.TelemetrySink\n\tEngineClient  *client.EngineClient\n\tChainSpec     chain.Spec\n}\n\nfunc ProvideReportingService(in ReportingServiceInput) *version.ReportingService {\n\treturn version.NewReportingService(\n\t\tin.Logger.With(\"service\", \"reporting\"),\n\t\tin.TelemetrySink,\n\t\tsdkversion.Version,\n\t\tin.EngineClient,\n\t\tin.ChainSpec,\n\t)\n}\n"
  },
  {
    "path": "node-core/components/service_registry.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/beacon/blockchain\"\n\t\"github.com/berachain/beacon-kit/beacon/validator\"\n\t\"github.com/berachain/beacon-kit/execution/client\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/node-api/server\"\n\t\"github.com/berachain/beacon-kit/node-core/components/metrics\"\n\tservice \"github.com/berachain/beacon-kit/node-core/services/registry\"\n\t\"github.com/berachain/beacon-kit/node-core/services/shutdown\"\n\t\"github.com/berachain/beacon-kit/node-core/services/version\"\n\t\"github.com/berachain/beacon-kit/node-core/types\"\n\t\"github.com/berachain/beacon-kit/observability/telemetry\"\n)\n\n// ServiceRegistryInput is the input for the service registry provider.\ntype ServiceRegistryInput struct {\n\tdepinject.In\n\tChainService     *blockchain.Service\n\tEngineClient     *client.EngineClient\n\tLogger           *phuslu.Logger\n\tNodeAPIServer    *server.Server\n\tReportingService *version.ReportingService\n\tTelemetrySink    *metrics.TelemetrySink\n\tTelemetryService *telemetry.Service\n\tValidatorService *validator.Service\n\tCometBFTService  types.ConsensusService\n\tShutdownService  *shutdown.Service\n}\n\n// ProvideServiceRegistry is the depinject provider for the service registry.\nfunc ProvideServiceRegistry(in ServiceRegistryInput) *service.Registry {\n\t// Note: the order of opts matters since the registry will start these services\n\t// in the order they are  declared in this slice, and in reverse order\n\t// during shutdown.\n\topts := []service.RegistryOption{\n\t\t// we want shutdownservice to be the first service to start and the last to stop\n\t\tservice.WithService(in.ShutdownService),\n\n\t\tservice.WithService(in.ValidatorService),\n\t\tservice.WithService(in.NodeAPIServer),\n\t\tservice.WithService(in.ReportingService),\n\t\tservice.WithService(in.TelemetryService),\n\n\t\t// engineClient will block until it connects to the execution layer\n\t\tservice.WithService(in.EngineClient),\n\n\t\t// only once we connect to an execution client will we start the\n\t\t// chain service and cometbft service\n\t\tservice.WithService(in.ChainService),\n\t\tservice.WithService(in.CometBFTService),\n\t}\n\n\treturn service.NewRegistry(in.Logger, opts...)\n}\n"
  },
  {
    "path": "node-core/components/shutdown_service.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"path/filepath\"\n\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/config\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/node-core/services/shutdown\"\n\t\"github.com/cosmos/cosmos-sdk/client/flags\"\n\t\"github.com/spf13/cast\"\n)\n\n// ShutDownServiceInput is the input for the shuchdown service provider.\ntype ShutDownServiceInput struct {\n\tdepinject.In\n\n\tLogger  *phuslu.Logger\n\tAppOpts config.AppOptions\n}\n\nfunc ProvideShutDownService(in ShutDownServiceInput) *shutdown.Service {\n\tpidFile := filepath.Join(cast.ToString(in.AppOpts.Get(flags.FlagHome)), \"data/beacond.pid\")\n\n\treturn shutdown.NewService(\n\t\tin.Logger.With(\"service\", \"shutdown\"),\n\t\tpidFile)\n}\n"
  },
  {
    "path": "node-core/components/sidecars.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"cosmossdk.io/depinject\"\n\tdablob \"github.com/berachain/beacon-kit/da/blob\"\n\t\"github.com/berachain/beacon-kit/node-core/components/metrics\"\n)\n\ntype SidecarFactoryInput struct {\n\tdepinject.In\n\n\tTelemetrySink *metrics.TelemetrySink\n}\n\nfunc ProvideSidecarFactory(in SidecarFactoryInput) *dablob.SidecarFactory {\n\treturn dablob.NewSidecarFactory(\n\t\tin.TelemetrySink,\n\t)\n}\n"
  },
  {
    "path": "node-core/components/signer/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage signer\n\nimport \"errors\"\n\nvar (\n\t// ErrInvalidSignature is returned when a signature is invalid.\n\tErrInvalidSignature = errors.New(\"signer returned an invalid signature\")\n\n\t// ErrValidatorPrivateKeyRequired is returned when the validator private key\n\t// is required but not provided.\n\tErrValidatorPrivateKeyRequired = errors.New(\n\t\t\"validator private key required\",\n\t)\n\t// ErrInvalidValidatorPrivateKeyLength is returned when the validator\n\t// private key has an invalid length.\n\tErrInvalidValidatorPrivateKeyLength = errors.New(\n\t\t\"invalid validator private key length\",\n\t)\n)\n"
  },
  {
    "path": "node-core/components/signer/legacy.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage signer\n\nimport (\n\t\"encoding/hex\"\n\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/cometbft/cometbft/crypto/bls12381\"\n)\n\n// LegacySigner is a BLS12-381 signer that uses a bls.PrivKey for signing.\ntype LegacySigner struct {\n\tbls12381.PrivKey\n}\n\n// NewLegacySigner creates a new Signer instance given a secret key.\nfunc NewLegacySigner(\n\tkeyBz LegacyKey,\n) (*LegacySigner, error) {\n\tpk, err := bls12381.NewPrivateKeyFromBytes(keyBz[:])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &LegacySigner{PrivKey: *pk}, nil\n}\n\n// PublicKey returns the public key of the signer.\nfunc (b *LegacySigner) PublicKey() crypto.BLSPubkey {\n\treturn crypto.BLSPubkey(b.PubKey().Bytes())\n}\n\n// Sign generates a signature for a given message using the signer's secret key.\n// It returns the signature and any error encountered during the signing\n// process.\nfunc (b *LegacySigner) Sign(msg []byte) (crypto.BLSSignature, error) {\n\tsig, err := b.PrivKey.Sign(msg)\n\tif err != nil {\n\t\treturn crypto.BLSSignature{}, err\n\t}\n\treturn crypto.BLSSignature(sig), nil\n}\n\n// VerifySignature verifies a signature against a message and public key.\nfunc (LegacySigner) VerifySignature(\n\tpubKey crypto.BLSPubkey,\n\tmsg []byte,\n\tsignature crypto.BLSSignature,\n) error {\n\tpk, err := bls12381.NewPublicKeyFromBytes(pubKey[:])\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !pk.VerifySignature(msg, signature[:]) {\n\t\treturn ErrInvalidSignature\n\t}\n\treturn nil\n}\n\n// LegacyKey is a byte array that represents a BLS12-381 secret key.\ntype LegacyKey [constants.BLSSecretKeyLength]byte\n\n// LegacyKeyFromString returns a LegacyKey from a hex-encoded string.\nfunc LegacyKeyFromString(privKey string) (LegacyKey, error) {\n\tprivKeyBz, err := hex.DecodeString(privKey)\n\tif err != nil {\n\t\treturn LegacyKey{}, err\n\t}\n\tif len(privKeyBz) != constants.BLSSecretKeyLength {\n\t\treturn LegacyKey{}, ErrInvalidValidatorPrivateKeyLength\n\t}\n\treturn LegacyKey(privKeyBz), nil\n}\n"
  },
  {
    "path": "node-core/components/signer/signer.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage signer\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/cometbft/cometbft/crypto/bls12381\"\n\t\"github.com/cometbft/cometbft/privval\"\n\t\"github.com/cometbft/cometbft/types\"\n)\n\n// BLSSigner utilize an underlying PrivValidator signer using data persisted to\n// disk to prevent double signing.\ntype BLSSigner struct {\n\ttypes.PrivValidator\n}\n\n// NewBLSSigner creates a new BLSSigner instance using the provided key and\n// state\n// file paths.\n// If the key file does not exist, the program will exit.\nfunc NewBLSSigner(keyFilePath string, stateFilePath string) *BLSSigner {\n\tfilePV := privval.LoadFilePV(keyFilePath, stateFilePath)\n\treturn &BLSSigner{PrivValidator: filePV}\n}\n\n// ========================== Implements BLS Signer ==========================\n\n// PublicKey returns the public key of the signer.\nfunc (f BLSSigner) PublicKey() crypto.BLSPubkey {\n\tkey, err := f.PrivValidator.GetPubKey()\n\tif err != nil {\n\t\treturn crypto.BLSPubkey{}\n\t}\n\n\tblsKey, err := bls12381.NewPublicKeyFromBytes(key.Bytes())\n\tif err != nil {\n\t\treturn crypto.BLSPubkey{}\n\t}\n\n\treturn crypto.BLSPubkey(blsKey.Compress())\n}\n\n// Sign generates a signature for a given message using the signer's secret key.\nfunc (f BLSSigner) Sign(msg []byte) (crypto.BLSSignature, error) {\n\tsig, err := f.PrivValidator.SignBytes(msg)\n\tif err != nil {\n\t\treturn crypto.BLSSignature{}, err\n\t} else if len(sig) != constants.BLSSignatureLength {\n\t\treturn crypto.BLSSignature{}, errors.Wrapf(\n\t\t\tErrInvalidSignature, \"expected signature length %d, got %d\",\n\t\t\tconstants.BLSSignatureLength, len(sig),\n\t\t)\n\t}\n\treturn crypto.BLSSignature(sig), nil\n}\n\n// VerifySignature verifies a signature against a message and a public key.\nfunc (f BLSSigner) VerifySignature(\n\tpubKey crypto.BLSPubkey,\n\tmsg []byte,\n\tsignature crypto.BLSSignature,\n) error {\n\tpk, err := bls12381.NewPublicKeyFromCompressedBytes(pubKey[:])\n\tif err != nil {\n\t\treturn fmt.Errorf(\"verifying signature: %w\", err)\n\t}\n\tif !pk.VerifySignature(msg, signature[:]) {\n\t\treturn ErrInvalidSignature\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "node-core/components/signer.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"cosmossdk.io/depinject\"\n\tbeaconflags \"github.com/berachain/beacon-kit/cli/flags\"\n\t\"github.com/berachain/beacon-kit/config\"\n\t\"github.com/berachain/beacon-kit/node-core/components/signer\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/cosmos/cosmos-sdk/client/flags\"\n\t\"github.com/spf13/cast\"\n)\n\n// BlsSignerInput is the input for the dep inject framework.\ntype BlsSignerInput struct {\n\tdepinject.In\n\tAppOpts config.AppOptions\n\tPrivKey LegacyKey `optional:\"true\"`\n}\n\n// ProvideBlsSigner is a function that provides the module to the application.\nfunc ProvideBlsSigner(in BlsSignerInput) (crypto.BLSSigner, error) {\n\tif in.PrivKey == [constants.BLSSecretKeyLength]byte{} {\n\t\t// if no private key is provided, use privval signer\n\t\thomeDir := cast.ToString(in.AppOpts.Get(flags.FlagHome))\n\t\tprivValKeyFile := cast.ToString(\n\t\t\tin.AppOpts.Get(beaconflags.PrivValidatorKeyFile),\n\t\t)\n\t\tprivValStateFile := cast.ToString(\n\t\t\tin.AppOpts.Get(beaconflags.PrivValidatorStateFile),\n\t\t)\n\t\t// If privValKeyFile is not an absolute path, join with homeDir\n\t\tif !filepath.IsAbs(privValKeyFile) {\n\t\t\tprivValKeyFile = filepath.Join(homeDir, privValKeyFile)\n\t\t}\n\t\t// If privValStateFile is not an absolute path, join with homeDir\n\t\tif !filepath.IsAbs(privValStateFile) {\n\t\t\tprivValStateFile = filepath.Join(homeDir, privValStateFile)\n\t\t}\n\n\t\t// Check key file existence here as the error in NewBLSSigner is vague.\n\t\tif _, err := os.Stat(privValKeyFile); os.IsNotExist(err) {\n\t\t\treturn nil, fmt.Errorf(\"key file does not exist at path: %s\", privValKeyFile)\n\t\t}\n\n\t\t// Check state file existence as the error in NewBLSSigner is vague.\n\t\tif _, err := os.Stat(privValStateFile); os.IsNotExist(err) {\n\t\t\treturn nil, fmt.Errorf(\"state file does not exist at path: %s\", privValStateFile)\n\t\t}\n\n\t\treturn signer.NewBLSSigner(privValKeyFile, privValStateFile), nil\n\t}\n\treturn signer.NewLegacySigner(in.PrivKey)\n}\n"
  },
  {
    "path": "node-core/components/state_processor.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/execution/engine\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/node-core/components/metrics\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/state-transition/core\"\n\t\"github.com/berachain/beacon-kit/storage/deposit\"\n)\n\n// StateProcessorInput is the input for the state processor for the depinject\n// framework.\ntype StateProcessorInput struct {\n\tdepinject.In\n\tLogger          *phuslu.Logger\n\tChainSpec       chain.Spec\n\tExecutionEngine *engine.Engine\n\tDepositStore    deposit.StoreManager\n\tSigner          crypto.BLSSigner\n\tTelemetrySink   *metrics.TelemetrySink\n}\n\n// ProvideStateProcessor provides the state processor to the depinject\n// framework.\nfunc ProvideStateProcessor(in StateProcessorInput) *core.StateProcessor {\n\treturn core.NewStateProcessor(\n\t\tin.Logger.With(\"service\", \"state-processor\"),\n\t\tin.ChainSpec,\n\t\tin.ExecutionEngine,\n\t\tin.DepositStore,\n\t\tin.Signer,\n\t\tcrypto.GetAddressFromPubKey,\n\t\tin.TelemetrySink,\n\t)\n}\n"
  },
  {
    "path": "node-core/components/storage/storage.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage storage\n\nimport (\n\t\"context\"\n\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\tdastore \"github.com/berachain/beacon-kit/da/store\"\n\t\"github.com/berachain/beacon-kit/log\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n\t\"github.com/berachain/beacon-kit/storage/beacondb\"\n\t\"github.com/berachain/beacon-kit/storage/block\"\n\t\"github.com/berachain/beacon-kit/storage/deposit\"\n)\n\n// Backend is a struct that holds the storage backend. It provides a simple\n// interface to access all types of storage required by the runtime.\ntype Backend struct {\n\tchainSpec         chain.Spec\n\tavailabilityStore *dastore.Store\n\tkvStore           *beacondb.KVStore\n\tdepositStore      deposit.StoreManager\n\tblockStore        *block.KVStore[*types.BeaconBlock]\n\tlogger            log.Logger\n\ttelemetrySink     statedb.TelemetrySink\n}\n\nfunc NewBackend(\n\tchainSpec chain.Spec,\n\tavailabilityStore *dastore.Store,\n\tkvStore *beacondb.KVStore,\n\tdepositStore deposit.StoreManager,\n\tblockStore *block.KVStore[*types.BeaconBlock],\n\tlogger log.Logger,\n\ttelemetrySink statedb.TelemetrySink,\n) *Backend {\n\treturn &Backend{\n\t\tchainSpec:         chainSpec,\n\t\tavailabilityStore: availabilityStore,\n\t\tkvStore:           kvStore,\n\t\tdepositStore:      depositStore,\n\t\tblockStore:        blockStore,\n\t\tlogger:            logger,\n\t\ttelemetrySink:     telemetrySink,\n\t}\n}\n\n// AvailabilityStore returns the availability store struct initialized with a\n// given context.\nfunc (k Backend) AvailabilityStore() *dastore.Store {\n\treturn k.availabilityStore\n}\n\n// StateFromContext returns the beacon state struct initialized with a given\n// context and the store key.\nfunc (k Backend) StateFromContext(ctx context.Context) *statedb.StateDB {\n\treturn statedb.NewBeaconStateFromDB(\n\t\tk.kvStore.WithContext(ctx),\n\t\tk.chainSpec,\n\t\tk.logger,\n\t\tk.telemetrySink,\n\t)\n}\n\n// BeaconStore returns the beacon store struct.\nfunc (k Backend) BeaconStore() *beacondb.KVStore {\n\treturn k.kvStore\n}\n\nfunc (k Backend) BlockStore() *block.KVStore[*types.BeaconBlock] {\n\treturn k.blockStore\n}\n\n// DepositStore returns the deposit store struct initialized with a.\nfunc (k Backend) DepositStore() deposit.StoreManager {\n\treturn k.depositStore\n}\n"
  },
  {
    "path": "node-core/components/store.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"github.com/berachain/beacon-kit/storage\"\n\t\"github.com/berachain/beacon-kit/storage/beacondb\"\n)\n\n// ProvideKVStore is the depinject provider that returns a beacon KV store.\nfunc ProvideKVStore() *beacondb.KVStore {\n\tkvStoreService := &storage.KVStoreService{Key: storage.StoreKey}\n\treturn beacondb.New(kvStoreService)\n}\n"
  },
  {
    "path": "node-core/components/telemetry_service.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"github.com/berachain/beacon-kit/config/config\"\n\t\"github.com/berachain/beacon-kit/observability/telemetry\"\n)\n\n// ProvideTelemetryService is a function that provides a TelemetrySink.\nfunc ProvideTelemetryService(\n\tcfg *config.Config,\n) (*telemetry.Service, error) {\n\treturn telemetry.NewService(&cfg.Telemetry)\n}\n"
  },
  {
    "path": "node-core/components/telemetry_sink.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport \"github.com/berachain/beacon-kit/node-core/components/metrics\"\n\n// ProvideTelemetrySink is a function that provides a TelemetrySink.\nfunc ProvideTelemetrySink() *metrics.TelemetrySink {\n\treturn &metrics.TelemetrySink{}\n}\n"
  },
  {
    "path": "node-core/components/trusted_setup.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"fmt\"\n\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/cli/flags\"\n\t\"github.com/berachain/beacon-kit/config\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n\tgokzg4844 \"github.com/crate-crypto/go-kzg-4844\"\n\t\"github.com/spf13/afero\"\n\t\"github.com/spf13/cast\"\n)\n\n// TrustedSetupInput is the input for the dep inject framework.\ntype TrustedSetupInput struct {\n\tdepinject.In\n\tAppOpts config.AppOptions\n}\n\n// ProvideTrustedSetup provides the module to the application.\nfunc ProvideTrustedSetup(\n\tin TrustedSetupInput,\n) (*gokzg4844.JSONTrustedSetup, error) {\n\treturn ReadTrustedSetup(\n\t\tcast.ToString(in.AppOpts.Get(flags.KZGTrustedSetupPath)),\n\t)\n}\n\n// ReadTrustedSetup reads the trusted setup from the file system.\nfunc ReadTrustedSetup(filePath string) (*gokzg4844.JSONTrustedSetup, error) {\n\tconfig, err := afero.ReadFile(afero.NewOsFs(), filePath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed reading path '%s', err: %w\", filePath, err)\n\t}\n\tparams := new(gokzg4844.JSONTrustedSetup)\n\tif err = json.Unmarshal(config, params); err != nil {\n\t\treturn nil, err\n\t}\n\tif err = gokzg4844.CheckTrustedSetupIsWellFormed(params); err != nil {\n\t\treturn nil, err\n\t}\n\treturn params, nil\n}\n"
  },
  {
    "path": "node-core/components/types.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\tappmodule \"cosmossdk.io/core/appmodule/v2\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\tconsruntimetypes \"github.com/berachain/beacon-kit/consensus/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/node-core/components/signer\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                    Types                                   */\n/* -------------------------------------------------------------------------- */\n\ntype (\n\t// AttestationData is a type alias for the attestation data.\n\tAttestationData = types.AttestationData\n\n\t// Context is a type alias for the transition context.\n\tContext = transition.Context\n\n\t// Fork is a type alias for the fork.\n\tFork = types.Fork\n\n\t// SlotData is a type alias for the incoming slot.\n\tSlotData = consruntimetypes.SlotData\n\n\t// LegacyKey type alias to LegacyKey used for LegacySinger construction.\n\tLegacyKey = signer.LegacyKey\n\n\t// PayloadID is a type alias for the payload ID.\n\tPayloadID = engineprimitives.PayloadID\n\n\t// SlashingInfo is a type alias for the slashing info.\n\tSlashingInfo = types.SlashingInfo\n\n\t// ValidatorUpdate is a type alias for the validator update.\n\tABCIValidatorUpdate = appmodule.ValidatorUpdate\n\n\t// ValidatorUpdate is a type alias for the validator update.\n\tValidatorUpdate = transition.ValidatorUpdate\n\n\t// ValidatorUpdates is a type alias for the validator updates.\n\tValidatorUpdates = transition.ValidatorUpdates\n\n\t// Withdrawal is a type alias for the engineprimitives withdrawal.\n\t// Withdrawal = engineprimitives.Withdrawal.\n\n\t// Withdrawals is a type alias for the engineprimitives withdrawals.\n\t// Withdrawals = engineprimitives.Withdrawals.\n\n\t// WithdrawalCredentials is a type alias for the withdrawal credentials.\n\tWithdrawalCredentials = types.WithdrawalCredentials\n)\n"
  },
  {
    "path": "node-core/components/validator_service.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage components\n\nimport (\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/beacon/validator\"\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/config\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/node-core/components/metrics\"\n\t\"github.com/berachain/beacon-kit/node-core/components/storage\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n)\n\n// ValidatorServiceInput is the input for the validator service provider.\ntype ValidatorServiceInput struct {\n\tdepinject.In\n\tCfg            *config.Config\n\tChainSpec      chain.Spec\n\tLocalBuilder   LocalBuilder\n\tLogger         *phuslu.Logger\n\tStateProcessor StateProcessor\n\tStorageBackend *storage.Backend\n\tSigner         crypto.BLSSigner\n\tSidecarFactory SidecarFactory\n\tTelemetrySink  *metrics.TelemetrySink\n}\n\n// ProvideValidatorService is a depinject provider for the validator service.\nfunc ProvideValidatorService(in ValidatorServiceInput) (*validator.Service, error) {\n\t// Build the builder service.\n\treturn validator.NewService(\n\t\t&in.Cfg.Validator,\n\t\tin.Logger.With(\"service\", \"validator\"),\n\t\tin.ChainSpec,\n\t\tin.StorageBackend,\n\t\tin.StateProcessor,\n\t\tin.Signer,\n\t\tin.SidecarFactory,\n\t\tin.LocalBuilder,\n\t\tin.TelemetrySink,\n\t), nil\n}\n"
  },
  {
    "path": "node-core/node/node.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage node\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/signal\"\n\t\"sync\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"cosmossdk.io/store\"\n\t\"github.com/berachain/beacon-kit/beacon/blockchain\"\n\tcometbft \"github.com/berachain/beacon-kit/consensus/cometbft/service\"\n\t\"github.com/berachain/beacon-kit/log\"\n\tservice \"github.com/berachain/beacon-kit/node-core/services/registry\"\n\t\"github.com/berachain/beacon-kit/node-core/types\"\n)\n\n// Compile-time assertion that node implements the NodeI interface.\nvar _ types.Node = (*node)(nil)\n\n// node is the hard-type representation of the beacon-kit node.\ntype node struct {\n\t// logger is the node's logger.\n\tlogger log.Logger\n\t// registry is the node's service registry.\n\tregistry *service.Registry\n\t// shutdownTimeout is the maximum time to wait for the node to gracefully shutdown before forcing an exit.\n\tshutdownTimeout time.Duration\n}\n\n// New returns a new node.\nfunc New[NodeT types.Node](shutdownTimeout time.Duration, registry *service.Registry, logger log.Logger) NodeT {\n\tn := &node{\n\t\tshutdownTimeout: shutdownTimeout,\n\t\tregistry:        registry,\n\t\tlogger:          logger,\n\t}\n\n\t//nolint:errcheck // should be safe\n\treturn types.Node(n).(NodeT)\n}\n\n// Start starts the node.\nfunc (n *node) Start(\n\tctx context.Context,\n) error {\n\tcctx, cancelFn := context.WithCancel(ctx) //#nosec:G118 -- cancelFn is called in the shutdownFunc\n\n\tstop := make(chan struct{})\n\tsigc := make(chan os.Signal, 1)\n\n\tsignal.Notify(sigc, syscall.SIGINT, syscall.SIGTERM)\n\tdefer signal.Stop(sigc)\n\n\t// make sure we only call shutdownFunc once\n\tvar once sync.Once\n\n\tshutdownFunc := func(err error) {\n\t\tnow := time.Now()\n\t\tn.logger.Error(\"Shutdown initiated\", \"timeout\", n.shutdownTimeout.String(), \"error\", err)\n\n\t\tcancelFn()\n\t\tn.registry.StopAll()\n\t\tclose(stop)\n\n\t\tn.logger.Info(\"Node shutdown completed\", \"duration\", time.Since(now).String())\n\t}\n\n\t// listen to signals in a separate goroutine\n\tgo func() {\n\t\tsig := <-sigc\n\n\t\ttimeout := time.AfterFunc(n.shutdownTimeout, func() {\n\t\t\tn.logger.Error(\"Shutdown timeout exceeded, forcing exit\", \"timeout\", n.shutdownTimeout.String())\n\t\t\tos.Exit(1)\n\t\t})\n\t\tdefer timeout.Stop()\n\n\t\tonce.Do(func() {\n\t\t\tshutdownFunc(fmt.Errorf(\"shutdown initiated by signal: %s\", sig.String()))\n\t\t})\n\t}()\n\n\terr := n.registry.StartAll(cctx)\n\tif err != nil {\n\t\tonce.Do(func() {\n\t\t\tshutdownFunc(fmt.Errorf(\"failed to start services: %w\", err))\n\t\t})\n\t\treturn err\n\t}\n\n\t// we wait here until the signal handler has shutdown the node\n\t<-stop\n\n\treturn nil\n}\n\n// CommitMultiStore returns the CommitMultiStore from cometbft service.\nfunc (n *node) CommitMultiStore() store.CommitMultiStore {\n\tvar cometService *cometbft.Service\n\terr := n.registry.FetchService(&cometService)\n\tif err != nil || cometService == nil { // appease nilaway\n\t\terr = fmt.Errorf(\"failed to fetch cometbft service: %w\", err)\n\t\tpanic(err)\n\t}\n\treturn cometService.CommitMultiStore()\n}\n\n// StorageBackend returns the storage backend from the blockchain service.\nfunc (n *node) StorageBackend() blockchain.StorageBackend {\n\tvar blockchainService *blockchain.Service\n\terr := n.registry.FetchService(&blockchainService)\n\tif err != nil || blockchainService == nil { // appease nilaway\n\t\terr = fmt.Errorf(\"failed to fetch blockchain service: %w\", err)\n\t\tpanic(err)\n\t}\n\treturn blockchainService.StorageBackend()\n}\n"
  },
  {
    "path": "node-core/services/registry/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage service\n\nimport \"github.com/berachain/beacon-kit/errors\"\n\nvar (\n\t// errServiceAlreadyExists defines an error for when a service already\n\t// exists.\n\terrServiceAlreadyExists = errors.Wrapf(\n\t\terrors.New(\"service already exists\"),\n\t\t\"%v\",\n\t)\n\n\t// errInputIsNotPointer defines an error for when the input must\n\t// be of pointer type.\n\terrInputIsNotPointer = errors.Wrapf(\n\t\terrors.New(\n\t\t\t\"input must be of pointer type, received value type instead\",\n\t\t),\n\t\t\"%T\",\n\t)\n\n\t// errUnknownService defines is returned when an unknown service is seen.\n\terrUnknownService = errors.Wrapf(\n\t\terrors.New(\"unknown service\"),\n\t\t\"%T\",\n\t)\n)\n"
  },
  {
    "path": "node-core/services/registry/mocks/basic.mock.go",
    "content": "// Code generated by mockery v2.53.5. DO NOT EDIT.\n\npackage mocks\n\nimport (\n\tcontext \"context\"\n\n\tmock \"github.com/stretchr/testify/mock\"\n)\n\n// Basic is an autogenerated mock type for the Basic type\ntype Basic struct {\n\tmock.Mock\n}\n\ntype Basic_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *Basic) EXPECT() *Basic_Expecter {\n\treturn &Basic_Expecter{mock: &_m.Mock}\n}\n\n// Name provides a mock function with no fields\nfunc (_m *Basic) Name() string {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for Name\")\n\t}\n\n\tvar r0 string\n\tif rf, ok := ret.Get(0).(func() string); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tr0 = ret.Get(0).(string)\n\t}\n\n\treturn r0\n}\n\n// Basic_Name_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Name'\ntype Basic_Name_Call struct {\n\t*mock.Call\n}\n\n// Name is a helper method to define mock.On call\nfunc (_e *Basic_Expecter) Name() *Basic_Name_Call {\n\treturn &Basic_Name_Call{Call: _e.mock.On(\"Name\")}\n}\n\nfunc (_c *Basic_Name_Call) Run(run func()) *Basic_Name_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *Basic_Name_Call) Return(_a0 string) *Basic_Name_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *Basic_Name_Call) RunAndReturn(run func() string) *Basic_Name_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// Start provides a mock function with given fields: ctx\nfunc (_m *Basic) Start(ctx context.Context) error {\n\tret := _m.Called(ctx)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for Start\")\n\t}\n\n\tvar r0 error\n\tif rf, ok := ret.Get(0).(func(context.Context) error); ok {\n\t\tr0 = rf(ctx)\n\t} else {\n\t\tr0 = ret.Error(0)\n\t}\n\n\treturn r0\n}\n\n// Basic_Start_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Start'\ntype Basic_Start_Call struct {\n\t*mock.Call\n}\n\n// Start is a helper method to define mock.On call\n//   - ctx context.Context\nfunc (_e *Basic_Expecter) Start(ctx interface{}) *Basic_Start_Call {\n\treturn &Basic_Start_Call{Call: _e.mock.On(\"Start\", ctx)}\n}\n\nfunc (_c *Basic_Start_Call) Run(run func(ctx context.Context)) *Basic_Start_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(context.Context))\n\t})\n\treturn _c\n}\n\nfunc (_c *Basic_Start_Call) Return(_a0 error) *Basic_Start_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *Basic_Start_Call) RunAndReturn(run func(context.Context) error) *Basic_Start_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// Stop provides a mock function with no fields\nfunc (_m *Basic) Stop() error {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for Stop\")\n\t}\n\n\tvar r0 error\n\tif rf, ok := ret.Get(0).(func() error); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tr0 = ret.Error(0)\n\t}\n\n\treturn r0\n}\n\n// Basic_Stop_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Stop'\ntype Basic_Stop_Call struct {\n\t*mock.Call\n}\n\n// Stop is a helper method to define mock.On call\nfunc (_e *Basic_Expecter) Stop() *Basic_Stop_Call {\n\treturn &Basic_Stop_Call{Call: _e.mock.On(\"Stop\")}\n}\n\nfunc (_c *Basic_Stop_Call) Run(run func()) *Basic_Stop_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *Basic_Stop_Call) Return(_a0 error) *Basic_Stop_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *Basic_Stop_Call) RunAndReturn(run func() error) *Basic_Stop_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewBasic creates a new instance of Basic. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewBasic(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *Basic {\n\tmock := &Basic{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "node-core/services/registry/mocks/commit_multistore_accessor.mock.go",
    "content": "// Code generated by mockery v2.49.0. DO NOT EDIT.\n\npackage mocks\n\nimport (\n\tmock \"github.com/stretchr/testify/mock\"\n\n\ttypes \"cosmossdk.io/store/types\"\n)\n\n// CommitMultistoreAccessor is an autogenerated mock type for the CommitMultistoreAccessor type\ntype CommitMultistoreAccessor struct {\n\tmock.Mock\n}\n\ntype CommitMultistoreAccessor_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *CommitMultistoreAccessor) EXPECT() *CommitMultistoreAccessor_Expecter {\n\treturn &CommitMultistoreAccessor_Expecter{mock: &_m.Mock}\n}\n\n// CommitMultiStore provides a mock function with given fields:\nfunc (_m *CommitMultistoreAccessor) CommitMultiStore() types.CommitMultiStore {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for CommitMultiStore\")\n\t}\n\n\tvar r0 types.CommitMultiStore\n\tif rf, ok := ret.Get(0).(func() types.CommitMultiStore); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(types.CommitMultiStore)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// CommitMultistoreAccessor_CommitMultiStore_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CommitMultiStore'\ntype CommitMultistoreAccessor_CommitMultiStore_Call struct {\n\t*mock.Call\n}\n\n// CommitMultiStore is a helper method to define mock.On call\nfunc (_e *CommitMultistoreAccessor_Expecter) CommitMultiStore() *CommitMultistoreAccessor_CommitMultiStore_Call {\n\treturn &CommitMultistoreAccessor_CommitMultiStore_Call{Call: _e.mock.On(\"CommitMultiStore\")}\n}\n\nfunc (_c *CommitMultistoreAccessor_CommitMultiStore_Call) Run(run func()) *CommitMultistoreAccessor_CommitMultiStore_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *CommitMultistoreAccessor_CommitMultiStore_Call) Return(_a0 types.CommitMultiStore) *CommitMultistoreAccessor_CommitMultiStore_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *CommitMultistoreAccessor_CommitMultiStore_Call) RunAndReturn(run func() types.CommitMultiStore) *CommitMultistoreAccessor_CommitMultiStore_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewCommitMultistoreAccessor creates a new instance of CommitMultistoreAccessor. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewCommitMultistoreAccessor(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *CommitMultistoreAccessor {\n\tmock := &CommitMultistoreAccessor{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "node-core/services/registry/mocks/dispatcher.mock.go",
    "content": "// Code generated by mockery v2.49.0. DO NOT EDIT.\n\npackage mocks\n\nimport (\n\tcontext \"context\"\n\n\tmock \"github.com/stretchr/testify/mock\"\n)\n\n// Dispatcher is an autogenerated mock type for the Dispatcher type\ntype Dispatcher struct {\n\tmock.Mock\n}\n\ntype Dispatcher_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *Dispatcher) EXPECT() *Dispatcher_Expecter {\n\treturn &Dispatcher_Expecter{mock: &_m.Mock}\n}\n\n// Start provides a mock function with given fields: ctx\nfunc (_m *Dispatcher) Start(ctx context.Context) error {\n\tret := _m.Called(ctx)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for Start\")\n\t}\n\n\tvar r0 error\n\tif rf, ok := ret.Get(0).(func(context.Context) error); ok {\n\t\tr0 = rf(ctx)\n\t} else {\n\t\tr0 = ret.Error(0)\n\t}\n\n\treturn r0\n}\n\n// Dispatcher_Start_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Start'\ntype Dispatcher_Start_Call struct {\n\t*mock.Call\n}\n\n// Start is a helper method to define mock.On call\n//   - ctx context.Context\nfunc (_e *Dispatcher_Expecter) Start(ctx interface{}) *Dispatcher_Start_Call {\n\treturn &Dispatcher_Start_Call{Call: _e.mock.On(\"Start\", ctx)}\n}\n\nfunc (_c *Dispatcher_Start_Call) Run(run func(ctx context.Context)) *Dispatcher_Start_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(context.Context))\n\t})\n\treturn _c\n}\n\nfunc (_c *Dispatcher_Start_Call) Return(_a0 error) *Dispatcher_Start_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *Dispatcher_Start_Call) RunAndReturn(run func(context.Context) error) *Dispatcher_Start_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewDispatcher creates a new instance of Dispatcher. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewDispatcher(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *Dispatcher {\n\tmock := &Dispatcher{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "node-core/services/registry/mocks/registry_option.mock.go",
    "content": "// Code generated by mockery v2.53.5. DO NOT EDIT.\n\npackage mocks\n\nimport (\n\tservice \"github.com/berachain/beacon-kit/node-core/services/registry\"\n\tmock \"github.com/stretchr/testify/mock\"\n)\n\n// RegistryOption is an autogenerated mock type for the RegistryOption type\ntype RegistryOption struct {\n\tmock.Mock\n}\n\ntype RegistryOption_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *RegistryOption) EXPECT() *RegistryOption_Expecter {\n\treturn &RegistryOption_Expecter{mock: &_m.Mock}\n}\n\n// Execute provides a mock function with given fields: _a0\nfunc (_m *RegistryOption) Execute(_a0 *service.Registry) error {\n\tret := _m.Called(_a0)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for Execute\")\n\t}\n\n\tvar r0 error\n\tif rf, ok := ret.Get(0).(func(*service.Registry) error); ok {\n\t\tr0 = rf(_a0)\n\t} else {\n\t\tr0 = ret.Error(0)\n\t}\n\n\treturn r0\n}\n\n// RegistryOption_Execute_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Execute'\ntype RegistryOption_Execute_Call struct {\n\t*mock.Call\n}\n\n// Execute is a helper method to define mock.On call\n//   - _a0 *service.Registry\nfunc (_e *RegistryOption_Expecter) Execute(_a0 interface{}) *RegistryOption_Execute_Call {\n\treturn &RegistryOption_Execute_Call{Call: _e.mock.On(\"Execute\", _a0)}\n}\n\nfunc (_c *RegistryOption_Execute_Call) Run(run func(_a0 *service.Registry)) *RegistryOption_Execute_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(*service.Registry))\n\t})\n\treturn _c\n}\n\nfunc (_c *RegistryOption_Execute_Call) Return(_a0 error) *RegistryOption_Execute_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *RegistryOption_Execute_Call) RunAndReturn(run func(*service.Registry) error) *RegistryOption_Execute_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewRegistryOption creates a new instance of RegistryOption. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewRegistryOption(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *RegistryOption {\n\tmock := &RegistryOption{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "node-core/services/registry/options.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage service\n\n// RegistryOption is a functional option for the Registry.\ntype RegistryOption func(*Registry) error\n\n// WithService is an Option that registers a service with the Registry.\nfunc WithService(svc Basic) RegistryOption {\n\treturn func(r *Registry) error {\n\t\treturn r.RegisterService(svc)\n\t}\n}\n"
  },
  {
    "path": "node-core/services/registry/registry.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage service\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"reflect\"\n\n\t\"github.com/berachain/beacon-kit/log\"\n)\n\n// Basic is the minimal interface for a service.\ntype Basic interface {\n\t// Start spawns any goroutines required by the service.\n\tStart(ctx context.Context) error\n\t// Stop stops the service. It should be safe to call\n\t// Stop on a service that has not been started\n\tStop() error\n\t// Name returns the name of the service.\n\tName() string\n}\n\n// Registry provides a useful pattern for managing services.\n// It allows for ease of dependency management and ensures services\n// dependent on others use the same references in memory.\ntype Registry struct {\n\t// logger is the logger for the Registry.\n\tlogger log.Logger\n\t// services is a map of service type -> service instance.\n\tservices map[string]Basic\n\t// servicesStarted is a map of services we have called Start() on.\n\tservicesStarted map[string]struct{}\n\t// serviceTypes is an ordered slice of registered service types.\n\tserviceTypes []string\n}\n\n// NewRegistry starts a registry instance for convenience.\nfunc NewRegistry(logger log.Logger, opts ...RegistryOption) *Registry {\n\tr := &Registry{\n\t\tlogger:          logger,\n\t\tservices:        make(map[string]Basic),\n\t\tservicesStarted: make(map[string]struct{}),\n\t}\n\n\tfor _, opt := range opts {\n\t\tif err := opt(r); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}\n\treturn r\n}\n\n// StartAll initialized each service in order of registration.\nfunc (s *Registry) StartAll(ctx context.Context) error {\n\t// start all services\n\ts.logger.Info(\"Starting services\", \"num\", len(s.serviceTypes))\n\tfor _, typeName := range s.serviceTypes {\n\t\ts.logger.Info(\"Starting service\", \"type\", typeName)\n\t\tsvc := s.services[typeName]\n\t\tif svc == nil {\n\t\t\ts.logger.Error(\"service not found\", \"type\", typeName)\n\t\t\tcontinue\n\t\t}\n\n\t\tif err := svc.Start(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"error when starting service %s: %w\", typeName, err)\n\t\t}\n\n\t\ts.servicesStarted[typeName] = struct{}{}\n\t}\n\ts.logger.Info(\"All services started\", \"num\", len(s.servicesStarted))\n\treturn nil\n}\n\nfunc (s *Registry) StopAll() {\n\t// stop all services in reverse order they were started\n\ts.logger.Info(\"Stopping services\", \"num\", len(s.serviceTypes))\n\tfor i := len(s.serviceTypes) - 1; i >= 0; i-- {\n\t\ttypeName := s.serviceTypes[i]\n\n\t\tif _, started := s.servicesStarted[typeName]; !started {\n\t\t\ts.logger.Info(\"Service not started\", \"type\", typeName)\n\t\t\tcontinue\n\t\t}\n\n\t\ts.logger.Info(\"Stopping service\", \"type\", typeName)\n\t\tsvc := s.services[typeName]\n\t\tif svc == nil {\n\t\t\ts.logger.Error(\"service not found\", \"type\", typeName)\n\t\t\tcontinue\n\t\t}\n\n\t\tif err := svc.Stop(); err != nil {\n\t\t\ts.logger.Error(\"error when stopping service\", \"type\", typeName, \"err\", err)\n\t\t}\n\t}\n\ts.logger.Info(\"All services stopped\", \"num\", len(s.servicesStarted))\n}\n\n// RegisterService appends a service constructor function to the service\n// registry.\nfunc (s *Registry) RegisterService(service Basic) error {\n\ttypeName := service.Name()\n\tif _, exists := s.services[typeName]; exists {\n\t\treturn errServiceAlreadyExists\n\t}\n\ts.services[typeName] = service\n\ts.serviceTypes = append(s.serviceTypes, typeName)\n\treturn nil\n}\n\n// FetchService takes in a struct pointer and sets the value of that pointer\n// to a service currently stored in the service registry. This ensures the\n// input argument is set to the right pointer that refers to the originally\n// registered service.\nfunc (s *Registry) FetchService(service interface{}) error {\n\tserviceType := reflect.TypeOf(service)\n\tif serviceType.Kind() != reflect.Ptr ||\n\t\tserviceType.Elem().Kind() != reflect.Ptr {\n\t\treturn errInputIsNotPointer\n\t}\n\n\telement := reflect.ValueOf(service).Elem()\n\n\ttypeName := \"\"\n\tfor name, svc := range s.services {\n\t\tsvcType := reflect.TypeOf(svc)\n\t\tif svcType.AssignableTo(serviceType.Elem()) {\n\t\t\ttypeName = name\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif typeName == \"\" {\n\t\treturn errUnknownService\n\t}\n\n\tif running, ok := s.services[typeName]; ok {\n\t\telement.Set(reflect.ValueOf(running))\n\t\treturn nil\n\t}\n\treturn errUnknownService\n}\n"
  },
  {
    "path": "node-core/services/registry/registry_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage service_test\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/log/noop\"\n\tservice \"github.com/berachain/beacon-kit/node-core/services/registry\"\n\t\"github.com/berachain/beacon-kit/node-core/services/registry/mocks\"\n\t\"github.com/stretchr/testify/mock\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestRegistry_StartAll(t *testing.T) {\n\tt.Parallel()\n\tlogger := noop.NewLogger[any]()\n\tregistry := service.NewRegistry(logger)\n\n\tservice1 := &mocks.Basic{}\n\tservice1.On(\"Start\", mock.Anything).Return(nil).Once()\n\tservice1.On(\"Name\").Return(\"Service1\")\n\n\tservice2 := &mocks.Basic{}\n\tservice2.On(\"Start\", mock.Anything).Return(nil).Once()\n\tservice2.On(\"Name\").Return(\"Service2\")\n\n\terr := registry.RegisterService(service1)\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to register Service1: %v\", err)\n\t}\n\n\terr = registry.RegisterService(service2)\n\tif err != nil {\n\t\tt.Fatalf(\"Failed to register Service2: %v\", err)\n\t}\n\n\trequire.NoError(t, registry.StartAll(t.Context()))\n\ttime.Sleep(25 * time.Millisecond)\n\n\tservice1.AssertCalled(t, \"Start\", mock.Anything)\n\tservice2.AssertCalled(t, \"Start\", mock.Anything)\n}\n\nfunc TestRegistry_FetchService(t *testing.T) {\n\tt.Parallel()\n\tlogger := noop.NewLogger[any]()\n\tregistry := service.NewRegistry(logger)\n\n\tservice1 := new(mocks.Basic)\n\tservice1.On(\"Name\").Return(\"Service1\")\n\tif err := registry.RegisterService(service1); err != nil {\n\t\tt.Fatalf(\"Failed to register Service1: %v\", err)\n\t}\n\n\tvar fetchedService *mocks.Basic\n\tif err := registry.FetchService(&fetchedService); err != nil {\n\t\tt.Fatalf(\"Failed to fetch service: %v\", err)\n\t}\n\n\tif reflect.TypeOf(fetchedService) != reflect.TypeOf(service1) {\n\t\tt.Errorf(\"Fetched service type mismatch\")\n\t}\n}\n"
  },
  {
    "path": "node-core/services/shutdown/service..go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage shutdown\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/log\"\n)\n\n// Service is a service that manages any startup or shutdown tasks that need to be done.\ntype Service struct {\n\t// logger is used for logging messages in the service.\n\tlogger log.Logger\n\n\t// pidFile is the path to the pid file we use to detect unsafe shutdowns.\n\tpidFile string\n}\n\nfunc NewService(logger log.Logger, pidFile string) *Service {\n\treturn &Service{logger: logger, pidFile: pidFile}\n}\n\n// Name returns the name of the service.\nfunc (*Service) Name() string {\n\treturn \"shutdown\"\n}\n\nfunc (s *Service) Start(_ context.Context) error {\n\t// if the pid file already exists it means we didn't gracefully shutdown.\n\tif _, err := os.Stat(s.pidFile); err == nil {\n\t\ts.printUnsafeShutDownDetected()\n\t}\n\n\t// create a new pid file and write our process id to it. If it already existed before\n\t// it will be truncated and overwritten with our new pid. The timestamp of the file\n\t// will be updated to the current time so we can compute the time it was running\n\tf, err := os.Create(s.pidFile)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to create pidfile\")\n\t}\n\tdefer f.Close()\n\t_, err = f.WriteString(strconv.Itoa(os.Getpid()))\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to write pid to pidfile\")\n\t}\n\n\treturn nil\n}\n\nfunc (s *Service) Stop() error {\n\ts.logger.Info(\"Stopping shutdown service\")\n\n\terr := os.Remove(s.pidFile)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to remove pidfile\")\n\t}\n\n\treturn nil\n}\n\nfunc (s *Service) printUnsafeShutDownDetected() {\n\t// collect info about the previous pid instance and when it was started\n\tpid := \"unknown\"\n\tif bytes, readErr := os.ReadFile(s.pidFile); readErr == nil {\n\t\tpid = string(bytes)\n\t}\n\tstarted := \"unknown\"\n\tif fi, statErr := os.Stat(s.pidFile); statErr == nil {\n\t\tstarted = fi.ModTime().String()\n\t}\n\n\ts.logger.Warn(fmt.Sprintf(`\n\n\t+==========================================================================+\n\t+ ⚠️ Detected an unsafe shutdown!\n\t+ 🧩 Previously running:\n\t+      PID: %s\n\t+      Started: %s\n\t+==========================================================================+\n\n`,\n\t\tpid, started))\n}\n"
  },
  {
    "path": "node-core/services/version/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage version\n\nimport \"github.com/berachain/beacon-kit/chain\"\n\n// TelemetrySink is an interface for sending telemetry data.\ntype TelemetrySink interface {\n\t// IncrementCounter increments a counter metric identified by the provided\n\t// keys.\n\tIncrementCounter(key string, args ...string)\n\t// SetGauge sets a gauge metric to the specified value, identified by the\n\t// provided keys.\n\tSetGauge(key string, value int64, args ...string)\n}\n\ntype ForkSpec interface {\n\tchain.ForkSpec\n}\n"
  },
  {
    "path": "node-core/services/version/version.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage version\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"runtime\"\n\t\"time\"\n\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/execution/client\"\n\t\"github.com/berachain/beacon-kit/execution/client/ethclient\"\n\t\"github.com/berachain/beacon-kit/log\"\n)\n\n// defaultReportingInterval is the default interval at which the version is\n// reported.\nconst defaultReportingInterval = 5 * time.Minute\n\n// ReportingService is a service that periodically logs the running chain\n// version.\ntype ReportingService struct {\n\t// logger is used to log information about the running chain version.\n\tlogger log.Logger\n\t// version represents the current version of the running chain.\n\tversion string\n\t// reportingInterval is the interval at which the version is reported.\n\treportingInterval time.Duration\n\t// sink is the telemetry sink used to report metrics.\n\tsink TelemetrySink\n\t// client to query the execution layer\n\tclient   *client.EngineClient\n\tforkSpec ForkSpec\n}\n\n// NewReportingService creates a new VersionReporterService.\nfunc NewReportingService(\n\tlogger log.Logger,\n\ttelemetrySink TelemetrySink,\n\tversion string,\n\tengineClient *client.EngineClient,\n\tforkSpec ForkSpec,\n) *ReportingService {\n\treturn &ReportingService{\n\t\tlogger:            logger,\n\t\tversion:           version,\n\t\treportingInterval: defaultReportingInterval,\n\t\tsink:              telemetrySink,\n\t\tclient:            engineClient,\n\t\tforkSpec:          forkSpec,\n\t}\n}\n\n// Name returns the name of the service.\nfunc (*ReportingService) Name() string {\n\treturn \"reporting\"\n}\n\n// Start begins the periodic logging of the chain version.\nfunc (rs *ReportingService) Start(ctx context.Context) error {\n\t// we print to console always at the beginning\n\trs.printToConsole(engineprimitives.ClientVersionV1{\n\t\tVersion: \"unknown\",\n\t\tName:    \"unknown\"},\n\t)\n\n\tconnectedTicker := time.NewTicker(time.Second)\n\tgo func() {\n\t\t// wait until the client is connected\n\t\tconnected := false\n\t\tfor !connected {\n\t\t\tselect {\n\t\t\tcase <-connectedTicker.C:\n\t\t\t\tconnected = rs.client.IsConnected()\n\t\t\tcase <-ctx.Done():\n\t\t\t\tconnectedTicker.Stop()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tconnectedTicker.Stop()\n\n\t\trs.logger.Info(\"Connected to execution client\")\n\n\t\t// log telemetry immediately after we are connected\n\t\tethVersion, err := rs.GetEthVersion(ctx)\n\t\tif err != nil {\n\t\t\trs.logger.Warn(\"Failed to get eth version\", \"err\", err)\n\t\t}\n\t\trs.logTelemetry(ethVersion)\n\n\t\t// then we start reporting at the reportingInterval interval\n\t\tticker := time.NewTicker(rs.reportingInterval)\n\t\tdefer ticker.Stop()\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-ticker.C:\n\t\t\t\t// since the eth client can be updated separately for beacon\n\t\t\t\t// node\n\t\t\t\t// we need to fetch the version every time\n\t\t\t\tethVersion, err = rs.GetEthVersion(ctx)\n\t\t\t\tif err != nil {\n\t\t\t\t\trs.logger.Warn(\"Failed to get eth version\", \"err\", err)\n\t\t\t\t}\n\n\t\t\t\t// print to console and log telemetry\n\t\t\t\trs.printToConsole(ethVersion)\n\t\t\t\trs.logTelemetry(ethVersion)\n\n\t\t\t\tcontinue\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\n\treturn nil\n}\n\nfunc (rs *ReportingService) Stop() error {\n\treturn nil\n}\n\nfunc (rs *ReportingService) printToConsole(\n\tethClient engineprimitives.ClientVersionV1) {\n\trs.logger.Info(fmt.Sprintf(`\n\n\n\t+==========================================================================+\n\t+ ⭐️ Star BeaconKit on GitHub @ https://github.com/berachain/beacon-kit    +\n\t+ 🧩 Your node is running version: %-40s+\n\t+ ♦ Eth client: %-59s+\n\t+ 💾 Your system: %-57s+\n\t+ 🍴 Deneb1 Fork Time: %-52d+\n\t+ 🍴 Electra Fork Time: %-51d+\n\t+ 🍴 Electra1 Fork Time: %-50d+\n\t+ 🦺 Please report issues @ https://github.com/berachain/beacon-kit/issues +\n\t+==========================================================================+\n\n\n`,\n\t\trs.version,\n\t\tfmt.Sprintf(\"%s (version: %s)\", ethClient.Name, ethClient.Version),\n\t\truntime.GOOS+\"/\"+runtime.GOARCH,\n\t\trs.forkSpec.Deneb1ForkTime(),\n\t\trs.forkSpec.ElectraForkTime(),\n\t\trs.forkSpec.Electra1ForkTime(),\n\t))\n}\n\nfunc (rs *ReportingService) GetEthVersion(\n\tctx context.Context) (engineprimitives.ClientVersionV1, error) {\n\tethVersion := engineprimitives.ClientVersionV1{\n\t\tVersion: \"unknown\",\n\t\tName:    \"unknown\",\n\t}\n\n\tif rs.client.HasCapability(ethclient.GetClientVersionV1) {\n\t\t// Get the client version from the execution layer.\n\t\tinfo, err := rs.client.GetClientVersionV1(ctx)\n\t\tif err != nil {\n\t\t\treturn ethVersion, fmt.Errorf(\n\t\t\t\t\"failed to get client version: %w\",\n\t\t\t\terr,\n\t\t\t)\n\t\t}\n\n\t\t// the spec says we should have at least one client version\n\t\tif len(info) == 0 {\n\t\t\treturn ethVersion, errors.New(\"no client version returned\")\n\t\t}\n\n\t\tethVersion.Version = info[0].Version\n\t\tethVersion.Name = info[0].Name\n\t} else {\n\t\trs.logger.Warn(\"Client does not have capability to get client version\")\n\t}\n\n\treturn ethVersion, nil\n}\n\nfunc (rs *ReportingService) logTelemetry(\n\tethVersion engineprimitives.ClientVersionV1) {\n\tsystemInfo := runtime.GOOS + \"/\" + runtime.GOARCH\n\n\t// TODO: Delete this counter as it should be included in the new\n\t// beacon_kit.runtime.version metric.\n\trs.sink.IncrementCounter(\n\t\t\"beacon_kit.runtime.version.reported\",\n\t\t\"version\", rs.version, \"system\", systemInfo,\n\t)\n\n\trs.logger.Info(\"Reporting version\", \"version\", rs.version,\n\t\t\"system\", systemInfo,\n\t\t\"eth_version\", ethVersion.Version,\n\t\t\"eth_name\", ethVersion.Name)\n\n\t// Report the version to the telemetry sink and include labels\n\t// for beacon node version and eth name and version\n\tvar args = [8]string{\n\t\t\"version\", rs.version,\n\t\t\"system\", systemInfo,\n\t\t\"eth_version\", ethVersion.Version,\n\t\t\"eth_name\", ethVersion.Name,\n\t}\n\trs.sink.SetGauge(\"beacon_kit.runtime.version\", 1, args[:]...)\n}\n"
  },
  {
    "path": "node-core/types/mocks/consensus_service.mock.go",
    "content": "// Code generated by mockery v2.53.5. DO NOT EDIT.\n\npackage mocks\n\nimport (\n\tcontext \"context\"\n\n\tcometbfttypes \"github.com/cometbft/cometbft/types\"\n\tmock \"github.com/stretchr/testify/mock\"\n\n\ttypes \"github.com/cosmos/cosmos-sdk/types\"\n)\n\n// ConsensusService is an autogenerated mock type for the ConsensusService type\ntype ConsensusService struct {\n\tmock.Mock\n}\n\ntype ConsensusService_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *ConsensusService) EXPECT() *ConsensusService_Expecter {\n\treturn &ConsensusService_Expecter{mock: &_m.Mock}\n}\n\n// CreateQueryContext provides a mock function with given fields: height, prove\nfunc (_m *ConsensusService) CreateQueryContext(height int64, prove bool) (types.Context, error) {\n\tret := _m.Called(height, prove)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for CreateQueryContext\")\n\t}\n\n\tvar r0 types.Context\n\tvar r1 error\n\tif rf, ok := ret.Get(0).(func(int64, bool) (types.Context, error)); ok {\n\t\treturn rf(height, prove)\n\t}\n\tif rf, ok := ret.Get(0).(func(int64, bool) types.Context); ok {\n\t\tr0 = rf(height, prove)\n\t} else {\n\t\tr0 = ret.Get(0).(types.Context)\n\t}\n\n\tif rf, ok := ret.Get(1).(func(int64, bool) error); ok {\n\t\tr1 = rf(height, prove)\n\t} else {\n\t\tr1 = ret.Error(1)\n\t}\n\n\treturn r0, r1\n}\n\n// ConsensusService_CreateQueryContext_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateQueryContext'\ntype ConsensusService_CreateQueryContext_Call struct {\n\t*mock.Call\n}\n\n// CreateQueryContext is a helper method to define mock.On call\n//   - height int64\n//   - prove bool\nfunc (_e *ConsensusService_Expecter) CreateQueryContext(height interface{}, prove interface{}) *ConsensusService_CreateQueryContext_Call {\n\treturn &ConsensusService_CreateQueryContext_Call{Call: _e.mock.On(\"CreateQueryContext\", height, prove)}\n}\n\nfunc (_c *ConsensusService_CreateQueryContext_Call) Run(run func(height int64, prove bool)) *ConsensusService_CreateQueryContext_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(int64), args[1].(bool))\n\t})\n\treturn _c\n}\n\nfunc (_c *ConsensusService_CreateQueryContext_Call) Return(_a0 types.Context, _a1 error) *ConsensusService_CreateQueryContext_Call {\n\t_c.Call.Return(_a0, _a1)\n\treturn _c\n}\n\nfunc (_c *ConsensusService_CreateQueryContext_Call) RunAndReturn(run func(int64, bool) (types.Context, error)) *ConsensusService_CreateQueryContext_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// GetBlock provides a mock function with given fields: height\nfunc (_m *ConsensusService) GetBlock(height int64) *cometbfttypes.Block {\n\tret := _m.Called(height)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetBlock\")\n\t}\n\n\tvar r0 *cometbfttypes.Block\n\tif rf, ok := ret.Get(0).(func(int64) *cometbfttypes.Block); ok {\n\t\tr0 = rf(height)\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(*cometbfttypes.Block)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// ConsensusService_GetBlock_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetBlock'\ntype ConsensusService_GetBlock_Call struct {\n\t*mock.Call\n}\n\n// GetBlock is a helper method to define mock.On call\n//   - height int64\nfunc (_e *ConsensusService_Expecter) GetBlock(height interface{}) *ConsensusService_GetBlock_Call {\n\treturn &ConsensusService_GetBlock_Call{Call: _e.mock.On(\"GetBlock\", height)}\n}\n\nfunc (_c *ConsensusService_GetBlock_Call) Run(run func(height int64)) *ConsensusService_GetBlock_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(int64))\n\t})\n\treturn _c\n}\n\nfunc (_c *ConsensusService_GetBlock_Call) Return(_a0 *cometbfttypes.Block) *ConsensusService_GetBlock_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *ConsensusService_GetBlock_Call) RunAndReturn(run func(int64) *cometbfttypes.Block) *ConsensusService_GetBlock_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// GetSignedHeader provides a mock function with given fields: height\nfunc (_m *ConsensusService) GetSignedHeader(height int64) *cometbfttypes.SignedHeader {\n\tret := _m.Called(height)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetSignedHeader\")\n\t}\n\n\tvar r0 *cometbfttypes.SignedHeader\n\tif rf, ok := ret.Get(0).(func(int64) *cometbfttypes.SignedHeader); ok {\n\t\tr0 = rf(height)\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(*cometbfttypes.SignedHeader)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// ConsensusService_GetSignedHeader_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSignedHeader'\ntype ConsensusService_GetSignedHeader_Call struct {\n\t*mock.Call\n}\n\n// GetSignedHeader is a helper method to define mock.On call\n//   - height int64\nfunc (_e *ConsensusService_Expecter) GetSignedHeader(height interface{}) *ConsensusService_GetSignedHeader_Call {\n\treturn &ConsensusService_GetSignedHeader_Call{Call: _e.mock.On(\"GetSignedHeader\", height)}\n}\n\nfunc (_c *ConsensusService_GetSignedHeader_Call) Run(run func(height int64)) *ConsensusService_GetSignedHeader_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(int64))\n\t})\n\treturn _c\n}\n\nfunc (_c *ConsensusService_GetSignedHeader_Call) Return(_a0 *cometbfttypes.SignedHeader) *ConsensusService_GetSignedHeader_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *ConsensusService_GetSignedHeader_Call) RunAndReturn(run func(int64) *cometbfttypes.SignedHeader) *ConsensusService_GetSignedHeader_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// GetSyncData provides a mock function with no fields\nfunc (_m *ConsensusService) GetSyncData() (int64, int64) {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for GetSyncData\")\n\t}\n\n\tvar r0 int64\n\tvar r1 int64\n\tif rf, ok := ret.Get(0).(func() (int64, int64)); ok {\n\t\treturn rf()\n\t}\n\tif rf, ok := ret.Get(0).(func() int64); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tr0 = ret.Get(0).(int64)\n\t}\n\n\tif rf, ok := ret.Get(1).(func() int64); ok {\n\t\tr1 = rf()\n\t} else {\n\t\tr1 = ret.Get(1).(int64)\n\t}\n\n\treturn r0, r1\n}\n\n// ConsensusService_GetSyncData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSyncData'\ntype ConsensusService_GetSyncData_Call struct {\n\t*mock.Call\n}\n\n// GetSyncData is a helper method to define mock.On call\nfunc (_e *ConsensusService_Expecter) GetSyncData() *ConsensusService_GetSyncData_Call {\n\treturn &ConsensusService_GetSyncData_Call{Call: _e.mock.On(\"GetSyncData\")}\n}\n\nfunc (_c *ConsensusService_GetSyncData_Call) Run(run func()) *ConsensusService_GetSyncData_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *ConsensusService_GetSyncData_Call) Return(latestHeight int64, syncToHeight int64) *ConsensusService_GetSyncData_Call {\n\t_c.Call.Return(latestHeight, syncToHeight)\n\treturn _c\n}\n\nfunc (_c *ConsensusService_GetSyncData_Call) RunAndReturn(run func() (int64, int64)) *ConsensusService_GetSyncData_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// IsAppReady provides a mock function with no fields\nfunc (_m *ConsensusService) IsAppReady() error {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for IsAppReady\")\n\t}\n\n\tvar r0 error\n\tif rf, ok := ret.Get(0).(func() error); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tr0 = ret.Error(0)\n\t}\n\n\treturn r0\n}\n\n// ConsensusService_IsAppReady_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsAppReady'\ntype ConsensusService_IsAppReady_Call struct {\n\t*mock.Call\n}\n\n// IsAppReady is a helper method to define mock.On call\nfunc (_e *ConsensusService_Expecter) IsAppReady() *ConsensusService_IsAppReady_Call {\n\treturn &ConsensusService_IsAppReady_Call{Call: _e.mock.On(\"IsAppReady\")}\n}\n\nfunc (_c *ConsensusService_IsAppReady_Call) Run(run func()) *ConsensusService_IsAppReady_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *ConsensusService_IsAppReady_Call) Return(_a0 error) *ConsensusService_IsAppReady_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *ConsensusService_IsAppReady_Call) RunAndReturn(run func() error) *ConsensusService_IsAppReady_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// Name provides a mock function with no fields\nfunc (_m *ConsensusService) Name() string {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for Name\")\n\t}\n\n\tvar r0 string\n\tif rf, ok := ret.Get(0).(func() string); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tr0 = ret.Get(0).(string)\n\t}\n\n\treturn r0\n}\n\n// ConsensusService_Name_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Name'\ntype ConsensusService_Name_Call struct {\n\t*mock.Call\n}\n\n// Name is a helper method to define mock.On call\nfunc (_e *ConsensusService_Expecter) Name() *ConsensusService_Name_Call {\n\treturn &ConsensusService_Name_Call{Call: _e.mock.On(\"Name\")}\n}\n\nfunc (_c *ConsensusService_Name_Call) Run(run func()) *ConsensusService_Name_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *ConsensusService_Name_Call) Return(_a0 string) *ConsensusService_Name_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *ConsensusService_Name_Call) RunAndReturn(run func() string) *ConsensusService_Name_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// Start provides a mock function with given fields: ctx\nfunc (_m *ConsensusService) Start(ctx context.Context) error {\n\tret := _m.Called(ctx)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for Start\")\n\t}\n\n\tvar r0 error\n\tif rf, ok := ret.Get(0).(func(context.Context) error); ok {\n\t\tr0 = rf(ctx)\n\t} else {\n\t\tr0 = ret.Error(0)\n\t}\n\n\treturn r0\n}\n\n// ConsensusService_Start_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Start'\ntype ConsensusService_Start_Call struct {\n\t*mock.Call\n}\n\n// Start is a helper method to define mock.On call\n//   - ctx context.Context\nfunc (_e *ConsensusService_Expecter) Start(ctx interface{}) *ConsensusService_Start_Call {\n\treturn &ConsensusService_Start_Call{Call: _e.mock.On(\"Start\", ctx)}\n}\n\nfunc (_c *ConsensusService_Start_Call) Run(run func(ctx context.Context)) *ConsensusService_Start_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(context.Context))\n\t})\n\treturn _c\n}\n\nfunc (_c *ConsensusService_Start_Call) Return(_a0 error) *ConsensusService_Start_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *ConsensusService_Start_Call) RunAndReturn(run func(context.Context) error) *ConsensusService_Start_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// Stop provides a mock function with no fields\nfunc (_m *ConsensusService) Stop() error {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for Stop\")\n\t}\n\n\tvar r0 error\n\tif rf, ok := ret.Get(0).(func() error); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tr0 = ret.Error(0)\n\t}\n\n\treturn r0\n}\n\n// ConsensusService_Stop_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Stop'\ntype ConsensusService_Stop_Call struct {\n\t*mock.Call\n}\n\n// Stop is a helper method to define mock.On call\nfunc (_e *ConsensusService_Expecter) Stop() *ConsensusService_Stop_Call {\n\treturn &ConsensusService_Stop_Call{Call: _e.mock.On(\"Stop\")}\n}\n\nfunc (_c *ConsensusService_Stop_Call) Run(run func()) *ConsensusService_Stop_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *ConsensusService_Stop_Call) Return(_a0 error) *ConsensusService_Stop_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *ConsensusService_Stop_Call) RunAndReturn(run func() error) *ConsensusService_Stop_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewConsensusService creates a new instance of ConsensusService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewConsensusService(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *ConsensusService {\n\tmock := &ConsensusService{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "node-core/types/node.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"context\"\n\n\t\"cosmossdk.io/store\"\n\t\"github.com/berachain/beacon-kit/beacon/blockchain\"\n\tservice \"github.com/berachain/beacon-kit/node-core/services/registry\"\n\tcmttypes \"github.com/cometbft/cometbft/types\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n)\n\n// Node defines the API for the node application.\n// It extends the Application interface from the Cosmos SDK.\ntype Node interface {\n\tCommitMultistoreAccessor\n\tStorageBackendAccessor\n\n\tStart(context.Context) error\n}\n\n// CommitMultistoreAccessor allows access to the commit multistore.\n// This is required by commands like rollback.\ntype CommitMultistoreAccessor interface {\n\tCommitMultiStore() store.CommitMultiStore\n}\n\n// StorageBackendAccessor allows access to the storage backend.\n// This is required by commands like db-check.\ntype StorageBackendAccessor interface {\n\tStorageBackend() blockchain.StorageBackend\n}\n\n// ConsensusService defines everything we utilise externally from CometBFT.\ntype ConsensusService interface {\n\tservice.Basic\n\n\tIsAppReady() error\n\tCreateQueryContext(height int64, prove bool) (sdk.Context, error)\n\tGetSyncData() (latestHeight int64, syncToHeight int64)\n\t// GetBlock returns the CometBFT block at the given height.\n\tGetBlock(height int64) *cmttypes.Block\n\t// GetSignedHeader returns the CometBFT signed header (header + commit) at the given height.\n\tGetSignedHeader(height int64) *cmttypes.SignedHeader\n}\n"
  },
  {
    "path": "observability/telemetry/service.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage telemetry\n\nimport (\n\t\"context\"\n\n\t\"github.com/cosmos/cosmos-sdk/telemetry\"\n)\n\ntype Config = telemetry.Config\n\n// Service is a telemetry service.\ntype Service struct {\n\tm *telemetry.Metrics\n}\n\n// NewService creates a new telemetry service.\nfunc NewService(cfg *telemetry.Config) (*Service, error) {\n\tm, err := telemetry.New(*cfg)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Service{\n\t\tm: m,\n\t}, nil\n}\n\n// Name returns the service name.\nfunc (s *Service) Name() string {\n\treturn \"telemetry\"\n}\n\n// Start starts the telemetry service.\nfunc (s *Service) Start(context.Context) error {\n\treturn nil\n}\n\nfunc (s *Service) Stop() error {\n\treturn nil\n}\n"
  },
  {
    "path": "payload/README.md",
    "content": "# payload module\n"
  },
  {
    "path": "payload/attributes/factory.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage attributes\n\nimport (\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// Factory is a factory for creating payload attributes.\ntype Factory struct {\n\t// chainSpec is the chain spec for the attributes factory.\n\tchainSpec ChainSpec\n\t// logger is the logger for the attributes factory.\n\tlogger log.Logger\n\t// suggestedFeeRecipient is the suggested fee recipient sent to\n\t// the execution client for the payload build.\n\tsuggestedFeeRecipient common.ExecutionAddress\n}\n\n// NewAttributesFactory creates a new instance of AttributesFactory.\nfunc NewAttributesFactory(\n\tchainSpec ChainSpec,\n\tlogger log.Logger,\n\tsuggestedFeeRecipient common.ExecutionAddress,\n) *Factory {\n\treturn &Factory{\n\t\tchainSpec:             chainSpec,\n\t\tlogger:                logger,\n\t\tsuggestedFeeRecipient: suggestedFeeRecipient,\n\t}\n}\n\n// BuildPayloadAttributes creates a new instance of PayloadAttributes.\nfunc (f *Factory) BuildPayloadAttributes(\n\ttimestamp math.U64,\n\tpayloadWithdrawals engineprimitives.Withdrawals,\n\tprevRandao common.Bytes32,\n\tprevHeadRoot common.Root,\n\tparentProposerPubkey *crypto.BLSPubkey,\n) (*engineprimitives.PayloadAttributes, error) {\n\treturn engineprimitives.NewPayloadAttributes(\n\t\tf.chainSpec.ActiveForkVersionForTimestamp(timestamp),\n\t\ttimestamp,\n\t\tprevRandao,\n\t\tf.suggestedFeeRecipient,\n\t\tpayloadWithdrawals,\n\t\tprevHeadRoot,\n\t\tparentProposerPubkey,\n\t)\n}\n"
  },
  {
    "path": "payload/attributes/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage attributes\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\ntype ChainSpec interface {\n\tActiveForkVersionForTimestamp(timestamp math.U64) common.Version\n\tEpochsPerHistoricalVector() uint64\n\tSlotToEpoch(slot math.Slot) math.Epoch\n}\n"
  },
  {
    "path": "payload/builder/builder.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage builder\n\nimport (\n\t\"sync\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// PayloadBuilder is used to build payloads on the\n// execution client.\ntype PayloadBuilder struct {\n\t// cfg holds the configuration settings for the PayloadBuilder.\n\tcfg *Config\n\t// chainSpec holds the chain specifications for the PayloadBuilder.\n\tchainSpec ChainSpec\n\t// logger is used for logging within the PayloadBuilder.\n\tlogger log.Logger\n\t// ee is the execution engine.\n\tee ExecutionEngine\n\t// pc is the payload ID cache, it is used to store\n\t// \"in-flight\" payloads that are being built on\n\t// the execution client.\n\tpc PayloadCache\n\t// attributesFactory is used to create attributes for the\n\tattributesFactory AttributesFactory\n\n\t// latestEnvelope caches the latest verified payload, so that\n\t// it can be re-issued if the verified payload is not finalized\n\t// and node is requested to build a block. This helps respecting\n\t// FCU invariants (can't ask to build Nth block if N+1th has already\n\t// being requested )\n\tmuEnv              sync.RWMutex\n\tlatestEnvelopeSlot math.Slot\n\tlatestEnvelope     ctypes.BuiltExecutionPayloadEnv\n}\n\n// New creates a new service.\nfunc New(\n\tcfg *Config,\n\tchainSpec ChainSpec,\n\tlogger log.Logger,\n\tee ExecutionEngine,\n\tpc PayloadCache,\n\taf AttributesFactory,\n) *PayloadBuilder {\n\treturn &PayloadBuilder{\n\t\tcfg:               cfg,\n\t\tchainSpec:         chainSpec,\n\t\tlogger:            logger,\n\t\tee:                ee,\n\t\tpc:                pc,\n\t\tattributesFactory: af,\n\t}\n}\n\n// Enabled returns true if the payload builder is enabled.\nfunc (pb *PayloadBuilder) Enabled() bool {\n\treturn pb.cfg.Enabled\n}\n"
  },
  {
    "path": "payload/builder/config.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage builder\n\nimport (\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n)\n\nconst (\n\t// defaultPayloadTimeout is the default value for local build\n\t// payload timeout.\n\tdefaultPayloadTimeout = 850 * time.Millisecond\n)\n\n// Config is the configuration for the payload builder.\ntype Config struct {\n\t// Enabled determines if the local builder is enabled.\n\tEnabled bool `mapstructure:\"enabled\"`\n\t// SuggestedFeeRecipient is the address that will receive the transaction\n\t// fees produced by any blocks from this node.\n\tSuggestedFeeRecipient common.ExecutionAddress `mapstructure:\"suggested-fee-recipient\"`\n\t// PayloadTimeout is the timeout parameter for local build\n\t// payload. This should match, or be slightly less than the configured\n\t// timeout on your execution client. It also must be less than\n\t// timeout_proposal in the CometBFT configuration.\n\tPayloadTimeout time.Duration `mapstructure:\"payload-timeout\"`\n}\n\n// DefaultConfig returns the default fork configuration.\nfunc DefaultConfig() Config {\n\treturn Config{\n\t\tEnabled:               true,\n\t\tSuggestedFeeRecipient: common.ExecutionAddress{},\n\t\tPayloadTimeout:        defaultPayloadTimeout,\n\t}\n}\n"
  },
  {
    "path": "payload/builder/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage builder\n\nimport \"github.com/berachain/beacon-kit/errors\"\n\nvar (\n\t// ErrPayloadBuilderDisabled is returned when the payload builder is\n\t// disabled.\n\tErrPayloadBuilderDisabled = errors.New(\"payload builder is disabled\")\n\n\t// ErrNilPayloadID is returned when a nil payload ID is received.\n\tErrNilPayloadID = errors.New(\"received nil payload ID\")\n\n\t// ErrPayloadIDNotFound is returned when a payload ID is not found in the\n\t// cache.\n\tErrPayloadIDNotFound = errors.New(\"unable to find payload ID in cache\")\n\n\t// ErrNilWithdrawals is returned when nil withdrawals list is received.\n\tErrNilWithdrawals = errors.New(\"nil withdrawals received from execution client\")\n)\n"
  },
  {
    "path": "payload/builder/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage builder\n\nimport (\n\t\"context\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/payload/cache\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\ntype PayloadCache interface {\n\tGet(slot math.Slot, stateRoot common.Root) (cache.PayloadIDCacheResult, bool)\n\tSet(slot math.Slot, stateRoot common.Root, pid engineprimitives.PayloadID, version common.Version)\n\tDelete(slot math.Slot, stateRoot common.Root)\n}\n\n// AttributesFactory is the interface for the attributes factory.\ntype AttributesFactory interface {\n\tBuildPayloadAttributes(\n\t\ttimestamp math.U64,\n\t\tpayloadWithdrawals engineprimitives.Withdrawals,\n\t\tprevRandao common.Bytes32,\n\t\tprevHeadRoot common.Root,\n\t\tparentProposerPubkey *crypto.BLSPubkey,\n\t) (*engineprimitives.PayloadAttributes, error)\n}\n\n// ExecutionEngine is the interface for the execution engine.\ntype ExecutionEngine interface {\n\t// GetPayload returns the payload and blobs bundle for the given slot.\n\tGetPayload(\n\t\tctx context.Context,\n\t\treq *ctypes.GetPayloadRequest,\n\t) (ctypes.BuiltExecutionPayloadEnv, error)\n\t// NotifyForkchoiceUpdate notifies the execution client of a forkchoice\n\t// update.\n\tNotifyForkchoiceUpdate(\n\t\tctx context.Context,\n\t\treq *ctypes.ForkchoiceUpdateRequest,\n\t) (*engineprimitives.PayloadID, error)\n}\n\ntype ChainSpec interface {\n\tActiveForkVersionForTimestamp(timestamp math.U64) common.Version\n\tSlotToEpoch(slot math.Slot) math.Epoch\n\tEpochsPerHistoricalVector() uint64\n}\n"
  },
  {
    "path": "payload/builder/payload.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage builder\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\tengineerrors \"github.com/berachain/beacon-kit/engine-primitives/errors\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n)\n\ntype RequestPayloadData struct {\n\tSlot                 math.Slot\n\tTimestamp            math.U64\n\tPayloadWithdrawals   engineprimitives.Withdrawals\n\tPrevRandao           common.Bytes32\n\tParentBlockRoot      common.Root\n\tFCState              engineprimitives.ForkchoiceStateV1\n\tParentProposerPubkey *crypto.BLSPubkey // nil for fork versions before Electra1\n}\n\n// RequestPayloadAsync builds a payload for the given slot and\n// returns the payload ID.\nfunc (pb *PayloadBuilder) RequestPayloadAsync(\n\tctx context.Context,\n\tr *RequestPayloadData,\n) (*engineprimitives.PayloadID, common.Version, error) {\n\tif !pb.Enabled() {\n\t\treturn nil, common.Version{}, ErrPayloadBuilderDisabled\n\t}\n\n\tif payloadID, found := pb.pc.Get(r.Slot, r.ParentBlockRoot); found {\n\t\tpb.logger.Info(\n\t\t\t\"aborting payload build; payload already exists in cache\",\n\t\t\t\"for_slot\", r.Slot.Base10(),\n\t\t\t\"parent_block_root\", r.ParentBlockRoot,\n\t\t)\n\t\treturn &payloadID.PayloadID, payloadID.ForkVersion, nil\n\t}\n\n\t// Assemble the payload attributes.\n\tattrs, err := pb.attributesFactory.BuildPayloadAttributes(\n\t\tr.Timestamp,\n\t\tr.PayloadWithdrawals,\n\t\tr.PrevRandao,\n\t\tr.ParentBlockRoot,\n\t\tr.ParentProposerPubkey,\n\t)\n\tif err != nil {\n\t\treturn nil, common.Version{}, err\n\t}\n\n\tforkVersion := pb.chainSpec.ActiveForkVersionForTimestamp(r.Timestamp)\n\t// Submit the forkchoice update to the execution client.\n\treq := ctypes.BuildForkchoiceUpdateRequest(\n\t\t&r.FCState,\n\t\tattrs,\n\t\tforkVersion,\n\t)\n\tpayloadID, err := pb.ee.NotifyForkchoiceUpdate(ctx, req)\n\tif err != nil {\n\t\treturn nil, common.Version{}, fmt.Errorf(\"RequestPayloadAsync failed sending forkchoice update: %w\", err)\n\t}\n\n\t// Only add to cache if we received back a payload ID.\n\tif payloadID != nil {\n\t\tpb.pc.Set(r.Slot, r.ParentBlockRoot, *payloadID, forkVersion)\n\t}\n\n\treturn payloadID, forkVersion, nil\n}\n\n// RequestPayloadSync request a payload for the given slot and\n// blocks until the payload is delivered.\nfunc (pb *PayloadBuilder) RequestPayloadSync(\n\tctx context.Context,\n\tr *RequestPayloadData,\n) (ctypes.BuiltExecutionPayloadEnv, error) {\n\tif !pb.Enabled() {\n\t\treturn nil, ErrPayloadBuilderDisabled\n\t}\n\n\t// Build the payload and wait for the execution client to\n\t// return the payload ID.\n\tpayloadID, forkVersion, err := pb.RequestPayloadAsync(ctx, r)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif payloadID == nil {\n\t\treturn nil, ErrNilPayloadID\n\t}\n\n\t// Wait for the payload to be delivered to the execution client.\n\tpb.logger.Info(\n\t\t\"Waiting for local payload to be delivered to execution client\",\n\t\t\"for_slot\", r.Slot.Base10(), \"timeout\", pb.cfg.PayloadTimeout.String(),\n\t)\n\tselect {\n\tcase <-time.After(pb.cfg.PayloadTimeout):\n\t\t// We want to trigger delivery of the payload to the execution client\n\t\t// before the timestamp expires.\n\t\tbreak\n\tcase <-ctx.Done():\n\t\treturn nil, ctx.Err()\n\t}\n\n\tpayload, err := pb.getPayload(ctx, *payloadID, forkVersion)\n\tif err != nil {\n\t\tif errors.Is(err, engineerrors.ErrUnknownPayload) {\n\t\t\t// We may have cached the payloadID, but the payload have become stale\n\t\t\t// in the EVM, or there could have been other issues forcing the EVM\n\t\t\t// to provide no payload. In both cases we can purge the payloadID as it\n\t\t\t// is not usable anymore.\n\t\t\tpb.pc.Delete(r.Slot, r.ParentBlockRoot)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"failed retrieving payload for ID %x: %w\", *payloadID, err)\n\t}\n\treturn payload, nil\n}\n\n// RetrievePayload attempts to pull a previously built payload\n// by reading a payloadID from the builder's cache. If it fails to\n// retrieve a payload, it will build a new payload and wait for the\n// execution client to return the payload.\nfunc (pb *PayloadBuilder) RetrievePayload(\n\tctx context.Context,\n\tslot math.Slot,\n\tparentBlockRoot common.Root,\n\texpectedForkVersion common.Version,\n) (ctypes.BuiltExecutionPayloadEnv, error) {\n\tif !pb.Enabled() {\n\t\treturn nil, ErrPayloadBuilderDisabled\n\t}\n\n\t// With optimistic block building enabled, multiple payloads can be available\n\t// when it's the proposer turn to build. We select them as follows:\n\t// - First we check if node has already built a payload for the requested slot. If so we use that\n\t// payload; note that such a payload may not be available (no payloadID associated or payload is stale).\n\t// - Secondly we try and reuse the latest payload we verified, even if produced by other validators.\n\t// The reason we have to do this has to do with an ENGINE API invariant: the node\n\t// could be asked to build a block at slot H even if it already verified a block at that slot H.\n\t// This happens if the block passes verification but is not finalized (e.g. due to network issue).\n\t// In such a case, the EVM may not be able to serve a new payload (e.g. if it has received a\n\t// FCU call with FINALIZED == H). To avoiding a failure in building the block\n\t// we reuse a validated payload if it's available\n\t// - Finally if neither of these payloads is available, we signal the block builder to build\n\t// the payload just in time with ErrPayloadIDNotFound error flag\n\tpayloadRes, found := pb.pc.Get(slot, parentBlockRoot)\n\tif !found {\n\t\t// No block built optimistically, try reusing the latest verified payload\n\t\tif verifiedEnvelope := pb.getLatestVerifiedPayload(slot, expectedForkVersion); verifiedEnvelope != nil {\n\t\t\treturn verifiedEnvelope, nil\n\t\t}\n\n\t\t// ErrPayloadIDNotFound tells to the block builder to build payload just in time\n\t\treturn nil, ErrPayloadIDNotFound\n\t}\n\tif !version.Equals(payloadRes.ForkVersion, expectedForkVersion) {\n\t\tpb.pc.Delete(slot, parentBlockRoot)\n\t\treturn nil, ErrPayloadIDNotFound // force payload rebuild with the right fork\n\t}\n\n\t// Get the payload from the execution client.\n\tenvelope, err := pb.getPayload(ctx, payloadRes.PayloadID, payloadRes.ForkVersion)\n\tif err != nil {\n\t\tif errors.Is(err, engineerrors.ErrUnknownPayload) {\n\t\t\t// We may have cached the payloadID, but the payload have become stale\n\t\t\t// in the EVM, or there could have been other issues. In any case the payloadID\n\t\t\t// can't be reused, so we can drop it.\n\t\t\tpb.pc.Delete(slot, parentBlockRoot)\n\n\t\t\t// Again here we should try reusing the latest verified block.\n\t\t\tif verifiedEnvelope := pb.getLatestVerifiedPayload(slot, expectedForkVersion); verifiedEnvelope != nil {\n\t\t\t\treturn verifiedEnvelope, nil\n\t\t\t}\n\t\t}\n\t\treturn nil, err\n\t}\n\n\t// Minor validations and logging below\n\tpayload := envelope.GetExecutionPayload()\n\tif payload.GetFeeRecipient() != pb.cfg.SuggestedFeeRecipient {\n\t\tpb.logger.Warn(\n\t\t\t\"Payload fee recipient does not match suggested fee recipient - \"+\n\t\t\t\t\"please check both your CL and EL configuration\",\n\t\t\t\"payload_fee_recipient\", payload.GetFeeRecipient(),\n\t\t\t\"suggested_fee_recipient\", pb.cfg.SuggestedFeeRecipient,\n\t\t)\n\t}\n\n\t// log some data\n\targs := []any{\n\t\t\"for_slot\", slot.Base10(),\n\t\t\"override_builder\", envelope.ShouldOverrideBuilder(),\n\t\t\"payload_block_hash\", payload.GetBlockHash(),\n\t\t\"parent_hash\", payload.GetParentHash(),\n\t}\n\tif blobsBundle := envelope.GetBlobsBundle(); blobsBundle != nil {\n\t\targs = append(args, \"num_blobs\", len(blobsBundle.GetBlobs()))\n\t}\n\tpb.logger.Info(\"Payload retrieved from local builder\", args...)\n\n\treturn envelope, err\n}\n\nfunc (pb *PayloadBuilder) CacheLatestVerifiedPayload(\n\tlatestEnvelopeSlot math.Slot,\n\tlatestEnvelope ctypes.BuiltExecutionPayloadEnv,\n) {\n\tpb.muEnv.Lock()\n\tdefer pb.muEnv.Unlock()\n\tpb.latestEnvelopeSlot = latestEnvelopeSlot\n\tpb.latestEnvelope = latestEnvelope\n}\n\n// getLatestVerifiedPayload returns the latest verified payload if it is for the given slot and fork version.\nfunc (pb *PayloadBuilder) getLatestVerifiedPayload(\n\tslot math.Slot,\n\texpectedForkVersion common.Version,\n) ctypes.BuiltExecutionPayloadEnv {\n\tpb.muEnv.RLock()\n\tdefer pb.muEnv.RUnlock()\n\tif pb.latestEnvelope == nil || slot != pb.latestEnvelopeSlot {\n\t\treturn nil\n\t}\n\tpayload := pb.latestEnvelope.GetExecutionPayload()\n\tif payload == nil {\n\t\treturn nil\n\t}\n\tif version.Equals(\n\t\tpb.chainSpec.ActiveForkVersionForTimestamp(payload.GetTimestamp()),\n\t\texpectedForkVersion,\n\t) {\n\t\treturn pb.latestEnvelope\n\t}\n\treturn nil\n}\n\nfunc (pb *PayloadBuilder) getPayload(\n\tctx context.Context,\n\tpayloadID engineprimitives.PayloadID,\n\tforkVersion common.Version,\n) (ctypes.BuiltExecutionPayloadEnv, error) {\n\tenvelope, err := pb.ee.GetPayload(\n\t\tctx,\n\t\t&ctypes.GetPayloadRequest{\n\t\t\tPayloadID:   payloadID,\n\t\t\tForkVersion: forkVersion,\n\t\t},\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// envelope is guaranteed to be non-nil here\n\tif envelope.GetExecutionPayload().Withdrawals == nil {\n\t\treturn nil, ErrNilWithdrawals\n\t}\n\treturn envelope, nil\n}\n"
  },
  {
    "path": "payload/builder/payload_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage builder_test\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/log/noop\"\n\t\"github.com/berachain/beacon-kit/payload/builder\"\n\t\"github.com/berachain/beacon-kit/payload/cache\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestRetrievePayload(t *testing.T) {\n\tt.Parallel()\n\n\tchainSpec, err := spec.MainnetChainSpec()\n\trequire.NoError(t, err)\n\n\tvar (\n\t\tslot            = math.Slot(10)\n\t\tparentBlockRoot = common.Root{0x01}\n\t\tdenebTimestamp  = math.U64(1_737_381_600) // before mainnet Deneb1ForkTime\n\t\tdummyPayloadID  = engineprimitives.PayloadID{0xab}\n\t)\n\n\tvalidEnvelope := &mockExecutionPayloadEnvelope[*engineprimitives.BlobsBundleV1]{\n\t\tExecutionPayload: &ctypes.ExecutionPayload{\n\t\t\tTimestamp:   denebTimestamp,\n\t\t\tWithdrawals: engineprimitives.Withdrawals{},\n\t\t},\n\t\tBlobsBundle: &engineprimitives.BlobsBundleV1{},\n\t}\n\tnilWithdrawalsEnvelope := &mockExecutionPayloadEnvelope[*engineprimitives.BlobsBundleV1]{\n\t\tExecutionPayload: &ctypes.ExecutionPayload{\n\t\t\tTimestamp:   denebTimestamp,\n\t\t\tWithdrawals: nil,\n\t\t},\n\t\tBlobsBundle: &engineprimitives.BlobsBundleV1{},\n\t}\n\tnilPayloadEnvelope := &mockExecutionPayloadEnvelope[*engineprimitives.BlobsBundleV1]{\n\t\tExecutionPayload: nil,\n\t}\n\n\ttests := []struct {\n\t\tname string\n\n\t\t// If non-nil, seed the PayloadIDCache before calling RetrievePayload.\n\t\tcachePayloadID   *engineprimitives.PayloadID\n\t\tcacheForkVersion common.Version\n\n\t\t// Stub response from the execution engine's GetPayload.\n\t\teeEnvelope ctypes.BuiltExecutionPayloadEnv\n\n\t\t// If non-nil, cache as the latest verified payload for the same slot.\n\t\tverifiedEnvelope ctypes.BuiltExecutionPayloadEnv\n\n\t\texpectedForkVersion common.Version\n\t\twantEnvelope        ctypes.BuiltExecutionPayloadEnv\n\t\twantErr             error\n\t}{\n\t\t{\n\t\t\tname:                \"sunny path via PayloadIDCache\",\n\t\t\tcachePayloadID:      &dummyPayloadID,\n\t\t\tcacheForkVersion:    version.Deneb(),\n\t\t\teeEnvelope:          validEnvelope,\n\t\t\texpectedForkVersion: version.Deneb(),\n\t\t\twantEnvelope:        validEnvelope,\n\t\t},\n\t\t{\n\t\t\tname:                \"nil withdrawals list rejected\",\n\t\t\tcachePayloadID:      &dummyPayloadID,\n\t\t\tcacheForkVersion:    version.Deneb(),\n\t\t\teeEnvelope:          nilWithdrawalsEnvelope,\n\t\t\texpectedForkVersion: version.Deneb(),\n\t\t\twantErr:             builder.ErrNilWithdrawals,\n\t\t},\n\t\t{\n\t\t\tname:                \"fallback reuses verified payload on fork version match\",\n\t\t\tverifiedEnvelope:    validEnvelope,\n\t\t\texpectedForkVersion: version.Deneb(),\n\t\t\twantEnvelope:        validEnvelope,\n\t\t},\n\t\t{\n\t\t\tname:                \"fallback rejects verified payload on fork version mismatch\",\n\t\t\tverifiedEnvelope:    validEnvelope,\n\t\t\texpectedForkVersion: version.Electra(),\n\t\t\twantErr:             builder.ErrPayloadIDNotFound,\n\t\t},\n\t\t{\n\t\t\tname:                \"fallback skips verified payload with nil execution payload\",\n\t\t\tverifiedEnvelope:    nilPayloadEnvelope,\n\t\t\texpectedForkVersion: version.Deneb(),\n\t\t\twantErr:             builder.ErrPayloadIDNotFound,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\tee := &stubExecutionEngine{payloadEnvToReturn: tt.eeEnvelope}\n\t\t\tpc := cache.NewPayloadIDCache()\n\t\t\tpb := builder.New(\n\t\t\t\t&builder.Config{Enabled: true},\n\t\t\t\tchainSpec,\n\t\t\t\tnoop.NewLogger[any](),\n\t\t\t\tee,\n\t\t\t\tpc,\n\t\t\t\t&stubAttributesFactory{},\n\t\t\t)\n\n\t\t\tif tt.cachePayloadID != nil {\n\t\t\t\tpc.Set(slot, parentBlockRoot, *tt.cachePayloadID, tt.cacheForkVersion)\n\t\t\t}\n\t\t\tif tt.verifiedEnvelope != nil {\n\t\t\t\tpb.CacheLatestVerifiedPayload(slot, tt.verifiedEnvelope)\n\t\t\t}\n\n\t\t\t//nolint:govet // shadow err so that parallel tests do not overwrite err.\n\t\t\tenvelope, err := pb.RetrievePayload(t.Context(), slot, parentBlockRoot, tt.expectedForkVersion)\n\t\t\tif tt.wantErr != nil {\n\t\t\t\trequire.ErrorIs(t, err, tt.wantErr)\n\t\t\t\treturn\n\t\t\t}\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tt.wantEnvelope, envelope)\n\t\t})\n\t}\n}\n\n// HELPERS section\n\ntype mockExecutionPayloadEnvelope[BlobsBundleT engineprimitives.BlobsBundle] struct {\n\tExecutionPayload  *ctypes.ExecutionPayload         `json:\"executionPayload\"`\n\tBlockValue        *math.U256                       `json:\"blockValue\"`\n\tBlobsBundle       BlobsBundleT                     `json:\"blobsBundle\"`\n\tExecutionRequests []ctypes.EncodedExecutionRequest `json:\"executionRequests\"`\n\tOverride          bool                             `json:\"shouldOverrideBuilder\"`\n}\n\nfunc (m mockExecutionPayloadEnvelope[BlobsBundleT]) GetExecutionPayload() *ctypes.ExecutionPayload {\n\treturn m.ExecutionPayload\n}\n\nfunc (m mockExecutionPayloadEnvelope[BlobsBundleT]) GetBlockValue() *math.U256 {\n\treturn m.BlockValue\n}\n\nfunc (m mockExecutionPayloadEnvelope[BlobsBundleT]) GetBlobsBundle() engineprimitives.BlobsBundle {\n\treturn m.BlobsBundle\n}\n\nfunc (m mockExecutionPayloadEnvelope[BlobsBundleT]) GetEncodedExecutionRequests() []ctypes.EncodedExecutionRequest {\n\treturn m.ExecutionRequests\n}\n\nfunc (m mockExecutionPayloadEnvelope[BlobsBundleT]) ShouldOverrideBuilder() bool {\n\treturn m.Override\n}\n\nvar errStubNotImplemented = errors.New(\"stub not implemented\")\n\ntype stubExecutionEngine struct {\n\tpayloadEnvToReturn ctypes.BuiltExecutionPayloadEnv\n\terrToReturn        error\n}\n\nfunc (ee *stubExecutionEngine) GetPayload(\n\tcontext.Context, *ctypes.GetPayloadRequest,\n) (ctypes.BuiltExecutionPayloadEnv, error) {\n\treturn ee.payloadEnvToReturn, ee.errToReturn\n}\n\nfunc (ee *stubExecutionEngine) NotifyForkchoiceUpdate(\n\tcontext.Context, *ctypes.ForkchoiceUpdateRequest,\n) (*engineprimitives.PayloadID, error) {\n\treturn nil, errStubNotImplemented\n}\n\ntype stubAttributesFactory struct{}\n\nfunc (ee *stubAttributesFactory) BuildPayloadAttributes(\n\tmath.U64, engineprimitives.Withdrawals, common.Bytes32, common.Root, *crypto.BLSPubkey,\n) (*engineprimitives.PayloadAttributes, error) {\n\treturn nil, errStubNotImplemented\n}\n"
  },
  {
    "path": "payload/cache/payload_id.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage cache\n\nimport (\n\t\"sync\"\n\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// historicalPayloadIDCacheSize defines the maximum number of slots to retain\n// in the cache. Beyond this number, older slots will be pruned to manage\n// memory usage.\nconst historicalPayloadIDCacheSize = 2\n\n// PayloadIDCache provides a mechanism to store and retrieve payload IDs based\n// on slot and parent block hash. It is designed to improve the efficiency of\n// payload ID retrieval by caching recent entries.\ntype PayloadIDCache struct {\n\t// mu protects access to the slotToBlockRootToPayloadID map.\n\tmu sync.RWMutex\n\t// slotToBlockRootToPayloadID is used for storing payload ID mappings\n\tslotToBlockRootToPayloadID map[payloadIDCacheKey]PayloadIDCacheResult\n}\n\n// payloadIDCacheKey is the (slot, root) tuple that is used to access a\n// payloadID from the cache.\ntype payloadIDCacheKey struct {\n\tslot math.Slot\n\troot common.Root\n}\n\ntype PayloadIDCacheResult struct {\n\tPayloadID   engineprimitives.PayloadID\n\tForkVersion common.Version\n}\n\n// NewPayloadIDCache initializes and returns a new instance of PayloadIDCache.\n// It prepares the internal data structures for storing payload ID mappings.\nfunc NewPayloadIDCache() *PayloadIDCache {\n\treturn &PayloadIDCache{\n\t\tmu: sync.RWMutex{},\n\t\tslotToBlockRootToPayloadID: make(\n\t\t\tmap[payloadIDCacheKey]PayloadIDCacheResult,\n\t\t),\n\t}\n}\n\n// Has retrieves the payload ID associated with a given slot and eth1 hash.\n// Has checks if a payload ID exists for a given slot and eth1 hash.\nfunc (p *PayloadIDCache) Has(\n\tslot math.Slot,\n\tblockRoot common.Root,\n) bool {\n\tp.mu.RLock()\n\tdefer p.mu.RUnlock()\n\t_, ok := p.slotToBlockRootToPayloadID[payloadIDCacheKey{slot, blockRoot}]\n\treturn ok\n}\n\n// Get retrieves the payloadID from the cache. It does *not* evict\n// payloadID from the cache upon successful retrieval. Clearing the cache is\n// done via Delete and via pruning in Set.\nfunc (p *PayloadIDCache) Get(\n\tslot math.Slot,\n\tblockRoot common.Root,\n) (PayloadIDCacheResult, bool) {\n\tp.mu.RLock()\n\tdefer p.mu.RUnlock()\n\tkey := payloadIDCacheKey{slot, blockRoot}\n\tpid, ok := p.slotToBlockRootToPayloadID[key]\n\tif !ok {\n\t\treturn PayloadIDCacheResult{}, false\n\t}\n\treturn pid, true\n}\n\n// Set updates or inserts a payload ID for a given slot and eth1 hash.\n// It also prunes entries in the cache that are older than the\n// historicalPayloadIDCacheSize limit.\nfunc (p *PayloadIDCache) Set(\n\tslot math.Slot, blockRoot common.Root,\n\tpid engineprimitives.PayloadID, version common.Version,\n) {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\n\t// Prune older slots to maintain the cache size limit.\n\tif slot >= historicalPayloadIDCacheSize {\n\t\tp.prunePrior(slot - historicalPayloadIDCacheSize)\n\t}\n\n\t// Update the cache with the new payload ID.\n\tp.slotToBlockRootToPayloadID[payloadIDCacheKey{slot, blockRoot}] = PayloadIDCacheResult{\n\t\tPayloadID:   pid,\n\t\tForkVersion: version,\n\t}\n}\n\n// Delete deletes a payload ID from the cache if it exists.\nfunc (p *PayloadIDCache) Delete(\n\tslot math.Slot,\n\tblockRoot common.Root,\n) {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tdelete(p.slotToBlockRootToPayloadID, payloadIDCacheKey{slot, blockRoot})\n}\n\n// prunePrior removes payload IDs from the cache for slots less than\n// the specified slot. This method helps in managing the memory usage\n// of the cache by discarding outdated entries.\nfunc (p *PayloadIDCache) prunePrior(slot math.Slot) {\n\tfor s := range p.slotToBlockRootToPayloadID {\n\t\tif s.slot < slot {\n\t\t\tdelete(p.slotToBlockRootToPayloadID, s)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "payload/cache/payload_id_fuzz_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage cache_test\n\nimport (\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/payload/cache\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc FuzzPayloadIDCacheBasic(f *testing.F) {\n\tf.Add(uint64(1), []byte{1, 2, 3}, []byte{1, 2, 3, 4, 5, 6, 7, 8})\n\tf.Add(uint64(2), []byte{4, 5, 6}, []byte{9, 10, 11, 12, 13, 14, 15, 16})\n\tf.Add(uint64(3), []byte{7, 8, 9}, []byte{17, 18, 19, 20, 21, 22, 23, 24})\n\tf.Fuzz(func(t *testing.T, s uint64, _r, _p []byte) {\n\t\tvar r [32]byte\n\t\tcopy(r[:], _r)\n\t\tslot := math.Slot(s)\n\t\tpid := engineprimitives.PayloadID(_p[:8])\n\t\tcacheUnderTest := cache.NewPayloadIDCache()\n\t\tcacheUnderTest.Set(slot, r, pid, version.Deneb())\n\n\t\tp, ok := cacheUnderTest.Get(slot, r)\n\t\trequire.True(t, ok)\n\t\trequire.Equal(t, pid, p.PayloadID)\n\n\t\t// Test overwriting the same slot and root with a different PayloadID\n\t\tnewPid := engineprimitives.PayloadID{}\n\t\tfor i := range pid {\n\t\t\tnewPid[i] = pid[i] + 1 // Simple mutation for a new PayloadID\n\t\t}\n\t\tcacheUnderTest.Set(slot, r, newPid, version.Deneb())\n\n\t\tp, ok = cacheUnderTest.Get(slot, r)\n\t\trequire.True(t, ok)\n\t\trequire.Equal(\n\t\t\tt, newPid, p.PayloadID, \"PayloadID should be overwritten with the new value\")\n\n\t\t// Verify deletion\n\t\tcacheUnderTest.Delete(slot, r)\n\t\tok = cacheUnderTest.Has(slot, r)\n\t\trequire.False(t, ok, \"Entry should be pruned and not found\")\n\t})\n}\n\nfunc FuzzPayloadIDInvalidInput(f *testing.F) {\n\t// Intentionally invalid inputs\n\tf.Add(uint64(1), []byte{1, 2, 3, 4, 5, 6, 7, 8, 9}, []byte{1, 2, 3})\n\n\tf.Fuzz(func(t *testing.T, s uint64, _r, _p []byte) {\n\t\tvar r [32]byte\n\t\tslot := math.Slot(s)\n\t\tif len(_r) > 32 {\n\t\t\t// Expecting an error or specific handling of oversized input\n\t\t\tt.Skip(\n\t\t\t\t\"Skipping test due to intentionally invalid input size for root.\",\n\t\t\t)\n\t\t}\n\t\tcopy(r[:], _r)\n\t\tvar paddedPayload [8]byte\n\t\tcopy(paddedPayload[:], _p[:min(len(_p), 8)])\n\t\tpid := [8]byte(paddedPayload[:])\n\t\tcacheUnderTest := cache.NewPayloadIDCache()\n\t\tcacheUnderTest.Set(slot, r, pid, version.Deneb())\n\n\t\t_, ok := cacheUnderTest.Get(slot, r)\n\t\trequire.True(t, ok)\n\t})\n}\n\nfunc FuzzPayloadIDCacheConcurrency(f *testing.F) {\n\tf.Add(uint64(1), []byte{1, 2, 3}, []byte{1, 2, 3, 4})\n\n\tf.Fuzz(func(t *testing.T, s uint64, _r, _p []byte) {\n\t\tcacheUnderTest := cache.NewPayloadIDCache()\n\t\tslot := math.Slot(s)\n\t\tvar wg sync.WaitGroup\n\t\twg.Add(2)\n\n\t\t// Set operation in one goroutine\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\tvar r [32]byte\n\t\t\tcopy(r[:], _r)\n\t\t\tvar paddedPayload [8]byte\n\t\t\tcopy(paddedPayload[:], _p[:min(len(_p), 8)])\n\t\t\tpid := [8]byte(paddedPayload[:])\n\t\t\tcacheUnderTest.Set(slot, r, pid, version.Deneb())\n\t\t}()\n\n\t\t// Get operation in another goroutine\n\t\tvar ok bool\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\t\t\ttime.Sleep(\n\t\t\t\t10 * time.Millisecond,\n\t\t\t) // Small delay to let the Set operation proceed\n\t\t\tvar r [32]byte\n\t\t\tcopy(r[:], _r)\n\t\t\t_, ok = cacheUnderTest.Get(slot, r)\n\t\t}()\n\n\t\twg.Wait()\n\t\trequire.True(t, ok)\n\t})\n}\n"
  },
  {
    "path": "payload/cache/payload_id_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage cache_test\n\nimport (\n\t\"testing\"\n\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/payload/cache\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestPayloadIDCache(t *testing.T) {\n\tt.Parallel()\n\tcacheUnderTest := cache.NewPayloadIDCache()\n\n\tt.Run(\"Get from empty cache\", func(t *testing.T) {\n\t\tvar r [32]byte\n\t\tp, ok := cacheUnderTest.Get(0, r)\n\t\trequire.False(t, ok)\n\t\trequire.Equal(t, engineprimitives.PayloadID{}, p.PayloadID)\n\t})\n\n\tt.Run(\"Set and Get\", func(t *testing.T) {\n\t\tslot := math.Slot(1234)\n\t\tr := [32]byte{1, 2, 3}\n\t\tpid := engineprimitives.PayloadID{1, 2, 3, 3, 7, 8, 7, 8}\n\t\tcacheUnderTest.Set(slot, r, pid, version.Deneb())\n\n\t\tp, ok := cacheUnderTest.Get(slot, r)\n\t\trequire.True(t, ok)\n\t\trequire.Equal(t, pid, p.PayloadID)\n\t})\n\n\tt.Run(\"Overwrite existing\", func(t *testing.T) {\n\t\tslot := math.Slot(1234)\n\t\tr := [32]byte{1, 2, 3}\n\t\tnewPid := engineprimitives.PayloadID{9, 9, 9, 9, 9, 9, 9, 9}\n\t\tcacheUnderTest.Set(slot, r, newPid, version.Deneb())\n\n\t\tp, ok := cacheUnderTest.Get(slot, r)\n\t\trequire.True(t, ok)\n\t\trequire.Equal(t, newPid, p.PayloadID)\n\t})\n\n\tt.Run(\"Prune and verify deletion\", func(t *testing.T) {\n\t\tslot := math.Slot(9456456)\n\t\tr := [32]byte{4, 5, 6}\n\t\tpid := engineprimitives.PayloadID{4, 5, 6, 6, 9, 0, 9, 0}\n\t\t// Set pid for slot.\n\t\tcacheUnderTest.Set(slot, r, pid, version.Deneb())\n\n\t\t// Set historicalPayloadIDCacheSize+1 number of pids. This should\n\t\t// prune the first slot from the cache.\n\t\tcacheUnderTest.Set(slot+1, r, pid, version.Deneb())\n\t\tcacheUnderTest.Set(slot+2, r, pid, version.Deneb())\n\t\tcacheUnderTest.Set(slot+3, r, pid, version.Deneb())\n\n\t\t// Attempt to retrieve pruned slot.\n\t\tok := cacheUnderTest.Has(slot, r)\n\t\trequire.False(t, ok)\n\t})\n\n\tt.Run(\"Multiple entries and prune\", func(t *testing.T) {\n\t\tnumEntries := 10\n\t\thistoricalPayloadIDCacheSize := 2\n\t\t// Set multiple entries\n\t\tfor i := range uint8(numEntries) {\n\t\t\tslot := math.Slot(i)\n\t\t\tr := [32]byte{i, i + 1, i + 2}\n\t\t\tpid := [8]byte{\n\t\t\t\ti, i, i, i, i, i, i, i,\n\t\t\t}\n\t\t\tcacheUnderTest.Set(slot, r, pid, version.Deneb())\n\t\t}\n\n\t\t// Only the last historicalPayloadIDCacheSize+1 number of entries\n\t\t// should still exist.\n\t\tfor i := range uint8(numEntries - (historicalPayloadIDCacheSize + 1)) {\n\t\t\tslot := math.Slot(i)\n\t\t\tr := [32]byte{i, i + 1, i + 2}\n\t\t\tok := cacheUnderTest.Has(slot, r)\n\t\t\trequire.False(t, ok, \"Expected entry to be pruned for slot\", slot)\n\t\t}\n\n\t\tfor i := uint8(numEntries - (historicalPayloadIDCacheSize + 1)); i < uint8(numEntries); i++ {\n\t\t\tslot := math.Slot(i)\n\t\t\tr := [32]byte{i, i + 1, i + 2}\n\t\t\tok := cacheUnderTest.Has(slot, r)\n\t\t\trequire.True(t, ok, \"Expected entry to exist for slot\", slot)\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "primitives/bytes/b.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n//\n\npackage bytes\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n)\n\n// Bytes marshals/unmarshals as a JSON string with 0x prefix.\n// The empty slice marshals as \"0x\".\ntype Bytes []byte\n\n// MarshalText implements encoding.TextMarshaler.\nfunc (b Bytes) MarshalText() ([]byte, error) {\n\treturn []byte(hex.EncodeBytes(b)), nil\n}\n\n// UnmarshalJSON implements json.Unmarshaler.\nfunc (b *Bytes) UnmarshalJSON(input []byte) error {\n\tstrippedInput, err := hex.ValidateQuotedString(input)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn b.UnmarshalText(strippedInput)\n}\n\n// UnmarshalText implements encoding.TextUnmarshaler.\nfunc (b *Bytes) UnmarshalText(input []byte) error {\n\tdec, err := hex.UnmarshalByteText(input)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*b = Bytes(dec)\n\treturn nil\n}\n\n// String returns the hex encoding of b.\nfunc (b Bytes) String() string {\n\treturn hex.EncodeBytes(b)\n}\n"
  },
  {
    "path": "primitives/bytes/b20.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n//\n\npackage bytes\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n)\n\nconst (\n\t// B20Size represents a 20-byte size.\n\tB20Size = 20\n)\n\n// B20 represents a 20-byte fixed-size byte array.\n// For SSZ purposes it is serialized a `Vector[Byte, 20]`.\ntype B20 [20]byte\n\n// ToBytes20 is a utility function that transforms a byte slice into a fixed\n// 20-byte array. It errs if input has not the required size.\nfunc ToBytes20(input []byte) (B20, error) {\n\tif len(input) != B20Size {\n\t\treturn B20{}, fmt.Errorf(\n\t\t\t\"%w, got %d, expected %d\",\n\t\t\tErrIncorrectLength,\n\t\t\tlen(input),\n\t\t\tB20Size,\n\t\t)\n\t}\n\treturn B20(input), nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                TextMarshaler                               */\n/* -------------------------------------------------------------------------- */\n\n// MarshalText implements the encoding.TextMarshaler interface for B20.\nfunc (h B20) MarshalText() ([]byte, error) {\n\treturn []byte(h.String()), nil\n}\n\n// UnmarshalText implements the encoding.TextUnmarshaler interface for B20.\nfunc (h *B20) UnmarshalText(text []byte) error {\n\treturn UnmarshalTextHelper(h[:], text)\n}\n\n// String returns the hex string representation of B20.\nfunc (h *B20) String() string {\n\treturn hex.EncodeBytes(h[:])\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                JSONMarshaler                               */\n/* -------------------------------------------------------------------------- */\n\n// UnmarshalJSON implements the json.Unmarshaler interface for B20.\nfunc (h *B20) UnmarshalJSON(input []byte) error {\n\treturn UnmarshalJSONHelper(h[:], input)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                SSZMarshaler                                */\n/* -------------------------------------------------------------------------- */\n\n// MarshalSSZ implements the SSZ marshaling for B20.\nfunc (h B20) MarshalSSZ() ([]byte, error) {\n\treturn h[:], nil\n}\n\n// HashTreeRoot returns the hash tree root of the B20.\nfunc (h B20) HashTreeRoot() (B32, error) {\n\treturn ToBytes32(ExtendToSize(h[:], B32Size))\n}\n"
  },
  {
    "path": "primitives/bytes/b20_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage bytes_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestBytes20MarshalText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname  string\n\t\tinput bytes.B20\n\t\twant  string\n\t}{\n\t\t{\n\t\t\tname: \"valid bytes\",\n\t\t\tinput: bytes.B20{\n\t\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,\n\t\t\t\t0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14},\n\t\t\twant: \"0x0102030405060708090a0b0c0d0e0f1011121314\",\n\t\t},\n\t\t{\n\t\t\tname: \"all zeros\",\n\t\t\tinput: bytes.B20{\n\t\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},\n\t\t\twant: \"0x0000000000000000000000000000000000000000\",\n\t\t},\n\t\t{\n\t\t\tname: \"all ones\",\n\t\t\tinput: bytes.B20{\n\t\t\t\t0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n\t\t\t\t0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},\n\t\t\twant: \"0xffffffffffffffffffffffffffffffffffffffff\",\n\t\t},\n\t\t{\n\t\t\tname: \"mixed bytes\",\n\t\t\tinput: bytes.B20{\n\t\t\t\t0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0x33, 0x44, 0x55,\n\t\t\t\t0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE},\n\t\t\twant: \"0xaabbccddeeff112233445566778899aabbccddee\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot, err := tt.input.MarshalText()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tt.want, string(got))\n\t\t})\n\t}\n}\n\nfunc TestBytes20MarshalSSZ(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname  string\n\t\tinput bytes.B20\n\t\twant  []byte\n\t}{\n\t\t{\n\t\t\tname: \"marshal B20\",\n\t\t\tinput: bytes.B20{\n\t\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,\n\t\t\t\t0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14,\n\t\t\t},\n\t\t\twant: []byte{\n\t\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,\n\t\t\t\t0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14,\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot, err := tt.input.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tt.want, got)\n\t\t})\n\t}\n}\n\nfunc TestBytes20HashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname  string\n\t\tinput bytes.B20\n\t\twant  bytes.B32\n\t}{\n\t\t{\n\t\t\tname: \"hash tree root\",\n\t\t\tinput: bytes.B20{\n\t\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,\n\t\t\t\t0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14,\n\t\t\t},\n\t\t\twant: [32]byte{\n\t\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,\n\t\t\t\t0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14,\n\t\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot, err := tt.input.HashTreeRoot()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tt.want, got)\n\t\t})\n\t}\n}\n\nfunc TestBytes20UnmarshalText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tinput   string\n\t\twant    bytes.B20\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\tname:  \"valid hex\",\n\t\t\tinput: \"0x0102030405060708090a0b0c0d0e0f1011121314\",\n\t\t\twant: bytes.B20{\n\t\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,\n\t\t\t\t0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14},\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid hex\",\n\t\t\tinput:   \"0xZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ\",\n\t\t\twant:    bytes.B20{},\n\t\t\twantErr: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar got bytes.B20\n\t\t\terr := got.UnmarshalText([]byte(tt.input))\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestBytes20UnmarshalJSON(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tinput   string\n\t\twant    bytes.B20\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\tname:  \"valid JSON\",\n\t\t\tinput: \"\\\"0x0102030405060708090a0b0c0d0e0f1011121314\\\"\",\n\t\t\twant: bytes.B20{\n\t\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,\n\t\t\t\t0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14},\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid JSON\",\n\t\t\tinput:   \"\\\"0xZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ\\\"\",\n\t\t\twant:    bytes.B20{},\n\t\t\twantErr: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar got bytes.B20\n\t\t\terr := got.UnmarshalJSON([]byte(tt.input))\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestToBytes20(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tinput   []byte\n\t\twantRes bytes.B20\n\t\twantErr error\n\t}{\n\t\t{\n\t\t\tname: \"exact 20 bytes\",\n\t\t\tinput: []byte{\n\t\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,\n\t\t\t\t0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14,\n\t\t\t},\n\t\t\twantRes: bytes.B20{\n\t\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,\n\t\t\t\t0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14,\n\t\t\t},\n\t\t\twantErr: nil,\n\t\t},\n\t\t{\n\t\t\tname:    \"less than 20 bytes\",\n\t\t\tinput:   []byte{0x01, 0x02, 0x03, 0x04, 0x05},\n\t\t\twantRes: bytes.B20{},\n\t\t\twantErr: bytes.ErrIncorrectLength,\n\t\t},\n\t\t{\n\t\t\tname: \"more than 20 bytes\",\n\t\t\tinput: []byte{\n\t\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,\n\t\t\t\t0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,\n\t\t\t},\n\t\t\twantRes: bytes.B20{},\n\t\t\twantErr: bytes.ErrIncorrectLength,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult, err := bytes.ToBytes20(tt.input)\n\t\t\tif tt.wantErr != nil {\n\t\t\t\trequire.ErrorIs(t, err, tt.wantErr)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.wantRes, result)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "primitives/bytes/b256.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n//\n\npackage bytes\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/prysmaticlabs/gohashtree\"\n)\n\nconst (\n\t// B256Size represents a 256-byte size.\n\tB256Size = 256\n)\n\n// B256 represents a 256-byte fixed-size byte array.\n// For SSZ purposes it is serialized a `Vector[Byte, 256]`.\ntype B256 [256]byte\n\n// ToBytes256 is a utility function that transforms a byte slice into a fixed\n// 256-byte array. It errs if input has not the required size.\nfunc ToBytes256(input []byte) (B256, error) {\n\tif len(input) != B256Size {\n\t\treturn B256{}, fmt.Errorf(\n\t\t\t\"%w, got %d, expected %d\",\n\t\t\tErrIncorrectLength,\n\t\t\tlen(input),\n\t\t\tB256Size,\n\t\t)\n\t}\n\treturn B256(input), nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                TextMarshaler                               */\n/* -------------------------------------------------------------------------- */\n\n// MarshalText implements the encoding.TextMarshaler interface for B256.\nfunc (h B256) MarshalText() ([]byte, error) {\n\treturn []byte(h.String()), nil\n}\n\n// UnmarshalText implements the encoding.TextUnmarshaler interface for B256.\nfunc (h *B256) UnmarshalText(text []byte) error {\n\treturn UnmarshalTextHelper(h[:], text)\n}\n\n// String returns the hex string representation of B256.\nfunc (h *B256) String() string {\n\treturn hex.EncodeBytes(h[:])\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                JSONMarshaler                               */\n/* -------------------------------------------------------------------------- */\n\n// UnmarshalJSON implements the json.Unmarshaler interface for B256.\nfunc (h *B256) UnmarshalJSON(input []byte) error {\n\treturn UnmarshalJSONHelper(h[:], input)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                SSZMarshaler                                */\n/* -------------------------------------------------------------------------- */\n\n// SizeSSZ returns the size of its SSZ encoding in bytes.\nfunc (h B256) SizeSSZ() uint32 {\n\treturn B256Size\n}\n\n// MarshalSSZ implements the SSZ marshaling for B256.\nfunc (h B256) MarshalSSZ() ([]byte, error) {\n\treturn h[:], nil\n}\n\n// HashTreeRoot returns the hash tree root of the B256.\nfunc (h B256) HashTreeRoot() (B32, error) {\n\t//nolint:mnd // for a tree height of 3 we need 8 working chunks.\n\tresult := make([][32]byte, 8)\n\tcopy(result[0][:], h[:32])\n\tcopy(result[1][:], h[32:64])\n\tcopy(result[2][:], h[64:96])\n\tcopy(result[3][:], h[96:128])\n\tcopy(result[4][:], h[128:160])\n\tcopy(result[5][:], h[160:192])\n\tcopy(result[6][:], h[192:224])\n\tcopy(result[7][:], h[224:256])\n\tgohashtree.HashChunks(result, result)\n\tgohashtree.HashChunks(result, result)\n\tgohashtree.HashChunks(result, result)\n\treturn result[0], nil\n}\n"
  },
  {
    "path": "primitives/bytes/b32.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n//\n\npackage bytes\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n)\n\nconst (\n\t// B32Size represents a 32-byte size.\n\tB32Size = 32\n)\n\n// B32 represents a 32-byte fixed-size byte array.\n// For SSZ purposes it is serialized a `Vector[Byte, 32]`.\ntype B32 [B32Size]byte\n\n// ToBytes32 is a utility function that transforms a byte slice into a fixed\n// 32-byte array It errs if input has not the required size.\nfunc ToBytes32(input []byte) (B32, error) {\n\tif len(input) != B32Size {\n\t\treturn B32{}, fmt.Errorf(\n\t\t\t\"%w, got %d, expected %d\",\n\t\t\tErrIncorrectLength,\n\t\t\tlen(input),\n\t\t\tB32Size,\n\t\t)\n\t}\n\treturn B32(input), nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                TextMarshaler                               */\n/* -------------------------------------------------------------------------- */\n\n// MarshalText implements the encoding.TextMarshaler interface for B32.\nfunc (h B32) MarshalText() ([]byte, error) {\n\treturn []byte(h.String()), nil\n}\n\n// UnmarshalText implements the encoding.TextUnmarshaler interface for B32.\nfunc (h *B32) UnmarshalText(text []byte) error {\n\treturn UnmarshalTextHelper(h[:], text)\n}\n\n// String returns the hex string representation of B32.\nfunc (h B32) String() string {\n\treturn hex.EncodeBytes(h[:])\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                JSONMarshaler                               */\n/* -------------------------------------------------------------------------- */\n\n// UnmarshalJSON implements the json.Unmarshaler interface for B32.\nfunc (h *B32) UnmarshalJSON(input []byte) error {\n\treturn UnmarshalJSONHelper(h[:], input)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                SSZMarshaler                                */\n/* -------------------------------------------------------------------------- */\n\n// MarshalSSZ implements the SSZ marshaling for B32.\nfunc (h B32) MarshalSSZ() ([]byte, error) {\n\treturn h[:], nil\n}\n\n// HashTreeRoot returns the hash tree root of the B32.\nfunc (h B32) HashTreeRoot() B32 {\n\treturn h\n}\n"
  },
  {
    "path": "primitives/bytes/b32_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage bytes_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestBytes32UnmarshalText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tinput   string\n\t\twant    bytes.B32\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\tname:  \"valid input\",\n\t\t\tinput: \"0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20\",\n\t\t\twant: bytes.B32{\n\t\t\t\t0x01,\n\t\t\t\t0x02,\n\t\t\t\t0x03,\n\t\t\t\t0x04,\n\t\t\t\t0x05,\n\t\t\t\t0x06,\n\t\t\t\t0x07,\n\t\t\t\t0x08,\n\t\t\t\t0x09,\n\t\t\t\t0x0a,\n\t\t\t\t0x0b,\n\t\t\t\t0x0c,\n\t\t\t\t0x0d,\n\t\t\t\t0x0e,\n\t\t\t\t0x0f,\n\t\t\t\t0x10,\n\t\t\t\t0x11,\n\t\t\t\t0x12,\n\t\t\t\t0x13,\n\t\t\t\t0x14,\n\t\t\t\t0x15,\n\t\t\t\t0x16,\n\t\t\t\t0x17,\n\t\t\t\t0x18,\n\t\t\t\t0x19,\n\t\t\t\t0x1a,\n\t\t\t\t0x1b,\n\t\t\t\t0x1c,\n\t\t\t\t0x1d,\n\t\t\t\t0x1e,\n\t\t\t\t0x1f,\n\t\t\t\t0x20,\n\t\t\t},\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid input - not hex\",\n\t\t\tinput:   \"0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20\",\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid input - wrong length\",\n\t\t\tinput:   \"0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\",\n\t\t\twantErr: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar got bytes.B32\n\t\t\terr := got.UnmarshalText([]byte(tt.input))\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestBytes32UnmarshalJSON(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tinput   string\n\t\twant    bytes.B32\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\tname:  \"valid input\",\n\t\t\tinput: `\"0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20\"`,\n\t\t\twant: bytes.B32{\n\t\t\t\t0x01,\n\t\t\t\t0x02,\n\t\t\t\t0x03,\n\t\t\t\t0x04,\n\t\t\t\t0x05,\n\t\t\t\t0x06,\n\t\t\t\t0x07,\n\t\t\t\t0x08,\n\t\t\t\t0x09,\n\t\t\t\t0x0a,\n\t\t\t\t0x0b,\n\t\t\t\t0x0c,\n\t\t\t\t0x0d,\n\t\t\t\t0x0e,\n\t\t\t\t0x0f,\n\t\t\t\t0x10,\n\t\t\t\t0x11,\n\t\t\t\t0x12,\n\t\t\t\t0x13,\n\t\t\t\t0x14,\n\t\t\t\t0x15,\n\t\t\t\t0x16,\n\t\t\t\t0x17,\n\t\t\t\t0x18,\n\t\t\t\t0x19,\n\t\t\t\t0x1a,\n\t\t\t\t0x1b,\n\t\t\t\t0x1c,\n\t\t\t\t0x1d,\n\t\t\t\t0x1e,\n\t\t\t\t0x1f,\n\t\t\t\t0x20,\n\t\t\t},\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid input - not hex\",\n\t\t\tinput:   `\"0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20\"`,\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid input - wrong length\",\n\t\t\tinput:   `\"0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\"`,\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid input - extra characters\",\n\t\t\tinput:   `\"0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122\"`,\n\t\t\twantErr: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar got bytes.B32\n\t\t\terr := got.UnmarshalJSON([]byte(tt.input))\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestBytes32MarshalText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname  string\n\t\tinput bytes.B32\n\t\twant  string\n\t}{\n\t\t{\n\t\t\tname: \"valid input\",\n\t\t\tinput: bytes.B32{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,\n\t\t\t\t0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,\n\t\t\t\t0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,\n\t\t\t\t0x1e, 0x1f, 0x20},\n\t\t\twant: \"0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20\",\n\t\t},\n\t\t{\n\t\t\tname:  \"empty input\",\n\t\t\tinput: bytes.B32{},\n\t\t\twant:  \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot, err := tt.input.MarshalText()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tt.want, string(got))\n\t\t})\n\t}\n}\n\nfunc TestBytes32String(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname  string\n\t\tinput bytes.B32\n\t\twant  string\n\t}{\n\t\t{\n\t\t\tname: \"valid input\",\n\t\t\tinput: bytes.B32{0x01, 0x02, 0x03, 0x04, 0x05, 0x06,\n\t\t\t\t0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,\n\t\t\t\t0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,\n\t\t\t\t0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20},\n\t\t\twant: \"0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20\",\n\t\t},\n\t\t{\n\t\t\tname:  \"empty input\",\n\t\t\tinput: bytes.B32{},\n\t\t\twant:  \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot := tt.input.String()\n\t\t\trequire.Equal(t, tt.want, got)\n\t\t})\n\t}\n}\n\nfunc TestToBytes32(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tinput   []byte\n\t\twantRes bytes.B32\n\t\twantErr error\n\t}{\n\t\t{\n\t\t\tname:    \"Input less than 32 bytes\",\n\t\t\tinput:   []byte{1, 2, 3},\n\t\t\twantRes: bytes.B32{},\n\t\t\twantErr: bytes.ErrIncorrectLength,\n\t\t},\n\t\t{\n\t\t\tname:    \"Input exactly 32 bytes\",\n\t\t\tinput:   make([]byte, 32),\n\t\t\twantRes: bytes.B32{},\n\t\t\twantErr: nil,\n\t\t},\n\t\t{\n\t\t\tname:    \"Input more than 32 bytes\",\n\t\t\tinput:   make([]byte, 40),\n\t\t\twantRes: bytes.B32{},\n\t\t\twantErr: bytes.ErrIncorrectLength,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult, err := bytes.ToBytes32(tt.input)\n\t\t\tif tt.wantErr != nil {\n\t\t\t\trequire.ErrorIs(t, err, tt.wantErr)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.wantRes, result)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestB32MarshalSSZ(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname  string\n\t\tinput bytes.B32\n\t\twant  []byte\n\t}{\n\t\t{\n\t\t\tname: \"valid bytes\",\n\t\t\tinput: bytes.B32{\n\t\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,\n\t\t\t\t0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,\n\t\t\t\t0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20},\n\t\t\twant: []byte{\n\t\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,\n\t\t\t\t0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,\n\t\t\t\t0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot, err := tt.input.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tt.want, got)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "primitives/bytes/b4.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n//\n\npackage bytes\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n)\n\nconst (\n\t// B4Size represents a 4-byte size.\n\tB4Size = 4\n)\n\n// B4 represents a 4-byte fixed-size byte array.\n// For SSZ purposes it is serialized a `Vector[Byte, 4]`.\ntype B4 [4]byte\n\n// ToBytes4 is a utility function that transforms a byte slice into a fixed\n// 4-byte array. It errs if input has not the required size.\nfunc ToBytes4(input []byte) (B4, error) {\n\tif len(input) != B4Size {\n\t\treturn B4{}, fmt.Errorf(\n\t\t\t\"%w, got %d, expected %d\",\n\t\t\tErrIncorrectLength,\n\t\t\tlen(input),\n\t\t\tB4Size,\n\t\t)\n\t}\n\treturn B4(input), nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                TextMarshaler                               */\n/* -------------------------------------------------------------------------- */\n\n// MarshalText implements the encoding.TextMarshaler interface for B4.\nfunc (h B4) MarshalText() ([]byte, error) {\n\treturn []byte(h.String()), nil\n}\n\n// UnmarshalText implements the encoding.TextUnmarshaler interface for B4.\nfunc (h *B4) UnmarshalText(text []byte) error {\n\treturn UnmarshalTextHelper(h[:], text)\n}\n\n// String returns the hex string representation of B4.\nfunc (h B4) String() string {\n\treturn hex.EncodeBytes(h[:])\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                JSONMarshaler                               */\n/* -------------------------------------------------------------------------- */\n\n// UnmarshalJSON implements the json.Unmarshaler interface for B4.\nfunc (h *B4) UnmarshalJSON(input []byte) error {\n\treturn UnmarshalJSONHelper(h[:], input)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                SSZMarshaler                                */\n/* -------------------------------------------------------------------------- */\n\n// MarshalSSZ implements the SSZ marshaling for B8.\nfunc (h B4) MarshalSSZ() ([]byte, error) {\n\treturn h[:], nil\n}\n\n// HashTreeRoot returns the hash tree root of the B8.\nfunc (h B4) HashTreeRoot() (B32, error) {\n\treturn ToBytes32(ExtendToSize(h[:], B32Size))\n}\n\n/* -------------------------------------------------------------------------- */\n/*                            uint32 conversion                               */\n/* -------------------------------------------------------------------------- */\n\n// FromUint32 returns a new B4 from a uint32.\nfunc FromUint32(v uint32) B4 {\n\th := B4{}\n\tbinary.LittleEndian.PutUint32(h[:], v)\n\treturn h\n}\n\n// ToUint32 returns a new uint32 from a B4.\nfunc (h B4) ToUint32() uint32 {\n\treturn binary.LittleEndian.Uint32(h[:])\n}\n"
  },
  {
    "path": "primitives/bytes/b48.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n//\n\npackage bytes\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/prysmaticlabs/gohashtree\"\n)\n\nconst (\n\t// B48Size represents a 48-byte size.\n\tB48Size = 48\n)\n\n// B48 represents a 48-byte fixed-size byte array.\n// For SSZ purposes it is serialized a `Vector[Byte, 48]`.\ntype B48 [48]byte\n\n// ToBytes48 is a utility function that transforms a byte slice into a fixed\n// 48-byte array. It errs if input has not the required size.\nfunc ToBytes48(input []byte) (B48, error) {\n\tif len(input) != B48Size {\n\t\treturn B48{}, fmt.Errorf(\n\t\t\t\"%w, got %d, expected %d\",\n\t\t\tErrIncorrectLength,\n\t\t\tlen(input),\n\t\t\tB48Size,\n\t\t)\n\t}\n\treturn B48(input), nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                TextMarshaler                               */\n/* -------------------------------------------------------------------------- */\n\n// MarshalText implements the encoding.TextMarshaler interface for B48.\nfunc (h B48) MarshalText() ([]byte, error) {\n\treturn []byte(h.String()), nil\n}\n\n// UnmarshalText implements the encoding.TextUnmarshaler interface for B48.\nfunc (h *B48) UnmarshalText(text []byte) error {\n\treturn UnmarshalTextHelper(h[:], text)\n}\n\n// String returns the hex string representation of B48.\nfunc (h B48) String() string {\n\treturn hex.EncodeBytes(h[:])\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                JSONMarshaler                               */\n/* -------------------------------------------------------------------------- */\n\n// UnmarshalJSON implements the json.Unmarshaler interface for B48.\nfunc (h *B48) UnmarshalJSON(input []byte) error {\n\treturn UnmarshalJSONHelper(h[:], input)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                SSZMarshaler                                */\n/* -------------------------------------------------------------------------- */\n\n// MarshalSSZ implements the SSZ marshaling for B48.\nfunc (h B48) MarshalSSZ() ([]byte, error) {\n\treturn h[:], nil\n}\n\nfunc (h B48) HashTreeRoot() B32 {\n\t//nolint:mnd // for a tree height of 1 we need 2 working chunks.\n\tresult := make([][32]byte, 2)\n\tcopy(result[0][:], h[:32])\n\tcopy(result[1][:], h[32:48])\n\tgohashtree.HashChunks(result, result)\n\treturn result[0]\n}\n"
  },
  {
    "path": "primitives/bytes/b48_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage bytes_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/merkle/zero\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestBytes48String(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname  string\n\t\tinput bytes.B48\n\t\twant  string\n\t}{\n\t\t{\n\t\t\tname: \"valid input\",\n\t\t\tinput: bytes.B48{\n\t\t\t\t0x01,\n\t\t\t\t0x02,\n\t\t\t\t0x03,\n\t\t\t\t0x04,\n\t\t\t\t0x05,\n\t\t\t\t0x06,\n\t\t\t\t0x07,\n\t\t\t\t0x08,\n\t\t\t\t0x09,\n\t\t\t\t0x0a,\n\t\t\t\t0x0b,\n\t\t\t\t0x0c,\n\t\t\t\t0x0d,\n\t\t\t\t0x0e,\n\t\t\t\t0x0f,\n\t\t\t\t0x10,\n\t\t\t\t0x11,\n\t\t\t\t0x12,\n\t\t\t\t0x13,\n\t\t\t\t0x14,\n\t\t\t\t0x15,\n\t\t\t\t0x16,\n\t\t\t\t0x17,\n\t\t\t\t0x18,\n\t\t\t\t0x19,\n\t\t\t\t0x1a,\n\t\t\t\t0x1b,\n\t\t\t\t0x1c,\n\t\t\t\t0x1d,\n\t\t\t\t0x1e,\n\t\t\t\t0x1f,\n\t\t\t\t0x20,\n\t\t\t\t0x21,\n\t\t\t\t0x22,\n\t\t\t\t0x23,\n\t\t\t\t0x24,\n\t\t\t\t0x25,\n\t\t\t\t0x26,\n\t\t\t\t0x27,\n\t\t\t\t0x28,\n\t\t\t\t0x29,\n\t\t\t\t0x2a,\n\t\t\t\t0x2b,\n\t\t\t\t0x2c,\n\t\t\t\t0x2d,\n\t\t\t\t0x2e,\n\t\t\t\t0x2f,\n\t\t\t\t0x30,\n\t\t\t},\n\t\t\twant: \"0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30\",\n\t\t},\n\t\t{\n\t\t\tname:  \"empty input\",\n\t\t\tinput: bytes.B48{},\n\t\t\twant:  \"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot := tt.input.String()\n\t\t\trequire.Equal(t, tt.want, got)\n\t\t})\n\t}\n}\n\nfunc TestBytes48MarshalText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname  string\n\t\tinput bytes.B48\n\t\twant  string\n\t}{\n\t\t{\n\t\t\tname: \"valid input\",\n\t\t\tinput: bytes.B48{\n\t\t\t\t0x01,\n\t\t\t\t0x02,\n\t\t\t\t0x03,\n\t\t\t\t0x04,\n\t\t\t\t0x05,\n\t\t\t\t0x06,\n\t\t\t\t0x07,\n\t\t\t\t0x08,\n\t\t\t\t0x09,\n\t\t\t\t0x0a,\n\t\t\t\t0x0b,\n\t\t\t\t0x0c,\n\t\t\t\t0x0d,\n\t\t\t\t0x0e,\n\t\t\t\t0x0f,\n\t\t\t\t0x10,\n\t\t\t\t0x11,\n\t\t\t\t0x12,\n\t\t\t\t0x13,\n\t\t\t\t0x14,\n\t\t\t\t0x15,\n\t\t\t\t0x16,\n\t\t\t\t0x17,\n\t\t\t\t0x18,\n\t\t\t\t0x19,\n\t\t\t\t0x1a,\n\t\t\t\t0x1b,\n\t\t\t\t0x1c,\n\t\t\t\t0x1d,\n\t\t\t\t0x1e,\n\t\t\t\t0x1f,\n\t\t\t\t0x20,\n\t\t\t\t0x21,\n\t\t\t\t0x22,\n\t\t\t\t0x23,\n\t\t\t\t0x24,\n\t\t\t\t0x25,\n\t\t\t\t0x26,\n\t\t\t\t0x27,\n\t\t\t\t0x28,\n\t\t\t\t0x29,\n\t\t\t\t0x2a,\n\t\t\t\t0x2b,\n\t\t\t\t0x2c,\n\t\t\t\t0x2d,\n\t\t\t\t0x2e,\n\t\t\t\t0x2f,\n\t\t\t\t0x30,\n\t\t\t},\n\t\t\twant: \"0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30\",\n\t\t},\n\t\t{\n\t\t\tname:  \"empty input\",\n\t\t\tinput: bytes.B48{},\n\t\t\twant:  \"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot, err := tt.input.MarshalText()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tt.want, string(got))\n\t\t})\n\t}\n}\n\nfunc TestBytes48UnmarshalText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tinput   string\n\t\twant    bytes.B48\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\tname:  \"valid input\",\n\t\t\tinput: \"0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30\",\n\t\t\twant: bytes.B48{\n\t\t\t\t0x01,\n\t\t\t\t0x02,\n\t\t\t\t0x03,\n\t\t\t\t0x04,\n\t\t\t\t0x05,\n\t\t\t\t0x06,\n\t\t\t\t0x07,\n\t\t\t\t0x08,\n\t\t\t\t0x09,\n\t\t\t\t0x0a,\n\t\t\t\t0x0b,\n\t\t\t\t0x0c,\n\t\t\t\t0x0d,\n\t\t\t\t0x0e,\n\t\t\t\t0x0f,\n\t\t\t\t0x10,\n\t\t\t\t0x11,\n\t\t\t\t0x12,\n\t\t\t\t0x13,\n\t\t\t\t0x14,\n\t\t\t\t0x15,\n\t\t\t\t0x16,\n\t\t\t\t0x17,\n\t\t\t\t0x18,\n\t\t\t\t0x19,\n\t\t\t\t0x1a,\n\t\t\t\t0x1b,\n\t\t\t\t0x1c,\n\t\t\t\t0x1d,\n\t\t\t\t0x1e,\n\t\t\t\t0x1f,\n\t\t\t\t0x20,\n\t\t\t\t0x21,\n\t\t\t\t0x22,\n\t\t\t\t0x23,\n\t\t\t\t0x24,\n\t\t\t\t0x25,\n\t\t\t\t0x26,\n\t\t\t\t0x27,\n\t\t\t\t0x28,\n\t\t\t\t0x29,\n\t\t\t\t0x2a,\n\t\t\t\t0x2b,\n\t\t\t\t0x2c,\n\t\t\t\t0x2d,\n\t\t\t\t0x2e,\n\t\t\t\t0x2f,\n\t\t\t\t0x30,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid input - not hex\",\n\t\t\tinput:   \"0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30\",\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid input - wrong length\",\n\t\t\tinput:   \"0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e\",\n\t\t\twantErr: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar got bytes.B48\n\t\t\terr := got.UnmarshalText([]byte(tt.input))\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestToBytes48(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tinput   []byte\n\t\twantRes bytes.B48\n\t\twantErr error\n\t}{\n\t\t{\n\t\t\tname:    \"Input less than 48 bytes\",\n\t\t\tinput:   []byte{1, 2, 3},\n\t\t\twantRes: bytes.B48{},\n\t\t\twantErr: bytes.ErrIncorrectLength,\n\t\t},\n\t\t{\n\t\t\tname:    \"Input exactly 48 bytes\",\n\t\t\tinput:   make([]byte, 48),\n\t\t\twantRes: bytes.B48{},\n\t\t},\n\t\t{\n\t\t\tname:    \"Input more than 48 bytes\",\n\t\t\tinput:   make([]byte, 60),\n\t\t\twantRes: bytes.B48{},\n\t\t\twantErr: bytes.ErrIncorrectLength,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult, err := bytes.ToBytes48(tt.input)\n\t\t\tif tt.wantErr != nil {\n\t\t\t\trequire.ErrorIs(t, err, tt.wantErr)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.wantRes, result)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestB48UnmarshalJSON(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected bytes.B48\n\t\twantErr  bool\n\t}{\n\t\t{\n\t\t\tname:     \"Valid input\",\n\t\t\tinput:    `\"0x010203000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"`,\n\t\t\texpected: bytes.B48{1, 2, 3},\n\t\t\twantErr:  false,\n\t\t},\n\t\t{\n\t\t\tname:     \"Empty input\",\n\t\t\tinput:    `\"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"`,\n\t\t\texpected: bytes.B48{},\n\t\t\twantErr:  false,\n\t\t},\n\t\t{\n\t\t\tname:     \"Invalid input - not hex\",\n\t\t\tinput:    `\"invalid\"`,\n\t\t\texpected: bytes.B48{},\n\t\t\twantErr:  true,\n\t\t},\n\t\t{\n\t\t\tname:     \"Invalid input - odd length\",\n\t\t\tinput:    `\"0x010203\"`,\n\t\t\texpected: bytes.B48{},\n\t\t\twantErr:  true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar got bytes.B48\n\t\t\terr := got.UnmarshalJSON([]byte(tt.input))\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.expected, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestB48_HashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname  string\n\t\tinput bytes.B48\n\t\twant  bytes.B32\n\t}{\n\t\t{\n\t\t\tname:  \"Zero bytes\",\n\t\t\tinput: bytes.B48{},\n\t\t\twant:  zero.Hashes[1],\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := tt.input.HashTreeRoot()\n\t\t\trequire.Equal(t, tt.want, result)\n\t\t})\n\t}\n}\n\nfunc TestB48MarshalSSZ(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname  string\n\t\tinput bytes.B48\n\t\twant  []byte\n\t}{\n\t\t{\n\t\t\tname: \"valid bytes\",\n\t\t\tinput: bytes.B48{\n\t\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,\n\t\t\t\t0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,\n\t\t\t\t0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21,\n\t\t\t\t0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C,\n\t\t\t\t0x2D, 0x2E, 0x2F, 0x30},\n\t\t\twant: []byte{\n\t\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,\n\t\t\t\t0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,\n\t\t\t\t0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21,\n\t\t\t\t0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C,\n\t\t\t\t0x2D, 0x2E, 0x2F, 0x30},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot, err := tt.input.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tt.want, got)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "primitives/bytes/b4_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage bytes_test\n\nimport (\n\t\"encoding/binary\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestFromUint32_CustomType(t *testing.T) {\n\tt.Parallel()\n\tinput := uint32(123456789)\n\texpected := bytes.B4{}\n\tbinary.LittleEndian.PutUint32(expected[:], input)\n\n\tresult := bytes.FromUint32(input)\n\trequire.Equal(t, expected, result)\n}\n\nfunc TestToUint32_CustomType(t *testing.T) {\n\tt.Parallel()\n\tinput := bytes.B4{0x15, 0xCD, 0x5B, 0x07}\n\texpected := uint32(123456789)\n\n\tresult := input.ToUint32()\n\trequire.Equal(t, expected, result)\n}\n\nfunc TestBytes4UnmarshalJSON(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tinput   string\n\t\twant    bytes.B4\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\tname:    \"valid input\",\n\t\t\tinput:   `\"0x01020304\"`,\n\t\t\twant:    bytes.B4{0x01, 0x02, 0x03, 0x04},\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid input - not hex\",\n\t\t\tinput:   `\"01020304\"`,\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid input - wrong length\",\n\t\t\tinput:   `\"0x010203\"`,\n\t\t\twantErr: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar got bytes.B4\n\t\t\terr := got.UnmarshalJSON([]byte(tt.input))\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestBytes4String(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname string\n\t\th    bytes.B4\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"non-empty bytes\",\n\t\t\th:    bytes.B4{0x01, 0x02, 0x03, 0x04},\n\t\t\twant: \"0x01020304\",\n\t\t},\n\t\t{\n\t\t\tname: \"empty bytes\",\n\t\t\th:    bytes.B4{},\n\t\t\twant: \"0x00000000\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot := tt.h.String()\n\t\t\trequire.Equal(t, tt.want, got)\n\t\t})\n\t}\n}\n\nfunc TestBytes4MarshalText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname string\n\t\th    bytes.B4\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"valid bytes\",\n\t\t\th:    bytes.B4{0x01, 0x02, 0x03, 0x04},\n\t\t\twant: \"0x01020304\",\n\t\t},\n\t\t{\n\t\t\tname: \"all zeros\",\n\t\t\th:    bytes.B4{0x00, 0x00, 0x00, 0x00},\n\t\t\twant: \"0x00000000\",\n\t\t},\n\t\t{\n\t\t\tname: \"all ones\",\n\t\t\th:    bytes.B4{0xFF, 0xFF, 0xFF, 0xFF},\n\t\t\twant: \"0xffffffff\",\n\t\t},\n\t\t{\n\t\t\tname: \"mixed bytes\",\n\t\t\th:    bytes.B4{0xAA, 0xBB, 0xCC, 0xDD},\n\t\t\twant: \"0xaabbccdd\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot, err := tt.h.MarshalText()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tt.want, string(got))\n\t\t})\n\t}\n}\n\nfunc TestBytes4UnmarshalText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tinput   string\n\t\twant    bytes.B4\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\tname:    \"valid input\",\n\t\t\tinput:   \"0x01020304\",\n\t\t\twant:    bytes.B4{0x01, 0x02, 0x03, 0x04},\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid input - not hex\",\n\t\t\tinput:   \"01020304\",\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid input - wrong length\",\n\t\t\tinput:   \"0x010203\",\n\t\t\twantErr: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar got bytes.B4\n\t\t\terr := got.UnmarshalText([]byte(tt.input))\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestToBytes4(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tinput   []byte\n\t\twantRes bytes.B4\n\t\twantErr error\n\t}{\n\t\t{\n\t\t\tname:    \"Input less than 4 bytes\",\n\t\t\tinput:   []byte{0x01, 0x02},\n\t\t\twantRes: bytes.B4{},\n\t\t\twantErr: bytes.ErrIncorrectLength,\n\t\t},\n\t\t{\n\t\t\tname:    \"Input exactly 4 bytes\",\n\t\t\tinput:   []byte{0x01, 0x02, 0x03, 0x04},\n\t\t\twantRes: bytes.B4{0x01, 0x02, 0x03, 0x04},\n\t\t},\n\t\t{\n\t\t\tname:    \"Input more than 4 bytes\",\n\t\t\tinput:   []byte{0x01, 0x02, 0x03, 0x04, 0x05},\n\t\t\twantRes: bytes.B4{},\n\t\t\twantErr: bytes.ErrIncorrectLength,\n\t\t},\n\t\t{\n\t\t\tname:    \"Empty input\",\n\t\t\tinput:   []byte{},\n\t\t\twantRes: bytes.B4{},\n\t\t\twantErr: bytes.ErrIncorrectLength,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult, err := bytes.ToBytes4(tt.input)\n\t\t\tif tt.wantErr != nil {\n\t\t\t\trequire.ErrorIs(t, err, tt.wantErr)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.wantRes, result)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestBytes4MarshalSSZ(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname  string\n\t\tinput bytes.B4\n\t\twant  []byte\n\t}{\n\t\t{\n\t\t\tname:  \"marshal B4\",\n\t\t\tinput: bytes.B4{0x01, 0x02, 0x03, 0x04},\n\t\t\twant:  []byte{0x01, 0x02, 0x03, 0x04},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot, err := tt.input.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tt.want, got)\n\t\t})\n\t}\n}\n\nfunc TestBytes4HashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname  string\n\t\tinput bytes.B4\n\t\twant  bytes.B32\n\t}{\n\t\t{\n\t\t\tname:  \"hash tree root\",\n\t\t\tinput: bytes.B4{0x01, 0x02, 0x03, 0x04},\n\t\t\twant:  bytes.B32{0x01, 0x02, 0x03, 0x04},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot, err := tt.input.HashTreeRoot()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tt.want, got)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "primitives/bytes/b8.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n//\n\npackage bytes\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n)\n\nconst (\n\t// B8Size represents an 8-byte size.\n\tB8Size = 8\n)\n\n// B8 represents an 8-byte fixed-size byte array.\n// For SSZ purposes it is serialized a `Vector[Byte, 8]`.\ntype B8 [8]byte\n\n// ToBytes8 is a utility function that transforms a byte slice into a fixed\n// 8-byte array. It errs if input has not the required size.\nfunc ToBytes8(input []byte) (B8, error) {\n\tif len(input) != B8Size {\n\t\treturn B8{}, fmt.Errorf(\n\t\t\t\"%w, got %d, expected %d\",\n\t\t\tErrIncorrectLength,\n\t\t\tlen(input),\n\t\t\tB8Size,\n\t\t)\n\t}\n\treturn B8(input), nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                TextMarshaler                               */\n/* -------------------------------------------------------------------------- */\n\n// MarshalText implements the encoding.TextMarshaler interface for B8.\nfunc (h B8) MarshalText() ([]byte, error) {\n\treturn []byte(h.String()), nil\n}\n\n// UnmarshalText implements the encoding.TextUnmarshaler interface for B8.\nfunc (h *B8) UnmarshalText(text []byte) error {\n\treturn UnmarshalTextHelper(h[:], text)\n}\n\n// String returns the hex string representation of B8.\nfunc (h B8) String() string {\n\treturn hex.EncodeBytes(h[:])\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                JSONMarshaler                               */\n/* -------------------------------------------------------------------------- */\n\n// UnmarshalJSON implements the json.Unmarshaler interface for B8.\nfunc (h *B8) UnmarshalJSON(input []byte) error {\n\treturn UnmarshalJSONHelper(h[:], input)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                SSZMarshaler                                */\n/* -------------------------------------------------------------------------- */\n\n// MarshalSSZ implements the SSZ marshaling for B8.\nfunc (h B8) MarshalSSZ() ([]byte, error) {\n\treturn h[:], nil\n}\n\n// HashTreeRoot returns the hash tree root of the B8.\nfunc (h B8) HashTreeRoot() (B32, error) {\n\treturn ToBytes32(ExtendToSize(h[:], B32Size))\n}\n"
  },
  {
    "path": "primitives/bytes/b8_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage bytes_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestBytes8UnmarshalJSON(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tinput   string\n\t\twant    bytes.B8\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\tname:    \"valid input\",\n\t\t\tinput:   `\"0x0102030405060708\"`,\n\t\t\twant:    bytes.B8{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid input - not hex\",\n\t\t\tinput:   `\"0102030405060708\"`,\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid input - wrong length\",\n\t\t\tinput:   `\"0x01020304\"`,\n\t\t\twantErr: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar got bytes.B8\n\t\t\terr := got.UnmarshalJSON([]byte(tt.input))\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestBytes8String(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname string\n\t\th    bytes.B8\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"non-empty bytes\",\n\t\t\th:    bytes.B8{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},\n\t\t\twant: \"0x0102030405060708\",\n\t\t},\n\t\t{\n\t\t\tname: \"empty bytes\",\n\t\t\th:    bytes.B8{},\n\t\t\twant: \"0x0000000000000000\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot := tt.h.String()\n\t\t\trequire.Equal(t, tt.want, got)\n\t\t})\n\t}\n}\n\nfunc TestBytes8MarshalText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname string\n\t\th    bytes.B8\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"valid bytes\",\n\t\t\th:    bytes.B8{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},\n\t\t\twant: \"0x0102030405060708\",\n\t\t},\n\t\t{\n\t\t\tname: \"empty bytes\",\n\t\t\th:    bytes.B8{},\n\t\t\twant: \"0x0000000000000000\",\n\t\t},\n\t\t{\n\t\t\tname: \"all zeros\",\n\t\t\th:    bytes.B8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},\n\t\t\twant: \"0x0000000000000000\",\n\t\t},\n\t\t{\n\t\t\tname: \"all ones\",\n\t\t\th:    bytes.B8{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},\n\t\t\twant: \"0xffffffffffffffff\",\n\t\t},\n\t\t{\n\t\t\tname: \"mixed bytes\",\n\t\t\th:    bytes.B8{0xaa, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22},\n\t\t\twant: \"0xaabbccddeeff1122\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot, err := tt.h.MarshalText()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tt.want, string(got))\n\t\t})\n\t}\n}\n\nfunc TestBytes8UnmarshalText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tinput   string\n\t\twant    bytes.B8\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\tname:    \"valid input\",\n\t\t\tinput:   \"0x0102030405060708\",\n\t\t\twant:    bytes.B8{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid input - not hex\",\n\t\t\tinput:   \"0102030405060708\",\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid input - wrong length\",\n\t\t\tinput:   \"0x01020304\",\n\t\t\twantErr: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar got bytes.B8\n\t\t\terr := got.UnmarshalText([]byte(tt.input))\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestToBytes8(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tinput   []byte\n\t\twantRes bytes.B8\n\t\twantErr error\n\t}{\n\t\t{\n\t\t\tname:    \"Exact 8 bytes\",\n\t\t\tinput:   []byte{1, 2, 3, 4, 5, 6, 7, 8},\n\t\t\twantRes: bytes.B8{1, 2, 3, 4, 5, 6, 7, 8},\n\t\t\twantErr: nil,\n\t\t},\n\t\t{\n\t\t\tname:    \"Less than 8 bytes\",\n\t\t\tinput:   []byte{1, 2, 3, 4},\n\t\t\twantErr: bytes.ErrIncorrectLength,\n\t\t},\n\t\t{\n\t\t\tname:    \"Two bytes\",\n\t\t\tinput:   []byte{1, 2},\n\t\t\twantErr: bytes.ErrIncorrectLength,\n\t\t},\n\t\t{\n\t\t\tname:    \"Empty input\",\n\t\t\tinput:   []byte{},\n\t\t\twantErr: bytes.ErrIncorrectLength,\n\t\t},\n\t\t{\n\t\t\tname:    \"More than 8 bytes\",\n\t\t\tinput:   []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},\n\t\t\twantErr: bytes.ErrIncorrectLength,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult, err := bytes.ToBytes8(tt.input)\n\t\t\tif tt.wantErr != nil {\n\t\t\t\trequire.ErrorIs(t, err, tt.wantErr)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.wantRes, result)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestBytes8MarshalSSZ(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname  string\n\t\tinput bytes.B8\n\t\twant  []byte\n\t}{\n\t\t{\n\t\t\tname:  \"marshal B8\",\n\t\t\tinput: bytes.B8{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},\n\t\t\twant:  []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot, err := tt.input.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tt.want, got)\n\t\t})\n\t}\n}\n\nfunc TestBytes8HashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname  string\n\t\tinput bytes.B8\n\t\twant  bytes.B32\n\t}{\n\t\t{\n\t\t\tname:  \"hash tree root\",\n\t\t\tinput: bytes.B8{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},\n\t\t\twant:  [32]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot, err := tt.input.HashTreeRoot()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tt.want, got)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "primitives/bytes/b96.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n//\n\npackage bytes\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/prysmaticlabs/gohashtree\"\n)\n\nconst (\n\t// B96Size represents a 96-byte size.\n\tB96Size = 96\n)\n\n// B96 represents a 96-byte fixed-size byte array.\n// For SSZ purposes it is serialized a `Vector[Byte, 96]`.\ntype B96 [96]byte\n\n// ToBytes96 is a utility function that transforms a byte slice into a fixed\n// 96-byte array. It errs if input has not the required size.\nfunc ToBytes96(input []byte) (B96, error) {\n\tif len(input) != B96Size {\n\t\treturn B96{}, fmt.Errorf(\n\t\t\t\"%w, got %d, expected %d\",\n\t\t\tErrIncorrectLength,\n\t\t\tlen(input),\n\t\t\tB96Size,\n\t\t)\n\t}\n\treturn B96(input), nil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                TextMarshaler                               */\n/* -------------------------------------------------------------------------- */\n\n// MarshalText implements the encoding.TextMarshaler interface for B96.\nfunc (h B96) MarshalText() ([]byte, error) {\n\treturn []byte(h.String()), nil\n}\n\n// UnmarshalText implements the encoding.TextUnmarshaler interface for B96.\nfunc (h *B96) UnmarshalText(text []byte) error {\n\treturn UnmarshalTextHelper(h[:], text)\n}\n\n// String returns the hex string representation of B96.\nfunc (h *B96) String() string {\n\treturn hex.EncodeBytes(h[:])\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                JSONMarshaler                               */\n/* -------------------------------------------------------------------------- */\n\n// UnmarshalJSON implements the json.Unmarshaler interface for B96.\nfunc (h *B96) UnmarshalJSON(input []byte) error {\n\treturn UnmarshalJSONHelper(h[:], input)\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                SSZMarshaler                                */\n/* -------------------------------------------------------------------------- */\n\n// MarshalSSZ implements the SSZ marshaling for B96.\nfunc (h B96) MarshalSSZ() ([]byte, error) {\n\treturn h[:], nil\n}\n\n// HashTreeRoot returns the hash tree root of the B96.\nfunc (h B96) HashTreeRoot() B32 {\n\t//nolint:mnd // for a tree height of 2 we need 4 working chunks.\n\tresult := make([][32]byte, 4)\n\tcopy(result[0][:], h[:32])\n\tcopy(result[1][:], h[32:64])\n\tcopy(result[2][:], h[64:96])\n\tgohashtree.HashChunks(result, result)\n\tgohashtree.HashChunks(result, result)\n\treturn result[0]\n}\n"
  },
  {
    "path": "primitives/bytes/b96_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//nolint:lll // long strings.\npackage bytes_test\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n\t\"github.com/berachain/beacon-kit/primitives/merkle/zero\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestBytes96UnmarshalText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tinput   string\n\t\twant    bytes.B96\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\tname:  \"valid input\",\n\t\t\tinput: \"0x\" + strings.Repeat(\"01\", 96),\n\t\t\twant: func() bytes.B96 {\n\t\t\t\tvar b bytes.B96\n\t\t\t\tfor i := range b {\n\t\t\t\t\tb[i] = 0x01\n\t\t\t\t}\n\t\t\t\treturn b\n\t\t\t}(),\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid input - not hex\",\n\t\t\tinput:   strings.Repeat(\"01\", 96),\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid input - wrong length\",\n\t\t\tinput:   \"0x\" + strings.Repeat(\"01\", 95),\n\t\t\twantErr: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar got bytes.B96\n\t\t\terr := got.UnmarshalText([]byte(tt.input))\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestBytes96UnmarshalJSON(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tinput   string\n\t\twant    bytes.B96\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\tname:  \"valid input\",\n\t\t\tinput: `\"0x` + strings.Repeat(\"01\", 96) + `\"`,\n\t\t\twant: func() bytes.B96 {\n\t\t\t\tvar b bytes.B96\n\t\t\t\tfor i := range b {\n\t\t\t\t\tb[i] = 0x01\n\t\t\t\t}\n\t\t\t\treturn b\n\t\t\t}(),\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid input - not hex\",\n\t\t\tinput:   `\"` + strings.Repeat(\"01\", 96) + `\"`,\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid input - wrong length\",\n\t\t\tinput:   `\"0x` + strings.Repeat(\"01\", 95) + `\"`,\n\t\t\twantErr: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar got bytes.B96\n\t\t\terr := got.UnmarshalJSON([]byte(tt.input))\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\nfunc TestBytes96MarshalText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname string\n\t\th    bytes.B96\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"valid bytes\",\n\t\t\th: func() bytes.B96 {\n\t\t\t\tvar b bytes.B96\n\t\t\t\tfor i := range b {\n\t\t\t\t\tb[i] = 0x01\n\t\t\t\t}\n\t\t\t\treturn b\n\t\t\t}(),\n\t\t\twant: \"0x\" + strings.Repeat(\"01\", 96),\n\t\t},\n\t\t{\n\t\t\tname: \"empty bytes\",\n\t\t\th:    bytes.B96{},\n\t\t\twant: \"0x\" + strings.Repeat(\"00\", 96),\n\t\t},\n\t\t{\n\t\t\tname: \"mixed bytes\",\n\t\t\th: func() bytes.B96 {\n\t\t\t\tvar b bytes.B96\n\t\t\t\tfor i := 0; i < len(b); i++ {\n\t\t\t\t\tb[i] = byte(i % 256)\n\t\t\t\t}\n\t\t\t\treturn b\n\t\t\t}(),\n\t\t\twant: \"0x\" + func() string {\n\t\t\t\tvar s string\n\t\t\t\tfor i := range 96 {\n\t\t\t\t\ts += fmt.Sprintf(\"%02x\", i%256)\n\t\t\t\t}\n\t\t\t\treturn s\n\t\t\t}(),\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot, err := tt.h.MarshalText()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tt.want, string(got))\n\t\t})\n\t}\n}\n\nfunc TestBytes96String(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname string\n\t\th    bytes.B96\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"non-empty bytes\",\n\t\t\th: func() bytes.B96 {\n\t\t\t\tvar b bytes.B96\n\t\t\t\tfor i := range b {\n\t\t\t\t\tb[i] = 0x01\n\t\t\t\t}\n\t\t\t\treturn b\n\t\t\t}(),\n\t\t\twant: \"0x\" + strings.Repeat(\"01\", 96),\n\t\t},\n\t\t{\n\t\t\tname: \"empty bytes\",\n\t\t\th:    bytes.B96{},\n\t\t\twant: \"0x\" + strings.Repeat(\"00\", 96),\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot := tt.h.String()\n\t\t\trequire.Equal(t, tt.want, got)\n\t\t})\n\t}\n}\n\nfunc TestToBytes96(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tinput   []byte\n\t\twantRes bytes.B96\n\t\twantErr error\n\t}{\n\t\t{\n\t\t\tname:    \"Input less than 96 bytes\",\n\t\t\tinput:   []byte{1, 2, 3},\n\t\t\twantRes: bytes.B96{},\n\t\t\twantErr: bytes.ErrIncorrectLength,\n\t\t},\n\t\t{\n\t\t\tname:    \"Input exactly 96 bytes\",\n\t\t\tinput:   make([]byte, 96),\n\t\t\twantRes: bytes.B96{},\n\t\t},\n\t\t{\n\t\t\tname:    \"Input more than 96 bytes\",\n\t\t\tinput:   make([]byte, 100),\n\t\t\twantRes: bytes.B96{},\n\t\t\twantErr: bytes.ErrIncorrectLength,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult, err := bytes.ToBytes96(tt.input)\n\t\t\tif tt.wantErr != nil {\n\t\t\t\trequire.ErrorIs(t, err, tt.wantErr)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.wantRes, result)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestB96_HashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname  string\n\t\tinput bytes.B96\n\t\twant  bytes.B32\n\t}{\n\t\t{\n\t\t\tname:  \"Zero bytes\",\n\t\t\tinput: bytes.B96{},\n\t\t\twant:  zero.Hashes[2],\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := tt.input.HashTreeRoot()\n\t\t\trequire.Equal(t, tt.want, result)\n\t\t})\n\t}\n}\n\nfunc BenchmarkB96_MarshalJSON(b *testing.B) {\n\tdata := bytes.B96{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}\n\tb.ResetTimer()\n\tfor range b.N {\n\t\t_, err := json.Marshal(data)\n\t\trequire.NoError(b, err)\n\t}\n}\n\nfunc BenchmarkB96_UnmarshalJSON(b *testing.B) {\n\t//nolint:lll // its a test.\n\tjsonData := []byte(\n\t\t`\"0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5fdd\"`,\n\t)\n\tvar data bytes.B96\n\tb.ResetTimer()\n\tfor range b.N {\n\t\terr := data.UnmarshalJSON(jsonData)\n\t\trequire.NoError(b, err)\n\t}\n}\n\nfunc TestB96MarshalSSZ(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname  string\n\t\tinput bytes.B96\n\t\twant  []byte\n\t}{\n\t\t{\n\t\t\tname: \"valid bytes\",\n\t\t\tinput: bytes.B96{\n\t\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,\n\t\t\t\t0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,\n\t\t\t\t0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21,\n\t\t\t\t0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C,\n\t\t\t\t0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,\n\t\t\t\t0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42,\n\t\t\t\t0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D,\n\t\t\t\t0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,\n\t\t\t\t0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60},\n\t\t\twant: []byte{\n\t\t\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,\n\t\t\t\t0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,\n\t\t\t\t0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21,\n\t\t\t\t0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C,\n\t\t\t\t0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,\n\t\t\t\t0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42,\n\t\t\t\t0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D,\n\t\t\t\t0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,\n\t\t\t\t0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot, err := tt.input.MarshalSSZ()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tt.want, got)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "primitives/bytes/b_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage bytes_test\n\nimport (\n\tstdhex \"encoding/hex\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestFromHex(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname       string\n\t\tinput      string\n\t\twantOutput bytes.Bytes\n\t\twantErr    error\n\t}{\n\t\t{\n\t\t\tname:       \"Valid hex string\",\n\t\t\tinput:      \"0x48656c6c6f\",\n\t\t\twantOutput: bytes.Bytes{0x48, 0x65, 0x6c, 0x6c, 0x6f},\n\t\t\twantErr:    nil,\n\t\t},\n\t\t{\n\t\t\tname:       \"Empty hex string\",\n\t\t\tinput:      \"0x\",\n\t\t\twantOutput: bytes.Bytes{},\n\t\t\twantErr:    nil,\n\t\t},\n\t\t{\n\t\t\tname:       \"Invalid hex string - odd length\",\n\t\t\tinput:      \"0x12345\",\n\t\t\twantOutput: nil,\n\t\t\twantErr:    stdhex.ErrLength,\n\t\t},\n\t\t{\n\t\t\tname:       \"Invalid hex string - no 0x prefix\",\n\t\t\tinput:      \"12345\",\n\t\t\twantOutput: nil,\n\t\t\twantErr:    hex.ErrMissingPrefix,\n\t\t},\n\t\t{\n\t\t\tname:       \"Empty input string\",\n\t\t\tinput:      \"\",\n\t\t\twantOutput: nil,\n\t\t\twantErr:    hex.ErrEmptyString,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot, err := hex.ToBytes(tt.input)\n\t\t\tif tt.wantErr != nil {\n\t\t\t\trequire.ErrorIs(t, err, tt.wantErr)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.wantOutput, bytes.Bytes(got))\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestMustFromHex(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname        string\n\t\tinput       string\n\t\texpected    []byte\n\t\tshouldPanic bool\n\t}{\n\t\t{\n\t\t\tname:        \"Valid hex string\",\n\t\t\tinput:       \"0x68656c6c6f\",\n\t\t\texpected:    bytes.Bytes(\"hello\"),\n\t\t\tshouldPanic: false,\n\t\t},\n\t\t{\n\t\t\tname:        \"Another valid hex string\",\n\t\t\tinput:       \"0x776f726c64\",\n\t\t\texpected:    bytes.Bytes(\"world\"),\n\t\t\tshouldPanic: false,\n\t\t},\n\t\t{\n\t\t\tname:        \"Empty hex string\",\n\t\t\tinput:       \"0x\",\n\t\t\texpected:    bytes.Bytes{},\n\t\t\tshouldPanic: false,\n\t\t},\n\t\t{\n\t\t\tname:        \"Invalid hex string\",\n\t\t\tinput:       \"0x12345\",\n\t\t\texpected:    nil,\n\t\t\tshouldPanic: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar (\n\t\t\t\tres []byte\n\t\t\t\tf   = func() {\n\t\t\t\t\tres = hex.MustToBytes(tt.input)\n\t\t\t\t}\n\t\t\t)\n\t\t\tif tt.shouldPanic {\n\t\t\t\trequire.Panics(t, f)\n\t\t\t} else {\n\t\t\t\trequire.NotPanics(t, f)\n\t\t\t\trequire.Equal(t, tt.expected, res)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestBytesUnmarshalJSONText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname      string\n\t\tinput     []byte\n\t\texpectErr bool\n\t}{\n\t\t{\n\t\t\tname:      \"Valid JSON text\",\n\t\t\tinput:     []byte(`\"0x48656c6c6f\"`),\n\t\t\texpectErr: false,\n\t\t},\n\t\t{\n\t\t\tname:      \"Invalid JSON text\",\n\t\t\tinput:     []byte(`\"invalid\"`),\n\t\t\texpectErr: true,\n\t\t},\n\t\t{\n\t\t\tname:      \"Invalid quoted JSON text\",\n\t\t\tinput:     []byte(`\"0x`),\n\t\t\texpectErr: true,\n\t\t},\n\t\t{\n\t\t\tname:      \"Empty JSON text\",\n\t\t\tinput:     []byte(`\"\"`),\n\t\t\texpectErr: false,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tb := &bytes.Bytes{}\n\t\t\terr := b.UnmarshalJSON(tt.input)\n\t\t\tif tt.expectErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestReverseEndianness(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tinput    []byte\n\t\texpected []byte\n\t}{\n\t\t{name: \"Even length\",\n\t\t\tinput:    []byte{1, 2, 3, 4},\n\t\t\texpected: []byte{4, 3, 2, 1}},\n\t\t{name: \"Odd length\",\n\t\t\tinput:    []byte{1, 2, 3, 4, 5},\n\t\t\texpected: []byte{5, 4, 3, 2, 1}},\n\t\t{name: \"Empty slice\",\n\t\t\tinput:    []byte{},\n\t\t\texpected: []byte{}},\n\t\t{name: \"Single element\",\n\t\t\tinput:    []byte{1},\n\t\t\texpected: []byte{1}},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := bytes.CopyAndReverseEndianess(tt.input)\n\t\t\trequire.Equal(t, tt.expected, result)\n\t\t})\n\t}\n}\n\nfunc TestHashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname  string\n\t\tinput bytes.B32\n\t\twant  bytes.B32\n\t}{\n\t\t{\n\t\t\tname:  \"Non-empty input\",\n\t\t\tinput: bytes.B32{1, 2, 3},\n\t\t\twant:  [32]byte{1, 2, 3},\n\t\t},\n\t\t{\n\t\t\tname:  \"Empty input\",\n\t\t\tinput: bytes.B32{},\n\t\t\twant:  [32]byte{},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := tt.input.HashTreeRoot()\n\t\t\trequire.Equal(t, tt.want, result)\n\t\t})\n\t}\n}\n\nfunc TestUnmarshalFixedJSON(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\ttyp      reflect.Type\n\t\tinput    []byte\n\t\tout      []byte\n\t\texpected []byte\n\t\twantErr  bool\n\t}{\n\t\t{\n\t\t\tname:     \"Valid input\",\n\t\t\ttyp:      reflect.TypeOf([4]byte{}),\n\t\t\tinput:    []byte(`\"0x01020304\"`),\n\t\t\tout:      make([]byte, 4),\n\t\t\texpected: []byte{0x01, 0x02, 0x03, 0x04},\n\t\t\twantErr:  false,\n\t\t},\n\t\t{\n\t\t\tname:     \"Invalid input - not hex\",\n\t\t\ttyp:      reflect.TypeOf([4]byte{}),\n\t\t\tinput:    []byte(`\"01020304\"`),\n\t\t\tout:      make([]byte, 4),\n\t\t\texpected: nil,\n\t\t\twantErr:  true,\n\t\t},\n\t\t{\n\t\t\tname:     \"Invalid input - wrong length\",\n\t\t\ttyp:      reflect.TypeOf([4]byte{}),\n\t\t\tinput:    []byte(`\"0x010203\"`),\n\t\t\tout:      make([]byte, 4),\n\t\t\texpected: nil,\n\t\t\twantErr:  true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\terr := bytes.UnmarshalFixedJSON(tt.input, tt.out)\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.expected, tt.out)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestUnmarshalFixedText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\ttypename string\n\t\tinput    []byte\n\t\tout      []byte\n\t\texpected []byte\n\t\twantErr  bool\n\t}{\n\t\t{\n\t\t\tname:     \"Valid input\",\n\t\t\ttypename: \"B4\",\n\t\t\tinput:    []byte(\"0x01020304\"),\n\t\t\tout:      make([]byte, 4),\n\t\t\texpected: []byte{0x01, 0x02, 0x03, 0x04},\n\t\t\twantErr:  false,\n\t\t},\n\t\t{\n\t\t\tname:     \"Invalid input - not hex\",\n\t\t\ttypename: \"B4\",\n\t\t\tinput:    []byte(\"01020304\"),\n\t\t\tout:      make([]byte, 4),\n\t\t\texpected: nil,\n\t\t\twantErr:  true,\n\t\t},\n\t\t{\n\t\t\tname:     \"Invalid input - wrong length\",\n\t\t\ttypename: \"B4\",\n\t\t\tinput:    []byte(\"0x010203\"),\n\t\t\tout:      make([]byte, 4),\n\t\t\texpected: nil,\n\t\t\twantErr:  true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\terr := bytes.UnmarshalFixedText(tt.input, tt.out)\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.expected, tt.out)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestBytes_String(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tinput    bytes.Bytes\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tname:     \"Empty bytes\",\n\t\t\tinput:    bytes.Bytes{},\n\t\t\texpected: \"0x\",\n\t\t},\n\t\t{\n\t\t\tname:     \"Single byte\",\n\t\t\tinput:    bytes.Bytes{0x01},\n\t\t\texpected: \"0x01\",\n\t\t},\n\t\t{\n\t\t\tname:     \"Multiple bytes\",\n\t\t\tinput:    bytes.Bytes{0x01, 0x02, 0x03, 0x04},\n\t\t\texpected: \"0x01020304\",\n\t\t},\n\t\t{\n\t\t\tname:     \"Bytes with leading zeros\",\n\t\t\tinput:    bytes.Bytes{0x00, 0x00, 0x01, 0x02},\n\t\t\texpected: \"0x00000102\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := tt.input.String()\n\t\t\trequire.Equal(t, tt.expected, result)\n\t\t})\n\t}\n}\n\nfunc TestBytes_MarshalText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tinput   bytes.Bytes\n\t\twant    string\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\tname:    \"Empty slice\",\n\t\t\tinput:   bytes.Bytes{},\n\t\t\twant:    \"0x\",\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"Single byte\",\n\t\t\tinput:   bytes.Bytes{0x01},\n\t\t\twant:    \"0x01\",\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"Multiple bytes\",\n\t\t\tinput:   bytes.Bytes{0x01, 0x02, 0x03},\n\t\t\twant:    \"0x010203\",\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"Nil slice\",\n\t\t\tinput:   nil,\n\t\t\twant:    \"0x\",\n\t\t\twantErr: false,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot, err := tt.input.MarshalText()\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.want, string(got))\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "primitives/bytes/buffer/buffer.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage buffer\n\n// initialBufferSize is the initial size of the internal buffer.\nconst initialBufferSize = 64\n\n// ReusableBuffer is a re-usable buffer for merkle tree hashing. Prevents\n// unnecessary allocations and garbage collection of byte slices.\n//\n// NOTE: this buffer is currently only safe for use in a single thread.\ntype ReusableBuffer[RootT ~[32]byte] struct {\n\tinternal []RootT\n}\n\n// NewReusableBuffer creates a new re-usable buffer for merkle tree hashing.\nfunc NewReusableBuffer[RootT ~[32]byte]() *ReusableBuffer[RootT] {\n\treturn &ReusableBuffer[RootT]{\n\t\tinternal: make([]RootT, initialBufferSize),\n\t}\n}\n\n// Get returns a slice of the internal buffer of roots of the given size.\nfunc (b *ReusableBuffer[RootT]) Get(size int) []RootT {\n\tif delta := size - len(b.internal); delta > 0 {\n\t\tb.grow(delta)\n\t}\n\n\treturn b.internal[:size]\n}\n\n// grow resizes the internal buffer by the requested delta.\nfunc (b *ReusableBuffer[RootT]) grow(delta int) {\n\tb.internal = append(b.internal, make([]RootT, delta)...)\n}\n\n// singleuseBuffer is a buffer for a single use case. Allocates new\n// memory for each use (call to `Get`).\n//\n// NOTE: this buffer is only used for testing.\ntype SingleUseBuffer[RootT ~[32]byte] struct{}\n\n// NewSingleuseBuffer creates a new single-use buffer.\nfunc NewSingleuseBuffer[RootT ~[32]byte]() *SingleUseBuffer[RootT] {\n\treturn &SingleUseBuffer[RootT]{}\n}\n\n// Get returns a new slice of roots the given size.\nfunc (b *SingleUseBuffer[RootT]) Get(size int) []RootT {\n\treturn make([]RootT, size)\n}\n"
  },
  {
    "path": "primitives/bytes/buffer/buffer_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage buffer_test\n\nimport (\n\t\"math/rand\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/primitives/bytes/buffer\"\n)\n\ntype bufferI interface {\n\tGet(size int) [][32]byte\n}\n\n// getBuffer returns a buffer of the given type.\nfunc getBuffer(usageType string) bufferI {\n\tswitch usageType {\n\tcase \"reusable\":\n\t\treturn buffer.NewReusableBuffer[[32]byte]()\n\tcase \"singleuse\":\n\t\treturn buffer.NewSingleuseBuffer[[32]byte]()\n\tdefault:\n\t\tpanic(\"unknown usage type: \" + usageType)\n\t}\n}\n\n// Test getting a slice of the internal re-usable buffer and modifying.\nfunc TestReusableGet(t *testing.T) {\n\tt.Parallel()\n\tbuffer := getBuffer(\"reusable\")\n\n\ttestCases := []struct {\n\t\tsize     int\n\t\texpected int\n\t}{\n\t\t{size: 0, expected: 0},\n\t\t{size: 1, expected: 1},\n\t\t{size: 5, expected: 5},\n\t\t{size: 16, expected: 16},\n\t\t{size: 33, expected: 33},\n\t\t{size: 17, expected: 17},\n\t\t{size: 100, expected: 100},\n\t}\n\n\tfor i, tc := range testCases {\n\t\tresult := buffer.Get(tc.size)\n\n\t\tif len(result) != tc.expected {\n\t\t\tt.Errorf(\n\t\t\t\t\"Expected result size to be %d, got %d\",\n\t\t\t\ttc.expected, len(result),\n\t\t\t)\n\t\t}\n\n\t\t// Ensure modifications to the underlying buffer persist.\n\t\tif i >= 1 {\n\t\t\tif result[0][i-1] != byte(i-1) {\n\t\t\t\tt.Errorf(\n\t\t\t\t\t\"Expected result[0][%d] to be %b, got %d\",\n\t\t\t\t\ti-1, byte(i-1), result[0][i-1],\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tresult[0] = [32]byte{}\n\t\t\tresult[0][i] = byte(i)\n\t\t}\n\t}\n}\n\n// Test getting a slice of the internal single-use buffer and modifying.\nfunc TestSingleuseGet(t *testing.T) {\n\tt.Parallel()\n\tbuffer := getBuffer(\"singleuse\")\n\n\ttestCases := []struct {\n\t\tsize     int\n\t\texpected int\n\t}{\n\t\t{size: 0, expected: 0},\n\t\t{size: 1, expected: 1},\n\t\t{size: 5, expected: 5},\n\t\t{size: 16, expected: 16},\n\t\t{size: 33, expected: 33},\n\t\t{size: 17, expected: 17},\n\t\t{size: 100, expected: 100},\n\t}\n\n\tfor i, tc := range testCases {\n\t\tresult := buffer.Get(tc.size)\n\n\t\tif len(result) != tc.expected {\n\t\t\tt.Errorf(\n\t\t\t\t\"Expected result size to be %d, got %d\",\n\t\t\t\ttc.expected, len(result),\n\t\t\t)\n\t\t}\n\n\t\t// Ensure modifications to the underlying buffer do not persist.\n\t\tif i >= 1 {\n\t\t\tif result[0][i-1] != byte(0) {\n\t\t\t\tt.Errorf(\n\t\t\t\t\t\"Expected result[0][%d] to be %b, got %d\",\n\t\t\t\t\ti-1, byte(0), result[0][i-1],\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tresult[0] = [32]byte{}\n\t\t\tresult[0][i] = byte(i)\n\t\t}\n\t}\n}\n\n// Benchmark for the Get method on the re-usable buffer\n//\n// goos: darwin\n// goarch: arm64\n// pkg: github.com/berachain/beacon-kit/primitives/merkle\n// BenchmarkReusableGet-12  158002471  7.439 ns/op  0 B/op  0 allocs/op.\nfunc BenchmarkReusableGet(b *testing.B) {\n\tbuffer := getBuffer(\"reusable\")\n\tr := rand.New(rand.NewSource(time.Now().UnixNano()))\n\n\tb.ResetTimer()\n\tfor range b.N {\n\t\tsize := r.Intn(100) + 1\n\t\tresult := buffer.Get(size)\n\n\t\t// Perform some operation on the result to avoid compiler optimizations.\n\t\tresult[0] = [32]byte{}\n\t\tindex := r.Intn(32)\n\t\tresult[0][index] = byte(index)\n\t}\n}\n\n// Benchmark for the Get method on the single-use buffer\n//\n// goos: darwin\n// goarch: arm64\n// pkg: github.com/berachain/beacon-kit/primitives/merkle\n// BenchmarkSingleuseGet-12  5388972  215.0 ns/op  1700 B/op  1 allocs/op.\nfunc BenchmarkSingleuseGet(b *testing.B) {\n\tbuffer := getBuffer(\"singleuse\")\n\tr := rand.New(rand.NewSource(time.Now().UnixNano()))\n\n\tb.ResetTimer()\n\tfor range b.N {\n\t\tsize := r.Intn(100) + 1\n\t\tresult := buffer.Get(size)\n\n\t\t// Perform some operation on the result to avoid compiler optimizations.\n\t\tresult[0] = [32]byte{}\n\t\tindex := r.Intn(32)\n\t\tresult[0][index] = byte(index)\n\t}\n}\n"
  },
  {
    "path": "primitives/bytes/utils.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage bytes\n\nimport (\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n)\n\nvar ErrIncorrectLength = errors.New(\"incorrect length\")\n\n// ------------------------------ Helpers ------------------------------\n\n// Helper function to unmarshal JSON for various byte types.\nfunc UnmarshalJSONHelper(target []byte, input []byte) error {\n\tbz := Bytes{}\n\tif err := bz.UnmarshalJSON(input); err != nil {\n\t\treturn err\n\t}\n\tif len(bz) != len(target) {\n\t\treturn ErrIncorrectLength\n\t}\n\tcopy(target, bz)\n\treturn nil\n}\n\n// UnmarshalTextHelper function to unmarshal text for various byte types.\nfunc UnmarshalTextHelper(target []byte, text []byte) error {\n\tbz := Bytes{}\n\tif err := bz.UnmarshalText(text); err != nil {\n\t\treturn err\n\t}\n\tif len(bz) != len(target) {\n\t\treturn ErrIncorrectLength\n\t}\n\tcopy(target, bz)\n\treturn nil\n}\n\n// CopyAndReverseEndianess will copy the input byte slice and return the\n// flipped version of it.\nfunc CopyAndReverseEndianess(input []byte) []byte {\n\tcopied := make([]byte, len(input))\n\tcopy(copied, input)\n\tfor i, j := 0, len(copied)-1; i < j; i, j = i+1, j-1 {\n\t\tcopied[i], copied[j] = copied[j], copied[i]\n\t}\n\treturn copied\n}\n\n// ExtendToSize extends a byte slice to a specified length. It returns the\n// original slice if it's already larger.\nfunc ExtendToSize(slice []byte, length int) []byte {\n\tif len(slice) >= length {\n\t\treturn slice\n\t}\n\treturn append(slice, make([]byte, length-len(slice))...)\n}\n\n// UnmarshalFixedJSON decodes the input as a string with 0x prefix. The length\n// of out determines the required input length. This function is commonly used\n// to implement the UnmarshalJSON method for fixed-size types.\nfunc UnmarshalFixedJSON(input, out []byte) error {\n\treturn hex.DecodeFixedJSON(input, out)\n}\n\n// UnmarshalFixedText decodes the input as a string with 0x prefix. The length\n// of out determines the required input length. This function is commonly used\n// to implement the UnmarshalText method for fixed-size types.\nfunc UnmarshalFixedText(input, out []byte) error {\n\treturn hex.DecodeFixedText(input, out)\n}\n"
  },
  {
    "path": "primitives/common/consensus.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage common\n\nimport (\n\tstdbytes \"bytes\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                    Root                                    */\n/* -------------------------------------------------------------------------- */\n\ntype (\n\t// Bytes32 defines the commonly used 32-byte array.\n\tBytes32 = bytes.B32\n\n\t// Domain as per the Ethereum 2.0 Specification:\n\t// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#custom-types\n\tDomain = bytes.B32\n\n\t// DomainType as per the Ethereum 2.0 Specification:\n\t// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#custom-types\n\tDomainType = bytes.B4\n\n\t// Hash32 as per the Ethereum 2.0 Specification:\n\t// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#custom-types\n\tHash32 = bytes.B32\n\n\t// Version as per the Ethereum 2.0 specification.\n\t// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#custom-types\n\tVersion = bytes.B4\n\n\t// ForkDigest as per the Ethereum 2.0 Specification:\n\t// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#custom-types\n\tForkDigest = bytes.B4\n)\n\n// Root represents a 32-byte Merkle root.\n// We use this type to represent roots that come from the consensus layer.\ntype Root [RootSize]byte\n\nconst RootSize = 32\n\n// NewRootFromHex creates a new root from a hex string.\n//\n// Errors if:\n// - input is not prefixed with \"0x\".\n// - input is not valid hex of 32 bytes.\nfunc NewRootFromHex(input string) (Root, error) {\n\tval, err := hex.ToBytes(input)\n\tif err != nil {\n\t\treturn Root{}, err\n\t}\n\tif len(val) != RootSize {\n\t\treturn Root{}, bytes.ErrIncorrectLength\n\t}\n\treturn Root(val), nil\n}\n\n// NewRootFromBytes creates a new root from a byte slice.\nfunc NewRootFromBytes(input []byte) Root {\n\tvar root Root\n\tcopy(root[:], input)\n\treturn root\n}\n\n// Equals returns true if the two roots are equal.\nfunc (r Root) Equals(other Root) bool {\n\treturn stdbytes.Equal(r[:], other[:])\n}\n\n// Hex converts a root to a hex string.\nfunc (r Root) Hex() string { return hex.EncodeBytes(r[:]) }\n\n// String implements the stringer interface and is used also by the logger when\n// doing full logging into a file.\nfunc (r Root) String() string {\n\treturn r.Hex()\n}\n\n// MarshalText returns the hex representation of r.\nfunc (r Root) MarshalText() ([]byte, error) {\n\treturn []byte(r.Hex()), nil\n}\n\n// UnmarshalText parses a root in hex syntax.\nfunc (r *Root) UnmarshalText(input []byte) error {\n\tvar err error\n\t*r, err = NewRootFromHex(string(input))\n\treturn err\n}\n\n// MarshalJSON returns the JSON representation of r.\nfunc (r Root) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(r.Hex())\n}\n\n// UnmarshalJSON parses a root in hex syntax.\n//\n// NOTE: Enforces the input to include any extra character in the first and last position.\n// Technically this is used to remove the quote `\"`. For example, the input may look like:\n// []byte(`\"0x6969696969696969696969696969696969696969696969696969696969696969\"`)\nfunc (r *Root) UnmarshalJSON(input []byte) error {\n\tif len(input) <= 1 {\n\t\treturn errors.Wrapf(\n\t\t\tbytes.ErrIncorrectLength, \"input length (%d) is too small\", len(input),\n\t\t)\n\t}\n\treturn r.UnmarshalText(input[1 : len(input)-1])\n}\n"
  },
  {
    "path": "primitives/common/consensus_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage common_test\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestNewRootFromHex(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname        string\n\t\tinput       func() string\n\t\texpectedErr error\n\t}{\n\t\t{\n\t\t\tname: \"EmptyString\",\n\t\t\tinput: func() string {\n\t\t\t\treturn \"\"\n\t\t\t},\n\t\t\texpectedErr: hex.ErrEmptyString,\n\t\t},\n\t\t{\n\t\t\tname: \"ShortSize\",\n\t\t\tinput: func() string {\n\t\t\t\treturn hex.Prefix + strings.Repeat(\"f\", 2*common.RootSize-2)\n\t\t\t},\n\t\t\texpectedErr: bytes.ErrIncorrectLength,\n\t\t},\n\t\t{\n\t\t\tname: \"RightSize\",\n\t\t\tinput: func() string {\n\t\t\t\treturn hex.Prefix + strings.Repeat(\"f\", 2*common.RootSize)\n\t\t\t},\n\t\t\texpectedErr: nil,\n\t\t},\n\t\t{\n\t\t\tname: \"LongSize\",\n\t\t\tinput: func() string {\n\t\t\t\treturn hex.Prefix + strings.Repeat(\"f\", 2*common.RootSize+2)\n\t\t\t},\n\t\t\texpectedErr: bytes.ErrIncorrectLength,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar err error\n\t\t\tf := func() {\n\t\t\t\tinput := tt.input()\n\t\t\t\t_, err = common.NewRootFromHex(input)\n\t\t\t}\n\t\t\trequire.NotPanics(t, f)\n\t\t\tif tt.expectedErr != nil {\n\t\t\t\trequire.ErrorIs(t, err, tt.expectedErr)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestRoot_UnmarshalJSON(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname        string\n\t\tinput       []byte\n\t\texpectedErr error\n\t}{\n\t\t{\n\t\t\tname:        \"nil input\",\n\t\t\tinput:       nil,\n\t\t\texpectedErr: bytes.ErrIncorrectLength,\n\t\t},\n\t\t{\n\t\t\tname:        \"empty input\",\n\t\t\tinput:       []byte(``),\n\t\t\texpectedErr: bytes.ErrIncorrectLength,\n\t\t},\n\t\t{\n\t\t\tname:        \"short input of 1 byte\",\n\t\t\tinput:       []byte{0x01},\n\t\t\texpectedErr: bytes.ErrIncorrectLength,\n\t\t},\n\t\t{\n\t\t\tname:        \"short input of just quotes\",\n\t\t\tinput:       []byte(`\"\"`),\n\t\t\texpectedErr: hex.ErrEmptyString,\n\t\t},\n\t\t{\n\t\t\tname:        \"valid input\",\n\t\t\tinput:       []byte(`\"0x6969696969696969696969696969696969696969696969696969696969696969\"`),\n\t\t\texpectedErr: nil,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar (\n\t\t\t\tr     common.Root\n\t\t\t\terr   error\n\t\t\t\tinput = tt.input\n\t\t\t)\n\n\t\t\tf := func() {\n\t\t\t\terr = r.UnmarshalJSON(input)\n\t\t\t}\n\t\t\trequire.NotPanics(t, f)\n\n\t\t\tif tt.expectedErr != nil {\n\t\t\t\trequire.ErrorContains(t, err, tt.expectedErr.Error())\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "primitives/common/execution.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage common\n\nimport (\n\tstdbytes \"bytes\"\n\t\"encoding\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n\t\"golang.org/x/crypto/sha3\"\n)\n\nvar (\n\t_ encoding.TextMarshaler   = (*ExecutionHash)(nil)\n\t_ encoding.TextUnmarshaler = (*ExecutionHash)(nil)\n\t_ json.Marshaler           = (*ExecutionHash)(nil)\n\t_ json.Unmarshaler         = (*ExecutionHash)(nil)\n\n\t_ encoding.TextMarshaler   = (*ExecutionAddress)(nil)\n\t_ encoding.TextUnmarshaler = (*ExecutionAddress)(nil)\n\t_ json.Marshaler           = (*ExecutionAddress)(nil)\n\t_ json.Unmarshaler         = (*ExecutionAddress)(nil)\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                ExecutionHash                               */\n/* -------------------------------------------------------------------------- */\n\n// ExecutionHash represents the 32 byte Keccak256 hash of arbitrary data.\n// We use this type to represent hashes of things that come from the execution\n// layer.\ntype ExecutionHash [32]byte\n\n// NewExecutionHashFromHex creates a new hash from a hex string.\nfunc NewExecutionHashFromHex(input string) ExecutionHash {\n\treturn ExecutionHash(hex.MustToBytes(input))\n}\n\n// Hex converts a hash to a hex string.\nfunc (h ExecutionHash) Hex() string { return hex.EncodeBytes(h[:]) }\n\n// String implements the stringer interface and is used also by the logger when\n// doing full logging into a file.\nfunc (h ExecutionHash) String() string {\n\treturn h.Hex()\n}\n\n// MarshalText returns the hex representation of h.\nfunc (h ExecutionHash) MarshalText() ([]byte, error) {\n\treturn []byte(hex.EncodeBytes(h[:])), nil\n}\n\n// UnmarshalText parses a hash in hex syntax.\n//\n// Errors if:\n// - input is not \"0x\" prefixed.\n// - input length is not 66.\nfunc (h *ExecutionHash) UnmarshalText(input []byte) error {\n\treturn hex.DecodeFixedText(input, h[:])\n}\n\n// MarshalJSON returns the JSON representation of h.\nfunc (h ExecutionHash) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(h.Hex())\n}\n\n// UnmarshalJSON parses a hash in hex syntax.\n//\n// NOTE: Enforces the input to include the `\"` characters in first and last position.\n// For example, the input may look like:\n// []byte(`\"0x6969696969696969696969696969696969696969696969696969696969696969\"`)\nfunc (h *ExecutionHash) UnmarshalJSON(input []byte) error {\n\treturn hex.DecodeFixedJSON(input, h[:])\n}\n\n/* -------------------------------------------------------------------------- */\n/*                              ExecutionAddress                              */\n/* -------------------------------------------------------------------------- */\n\n// ExecutionAddress represents a 20-byte Ethereum address.\n// We use this type to represent addresses that come from the execution layer.\n// It is EIP-55 checksummed and compliant.\ntype ExecutionAddress [20]byte\n\n// NewExecutionAddressFromHex creates a new address from a hex string.\nfunc NewExecutionAddressFromHex(input string) (ExecutionAddress, error) {\n\tbz, err := hex.ToBytes(input)\n\tif err != nil {\n\t\treturn ExecutionAddress{}, err\n\t}\n\treturn ExecutionAddress(bz), nil\n}\n\n// MustNewExecutionAddressFromHex creates a new address from a hex string,\n// panicking if the input is not a valid hex string.\nfunc MustNewExecutionAddressFromHex(input string) ExecutionAddress {\n\treturn ExecutionAddress(hex.MustToBytes(input))\n}\n\n// Equals returns true if the two addresses are the same.\nfunc (a ExecutionAddress) Equals(other ExecutionAddress) bool {\n\treturn stdbytes.Equal(a[:], other[:])\n}\n\n// Hex converts an address to a hex string.\nfunc (a ExecutionAddress) Hex() string { return string(a.checksumHex()) }\n\n// String implements the stringer interface and is used also by the logger when\n// doing full logging into a file.\nfunc (a ExecutionAddress) String() string {\n\treturn a.Hex()\n}\n\n// MarshalText returns the hex representation of a.\nfunc (a ExecutionAddress) MarshalText() ([]byte, error) {\n\treturn []byte(a.Hex()), nil\n}\n\n// UnmarshalText parses an address in hex syntax.\n//\n// Errors if:\n// - input is not \"0x\" prefixed.\n// - input length is not 42.\nfunc (a *ExecutionAddress) UnmarshalText(input []byte) error {\n\treturn hex.DecodeFixedText(input, a[:])\n}\n\n// MarshalJSON returns the JSON representation of a.\nfunc (a ExecutionAddress) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(a.Hex())\n}\n\n// UnmarshalJSON parses an address in hex syntax.\n//\n// NOTE: Enforces the input to include any extra character in the first and last position.\n// Technically this is used to remove the quote `\"`. For example, the input may look like:\n// []byte(`\"0x6969696969696969696969696969696969696969\"`)\nfunc (a *ExecutionAddress) UnmarshalJSON(input []byte) error {\n\tif len(input) <= 1 {\n\t\treturn errors.Wrapf(\n\t\t\tbytes.ErrIncorrectLength, \"input length (%d) is too small\", len(input),\n\t\t)\n\t}\n\treturn a.UnmarshalText(input[1 : len(input)-1])\n}\n\n// checksumHex returns the checksummed hex representation of a.\nfunc (a *ExecutionAddress) checksumHex() []byte {\n\tbuf := []byte(hex.EncodeBytes(a[:]))\n\n\t// compute checksum\n\tsha := sha3.NewLegacyKeccak256()\n\tsha.Write(buf[2:])\n\thash := sha.Sum(nil)\n\tfor i := 2; i < len(buf); i++ {\n\t\t//nolint:mnd // todo fix.\n\t\thashByte := hash[(i-2)/2]\n\t\tif i%2 == 0 {\n\t\t\thashByte >>= 4\n\t\t} else {\n\t\t\thashByte &= 0xf\n\t\t}\n\t\tif buf[i] > '9' && hashByte > 7 {\n\t\t\tbuf[i] -= 32\n\t\t}\n\t}\n\treturn buf\n}\n"
  },
  {
    "path": "primitives/common/execution_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage common_test\n\nimport (\n\t\"encoding/json\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestExecutionAddressMarshalling(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname        string\n\t\tinput       []byte\n\t\texpectedErr error\n\t}{\n\t\t{\n\t\t\tname:        \"address too short\",\n\t\t\tinput:       []byte(\"\\\"0xab\\\"\"),\n\t\t\texpectedErr: hex.ErrInvalidHexStringLength,\n\t\t},\n\t\t{\n\t\t\tname:        \"address missing hex prefix\",\n\t\t\tinput:       []byte(\"\\\"abc\\\"\"),\n\t\t\texpectedErr: hex.ErrMissingPrefix,\n\t\t},\n\t\t{\n\t\t\tname: \"address too long\",\n\t\t\tinput: []byte(\n\t\t\t\t\"\\\"0x000102030405060708090a0b0c0d0e0f101112131415161718\\\"\",\n\t\t\t),\n\t\t\texpectedErr: hex.ErrInvalidHexStringLength,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar (\n\t\t\t\tv   common.ExecutionAddress\n\t\t\t\terr error\n\t\t\t)\n\t\t\trequire.NotPanics(t, func() {\n\t\t\t\terr = json.Unmarshal(tt.input, &v)\n\t\t\t})\n\t\t\trequire.ErrorIs(t, err, tt.expectedErr)\n\t\t})\n\t}\n}\n\nfunc TestExecutionAddressUnmarshalJSON_Short(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname        string\n\t\tinput       []byte\n\t\texpectedErr error\n\t}{\n\t\t{\n\t\t\tname:        \"empty input\",\n\t\t\tinput:       []byte(``),\n\t\t\texpectedErr: bytes.ErrIncorrectLength,\n\t\t},\n\t\t{\n\t\t\tname:        \"nil input\",\n\t\t\tinput:       nil,\n\t\t\texpectedErr: bytes.ErrIncorrectLength,\n\t\t},\n\t\t{\n\t\t\tname:        \"short input of 1 byte\",\n\t\t\tinput:       []byte{0x01},\n\t\t\texpectedErr: bytes.ErrIncorrectLength,\n\t\t},\n\t\t{\n\t\t\tname:        \"short input of just quotes\",\n\t\t\tinput:       []byte(`\"\"`),\n\t\t\texpectedErr: hex.ErrInvalidHexStringLength,\n\t\t},\n\t\t{\n\t\t\tname:        \"valid input\",\n\t\t\tinput:       []byte(`\"0x6969696969696969696969696969696969696969\"`),\n\t\t\texpectedErr: nil,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar (\n\t\t\t\taddr  common.ExecutionAddress\n\t\t\t\terr   error\n\t\t\t\tinput = tt.input\n\t\t\t)\n\n\t\t\tf := func() {\n\t\t\t\terr = addr.UnmarshalJSON(input)\n\t\t\t}\n\t\t\trequire.NotPanics(t, f)\n\n\t\t\tif tt.expectedErr != nil {\n\t\t\t\trequire.ErrorContains(t, err, tt.expectedErr.Error())\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "primitives/common/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage common\n\nimport (\n\t\"github.com/karalabe/ssz\"\n)\n\n// sszMarshaler is an interface for objects that can be marshaled to SSZ format.\ntype sszMarshaler interface {\n\t// MarshalSSZ marshals the object into SSZ format.\n\tMarshalSSZ() ([]byte, error)\n}\n\n// SSZUnmarshaler is an interface for objects that can be unmarshaled from SSZ format.\ntype SSZUnmarshaler interface {\n\tssz.Object\n\tValidateAfterDecodingSSZ() error // once unmarshalled we will check whether type syntax is correct\n}\n\n// SSZMarshallable is an interface that combines SSZMarshaler and SSZUnmarshaler.\ntype SSZMarshallable interface {\n\tsszMarshaler\n\tSSZUnmarshaler\n}\n\n// SSZRootable is an interface for objects that can compute their hash tree root.\ntype SSZRootable interface {\n\t// HashTreeRoot computes the hash tree root of the object.\n\tHashTreeRoot() Root\n}\n\n// SSZMarshallableRootable is an interface that combines\n// sszMarshaler, sszUnmarshaler, and SSZRootable.\ntype SSZMarshallableRootable interface {\n\tSSZMarshallable\n\tSSZRootable\n}\n"
  },
  {
    "path": "primitives/common/unused_type.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage common\n\nimport (\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// UnusedEnforcer is an interface that asserts that a type is unused.\ntype UnusedEnforcer interface {\n\tEnforceUnused() error\n}\n\n// Compile-time assertions to ensure UnusedType implements necessary interfaces.\nvar (\n\t_ ssz.StaticObject        = (*UnusedType)(nil)\n\t_ SSZMarshallableRootable = (*UnusedType)(nil)\n\t_ UnusedEnforcer          = (*UnusedType)(nil)\n)\n\ntype UnusedType uint8\n\n// SizeSSZ returns the SSZ encoded size in bytes for the UnusedType.\nfunc (ut *UnusedType) SizeSSZ(_ *ssz.Sizer) uint32 {\n\treturn 1\n}\n\n// DefineSSZ defines the SSZ encoding for the UnusedType object.\nfunc (ut *UnusedType) DefineSSZ(c *ssz.Codec) {\n\tssz.DefineUint8(c, ut)\n}\n\n// MarshalSSZ marshals the UnusedType object to SSZ format.\nfunc (ut *UnusedType) MarshalSSZ() ([]byte, error) {\n\tbuf := make([]byte, ssz.Size(ut))\n\treturn buf, ssz.EncodeToBytes(buf, ut)\n}\n\nfunc (ut *UnusedType) ValidateAfterDecodingSSZ() error {\n\treturn ut.EnforceUnused()\n}\n\n// HashTreeRoot returns the hash tree root of the Deposits.\nfunc (ut *UnusedType) HashTreeRoot() Root {\n\treturn ssz.HashSequential(ut)\n}\n\n// EnforceUnused return true if the UnusedType contains all zero values.\n// As long as this type remains unused and unvalidated by consensus,\n// we must enforce that it contains no data.\nfunc (ut *UnusedType) EnforceUnused() error {\n\tif *ut != UnusedType(0) {\n\t\treturn errors.New(\"UnusedType must be unused\")\n\t}\n\treturn nil\n}\n\nfunc EnforceAllUnused(enforcers ...UnusedEnforcer) error {\n\tfor _, enforcer := range enforcers {\n\t\tif err := enforcer.EnforceUnused(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "primitives/common/unused_type_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage common_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/karalabe/ssz\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// Verify that DecodeFromBytes produces the same UnusedType obj as the previous implementation\n// defined by *v = UnusedType(buf[0])\nfunc TestDecodeUnusedTypeEquality(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tbuf     []byte\n\t\twantErr bool\n\t}{\n\t\t{name: \"decode-unused-type-empty\", buf: []byte{0x00}, wantErr: false},\n\t\t{name: \"decode-unused-type-one\", buf: []byte{0x01}, wantErr: false},\n\t\t{name: \"decode-unused-type-max\", buf: []byte{0xff}, wantErr: false},\n\t\t{name: \"decode-unused-type-too-long\", buf: []byte{0xff, 0xff}, wantErr: true},\n\t\t{name: \"decode-unused-type-too-short\", buf: []byte{}, wantErr: true},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tgot := new(common.UnusedType)\n\t\t\tif err := ssz.DecodeFromBytes(tt.buf, got); err != nil {\n\t\t\t\tif tt.wantErr {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tt.Errorf(\"DecodeFromBytes() error = %v\", err)\n\t\t\t}\n\t\t\twant := common.UnusedType(tt.buf[0])\n\t\t\trequire.Equal(t, &want, got)\n\t\t})\n\t}\n}\n\n// Verify that MarshalSSZ produces the same bytes as the previous implementation\n// defined by:\n// []byte{uint8(*ut)}\nfunc TestEncodeUnusedTypeEquality(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname string\n\t\tut   common.UnusedType\n\t}{\n\t\t{name: \"encode-unused-type-empty\", ut: common.UnusedType(0)},\n\t\t{name: \"encode-unused-type-one\", ut: common.UnusedType(1)},\n\t\t{name: \"encode-unused-type-max\", ut: ^common.UnusedType(0)},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tgot, err := tt.ut.MarshalSSZ()\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"MarshalSSZ() error = %v\", err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\twant := []byte{uint8(tt.ut)}\n\t\t\trequire.Equal(t, want, got)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "primitives/constants/bls12_381.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage constants\n\nconst (\n\t// BLSSignatureLength defines the byte length of a BLS12-381 Signature.\n\t// It is 96 bytes as defined in the Ethereum 2.0 Specification.\n\tBLSSignatureLength = 96\n\n\t// BLSPubkeyLength defines the byte length of a BLS12-381 public key.\n\t// As per the standard, it is set to 48 bytes.\n\tBLSPubkeyLength = 48\n\n\t// BLSSecretKeyLength defines the byte length of a BLS12-381 secret key.\n\t// It is defined to be 32 bytes in length.\n\tBLSSecretKeyLength = 32\n)\n"
  },
  {
    "path": "primitives/constants/constants.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage constants\n\nconst (\n\t// RootLength the length of a HashTreeRoot in bytes.\n\tRootLength = 32\n\n\t// SSZOffsetSize is the number of bytes that an SSZ Offset contains.\n\tSSZOffsetSize uint32 = 4\n)\n"
  },
  {
    "path": "primitives/constants/eip4844.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage constants\n\nconst (\n\t// BlobCommitmentVersion is the version of the blob commitment.\n\t// It is the Version byte for the point evaluation precompile as\n\t// defined in EIP-4844.\n\t//\n\t// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4844.md\n\tBlobCommitmentVersion uint8 = 0x01\n\n\t// MaxBlobCommitmentsPerBlock is the hardfork-independent fixed\n\t// theoretical limit same as TARGET_BLOB_GAS_PER_BLOCK (see EIP 4844).\n\t//\n\t// https://ethereum.github.io/consensus-specs/specs/deneb/beacon-chain/#execution\n\tMaxBlobCommitmentsPerBlock = 4096\n\n\t// MaxBlobSidecarsPerBlock is the maximum number of blob sidecars that can\n\t// be included in a block.\n\tMaxBlobSidecarsPerBlock = 6\n)\n"
  },
  {
    "path": "primitives/constants/misc.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage constants\n\nimport (\n\tstdmath \"math\"\n\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// Genesis constants taken from:\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#misc\nconst (\n\t// GenesisSlot represents the initial slot in the system.\n\tGenesisSlot math.Slot = 0\n\t// GenesisEpoch represents the initial epoch in the system.\n\tGenesisEpoch math.Epoch = 0\n\t// FarFutureEpoch represents a far future epoch value.\n\tFarFutureEpoch math.Epoch = stdmath.MaxUint64\n)\n\n// Electra constants taken from :\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/electra/beacon-chain.md#misc\nconst (\n\t// FullExitRequestAmount is the request amount for a full exit request, i.e. when a validator\n\t// wants to withdraw its entire balance.\n\tFullExitRequestAmount math.Gwei = 0\n)\n\n// Berachain constants.\nconst (\n\t// FirstDepositIndex represents the index of the first deposit in the system, set at genesis.\n\tFirstDepositIndex uint64 = 0\n)\n\n// State list lengths.\nconst (\n\t// ValidatorsRegistryLimit is the maximum number of validators that can be registered.\n\t// https://github.com/ethereum/consensus-specs/blob/dev/presets/mainnet/phase0.yaml#L55\n\t// 2**40 (= 1,099,511,627,776) validator spots.\n\tValidatorsRegistryLimit = 1_099_511_627_776\n\n\t// PendingPartialWithdrawalsLimit is the maximum number of pending partial withdrawals.\n\t// https://github.com/ethereum/consensus-specs/blob/dev/specs/electra/beacon-chain.md#state-list-lengths\n\t// 2**27 (= 134,217,728) pending partial withdrawals\n\t// If the limit is hit, any new partial withdrawal requests will be dropped. This is not likely to happen but\n\t// theoretically possible.\n\tPendingPartialWithdrawalsLimit = 134_217_728\n)\n"
  },
  {
    "path": "primitives/constants/operations_per_block.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage constants\n\nconst (\n\tMaxProposerSlashings     = 16\n\tMaxAttesterSlashings     = 2\n\tMaxAttestations          = 128\n\tMaxVoluntaryExits        = 16\n\tMaxBlsToExecutionChanges = 16\n\n\t// MaxTxsPerPayload is the maximum number of transactions in a execution payload.\n\tMaxTxsPerPayload uint64 = 1048576\n\n\t// MaxWithdrawalsPerPayload is the maximum number of withdrawals in a execution payload.\n\tMaxWithdrawalsPerPayload uint64 = 16\n\n\t// MaxWithdrawalRequestsPerPayload is the maximum number of withdrawal requests in a execution\n\t// payload.\n\tMaxWithdrawalRequestsPerPayload = 16\n\n\t// MaxConsolidationRequestsPerPayload is the maximum number of consolidation requests in a\n\t// execution payload.\n\tMaxConsolidationRequestsPerPayload = 2\n\n\t// MaxDepositRequestsPerPayload is the maximum number of deposit requests in a execution payload.\n\tMaxDepositRequestsPerPayload = 8192\n)\n"
  },
  {
    "path": "primitives/constants/payload.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage constants\n\nconst (\n\t// LogsBloomLength the length of a LogsBloom in bytes.\n\tLogsBloomLength = 256\n\n\t// ExtraDataLength is the length of the extra data in bytes.\n\tExtraDataLength = 32\n\n\t// DepositContractDepth is the depth of the deposit contract merkle tree.\n\tDepositContractDepth uint64 = 32\n\n\t// MaxDeposits is the maximum number of deposits supported by the\n\t// deposit tree (2**32). This is different from the enforced\n\t// MaxDepositsPerBlock.\n\tMaxDeposits uint64 = 1 << DepositContractDepth\n\n\t// MaxBytesPerTx is the maximum number of bytes per transaction.\n\tMaxBytesPerTx uint64 = 1073741824\n)\n\n// Execution Layer Triggered Requests:\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/electra/beacon-chain.md#execution-layer-triggered-requests\nconst (\n\tDepositRequestType       = byte(0x00)\n\tWithdrawalRequestType    = byte(0x01)\n\tConsolidationRequestType = byte(0x02)\n)\n\n// Withdrawals processing:\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/electra/beacon-chain.md#withdrawals-processing\nconst (\n\t// MaxPendingPartialsPerWithdrawalsSweep is the maximum number of pending partial withdrawals\n\t// per sweep.\n\tMaxPendingPartialsPerWithdrawalsSweep = 8\n)\n"
  },
  {
    "path": "primitives/constants/validator.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage constants\n\n// Validator status strings.\nconst (\n\tValidatorStatusPendingInitialized = \"pending_initialized\"\n\tValidatorStatusPendingQueued      = \"pending_queued\"\n\tValidatorStatusActiveOngoing      = \"active_ongoing\"\n\tValidatorStatusActiveExiting      = \"active_exiting\"\n\tValidatorStatusActiveSlashed      = \"active_slashed\"\n\tValidatorStatusExitedUnslashed    = \"exited_unslashed\"\n\tValidatorStatusExitedSlashed      = \"exited_slashed\"\n\tValidatorStatusWithdrawalPossible = \"withdrawal_possible\"\n\tValidatorStatusWithdrawalDone     = \"withdrawal_done\"\n)\n"
  },
  {
    "path": "primitives/constraints/ssz.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage constraints\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// SSZMarshaler is an interface for objects that can be\n// marshaled to SSZ format.\ntype SSZMarshaler interface {\n\t// MarshalSSZ marshals the object into SSZ format.\n\tMarshalSSZ() ([]byte, error)\n}\n\n// SSZUnmarshaler is an interface for objects that can be unmarshaled from SSZ format.\ntype SSZUnmarshaler interface {\n\tssz.Object\n\tValidateAfterDecodingSSZ() error // once unmarshalled we will check whether type syntax is correct\n}\n\n// SSZMarshallable is an interface that combines SSZMarshaler and SSZUnmarshaler.\ntype SSZMarshallable interface {\n\tSSZMarshaler\n\tSSZUnmarshaler\n}\n\n// Versionable is a constraint that requires a type to have a GetForkVersion method.\ntype Versionable interface {\n\tGetForkVersion() common.Version\n}\n\n// SSZVersionable is an interface that combines SSZMarshallable and Versionable.\ntype SSZVersionedMarshallable interface {\n\tVersionable\n\tSSZMarshallable\n}\n\n// SSZRootable is an interface for objects that can compute their hash tree root.\ntype SSZRootable interface {\n\t// HashTreeRoot computes the hash tree root of the object.\n\tHashTreeRoot() common.Root\n}\n\n// SSZMarshallableRootable is an interface that combines\n// sszMarshaler, sszUnmarshaler, and SSZRootable.\ntype SSZMarshallableRootable interface {\n\tSSZMarshallable\n\tSSZRootable\n}\n\n// SSZVersionedMarshallableRootable is an interface that combines\n// SSZVersionedMarshallable and SSZRootable.\ntype SSZVersionedMarshallableRootable interface {\n\tSSZVersionedMarshallable\n\tSSZRootable\n}\n"
  },
  {
    "path": "primitives/crypto/bls.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage crypto\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\tcometencoding \"github.com/cometbft/cometbft/crypto/encoding\"\n)\n\n// CometBLSType is the BLS curve type used in the Comet BFT consensus\n// algorithm.\nconst CometBLSType = \"bls12_381\"\n\ntype (\n\t// BLSPubkey as per the Ethereum 2.0 Specification:\n\t// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#custom-types\n\tBLSPubkey = bytes.B48\n\n\t// BLSSignature as per the Ethereum 2.0 Specification:\n\t// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#custom-types\n\tBLSSignature = bytes.B96\n)\n\nfunc GetAddressFromPubKey(pubKey BLSPubkey) ([]byte, error) {\n\tpk, err := cometencoding.PubKeyFromTypeAndBytes(CometBLSType, pubKey[:])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed retrieving pubKey from bytes: %w\", err)\n\t}\n\treturn pk.Address(), nil\n}\n\n// BLSSigner defines an interface for cryptographic signing operations.\n// It uses generic type parameters Signature and Pubkey, both of which are\n// slices of bytes.\ntype BLSSigner interface {\n\t// PublicKey returns the public key of the signer.\n\tPublicKey() BLSPubkey\n\n\t// Sign takes a message as a slice of bytes and returns a signature as a\n\t// slice of bytes and an error.\n\tSign([]byte) (BLSSignature, error)\n\n\t// VerifySignature verifies a signature against a message and a public key.\n\tVerifySignature(pubKey BLSPubkey, msg []byte, signature BLSSignature) error\n}\n"
  },
  {
    "path": "primitives/crypto/mocks/bls_signer.mock.go",
    "content": "// Code generated by mockery v2.53.5. DO NOT EDIT.\n\npackage mocks\n\nimport (\n\tcrypto \"github.com/berachain/beacon-kit/primitives/crypto\"\n\tmock \"github.com/stretchr/testify/mock\"\n)\n\n// Blssigner is an autogenerated mock type for the BLSSigner type\ntype Blssigner struct {\n\tmock.Mock\n}\n\ntype Blssigner_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *Blssigner) EXPECT() *Blssigner_Expecter {\n\treturn &Blssigner_Expecter{mock: &_m.Mock}\n}\n\n// PublicKey provides a mock function with no fields\nfunc (_m *Blssigner) PublicKey() crypto.BLSPubkey {\n\tret := _m.Called()\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for PublicKey\")\n\t}\n\n\tvar r0 crypto.BLSPubkey\n\tif rf, ok := ret.Get(0).(func() crypto.BLSPubkey); ok {\n\t\tr0 = rf()\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(crypto.BLSPubkey)\n\t\t}\n\t}\n\n\treturn r0\n}\n\n// Blssigner_PublicKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PublicKey'\ntype Blssigner_PublicKey_Call struct {\n\t*mock.Call\n}\n\n// PublicKey is a helper method to define mock.On call\nfunc (_e *Blssigner_Expecter) PublicKey() *Blssigner_PublicKey_Call {\n\treturn &Blssigner_PublicKey_Call{Call: _e.mock.On(\"PublicKey\")}\n}\n\nfunc (_c *Blssigner_PublicKey_Call) Run(run func()) *Blssigner_PublicKey_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun()\n\t})\n\treturn _c\n}\n\nfunc (_c *Blssigner_PublicKey_Call) Return(_a0 crypto.BLSPubkey) *Blssigner_PublicKey_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *Blssigner_PublicKey_Call) RunAndReturn(run func() crypto.BLSPubkey) *Blssigner_PublicKey_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// Sign provides a mock function with given fields: _a0\nfunc (_m *Blssigner) Sign(_a0 []byte) (crypto.BLSSignature, error) {\n\tret := _m.Called(_a0)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for Sign\")\n\t}\n\n\tvar r0 crypto.BLSSignature\n\tvar r1 error\n\tif rf, ok := ret.Get(0).(func([]byte) (crypto.BLSSignature, error)); ok {\n\t\treturn rf(_a0)\n\t}\n\tif rf, ok := ret.Get(0).(func([]byte) crypto.BLSSignature); ok {\n\t\tr0 = rf(_a0)\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(crypto.BLSSignature)\n\t\t}\n\t}\n\n\tif rf, ok := ret.Get(1).(func([]byte) error); ok {\n\t\tr1 = rf(_a0)\n\t} else {\n\t\tr1 = ret.Error(1)\n\t}\n\n\treturn r0, r1\n}\n\n// Blssigner_Sign_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Sign'\ntype Blssigner_Sign_Call struct {\n\t*mock.Call\n}\n\n// Sign is a helper method to define mock.On call\n//   - _a0 []byte\nfunc (_e *Blssigner_Expecter) Sign(_a0 interface{}) *Blssigner_Sign_Call {\n\treturn &Blssigner_Sign_Call{Call: _e.mock.On(\"Sign\", _a0)}\n}\n\nfunc (_c *Blssigner_Sign_Call) Run(run func(_a0 []byte)) *Blssigner_Sign_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].([]byte))\n\t})\n\treturn _c\n}\n\nfunc (_c *Blssigner_Sign_Call) Return(_a0 crypto.BLSSignature, _a1 error) *Blssigner_Sign_Call {\n\t_c.Call.Return(_a0, _a1)\n\treturn _c\n}\n\nfunc (_c *Blssigner_Sign_Call) RunAndReturn(run func([]byte) (crypto.BLSSignature, error)) *Blssigner_Sign_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// VerifySignature provides a mock function with given fields: pubKey, msg, signature\nfunc (_m *Blssigner) VerifySignature(pubKey crypto.BLSPubkey, msg []byte, signature crypto.BLSSignature) error {\n\tret := _m.Called(pubKey, msg, signature)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for VerifySignature\")\n\t}\n\n\tvar r0 error\n\tif rf, ok := ret.Get(0).(func(crypto.BLSPubkey, []byte, crypto.BLSSignature) error); ok {\n\t\tr0 = rf(pubKey, msg, signature)\n\t} else {\n\t\tr0 = ret.Error(0)\n\t}\n\n\treturn r0\n}\n\n// Blssigner_VerifySignature_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'VerifySignature'\ntype Blssigner_VerifySignature_Call struct {\n\t*mock.Call\n}\n\n// VerifySignature is a helper method to define mock.On call\n//   - pubKey crypto.BLSPubkey\n//   - msg []byte\n//   - signature crypto.BLSSignature\nfunc (_e *Blssigner_Expecter) VerifySignature(pubKey interface{}, msg interface{}, signature interface{}) *Blssigner_VerifySignature_Call {\n\treturn &Blssigner_VerifySignature_Call{Call: _e.mock.On(\"VerifySignature\", pubKey, msg, signature)}\n}\n\nfunc (_c *Blssigner_VerifySignature_Call) Run(run func(pubKey crypto.BLSPubkey, msg []byte, signature crypto.BLSSignature)) *Blssigner_VerifySignature_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(crypto.BLSPubkey), args[1].([]byte), args[2].(crypto.BLSSignature))\n\t})\n\treturn _c\n}\n\nfunc (_c *Blssigner_VerifySignature_Call) Return(_a0 error) *Blssigner_VerifySignature_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *Blssigner_VerifySignature_Call) RunAndReturn(run func(crypto.BLSPubkey, []byte, crypto.BLSSignature) error) *Blssigner_VerifySignature_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewBlssigner creates a new instance of Blssigner. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewBlssigner(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *Blssigner {\n\tmock := &Blssigner{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "primitives/crypto/sha256/sha256.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage sha256\n\nimport (\n\t\"hash\"\n\t\"sync\"\n\n\t\"github.com/minio/sha256-simd\"\n)\n\n// sha256Pool is a pool of sha256 hash functions.\n//\n//nolint:gochecknoglobals // needed for pool.\nvar sha256Pool = sync.Pool{New: func() interface{} {\n\treturn sha256.New()\n}}\n\n// Sha256 defines a function that returns the sha256 checksum of the data passed\n// in. Adheres to the crypto.HashFn signature.\n// https://github.com/ethereum/consensus-specs/blob/v0.9.3/specs/core/0_beacon-chain.md#hash\nfunc Hash(data []byte) [32]byte {\n\th, ok := sha256Pool.Get().(hash.Hash)\n\tif !ok {\n\t\th = sha256.New()\n\t}\n\tdefer sha256Pool.Put(h)\n\th.Reset()\n\n\tvar b [32]byte\n\t//#nosec:G104 bet\n\th.Write(data)\n\th.Sum(b[:0])\n\treturn b\n}\n\n// CustomHashFn provides a hash function utilizing\n// an internal hasher. It is not thread-safe as the same\n// hasher instance is reused.\n//\n// Note: This method is more efficient only if the callback\n// is invoked more than 5 times.\nfunc CustomHashFn() func([]byte) [32]byte {\n\thasher, ok := sha256Pool.Get().(hash.Hash)\n\tif !ok {\n\t\thasher = sha256.New()\n\t} else {\n\t\thasher.Reset()\n\t}\n\tvar h [32]byte\n\n\treturn func(data []byte) [32]byte {\n\t\t//#nosec:G104 // bet\n\t\thasher.Write(data)\n\t\thasher.Sum(h[:0])\n\t\thasher.Reset()\n\n\t\treturn h\n\t}\n}\n"
  },
  {
    "path": "primitives/eip4844/blob.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage eip4844\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n)\n\n// Blob represents an EIP-4844 data blob.\ntype Blob [131072]byte\n\n// UnmarshalJSON parses a blob in hex syntax.\nfunc (b *Blob) UnmarshalJSON(input []byte) error {\n\treturn bytes.UnmarshalFixedJSON(input, b[:])\n}\n\n// MarshalText returns the hex representation of b.\nfunc (b Blob) MarshalText() ([]byte, error) {\n\treturn bytes.Bytes(b[:]).MarshalText()\n}\n"
  },
  {
    "path": "primitives/eip4844/blob_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage eip4844_test\n\nimport (\n\t\"encoding/hex\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestBlob_UnmarshalJSON(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tinput    []byte\n\t\texpected []byte\n\t\twantErr  bool\n\t}{\n\t\t{\n\t\t\tname: \"valid hex input\",\n\t\t\tinput: []byte(\n\t\t\t\t`\"0x` + hex.EncodeToString(make([]byte, 131072)) + `\"`,\n\t\t\t),\n\t\t\texpected: []byte{\n\t\t\t\t0x0,\n\t\t\t\t0x0,\n\t\t\t\t0x0,\n\t\t\t\t0x0,\n\t\t\t\t0x0,\n\t\t\t\t0x0,\n\t\t\t\t0x0,\n\t\t\t\t0x0,\n\t\t\t\t0x0,\n\t\t\t\t0x0,\n\t\t\t\t0x0,\n\t\t\t\t0x0,\n\t\t\t\t0x0,\n\t\t\t\t0x0,\n\t\t\t\t0x0,\n\t\t\t\t0x0,\n\t\t\t},\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid hex input\",\n\t\t\tinput:   []byte(`\"invalidhex\"`),\n\t\t\twantErr: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar b eip4844.Blob\n\t\t\terr := b.UnmarshalJSON(tt.input)\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err, \"Test case: %s\", tt.name)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err, \"Test case: %s\", tt.name)\n\t\t\t\trequire.Equal(t, tt.expected, b[:len(tt.expected)],\n\t\t\t\t\t\"Test case: %s\", tt.name)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestBlob_MarshalText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tinput    eip4844.Blob\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tname: \"valid blob\",\n\t\t\tinput: func() eip4844.Blob {\n\t\t\t\tvar b eip4844.Blob\n\t\t\t\tcopy(\n\t\t\t\t\tb[:],\n\t\t\t\t\t[]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,\n\t\t\t\t\t\t0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},\n\t\t\t\t)\n\t\t\t\treturn b\n\t\t\t}(),\n\t\t\texpected: func() string {\n\t\t\t\tvar b eip4844.Blob\n\t\t\t\tcopy(\n\t\t\t\t\tb[:],\n\t\t\t\t\t[]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,\n\t\t\t\t\t\t0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},\n\t\t\t\t)\n\t\t\t\treturn \"0x\" + hex.EncodeToString(b[:])\n\t\t\t}(),\n\t\t},\n\t\t{\n\t\t\tname: \"all zero bytes\",\n\t\t\tinput: func() eip4844.Blob {\n\t\t\t\tvar b eip4844.Blob\n\t\t\t\tcopy(b[:], make([]byte, len(b)))\n\t\t\t\treturn b\n\t\t\t}(),\n\t\t\texpected: func() string {\n\t\t\t\tvar b eip4844.Blob\n\t\t\t\tcopy(b[:], make([]byte, len(b)))\n\t\t\t\treturn \"0x\" + hex.EncodeToString(b[:])\n\t\t\t}(),\n\t\t},\n\t\t{\n\t\t\tname: \"all max bytes\",\n\t\t\tinput: func() eip4844.Blob {\n\t\t\t\tvar b eip4844.Blob\n\t\t\t\tfor i := range b {\n\t\t\t\t\tb[i] = 0xFF\n\t\t\t\t}\n\t\t\t\treturn b\n\t\t\t}(),\n\t\t\texpected: func() string {\n\t\t\t\tvar b eip4844.Blob\n\t\t\t\tfor i := range b {\n\t\t\t\t\tb[i] = 0xFF\n\t\t\t\t}\n\t\t\t\treturn \"0x\" + hex.EncodeToString(b[:])\n\t\t\t}(),\n\t\t},\n\t\t{\n\t\t\tname: \"mixed values\",\n\t\t\tinput: func() eip4844.Blob {\n\t\t\t\tvar b eip4844.Blob\n\t\t\t\tcopy(\n\t\t\t\t\tb[:],\n\t\t\t\t\t[]byte{0x00, 0xFF, 0xAA, 0x55, 0x11, 0x22, 0x33, 0x44,\n\t\t\t\t\t\t0x88, 0x99, 0x77, 0x66, 0xEE, 0xDD, 0xCC, 0xBB},\n\t\t\t\t)\n\t\t\t\treturn b\n\t\t\t}(),\n\t\t\texpected: func() string {\n\t\t\t\tvar b eip4844.Blob\n\t\t\t\tcopy(\n\t\t\t\t\tb[:],\n\t\t\t\t\t[]byte{0x00, 0xFF, 0xAA, 0x55, 0x11, 0x22, 0x33, 0x44,\n\t\t\t\t\t\t0x88, 0x99, 0x77, 0x66, 0xEE, 0xDD, 0xCC, 0xBB},\n\t\t\t\t)\n\t\t\t\treturn \"0x\" + hex.EncodeToString(b[:])\n\t\t\t}(),\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\toutput, err := tt.input.MarshalText()\n\t\t\trequire.NoError(t, err, \"Test case: %s\", tt.name)\n\t\t\trequire.Equal(\n\t\t\t\tt,\n\t\t\t\ttt.expected,\n\t\t\t\tstring(output),\n\t\t\t\t\"Test case: %s\",\n\t\t\t\ttt.name,\n\t\t\t)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "primitives/eip4844/kzg_commitment.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage eip4844\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto/sha256\"\n\t\"github.com/prysmaticlabs/gohashtree\"\n)\n\n// KZGCommitment is a KZG commitment.\ntype KZGCommitment [48]byte\n\n// ToVersionedHash converts this KZG commitment into a versioned hash\n// as per the Ethereum 2.0 specification:\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/deneb/beacon-chain.md#kzg_commitment_to_versioned_hash\nfunc (c KZGCommitment) ToVersionedHash() [32]byte {\n\tsum := sha256.Hash(c[:])\n\t// Prefix the hash with the BlobCommitmentVersion\n\t// to create a versioned hash.\n\tsum[0] = constants.BlobCommitmentVersion\n\treturn sum\n}\n\n// ToHashChunks converts this KZG commitment into a set of hash chunks.\nfunc (c KZGCommitment) ToHashChunks() [][32]byte {\n\tchunks := make([][32]byte, 2) //nolint:mnd // 2 chunks.\n\tcopy(chunks[0][:], c[:constants.RootLength])\n\tcopy(chunks[1][:], c[constants.RootLength:])\n\tgohashtree.HashChunks(chunks, chunks)\n\treturn chunks\n}\n\n// HashTreeRoot returns the hash tree root of the commitment.\nfunc (c KZGCommitment) HashTreeRoot() common.Root {\n\tchunks := c.ToHashChunks()\n\treturn chunks[0]\n}\n\n// UnmarshalJSON parses a commitment in hex syntax.\nfunc (c *KZGCommitment) UnmarshalJSON(input []byte) error {\n\treturn bytes.UnmarshalFixedJSON(\n\t\tinput,\n\t\tc[:],\n\t)\n}\n\n// MarshalText returns the hex representation of c.\nfunc (c KZGCommitment) MarshalText() ([]byte, error) {\n\treturn bytes.Bytes(c[:]).MarshalText()\n}\n\n// KZGCommitments represents a slice of KZG commitments.\ntype KZGCommitments[HashT ~[32]byte] []KZGCommitment\n\n// ToVersionedHashes converts the commitments to a set of\n// versioned hashes. It is simplify a convenience method\n// for converting a slice of commitments to a slice of\n// versioned hashes.\nfunc (c KZGCommitments[HashT]) ToVersionedHashes() []HashT {\n\thashes := make([]HashT, len(c))\n\tfor i, bz := range c {\n\t\thashes[i] = bz.ToVersionedHash()\n\t}\n\treturn hashes\n}\n\n// Leafify converts the commitments to a slice of leaves. Each leaf is the\n// hash tree root of each commitment.\nfunc (c KZGCommitments[HashT]) Leafify() []common.Root {\n\tleaves := make([]common.Root, len(c))\n\tfor i, commitment := range c {\n\t\tleaves[i] = commitment.HashTreeRoot()\n\t}\n\treturn leaves\n}\n"
  },
  {
    "path": "primitives/eip4844/kzg_commitment_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage eip4844_test\n\nimport (\n\t\"encoding/hex\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestKzgCommitmentToVersionedHash(t *testing.T) {\n\tt.Parallel()\n\n\tcommitment := newTestCommitment(\"test commitment\")\n\texpectedPrefix := constants.BlobCommitmentVersion\n\n\thash := commitment.ToVersionedHash()\n\trequire.Equal(t, expectedPrefix, hash[0],\n\t\t\"First byte of hash should match BlobCommitmentVersion\")\n\trequire.Len(t, hash, 32, \"Hash length should be 32 bytes\")\n}\n\nfunc TestKzgCommitmentsToVersionedHashHashes(t *testing.T) {\n\tt.Parallel()\n\tcommitments := []eip4844.KZGCommitment{\n\t\tnewTestCommitment(\"commitment 1\"),\n\t\tnewTestCommitment(\"commitment 2\"),\n\t}\n\n\thashes := eip4844.KZGCommitments[[32]byte](commitments).ToVersionedHashes()\n\trequire.Len(t, hashes, len(commitments),\n\t\t\"Number of hashes should match number of commitments\")\n\n\tfor i, hash := range hashes {\n\t\trequire.Equal(t, constants.BlobCommitmentVersion, hash[0],\n\t\t\t\"First byte of hash %d should match BlobCommitmentVersion\", i)\n\t}\n}\n\nfunc TestKZGCommitmentToHashChunks(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tinput    eip4844.KZGCommitment\n\t\texpected int\n\t}{\n\t\t{\"Valid input\",\n\t\t\tnewTestCommitment(\"example commitment data that \" +\n\t\t\t\t\"exceeds root length to test chunking\"),\n\t\t\t2},\n\t\t{\"Short input\", newTestCommitment(\"short\"), 2},\n\t\t{\"Empty input\", eip4844.KZGCommitment{}, 2},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tchunks := tt.input.ToHashChunks()\n\t\t\trequire.Len(t, chunks, tt.expected,\n\t\t\t\t\"Incorrect number of chunks for test: \"+tt.name)\n\t\t})\n\t}\n}\n\nfunc TestKZGCommitmentHashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tinput    eip4844.KZGCommitment\n\t\texpected common.Root\n\t}{\n\t\t{\"Simple input\", newTestCommitment(\"example commitment\"),\n\t\t\t[32]byte{138, 20, 122, 217, 77, 116, 246, 111, 195, 118, 240,\n\t\t\t\t67, 111, 145, 176, 117, 67, 82, 153, 245, 152, 25, 235, 239, 171,\n\t\t\t\t54, 148, 169, 30, 169, 167, 229}},\n\t\t{\"Empty input\", eip4844.KZGCommitment{},\n\t\t\t[32]byte{245, 165, 253, 66, 209, 106, 32, 48, 39, 152, 239,\n\t\t\t\t110, 211, 9, 151, 155, 67, 0, 61, 35, 32, 217, 240, 232, 234, 152,\n\t\t\t\t49, 169, 39, 89, 251, 75}},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\thashTreeRoot := tt.input.HashTreeRoot()\n\t\t\trequire.Equal(\n\t\t\t\tt,\n\t\t\t\ttt.expected,\n\t\t\t\thashTreeRoot,\n\t\t\t\t\"Hash tree root does not \"+\n\t\t\t\t\t\"match expected for test: \"+tt.name,\n\t\t\t)\n\t\t})\n\t}\n}\n\nfunc TestKZGCommitmentUnmarshalJSON(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname        string\n\t\tinput       string\n\t\texpected    eip4844.KZGCommitment\n\t\tshouldError bool\n\t}{\n\t\t{\n\t\t\tname: \"Valid hex input\",\n\t\t\tinput: `\"0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789` +\n\t\t\t\t`abcdef0123456789abcdef0123456789abcdef\"`,\n\t\t\texpected: func() eip4844.KZGCommitment {\n\t\t\t\tvar c eip4844.KZGCommitment\n\t\t\t\tdata, _ := hex.DecodeString(\n\t\t\t\t\t\"0123456789abcdef0123456789abcdef0\" +\n\t\t\t\t\t\t\"123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\n\t\t\t\t)\n\t\t\t\tcopy(c[:], data)\n\t\t\t\treturn c\n\t\t\t}(),\n\t\t\tshouldError: false,\n\t\t},\n\t\t{\n\t\t\tname:        \"Invalid hex input\",\n\t\t\tinput:       `\"0xG123456789abcdef\"`,\n\t\t\texpected:    eip4844.KZGCommitment{},\n\t\t\tshouldError: true,\n\t\t},\n\t\t{\n\t\t\tname:        \"Empty input\",\n\t\t\tinput:       `\"\"`,\n\t\t\texpected:    eip4844.KZGCommitment{},\n\t\t\tshouldError: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar commitment eip4844.KZGCommitment\n\t\t\terr := commitment.UnmarshalJSON([]byte(tt.input))\n\t\t\tif tt.shouldError {\n\t\t\t\trequire.Error(t, err, \"Expected an error for test: \"+tt.name)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.expected, commitment, \"Unmarshaled commitment does \"+\n\t\t\t\t\t\"not match expected for test: \"+tt.name)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestKZGCommitment_MarshalText(t *testing.T) {\n\tt.Parallel()\n\ttestCases := []struct {\n\t\tname     string\n\t\tinput    eip4844.KZGCommitment\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tname:  \"Empty Commitment\",\n\t\t\tinput: eip4844.KZGCommitment{},\n\t\t\texpected: \"3078303030303030303030303030303030303030303030303030303030\" +\n\t\t\t\t\"3030303030303030303030303030303030303030303030303030303030303030\" +\n\t\t\t\t\"3030303030303030303030303030303030303030303030303030303030303030\" +\n\t\t\t\t\"3030303030\",\n\t\t},\n\t\t{\n\t\t\tname: \"Non-Empty Commitment\",\n\t\t\tinput: func() eip4844.KZGCommitment {\n\t\t\t\tvar c eip4844.KZGCommitment\n\t\t\t\tfor i := range c {\n\t\t\t\t\tc[i] = byte(i % 256)\n\t\t\t\t}\n\t\t\t\treturn c\n\t\t\t}(),\n\t\t\texpected: \"30783030303130323033303430353036303730383039306130623063306\" +\n\t\t\t\t\"43065306631303131313231333134313531363137313831393161316231633164\" +\n\t\t\t\t\"31653166323032313232323332343235323632373238323932613262326332643\" +\n\t\t\t\t\"2653266\",\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\toutput, err := tc.input.MarshalText()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tc.expected, hex.EncodeToString(output),\n\t\t\t\t\"Test case: %s\", tc.name)\n\t\t})\n\t}\n}\n\nfunc TestKZGCommitments_Leafify(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname  string\n\t\tinput []eip4844.KZGCommitment\n\t}{\n\t\t{\n\t\t\tname: \"Single Commitment\",\n\t\t\tinput: []eip4844.KZGCommitment{\n\t\t\t\tnewTestCommitment(\"single commitment\"),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Multiple Commitments\",\n\t\t\tinput: []eip4844.KZGCommitment{\n\t\t\t\tnewTestCommitment(\"commitment one\"),\n\t\t\t\tnewTestCommitment(\"commitment two\"),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"Empty Commitments\",\n\t\t\tinput: []eip4844.KZGCommitment{},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\t// Dynamically compute expected values based on input\n\t\t\texpected := make([]common.Root, len(tt.input))\n\t\t\tfor i, commitment := range tt.input {\n\t\t\t\texpected[i] = commitment.ToHashChunks()[0]\n\t\t\t}\n\n\t\t\tleaves := eip4844.KZGCommitments[common.Root](tt.input).Leafify()\n\t\t\trequire.Equal(t, expected, leaves,\n\t\t\t\t\"Leaves do not match expected for test: \"+tt.name)\n\t\t})\n\t}\n}\n\nfunc newTestCommitment(data string) eip4844.KZGCommitment {\n\tvar c eip4844.KZGCommitment\n\tcopy(c[:], data)\n\treturn c\n}\n"
  },
  {
    "path": "primitives/eip4844/kzg_proof.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage eip4844\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n)\n\n// KZGProof represents a KZG proof, which is a 48-byte slice.\ntype KZGProof = bytes.B48\n"
  },
  {
    "path": "primitives/encoding/hex/bytes.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage hex\n\nimport (\n\t\"encoding/hex\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n)\n\nvar ErrInvalidHexStringLength = errors.New(\"invalid hex string length\")\n\n// EncodeBytes creates a hex string with 0x prefix.\n// Inverse operation is ToBytes or MustToBytes.\nfunc EncodeBytes(b []byte) string {\n\thexStr := make([]byte, len(b)*2+prefixLen)\n\tcopy(hexStr, Prefix)\n\thex.Encode(hexStr[prefixLen:], b)\n\treturn string(hexStr)\n}\n\n// MustToBytes returns the bytes represented by the given hex string.\n// It panics if the input is not a valid hex string.\nfunc MustToBytes(input string) []byte {\n\tbz, err := ToBytes(input)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn bz\n}\n\n// ToBytes returns the bytes represented by the given hex string.\n// An error is returned if the input is not a valid hex string.\nfunc ToBytes(input string) ([]byte, error) {\n\tstrippedInput, err := IsValidHex(input)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn hex.DecodeString(strippedInput)\n}\n\nfunc UnmarshalByteText(input []byte) ([]byte, error) {\n\traw, err := formatAndValidateText(input)\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\tdec := make([]byte, len(raw)/encDecRatio)\n\tif _, err = hex.Decode(dec, raw); err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn dec, nil\n}\n\n// DecodeFixedJSON decodes the input as a string with 0x prefix. The length\n// of out determines the required input length. This function is commonly used\n// to implement the UnmarshalJSON method for fixed-size types.\nfunc DecodeFixedJSON(input, out []byte) error {\n\tstrippedInput, err := ValidateQuotedString(input)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn DecodeFixedText(strippedInput, out)\n}\n\n// DecodeFixedText decodes the input as a string with 0x prefix. The length\n// of out determines the required input length.\nfunc DecodeFixedText(input, out []byte) error {\n\traw, err := formatAndValidateText(input)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif len(raw)/encDecRatio != len(out) {\n\t\treturn errors.Wrapf(\n\t\t\tErrInvalidHexStringLength,\n\t\t\t\"hex string has length %d, want %d\",\n\t\t\tlen(raw), len(out)*encDecRatio,\n\t\t)\n\t}\n\t// Pre-verify syntax and decode in a single pass\n\tfor i := 0; i < len(raw); i += 2 {\n\t\thighNibble := decodeNibble(raw[i])\n\t\tlowNibble := decodeNibble(raw[i+1])\n\t\tif highNibble == badNibble || lowNibble == badNibble {\n\t\t\treturn ErrInvalidString\n\t\t}\n\t\tout[i/2] = byte((highNibble << nibbleShift) | lowNibble) // #nosec G115 -- nibbles are validated 0-15, combined result is 0-255.\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "primitives/encoding/hex/bytes_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage hex_test\n\nimport (\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestEncodeAndDecodeBytes(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tinput    []byte\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tname:     \"typical byte slice\",\n\t\t\tinput:    []byte{0x48, 0x65, 0x6c, 0x6c, 0x6f},\n\t\t\texpected: \"0x48656c6c6f\",\n\t\t},\n\t\t{\n\t\t\tname:     \"empty byte slice\",\n\t\t\tinput:    []byte{},\n\t\t\texpected: \"0x\",\n\t\t},\n\t\t{\n\t\t\tname:     \"single byte\",\n\t\t\tinput:    []byte{0x01},\n\t\t\texpected: \"0x01\",\n\t\t},\n\t\t{\n\t\t\tname: \"long byte slice\",\n\t\t\tinput: []byte{\n\t\t\t\t0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0xba, 0xbe, 0xde, 0xad,\n\t\t\t\t0xbe, 0xef, 0xca, 0xfe, 0xba, 0xbe, 0xde, 0xad, 0xbe, 0xef,\n\t\t\t\t0xca, 0xfe, 0xba, 0xbe, 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe,\n\t\t\t\t0xba, 0xbe},\n\t\t\texpected: \"0xdeadbeefcafebabe\" + \"deadbeefcafebabe\" + \"deadbeefcafebabe\" + \"deadbeefcafebabe\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := hex.EncodeBytes(tt.input)\n\t\t\trequire.Equal(t, tt.expected, result)\n\n\t\t\t_, err := hex.IsValidHex(result)\n\t\t\trequire.NoError(t, err)\n\n\t\t\tdecoded, err := hex.ToBytes(result)\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tt.input, decoded)\n\n\t\t\trequire.NotPanics(t, func() {\n\t\t\t\tdecoded = hex.MustToBytes(result)\n\t\t\t})\n\t\t\trequire.Equal(t, tt.input, decoded)\n\t\t})\n\t}\n}\n\nfunc TestUnmarshalByteText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname      string\n\t\tinput     []byte\n\t\texpected  []byte\n\t\texpectErr bool\n\t}{\n\t\t{\n\t\t\tname:      \"valid hex string\",\n\t\t\tinput:     []byte(\"0x48656c6c6f\"),\n\t\t\texpected:  []byte{0x48, 0x65, 0x6c, 0x6c, 0x6f},\n\t\t\texpectErr: false,\n\t\t},\n\t\t{\n\t\t\tname:      \"empty hex string\",\n\t\t\tinput:     []byte(\"0x\"),\n\t\t\texpected:  []byte{},\n\t\t\texpectErr: false,\n\t\t},\n\t\t{\n\t\t\tname:      \"invalid hex string\",\n\t\t\tinput:     []byte(\"0xZZZZ\"),\n\t\t\texpected:  nil,\n\t\t\texpectErr: true,\n\t\t},\n\t\t{\n\t\t\tname:      \"invalid format\",\n\t\t\tinput:     []byte(\"invalid hex string\"),\n\t\t\texpected:  nil,\n\t\t\texpectErr: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult, err := hex.UnmarshalByteText(tt.input)\n\t\t\tif tt.expectErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.expected, result)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestDecodeFixedText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname      string\n\t\ttypename  string\n\t\tinput     []byte\n\t\texpected  []byte\n\t\texpectErr bool\n\t}{\n\t\t{\n\t\t\tname:      \"valid hex string\",\n\t\t\ttypename:  \"testType\",\n\t\t\tinput:     []byte(\"0x48656c6c6f\"),\n\t\t\texpected:  []byte{0x48, 0x65, 0x6c, 0x6c, 0x6f},\n\t\t\texpectErr: false,\n\t\t},\n\t\t{\n\t\t\tname:      \"invalid hex string length\",\n\t\t\ttypename:  \"testType\",\n\t\t\tinput:     []byte(\"0x48656c6c\"),\n\t\t\texpected:  make([]byte, 5),\n\t\t\texpectErr: true,\n\t\t},\n\t\t{\n\t\t\tname:      \"invalid hex characters\",\n\t\t\ttypename:  \"testType\",\n\t\t\tinput:     []byte(\"0xZZZZZZZZZZ\"),\n\t\t\texpected:  make([]byte, 5),\n\t\t\texpectErr: true,\n\t\t},\n\t\t{\n\t\t\tname:      \"hex.Decode error\",\n\t\t\ttypename:  \"testType\",\n\t\t\tinput:     []byte(\"0x123\"), // Invalid length for hex.Decode\n\t\t\texpected:  make([]byte, 2),\n\t\t\texpectErr: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tout := make([]byte, len(tt.expected))\n\t\t\terr := hex.DecodeFixedText(tt.input, out)\n\t\t\tif tt.expectErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.expected, out)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestDecodeFixedJSON(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname      string\n\t\ttypename  string\n\t\tinput     []byte\n\t\tout       []byte\n\t\texpectErr bool\n\t}{\n\t\t{\n\t\t\tname:      \"valid hex string\",\n\t\t\ttypename:  \"testType\",\n\t\t\tinput:     []byte(`\"0x48656c6c6f\"`),\n\t\t\tout:       make([]byte, 5),\n\t\t\texpectErr: false,\n\t\t},\n\t\t{\n\t\t\tname:      \"invalid hex string length\",\n\t\t\ttypename:  \"testType\",\n\t\t\tinput:     []byte(`\"0x48656c6c\"`),\n\t\t\tout:       make([]byte, 5),\n\t\t\texpectErr: true,\n\t\t},\n\t\t{\n\t\t\tname:      \"invalid hex characters\",\n\t\t\ttypename:  \"testType\",\n\t\t\tinput:     []byte(`\"0xZZZZZZZZZZ\"`),\n\t\t\tout:       make([]byte, 5),\n\t\t\texpectErr: true,\n\t\t},\n\t\t{\n\t\t\tname:      \"non-quoted string\",\n\t\t\ttypename:  \"testType\",\n\t\t\tinput:     []byte(`0x48656c6c6f`),\n\t\t\tout:       make([]byte, 5),\n\t\t\texpectErr: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\terr := hex.DecodeFixedJSON(\n\t\t\t\ttt.input,\n\t\t\t\ttt.out,\n\t\t\t)\n\t\t\tif tt.expectErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, []byte{0x48, 0x65, 0x6c, 0x6c, 0x6f}, tt.out)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc BenchmarkDecodeFixedText(b *testing.B) {\n\tsizes := []int{100, 1000, 10000} // Different input sizes\n\n\tfor _, size := range sizes {\n\t\tbenchName := \"Size\" + strconv.Itoa(size)\n\t\tb.Run(benchName, func(b *testing.B) {\n\t\t\tinput := make(\n\t\t\t\t[]byte,\n\t\t\t\tsize*2+2,\n\t\t\t) // Each byte is represented by 2 hex characters + \"0x\" prefix\n\t\t\tinput[0] = '0'\n\t\t\tinput[1] = 'x'\n\t\t\tfor i := 2; i < len(input); i += 2 {\n\t\t\t\tinput[i] = 'a'\n\t\t\t\tinput[i+1] = 'f'\n\t\t\t}\n\t\t\tout := make(\n\t\t\t\t[]byte,\n\t\t\t\tsize,\n\t\t\t) // Adjust the size based on the expected output length\n\n\t\t\tb.ResetTimer()\n\t\t\tfor range b.N {\n\t\t\t\terr := hex.DecodeFixedText(input, out)\n\t\t\t\tif err != nil {\n\t\t\t\t\tb.Fatalf(\"DecodeFixedText failed: %v\", err)\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "primitives/encoding/hex/const.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage hex\n\nconst (\n\tPrefix            = \"0x\"\n\tprefixLen         = len(Prefix)\n\tbadNibble         = ^uint64(0)\n\thexBase           = 16\n\tinitialCapacity   = 10\n\tencDecRatio       = 2\n\tnibblesPer64Bits  = 16 // 64/4\n\tnibblesPer256Bits = 64 // 256/4\n\tnibbleShift       = 4\n\n\t// hexadecimal conversion constants.\n\thexBaseOffset       = '0'\n\thexAlphaOffsetUpper = 'A' - 10\n\thexAlphaOffsetLower = 'a' - 10\n)\n"
  },
  {
    "path": "primitives/encoding/hex/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage hex\n\nimport (\n\t\"errors\"\n)\n\nvar (\n\tErrEmptyString        = errors.New(\"empty hex string\")\n\tErrMissingPrefix      = errors.New(\"hex string without 0x prefix\")\n\tErrOddLength          = errors.New(\"hex string of odd length\")\n\tErrNonQuotedString    = errors.New(\"non-quoted hex string\")\n\tErrInvalidString      = errors.New(\"invalid hex string\")\n\tErrLeadingZero        = errors.New(\"hex number with leading zero digits\")\n\tErrEmptyNumber        = errors.New(\"hex string \\\"0x\\\"\")\n\tErrUint64Range        = errors.New(\"hex number > 64 bits\")\n\tErrBig256Range        = errors.New(\"hex number > 256 bits\")\n\tErrInvalidBigWordSize = errors.New(\"weird big.Word size\")\n)\n"
  },
  {
    "path": "primitives/encoding/hex/format.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage hex\n\nimport (\n\t\"errors\"\n\t\"strings\"\n)\n\n// IsValidHex performs basic validations that every hex string\n// must pass (there may be extra ones depending on the type encoded)\n// It returns the suffix (dropping 0x prefix) in the hope to appease nilaway.\nfunc IsValidHex[T ~[]byte | ~string](s T) (T, error) {\n\tif len(s) == 0 {\n\t\treturn *new(T), ErrEmptyString\n\t}\n\tif len(s) < prefixLen {\n\t\treturn *new(T), ErrMissingPrefix\n\t}\n\tif strings.ToLower(string(s[:prefixLen])) != Prefix {\n\t\treturn *new(T), ErrMissingPrefix\n\t}\n\treturn s[prefixLen:], nil\n}\n\n// ValidateQuotedString errs if input has no quotes.\n// For convenience it returns the unstrip content if it does not err.\nfunc ValidateQuotedString(input []byte) ([]byte, error) {\n\tif len(input) >= 2 && input[0] == '\"' && input[len(input)-1] == '\"' {\n\t\treturn input[1 : len(input)-1], nil\n\t}\n\treturn nil, ErrNonQuotedString\n}\n\n// formatAndValidateText validates the input text for a hex string.\nfunc formatAndValidateText(input []byte) ([]byte, error) {\n\tinput, err := IsValidHex(input)\n\tif errors.Is(err, ErrEmptyString) {\n\t\treturn nil, nil // empty strings are allowed\n\t} else if err != nil {\n\t\treturn nil, err\n\t}\n\n\tif len(input)%2 != 0 {\n\t\treturn nil, ErrOddLength\n\t}\n\treturn input, nil\n}\n\n// formatAndValidateNumber checks the input text for a hex number.\nfunc formatAndValidateNumber[T []byte | string](input T) (T, error) {\n\tinput, err := IsValidHex(input)\n\tif err != nil {\n\t\treturn *new(T), err\n\t}\n\n\tif len(input) == 0 {\n\t\treturn *new(T), ErrEmptyNumber\n\t}\n\tif len(input) > 1 && input[0] == '0' {\n\t\treturn *new(T), ErrLeadingZero\n\t}\n\treturn input, nil\n}\n"
  },
  {
    "path": "primitives/encoding/hex/format_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage hex_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestIsValidHex(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tinput   string\n\t\twantErr error\n\t}{\n\t\t{\n\t\t\tname:    \"Valid hex string\",\n\t\t\tinput:   \"0x48656c6c6f\",\n\t\t\twantErr: nil,\n\t\t},\n\t\t{\n\t\t\tname:    \"Empty string\",\n\t\t\tinput:   \"\",\n\t\t\twantErr: hex.ErrEmptyString,\n\t\t},\n\t\t{\n\t\t\tname:    \"No 0x prefix\",\n\t\t\tinput:   \"48656c6c6f\",\n\t\t\twantErr: hex.ErrMissingPrefix,\n\t\t},\n\t\t{\n\t\t\tname:    \"Valid single hex character\",\n\t\t\tinput:   \"0x0\",\n\t\t\twantErr: nil,\n\t\t},\n\t\t{\n\t\t\tname:    \"Empty hex string\",\n\t\t\tinput:   \"0x\",\n\t\t\twantErr: nil,\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\t_, err := hex.IsValidHex(test.input)\n\t\t\tif test.wantErr != nil {\n\t\t\t\trequire.ErrorIs(t, test.wantErr, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "primitives/encoding/hex/nibble.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage hex\n\n// decodeNibble decodes a single hexadecimal nibble (half-byte) into uint64.\nfunc decodeNibble(in byte) uint64 {\n\t// uint64 conversion here is safe\n\tswitch {\n\tcase in >= '0' && in <= '9':\n\t\t//#nosec G701 // The resulting value will be in the range 0-9.\n\t\treturn uint64(in - hexBaseOffset)\n\tcase in >= 'A' && in <= 'F':\n\t\t//#nosec G701 // The resulting value will be in the range 10-15.\n\t\treturn uint64(in - hexAlphaOffsetUpper)\n\tcase in >= 'a' && in <= 'f':\n\t\t//#nosec G701 // The resulting value will be in the range 10-15.\n\t\treturn uint64(in - hexAlphaOffsetLower)\n\tdefault:\n\t\treturn badNibble\n\t}\n}\n"
  },
  {
    "path": "primitives/encoding/hex/u64.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage hex\n\nimport (\n\t\"strconv\"\n)\n\n// This file contains functions for encoding and decoding uint64 values to and\n// from hexadecimal strings, and marshaling and unmarshaling uint64 values to\n// and from byte slices representing hexadecimal strings.\n\n// MarshalText returns a byte slice containing the hexadecimal representation\n// of uint64 input.\nfunc MarshalText(b uint64) ([]byte, error) {\n\tbuf := make([]byte, prefixLen, initialCapacity)\n\tcopy(buf, Prefix)\n\tbuf = strconv.AppendUint(buf, b, hexBase)\n\treturn buf, nil\n}\n\n// UnmarshalUint64Text parses a byte slice containing a hexadecimal string and\n// returns the uint64 value it represents.\nfunc UnmarshalUint64Text(input []byte) (uint64, error) {\n\traw, err := formatAndValidateNumber(input)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tif len(raw) > nibblesPer64Bits {\n\t\treturn 0, ErrUint64Range\n\t}\n\tvar dec uint64\n\tfor _, byte := range raw {\n\t\tnib := decodeNibble(byte)\n\t\tif nib == badNibble {\n\t\t\treturn dec, ErrInvalidString\n\t\t}\n\t\tdec *= hexBase // hex shift left :D\n\t\tdec += nib\n\t}\n\treturn dec, nil\n}\n"
  },
  {
    "path": "primitives/encoding/hex/u64_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage hex_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestMarshalText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tinput    uint64\n\t\texpected []byte\n\t}{\n\t\t{\"Zero\", 0, []byte(\"0x0\")},\n\t\t{\"MaxByte\", 255, []byte(\"0xff\")},\n\t\t{\"Positive value\", 12345, []byte(\"0x3039\")},\n\t\t{\"MaxWord\", 65535, []byte(\"0xffff\")},\n\t\t{\"MaxDWord\", 4294967295, []byte(\"0xffffffff\")},\n\t\t{\"MaxQWord\", 18446744073709551615, []byte(\"0xffffffffffffffff\")},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult, err := hex.MarshalText(tt.input)\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tt.expected, result)\n\n\t\t\tdecoded, err := hex.UnmarshalUint64Text(result)\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tt.input, decoded)\n\t\t})\n\t}\n}\n\nfunc TestValidateQuotedString(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tinput    []byte\n\t\texpected error\n\t}{\n\t\t{\"ValidQuotedString\", []byte(`\"0x0\"`), nil},\n\t\t{\"ValidQuotedStringFF\", []byte(`\"0xff\"`), nil},\n\t\t{\"NonQuotedString\", []byte(`0xff`), hex.ErrNonQuotedString},\n\t\t{\"InvalidQuotedString\", []byte(`\"z`), hex.ErrNonQuotedString},\n\t}\n\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\t_, err := hex.ValidateQuotedString(test.input)\n\t\t\tif test.expected != nil {\n\t\t\t\trequire.ErrorIs(t, test.expected, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestUnmarshalUint64Text(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tinput    []byte\n\t\texpected uint64\n\t\terr      error\n\t}{\n\t\t{\"Zero\", []byte(\"0x0\"), 0, nil},\n\t\t{\"MaxByte\", []byte(\"0xff\"), 255, nil},\n\t\t{\"MaxWord\", []byte(\"0xffff\"), 65535, nil},\n\t\t{\"MaxDWord\", []byte(\"0xffffffff\"), 4294967295, nil},\n\t\t{\"MaxQWord\", []byte(\"0xffffffffffffffff\"), 18446744073709551615, nil},\n\t\t{\"OutOfRange\", []byte(\"0x10000000000000000\"), 0, hex.ErrUint64Range},\n\t\t{\"InvalidString\", []byte(\"0xzz\"), 0, hex.ErrInvalidString},\n\t}\n\n\tfor _, test := range tests {\n\t\tt.Run(test.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult, err := hex.UnmarshalUint64Text(test.input)\n\t\t\tif test.err != nil {\n\t\t\t\trequire.ErrorIs(t, test.err, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, test.expected, result)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "primitives/encoding/json/json.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n//\n//nolint:gochecknoglobals // intentional aliases.\npackage json\n\nimport (\n\t\"encoding/json\"\n)\n\n// Marshaler is the interface implemented by types that\n// can marshal themselves into valid JSON.\ntype Marshaler = json.Marshaler\n\n// Unmarshaler is the interface implemented by types\n// that can unmarshal a JSON description of themselves.\ntype Unmarshaler = json.Unmarshaler\n\nvar Marshal = json.Marshal\n\nvar MarshalIndent = json.MarshalIndent\n\nvar Unmarshal = json.Unmarshal\n\n// RawMessage is an alias for json.RawMessage, represensting a raw encoded JSON\n// value. It implements Marshaler and Unmarshaler and can be used to delay JSON\n// decoding or precompute a JSON encoding.\ntype RawMessage = json.RawMessage\n"
  },
  {
    "path": "primitives/encoding/ssz/schema/common.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage schema\n\nconst (\n\tBoolSize = 1\n\tU8Size   = 1\n\tU16Size  = 2\n\tU32Size  = 4\n\tU64Size  = 8\n\tU128Size = 16\n\tU256Size = 32\n\n\tB4Size   = 4\n\tB8Size   = 8\n\tB16Size  = 16\n\tB20Size  = 20\n\tB32Size  = 32\n\tB48Size  = 48\n\tB64Size  = 64\n\tB96Size  = 96\n\tB256Size = 256\n)\n\n// Basic SSZ types.\n// Bool returns an SSZType representing a boolean.\nfunc Bool() SSZType { return basic(BoolSize) }\n\n// U8 returns an SSZType representing an 8-bit unsigned integer.\nfunc U8() SSZType { return basic(U8Size) }\n\n// U16 returns an SSZType representing a 16-bit unsigned integer.\nfunc U16() SSZType { return basic(U16Size) }\n\n// U32 returns an SSZType representing a 32-bit unsigned integer.\nfunc U32() SSZType { return basic(U32Size) }\n\n// U64 returns an SSZType representing a 64-bit unsigned integer.\nfunc U64() SSZType { return basic(U64Size) }\n\n// U128 returns an SSZType representing a 128-bit unsigned integer.\nfunc U128() SSZType { return basic(U128Size) }\n\n// U256 returns an SSZType representing a 256-bit unsigned integer.\nfunc U256() SSZType { return basic(U256Size) }\n\n// B4 creates a DefineByteVector of 4 bytes (32 bits).\nfunc B4() SSZType { return DefineByteVector(B4Size) }\n\n// B8 creates a DefineByteVector of 8 bytes (64 bits).\nfunc B8() SSZType { return DefineByteVector(B8Size) }\n\n// B16 creates a DefineByteVector of 16 bytes (128 bits).\nfunc B16() SSZType { return DefineByteVector(B16Size) }\n\n// B20 creates a DefineByteVector of 20 bytes (160 bits).\nfunc B20() SSZType { return DefineByteVector(B20Size) }\n\n// B32 creates a DefineByteVector of 32 bytes (256 bits).\nfunc B32() SSZType { return DefineByteVector(B32Size) }\n\n// B48 creates a DefineByteVector of 48 bytes (384 bits).\nfunc B48() SSZType { return DefineByteVector(B48Size) }\n\n// B64 creates a DefineByteVector of 64 bytes (512 bits).\nfunc B64() SSZType { return DefineByteVector(B64Size) }\n\n// B96 creates a DefineByteVector of 96 bytes (768 bits).\nfunc B96() SSZType { return DefineByteVector(B96Size) }\n\n// B256 creates a Vector of 256 bytes (2048 bits).\nfunc B256() SSZType { return DefineByteVector(B256Size) }\n"
  },
  {
    "path": "primitives/encoding/ssz/schema/definitions.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage schema\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// BytesPerChunk is the number of bytes per chunk.\nconst BytesPerChunk = 32\n\n/* -------------------------------------------------------------------------- */\n/*                                    Basic                                   */\n/* -------------------------------------------------------------------------- */\n\n// basic represents a basic SSZ type.\ntype basic uint64\n\n// ID returns the type ID of the basic type.\nfunc (b basic) ID() ID { return Basic }\n\n// ItemLength returns the size of the basic type in bytes.\nfunc (b basic) ItemLength() uint64 { return uint64(b) }\n\n// ItemPosition always returns an error for basic types,\n// as they have no children.\nfunc (b basic) ItemPosition(_ string) (uint64, uint8, uint8, error) {\n\treturn 0, 0, 0, errors.New(\"basic type has no children\")\n}\n\n// ElementType returns the basic type itself, as it has no children.\nfunc (b basic) ElementType(_ string) SSZType { return b }\n\n// HashChunkCount returns the number of 32-byte chunks\n// required to represent the basic type.\nfunc (b basic) HashChunkCount() uint64 { return 1 }\n\n/* -------------------------------------------------------------------------- */\n/*                                   Vector                                   */\n/* -------------------------------------------------------------------------- */\n\ntype vector struct {\n\telementType SSZType\n\tlength      uint64\n}\n\nfunc DefineVector(elementType SSZType, length uint64) SSZType {\n\treturn vector{elementType: elementType, length: length}\n}\n\nfunc DefineByteVector(length uint64) SSZType {\n\treturn DefineVector(U8(), length)\n}\n\nfunc (v vector) ID() ID { return Vector }\n\nfunc (v vector) ItemLength() uint64 { return BytesPerChunk }\n\nfunc (v vector) ItemPosition(p string) (uint64, uint8, uint8, error) {\n\ti, err := math.U64FromString(p)\n\tif err != nil {\n\t\treturn 0, 0, 0, fmt.Errorf(\"expected index, got name %s\", p)\n\t}\n\tstart := i.Unwrap() * v.elementType.ItemLength()\n\treturn start / BytesPerChunk,\n\t\tuint8(start % BytesPerChunk), // #nosec G115 -- can't overflow.\n\t\tuint8(start%BytesPerChunk + v.ItemLength()), // #nosec G115 -- can't overflow.\n\t\tnil\n}\n\nfunc (v vector) HashChunkCount() uint64 {\n\ttotalBytes := v.Length() * v.elementType.ItemLength()\n\tchunks := (totalBytes + BytesPerChunk - 1) / BytesPerChunk\n\treturn chunks\n}\n\n// Length describes the length for vector.\nfunc (v vector) Length() uint64 {\n\treturn v.length\n}\n\nfunc (v vector) ElementType(_ string) SSZType {\n\treturn v.elementType\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                    List                                    */\n/* -------------------------------------------------------------------------- */\n\n// List Type.\ntype list struct {\n\telementType SSZType\n\tlimit       uint64\n}\n\nfunc DefineList(elementType SSZType, limit uint64) SSZType {\n\treturn list{elementType: elementType, limit: limit}\n}\n\nfunc DefineByteList(limit uint64) SSZType {\n\treturn DefineList(U8(), limit)\n}\n\nfunc (l list) ID() ID { return List }\n\nfunc (l list) ItemLength() uint64 { return l.elementType.ItemLength() }\n\nfunc (l list) HashChunkCount() uint64 {\n\ttotalBytes := l.Length() * l.elementType.ItemLength()\n\tchunks := (totalBytes + BytesPerChunk - 1) / BytesPerChunk\n\treturn chunks\n}\n\nfunc (l list) ElementType(_ string) SSZType {\n\treturn l.elementType\n}\n\n// Length describes the limit for list.\nfunc (l list) Length() uint64 {\n\treturn l.limit\n}\n\n// ItemPosition returns the chunk index and offset for a given list index.\nfunc (l list) ItemPosition(p string) (uint64, uint8, uint8, error) {\n\ti, err := math.U64FromString(p)\n\tif err != nil {\n\t\treturn 0, 0, 0, fmt.Errorf(\"expected index, got name %s\", p)\n\t}\n\tstart := i.Unwrap() * l.elementType.ItemLength()\n\treturn start / BytesPerChunk,\n\t\tuint8(start % BytesPerChunk), // #nosec G115 -- can't overflow.\n\t\tuint8(start%BytesPerChunk + l.ItemLength()), // #nosec G115 -- can't overflow.\n\t\tnil\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                  Container                                 */\n/* -------------------------------------------------------------------------- */\n\ntype container struct {\n\tFields     []SSZType\n\tFieldIndex map[string]uint64\n}\n\nfunc DefineContainer(fields ...*Field) SSZType {\n\tfieldIndex := make(map[string]uint64)\n\ttypes := make([]SSZType, len(fields))\n\tfor i, f := range fields {\n\t\tfieldIndex[f.GetName()] = uint64(i) // #nosec G115 -- todo fix.\n\t\ttypes[i] = f.GetValue()\n\t}\n\treturn container{Fields: types, FieldIndex: fieldIndex}\n}\n\nfunc (c container) ID() ID { return Container }\n\nfunc (c container) ItemLength() uint64 { return BytesPerChunk }\n\nfunc (c container) ItemPosition(p string) (uint64, uint8, uint8, error) {\n\tpos, ok := c.FieldIndex[p]\n\tif !ok {\n\t\treturn 0, 0, 0, fmt.Errorf(\"field %s not found\", p)\n\t}\n\t// #nosec G115 -- can't overflow.\n\treturn pos, 0, uint8(c.Fields[pos].ItemLength()), nil\n}\n\nfunc (c container) ElementType(p string) SSZType {\n\treturn c.Fields[c.FieldIndex[p]]\n}\n\nfunc (c container) Length() uint64 { return uint64(len(c.Fields)) }\n\nfunc (c container) HashChunkCount() uint64 { return uint64(len(c.Fields)) }\n"
  },
  {
    "path": "primitives/encoding/ssz/schema/field.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage schema\n\n// Field represents a named value of a generic type.\ntype Field struct {\n\t// name is the name of the field\n\tname string\n\t// value is the value of the field\n\tvalue SSZType\n}\n\n// NewField creates a new field.\nfunc NewField(name string, typ SSZType) *Field {\n\treturn &Field{name: name, value: typ}\n}\n\n// GetName returns the name of the field.\nfunc (f Field) GetName() string {\n\treturn f.name\n}\n\n// GetValue returns the value of the field.\nfunc (f Field) GetValue() SSZType {\n\treturn f.value\n}\n"
  },
  {
    "path": "primitives/encoding/ssz/schema/id.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage schema\n\ntype ID uint8\n\nconst (\n\tBasic ID = iota\n\tVector\n\tList\n\tContainer\n)\n\n// IsBasic returns true if the type is a basic type.\nfunc (t ID) IsBasic() bool {\n\treturn t == Basic\n}\n\n// IsElements returns true if the type is an enumerable type.\nfunc (t ID) IsElements() bool {\n\treturn t == Vector || t == List\n}\n\n// IsComposite returns true if the type is a composite type.\nfunc (t ID) IsComposite() bool {\n\treturn t == Vector || t == List || t == Container\n}\n\n// IsEnumerable returns true if the type is an enumerable type.\nfunc (t ID) IsEnumerable() bool {\n\treturn t == Vector || t == List\n}\n\n// IsList returns true if the type is a list type.\nfunc (t ID) IsList() bool {\n\treturn t == List\n}\n\n// IsContainer returns true if the type is a container type.\nfunc (t ID) IsContainer() bool {\n\treturn t == Container\n}\n\n/* -------------------------------------------------------------------------- */\n/*                              Type Definitions                              */\n/* -------------------------------------------------------------------------- */\n\n// SSZType defines the interface that type definitions must adhere to.\n// An SSZType *REPRESENTS* an underlying type, but it is NOT an instance\n// of this type.\ntype SSZType interface {\n\t// ID returns the type identifier for the SSZ type.\n\tID() ID\n\t// ItemLength returns the length of an item in bytes for the SSZ type.\n\tItemLength() uint64\n\t// ItemPosition calculates the position of an item within the SSZ type.\n\t// It returns the generalized index, start offset, end offset, and any error\n\t// encountered.\n\tItemPosition(p string) (uint64, uint8, uint8, error)\n\t// ElementType returns the SSZ type of the element at the given path.\n\tElementType(p string) SSZType\n\t// HashChunkCount returns the number of 32-byte chunks required to represent\n\t// the SSZ type in a Merkle tree.\n\tHashChunkCount() uint64\n}\n"
  },
  {
    "path": "primitives/encoding/ssz/utils.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage ssz\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/karalabe/ssz\"\n)\n\n// Unmarshal is the way we build objects from byte formatted in SSZ encoding.\n// This function highlights the common template for SSZ decoding different objects.\nfunc Unmarshal[T constraints.SSZUnmarshaler](buf []byte, v T) error {\n\tif err := ssz.DecodeFromBytes(buf, v); err != nil {\n\t\treturn fmt.Errorf(\"failed decoding %T: %w\", v, err)\n\t}\n\n\t// Note: ValidateAfterDecodingSSZ may change v even if it returns error\n\t// (depending on the specific implementations)\n\treturn v.ValidateAfterDecodingSSZ()\n}\n\n// MarshalItemsEIP7685 marshals a slice of items that satisfy SSZMarshaler according\n// to the EIP-7685 standard. It encodes each item individually and appends its bytes\n// to the output buffer.\nfunc MarshalItemsEIP7685[T constraints.SSZMarshaler](items []T) ([]byte, error) {\n\tvar buf []byte\n\tfor i, item := range items {\n\t\titemBytes, err := item.MarshalSSZ()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to marshal item at index %d: %w\", i, err)\n\t\t}\n\t\tbuf = append(buf, itemBytes...)\n\t}\n\treturn buf, nil\n}\n\n// UnmarshalItemsEIP7685 decodes a slice of items from the provided data according\n// to the EIP-7685 standard. It assumes that each item is encoded into a fixed number\n// of bytes (itemSize) and that newItem returns a new instance of the item.\nfunc UnmarshalItemsEIP7685[T constraints.SSZUnmarshaler](\n\tdata []byte,\n\titemSize int,\n\tnewItem func() T,\n) ([]T, error) {\n\tif len(data)%itemSize != 0 {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"invalid data length: %d is not a multiple of item size %d\",\n\t\t\tlen(data), itemSize,\n\t\t)\n\t}\n\tnumItems := len(data) / itemSize\n\titems := make([]T, 0, numItems)\n\tfor i := 0; i < len(data); i += itemSize {\n\t\tchunk := data[i : i+itemSize]\n\t\titem := newItem()\n\t\tif err := Unmarshal(chunk, item); err != nil {\n\t\t\treturn nil, fmt.Errorf(\n\t\t\t\t\"failed to unmarshal item at index %d: %w\", i/itemSize, err,\n\t\t\t)\n\t\t}\n\t\titems = append(items, item)\n\t}\n\treturn items, nil\n}\n"
  },
  {
    "path": "primitives/math/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage math\n\nimport (\n\t\"github.com/berachain/beacon-kit/errors\"\n)\n\nvar (\n\t// ErrUnexpectedInputLengthBase is the base error for unexpected input\n\t// length errors.\n\tErrUnexpectedInputLengthBase = errors.New(\"unexpected input length\")\n)\n\n// ErrUnexpectedInputLength returns an error indicating that the input length.\nfunc ErrUnexpectedInputLength(expected uint32, actual int) error {\n\treturn errors.Wrapf(\n\t\tErrUnexpectedInputLengthBase,\n\t\t\"expected %d, got %d\", expected, actual,\n\t)\n}\n"
  },
  {
    "path": "primitives/math/log/log.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage log\n\nimport \"math/bits\"\n\n// ILog2Ceil returns the ceiling of the base 2 logarithm of the input.\nfunc ILog2Ceil[U64T ~uint64](u U64T) uint8 {\n\t// Log2(0) is undefined, should we panic?\n\tif u == 0 {\n\t\treturn 0\n\t}\n\t// #nosec G115 -- we handle the case of u == 0 above, so this is safe.\n\treturn uint8(bits.Len64(uint64(u - 1)))\n}\n\n// ILog2Floor returns the floor of the base 2 logarithm of the input.\nfunc ILog2Floor[U64T ~uint64](u U64T) uint8 {\n\t// Log2(0) is undefined, should we panic?\n\tif u == 0 {\n\t\treturn 0\n\t}\n\t// #nosec G115 -- we handle the case of u == 0 above, so this is safe.\n\treturn uint8(bits.Len64(uint64(u))) - 1\n}\n"
  },
  {
    "path": "primitives/math/log/log_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage log_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/math/log\"\n)\n\nfunc TestILog2Ceil(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tinput    uint64\n\t\texpected uint8\n\t}{\n\t\t{0, 0},\n\t\t{1, 0},\n\t\t{2, 1},\n\t\t{3, 2},\n\t\t{4, 2},\n\t\t{5, 3},\n\t\t{8, 3},\n\t\t{9, 4},\n\t\t{16, 4},\n\t\t{17, 5},\n\t}\n\n\tfor _, test := range tests {\n\t\tresult := log.ILog2Ceil(test.input)\n\t\tif result != test.expected {\n\t\t\tt.Errorf(\n\t\t\t\t\"ILog2Ceil(%d) = %d; want %d\",\n\t\t\t\ttest.input, result, test.expected,\n\t\t\t)\n\t\t}\n\t}\n}\n\nfunc TestILog2Floor(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tinput    uint64\n\t\texpected uint8\n\t}{\n\t\t{0, 0},\n\t\t{1, 0},\n\t\t{2, 1},\n\t\t{3, 1},\n\t\t{4, 2},\n\t\t{5, 2},\n\t\t{8, 3},\n\t\t{9, 3},\n\t\t{16, 4},\n\t\t{17, 4},\n\t}\n\n\tfor _, test := range tests {\n\t\tresult := log.ILog2Floor(test.input)\n\t\tif result != test.expected {\n\t\t\tt.Errorf(\n\t\t\t\t\"ILog2Floor(%d) = %d; want %d\",\n\t\t\t\ttest.input, result, test.expected,\n\t\t\t)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "primitives/math/pow/pow.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage pow\n\n// PrevPowerOfTwo returns the previous power of 2 for the given input.\n//\n//nolint:mnd // todo fix.\nfunc PrevPowerOfTwo[U64T ~uint64](u U64T) U64T {\n\tif u <= 1 {\n\t\treturn 1\n\t}\n\tu |= u >> 1\n\tu |= u >> 2\n\tu |= u >> 4\n\tu |= u >> 8\n\tu |= u >> 16\n\tu |= u >> 32\n\treturn u - (u >> 1)\n}\n\n// NextPowerOfTwo returns the next power of 2 for the given input.\n//\n//nolint:mnd // todo fix.\nfunc NextPowerOfTwo[U64T ~uint64](u U64T) U64T {\n\tif u <= 1 {\n\t\treturn 1\n\t}\n\tif u > 1<<63 {\n\t\tpanic(\"Next power of 2 is 1 << 64.\")\n\t}\n\tu--\n\tu |= u >> 1\n\tu |= u >> 2\n\tu |= u >> 4\n\tu |= u >> 8\n\tu |= u >> 16\n\tu |= u >> 32\n\tu++\n\treturn u\n}\n"
  },
  {
    "path": "primitives/math/pow/pow_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage pow_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/math/pow\"\n)\n\nfunc TestPrevPowerOfTwo(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tinput    uint64\n\t\texpected uint64\n\t}{\n\t\t{0, 1},\n\t\t{1, 1},\n\t\t{2, 2},\n\t\t{3, 2},\n\t\t{4, 4},\n\t\t{5, 4},\n\t\t{6, 4},\n\t\t{7, 4},\n\t\t{8, 8},\n\t\t{9, 8},\n\t\t{16, 16},\n\t\t{17, 16},\n\t\t{31, 16},\n\t\t{32, 32},\n\t\t{33, 32},\n\t}\n\n\tfor _, test := range tests {\n\t\tresult := pow.PrevPowerOfTwo(test.input)\n\t\tif result != test.expected {\n\t\t\tt.Errorf(\n\t\t\t\t\"PrevPowerOfTwo(%d) = %d; want %d\",\n\t\t\t\ttest.input, result, test.expected,\n\t\t\t)\n\t\t}\n\t}\n}\n\nfunc TestNextPowerOfTwo(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tinput    uint64\n\t\texpected uint64\n\t}{\n\t\t{0, 1},\n\t\t{1, 1},\n\t\t{2, 2},\n\t\t{3, 4},\n\t\t{4, 4},\n\t\t{5, 8},\n\t\t{6, 8},\n\t\t{7, 8},\n\t\t{8, 8},\n\t\t{9, 16},\n\t\t{16, 16},\n\t\t{17, 32},\n\t\t{31, 32},\n\t\t{32, 32},\n\t\t{33, 64},\n\t}\n\n\tfor _, test := range tests {\n\t\tresult := pow.NextPowerOfTwo(test.input)\n\t\tif result != test.expected {\n\t\t\tt.Errorf(\n\t\t\t\t\"NextPowerOfTwo(%d) = %d; want %d\",\n\t\t\t\ttest.input, result, test.expected,\n\t\t\t)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "primitives/math/u256.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage math\n\nimport (\n\t\"fmt\"\n\t\"math/big\"\n\n\t\"github.com/holiman/uint256\"\n)\n\n// U256 represents a 256-bit unsigned integer that is both SSZ and JSON.\ntype U256 = uint256.Int\n\n// NewU256 creates a new U256 from a uint64.\nfunc NewU256(v uint64) *U256 {\n\treturn uint256.NewInt(v)\n}\n\n// NewU256FromBigInt creates a new U256 from a big.Int.\nfunc NewU256FromBigInt(b *big.Int) (*U256, error) {\n\t// Negative integers ought to be rejected by math.NewU256FromBigInt(b)\n\t// since they cannot be expressed in the U256 type. However this does\n\t// not seem to happen (see holiman/uint256#115), so guarding here.\n\tif b.Sign() < 0 {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"cannot convert negative big.Int %s to uint256\",\n\t\t\tb.String(),\n\t\t)\n\t}\n\treturn uint256.MustFromBig(b), nil\n}\n\n// U256Hex represents a 256-bit unsigned integer that is marshaled to JSON\n// as a hexadecimal string.\ntype U256Hex uint256.Int\n\n// MarshalJSON implements the json.Marshaler interface.\n// It returns the hexadecimal string representation of the U256Hex value.\nfunc (u *U256Hex) MarshalJSON() ([]byte, error) {\n\treturn []byte(`\"` + (*uint256.Int)(u).Hex() + `\"`), nil\n}\n\n// UnmarshalJSON implements the json.Unmarshaler interface.\n// It expects the input to be a hexadecimal string.\nfunc (u *U256Hex) UnmarshalJSON(data []byte) error {\n\treturn (*uint256.Int)(u).UnmarshalJSON(data)\n}\n"
  },
  {
    "path": "primitives/math/u64.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage math\n\nimport (\n\t\"encoding/binary\"\n\t\"math/big\"\n\t\"strconv\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/berachain/beacon-kit/primitives/math/log\"\n\t\"github.com/berachain/beacon-kit/primitives/math/pow\"\n\t\"github.com/ethereum/go-ethereum/params\"\n)\n\ntype (\n\t// U64 represents a 64-bit unsigned integer that is both SSZ and JSON\n\t// marshallable. We marshal U64 as hex strings in JSON in order to keep the\n\t// execution client apis happy, and we marshal U64 as little-endian in SSZ\n\t// to be\n\t// compatible with the spec.\n\tU64 uint64\n\n\t// Gwei is a denomination of 1e9 Wei represented as a U64.\n\tGwei = U64\n\n\t// Slot as per the Ethereum 2.0 Specification:\n\t// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#custom-types\n\tSlot = U64\n\n\t// CommitteeIndex as per the Ethereum 2.0 Specification:\n\t// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#custom-types\n\tCommitteeIndex = U64\n\n\t// ValidatorIndex as per the Ethereum 2.0  Specification:\n\t// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#custom-types\n\tValidatorIndex = U64\n\n\t// Epoch as per the Ethereum 2.0 Specification:\n\t// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#custom-types\n\tEpoch = U64\n)\n\n// -------------------------- JSONMarshallable -------------------------\n\n// MarshalText implements encoding.TextMarshaler.\nfunc (u U64) MarshalText() ([]byte, error) {\n\treturn hex.MarshalText(u.Unwrap())\n}\n\n// UnmarshalJSON implements json.Unmarshaler.\nfunc (u *U64) UnmarshalJSON(input []byte) error {\n\tstrippedInput, err := hex.ValidateQuotedString(input)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn u.UnmarshalText(strippedInput)\n}\n\nfunc U64FromString(id string) (U64, error) {\n\tu64, err := strconv.ParseUint(id, 10, 64)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\treturn U64(u64), nil\n}\n\n// ---------------------------------- Hex ----------------------------------\n\n// UnmarshalText implements encoding.TextUnmarshaler.\nfunc (u *U64) UnmarshalText(input []byte) error {\n\tdec, err := hex.UnmarshalUint64Text(input)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*u = U64(dec)\n\treturn nil\n}\n\n// String returns the string representation of the U64.\nfunc (u U64) Base10() string {\n\treturn strconv.FormatUint(uint64(u), 10)\n}\n\n// ----------------------- U64 Mathematical Methods -----------------------\n\n// Unwrap returns a copy of the underlying uint64 value of U64.\nfunc (u U64) Unwrap() uint64 {\n\treturn uint64(u)\n}\n\n// UnwrapPtr returns a pointer to the underlying uint64 value of U64.\nfunc (u U64) UnwrapPtr() *uint64 {\n\treturn (*uint64)(&u)\n}\n\n// Get the power of 2 for given input, or the closest higher power of 2 if the\n// input is not a power of 2. Commonly used for \"how many nodes do I need for a\n// bottom tree layer fitting x elements?\"\n// Example: 0->1, 1->1, 2->2, 3->4, 4->4, 5->8, 6->8, 7->8, 8->8, 9->16.\n//\n// https://github.com/ethereum/consensus-specs/blob/dev/ssz/merkle-proofs.md#helper-functions\nfunc (u U64) NextPowerOfTwo() U64 {\n\treturn pow.NextPowerOfTwo(u)\n}\n\n// Get the power of 2 for given input, or the closest lower power of 2 if the\n// input is not a power of 2. The zero case is a placeholder and not used for\n// math with generalized indices. Commonly used for \"what power of two makes up\n// the root bit of the generalized index?\"\n// Example: 0->1, 1->1, 2->2, 3->2, 4->4, 5->4, 6->4, 7->4, 8->8, 9->8.\n//\n// https://github.com/ethereum/consensus-specs/blob/dev/ssz/merkle-proofs.md#helper-functions\nfunc (u U64) PrevPowerOfTwo() U64 {\n\treturn pow.PrevPowerOfTwo(u)\n}\n\n// ILog2Ceil returns the ceiling of the base 2 logarithm of the U64.\nfunc (u U64) ILog2Ceil() uint8 {\n\treturn log.ILog2Ceil(u)\n}\n\n// ILog2Floor returns the floor of the base 2 logarithm of the U64.\nfunc (u U64) ILog2Floor() uint8 {\n\treturn log.ILog2Floor(u)\n}\n\n// -------------------------------- SSZ ---------------------------------\n\n// HashTreeRoot returns the hash tree root of the U64.\nfunc (u U64) HashTreeRoot() common.Root {\n\tvar root common.Root\n\tbinary.LittleEndian.PutUint64(root[:], u.Unwrap())\n\treturn root\n}\n\n// ---------------------------- Gwei Methods ----------------------------\n\nvar ErrGweiOverflow = errors.New(\"gwei from big.Int overflows\")\n\n// GweiFromWei returns the value of Wei in Gwei.\nfunc GweiFromWei(i *big.Int) (Gwei, error) {\n\tintToGwei := big.NewInt(0).SetUint64(params.GWei)\n\ti.Div(i, intToGwei)\n\tif !i.IsUint64() {\n\t\t// a Gwei amount >= (2**64) * (10**9) or negative would not\n\t\t// be representable as uint64. This should not happen but\n\t\t// we still guard against a serialization bug or other mishap.\n\t\treturn 0, ErrGweiOverflow\n\t}\n\treturn Gwei(i.Uint64()), nil\n}\n\n// ToWei converts a value from Gwei to Wei.\nfunc (u Gwei) ToWei() *U256 {\n\treturn (&U256{}).Mul(NewU256(uint64(u)), NewU256(params.GWei))\n}\n"
  },
  {
    "path": "primitives/math/u64_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage math_test\n\nimport (\n\t\"math/big\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/ethereum/go-ethereum/params\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestU64_MarshalText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tinput    uint64\n\t\texpected string\n\t}{\n\t\t{\"Zero value\", 0, \"0x0\"},\n\t\t{\"Small value\", 123, \"0x7b\"},\n\t\t{\"Max uint64 value\", ^uint64(0), \"0xffffffffffffffff\"},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tu := math.U64(tt.input)\n\t\t\tresult, err := u.MarshalText()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, tt.expected, string(result))\n\t\t})\n\t}\n}\n\nfunc TestU64_UnmarshalJSON(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tjson     string\n\t\texpected uint64\n\t\terr      error\n\t}{\n\t\t{\"Valid hex string\", \"\\\"0x7b\\\"\", 123, nil},\n\t\t{\"Zero value\", \"\\\"0x0\\\"\", 0, nil},\n\t\t{\"Max uint64 value\", \"\\\"0xffffffffffffffff\\\"\", ^uint64(0), nil},\n\t\t{\"Invalid hex string\", \"\\\"0xxyz\\\"\", 0, hex.ErrInvalidString},\n\t\t{\"Invalid JSON text\", \"\", 0, hex.ErrNonQuotedString},\n\t\t{\"Invalid quoted JSON text\", `\"0x`, 0, hex.ErrNonQuotedString},\n\t\t{\"Empty JSON text\", `\"\"`, 0, hex.ErrEmptyString},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar u math.U64\n\t\t\terr := u.UnmarshalJSON([]byte(tt.json))\n\t\t\tif tt.err != nil {\n\t\t\t\trequire.Error(t, err)\n\t\t\t\trequire.Equal(t, tt.err, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, math.U64(tt.expected), u)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestU64_UnmarshalText(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tinput    string\n\t\texpected uint64\n\t\terr      error\n\t}{\n\t\t{\"Valid hex string\", \"0x7b\", 123, nil},\n\t\t{\"Zero value\", \"0x0\", 0, nil},\n\t\t{\"Max uint64 value\", \"0xffffffffffffffff\", ^uint64(0), nil},\n\t\t{\"Invalid hex string\", \"0xxyz\", 0, hex.ErrInvalidString},\n\t\t{\"Overflow hex string\", \"0x10000000000000000\", 0, hex.ErrUint64Range},\n\t\t{\"Empty string\", \"\", 0, hex.ErrEmptyString},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tvar u math.U64\n\t\t\terr := u.UnmarshalText([]byte(tt.input))\n\t\t\tif tt.err != nil {\n\t\t\t\trequire.Error(t, err)\n\t\t\t\trequire.EqualError(t, err, tt.err.Error())\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, math.U64(tt.expected), u)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestU64_NextPowerOfTwo(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tvalue    math.U64\n\t\texpected math.U64\n\t}{\n\t\t{\n\t\t\tname:     \"zero\",\n\t\t\tvalue:    math.U64(0),\n\t\t\texpected: math.U64(1),\n\t\t},\n\t\t{\n\t\t\tname:     \"one\",\n\t\t\tvalue:    math.U64(1),\n\t\t\texpected: math.U64(1),\n\t\t},\n\t\t{\n\t\t\tname:     \"already a power of two\",\n\t\t\tvalue:    math.U64(8),\n\t\t\texpected: math.U64(8),\n\t\t},\n\t\t{\n\t\t\tname:     \"not a power of two\",\n\t\t\tvalue:    math.U64(9),\n\t\t\texpected: math.U64(16),\n\t\t},\n\t\t{\n\t\t\tname:     \"large number\",\n\t\t\tvalue:    math.U64(1<<20 + 1<<46),\n\t\t\texpected: math.U64(1 << 47),\n\t\t},\n\t\t{\n\t\t\tname:     \"large number with lots zeros\",\n\t\t\tvalue:    math.U64(1<<62 + 1),\n\t\t\texpected: math.U64(1 << 63),\n\t\t},\n\t\t{\n\t\t\tname:     \"large number at the limit\",\n\t\t\tvalue:    math.U64(1 << 63),\n\t\t\texpected: math.U64(1 << 63),\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := tt.value.NextPowerOfTwo()\n\t\t\trequire.Equal(t, tt.expected, result)\n\t\t\trequire.Equal(\n\t\t\t\tt,\n\t\t\t\ttt.expected,\n\t\t\t\tmath.U64(uint64(1)<<tt.value.ILog2Ceil()),\n\t\t\t)\n\t\t})\n\t}\n}\n\nfunc TestU64_NextPowerOfTwoPanic(t *testing.T) {\n\tt.Parallel()\n\tu := ^math.U64(0)\n\trequire.Panics(t, func() {\n\t\t_ = u.NextPowerOfTwo()\n\t})\n}\n\nfunc TestU64_ILog2Ceil(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tvalue    math.U64\n\t\texpected uint8\n\t}{\n\t\t{\n\t\t\tname:     \"zero\",\n\t\t\tvalue:    math.U64(0),\n\t\t\texpected: 0,\n\t\t},\n\t\t{\n\t\t\tname:     \"one\",\n\t\t\tvalue:    math.U64(1),\n\t\t\texpected: 0,\n\t\t},\n\t\t{\n\t\t\tname:     \"power of two\",\n\t\t\tvalue:    math.U64(8),\n\t\t\texpected: 3,\n\t\t},\n\t\t{\n\t\t\tname:     \"not a power of two\",\n\t\t\tvalue:    math.U64(9),\n\t\t\texpected: 4,\n\t\t},\n\t\t{\n\t\t\tname:     \"max uint64\",\n\t\t\tvalue:    math.U64(1<<64 - 1),\n\t\t\texpected: 64,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := tt.value.ILog2Ceil()\n\t\t\trequire.Equal(t, tt.expected, result)\n\t\t})\n\t}\n}\n\nfunc TestU64_ILog2Floor(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tvalue    math.U64\n\t\texpected uint8\n\t}{\n\t\t{\n\t\t\tname:     \"zero\",\n\t\t\tvalue:    math.U64(0),\n\t\t\texpected: 0,\n\t\t},\n\t\t{\n\t\t\tname:     \"one\",\n\t\t\tvalue:    math.U64(1),\n\t\t\texpected: 0,\n\t\t},\n\t\t{\n\t\t\tname:     \"power of two\",\n\t\t\tvalue:    math.U64(8),\n\t\t\texpected: 3,\n\t\t},\n\t\t{\n\t\t\tname:     \"not a power of two\",\n\t\t\tvalue:    math.U64(9),\n\t\t\texpected: 3,\n\t\t},\n\t\t{\n\t\t\tname:     \"max uint64\",\n\t\t\tvalue:    math.U64(1<<64 - 1),\n\t\t\texpected: 63,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := tt.value.ILog2Floor()\n\t\t\trequire.Equal(t, tt.expected, result)\n\t\t})\n\t}\n}\n\nfunc TestU64_PrevPowerOfTwo(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tvalue    math.U64\n\t\texpected math.U64\n\t}{\n\t\t{\n\t\t\tname:     \"zero\",\n\t\t\tvalue:    math.U64(0),\n\t\t\texpected: 1,\n\t\t},\n\t\t{\n\t\t\tname:     \"one\",\n\t\t\tvalue:    math.U64(1),\n\t\t\texpected: 1,\n\t\t},\n\t\t{\n\t\t\tname:     \"two\",\n\t\t\tvalue:    math.U64(2),\n\t\t\texpected: 2,\n\t\t},\n\t\t{\n\t\t\tname:     \"three\",\n\t\t\tvalue:    math.U64(3),\n\t\t\texpected: 2,\n\t\t},\n\t\t{\n\t\t\tname:     \"four\",\n\t\t\tvalue:    math.U64(4),\n\t\t\texpected: 4,\n\t\t},\n\t\t{\n\t\t\tname:     \"five\",\n\t\t\tvalue:    math.U64(5),\n\t\t\texpected: 4,\n\t\t},\n\t\t{\n\t\t\tname:     \"eight\",\n\t\t\tvalue:    math.U64(8),\n\t\t\texpected: 8,\n\t\t},\n\t\t{\n\t\t\tname:     \"nine\",\n\t\t\tvalue:    math.U64(9),\n\t\t\texpected: 8,\n\t\t},\n\t\t{\n\t\t\tname:     \"thirty-two\",\n\t\t\tvalue:    math.U64(32),\n\t\t\texpected: 32,\n\t\t},\n\t\t{\n\t\t\tname:     \"thirty-three\",\n\t\t\tvalue:    math.U64(33),\n\t\t\texpected: 32,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := tt.value.PrevPowerOfTwo()\n\t\t\trequire.Equal(t, tt.expected, result)\n\t\t\trequire.Equal(\n\t\t\t\tt,\n\t\t\t\ttt.expected,\n\t\t\t\tmath.U64(uint64(1)<<tt.value.ILog2Floor()),\n\t\t\t)\n\t\t})\n\t}\n}\n\nfunc TestU64_HashTreeRoot(t *testing.T) {\n\tt.Parallel()\n\n\ttests := []struct {\n\t\tname        string\n\t\tvalue       math.U64\n\t\texpectedHex string\n\t}{\n\t\t{\n\t\t\tname:        \"zero\",\n\t\t\tvalue:       math.U64(0),\n\t\t\texpectedHex: \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n\t\t},\n\t\t{\n\t\t\t// https://eth2book.info/capella/part2/building_blocks/merkleization/#the-data-root\n\t\t\tname:        \"nine\",\n\t\t\tvalue:       math.U64(9),\n\t\t\texpectedHex: \"0x0900000000000000000000000000000000000000000000000000000000000000\",\n\t\t},\n\t\t{\n\t\t\tname:        \"max uint64\",\n\t\t\tvalue:       math.U64(1<<64 - 1),\n\t\t\texpectedHex: \"0xffffffffffffffff000000000000000000000000000000000000000000000000\",\n\t\t},\n\t\t{\n\t\t\t// https://eth2book.info/capella/part2/building_blocks/merkleization/#the-data-root\n\t\t\tname:        \"large number\",\n\t\t\tvalue:       math.U64(3080829),\n\t\t\texpectedHex: \"0x7d022f0000000000000000000000000000000000000000000000000000000000\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\n\t\t\trequire.Equal(t, tt.expectedHex, tt.value.HashTreeRoot().String())\n\t\t})\n\t}\n}\n\nfunc TestGweiFromWei(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname        string\n\t\tinput       func(t *testing.T) *big.Int\n\t\texpectedErr error\n\t\texpectedRes math.Gwei\n\t}{\n\t\t{\n\t\t\tname: \"invalid negative gwei\",\n\t\t\tinput: func(t *testing.T) *big.Int {\n\t\t\t\tt.Helper()\n\t\t\t\tb, _ := new(big.Int).SetString(\"-1\", 10)\n\t\t\t\treturn b\n\t\t\t},\n\t\t\texpectedErr: math.ErrGweiOverflow,\n\t\t\texpectedRes: math.Gwei(0),\n\t\t},\n\t\t{\n\t\t\tname: \"invalid huge gwei\",\n\t\t\tinput: func(t *testing.T) *big.Int {\n\t\t\t\tt.Helper()\n\t\t\t\tb, _ := new(\n\t\t\t\t\tbig.Int,\n\t\t\t\t).SetString(\"18446744073709551616000000000\", 10)\n\t\t\t\treturn b\n\t\t\t},\n\t\t\texpectedErr: math.ErrGweiOverflow,\n\t\t\texpectedRes: math.Gwei(0),\n\t\t},\n\t\t{\n\t\t\tname: \"zero wei\",\n\t\t\tinput: func(t *testing.T) *big.Int {\n\t\t\t\tt.Helper()\n\t\t\t\treturn big.NewInt(0)\n\t\t\t},\n\t\t\texpectedErr: nil,\n\t\t\texpectedRes: math.Gwei(0),\n\t\t},\n\t\t{\n\t\t\tname: \"one gwei\",\n\t\t\tinput: func(t *testing.T) *big.Int {\n\t\t\t\tt.Helper()\n\t\t\t\treturn big.NewInt(params.GWei)\n\t\t\t},\n\t\t\texpectedErr: nil,\n\t\t\texpectedRes: math.Gwei(1),\n\t\t},\n\t\t{\n\t\t\tname: \"arbitrary wei\",\n\t\t\tinput: func(t *testing.T) *big.Int {\n\t\t\t\tt.Helper()\n\t\t\t\treturn big.NewInt(params.GWei * 123456789)\n\t\t\t},\n\t\t\texpectedErr: nil,\n\t\t\texpectedRes: math.Gwei(123456789),\n\t\t},\n\t\t{\n\t\t\tname: \"max uint64 wei\",\n\t\t\tinput: func(t *testing.T) *big.Int {\n\t\t\t\tt.Helper()\n\t\t\t\treturn new(big.Int).Mul(\n\t\t\t\t\tbig.NewInt(params.GWei),\n\t\t\t\t\tnew(big.Int).SetUint64(^uint64(0)),\n\t\t\t\t)\n\t\t\t},\n\t\t\texpectedErr: nil,\n\t\t\texpectedRes: math.Gwei(1<<64 - 1),\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult, err := math.GweiFromWei(tt.input(t))\n\t\t\tif tt.expectedErr != nil {\n\t\t\t\trequire.ErrorIs(t, err, tt.expectedErr)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, tt.expectedRes, result, \"Test case: %s\", tt.name)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestGwei_ToWei(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tinput    math.Gwei\n\t\texpected func(t *testing.T) *math.U256\n\t}{\n\t\t{\n\t\t\tname:  \"zero gwei\",\n\t\t\tinput: math.Gwei(0),\n\t\t\texpected: func(t *testing.T) *math.U256 {\n\t\t\t\tt.Helper()\n\t\t\t\tres, err := math.NewU256FromBigInt(big.NewInt(0))\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\treturn res\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"one gwei\",\n\t\t\tinput: math.Gwei(1),\n\t\t\texpected: func(t *testing.T) *math.U256 {\n\t\t\t\tt.Helper()\n\t\t\t\tres, err := math.NewU256FromBigInt(big.NewInt(params.GWei))\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\treturn res\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"arbitrary gwei\",\n\t\t\tinput: math.Gwei(123456789),\n\t\t\texpected: func(t *testing.T) *math.U256 {\n\t\t\t\tt.Helper()\n\t\t\t\tn := new(big.Int).Mul(\n\t\t\t\t\tbig.NewInt(params.GWei),\n\t\t\t\t\tbig.NewInt(123456789),\n\t\t\t\t)\n\t\t\t\tres, err := math.NewU256FromBigInt(n)\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\treturn res\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:  \"max uint64 gwei\",\n\t\t\tinput: math.Gwei(1<<64 - 1),\n\t\t\texpected: func(t *testing.T) *math.U256 {\n\t\t\t\tt.Helper()\n\t\t\t\tn := new(big.Int).Mul(\n\t\t\t\t\tbig.NewInt(params.GWei),\n\t\t\t\t\tnew(big.Int).SetUint64(1<<64-1),\n\t\t\t\t)\n\t\t\t\tres, err := math.NewU256FromBigInt(n)\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\treturn res\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := tt.input.ToWei()\n\t\t\trequire.Equal(t, tt.expected(t), result)\n\t\t})\n\t}\n}\n\nfunc TestU64_Base10(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tvalue    math.U64\n\t\texpected string\n\t}{\n\t\t{\n\t\t\tname:     \"zero value\",\n\t\t\tvalue:    math.U64(0),\n\t\t\texpected: \"0\",\n\t\t},\n\t\t{\n\t\t\tname:     \"small value\",\n\t\t\tvalue:    math.U64(123),\n\t\t\texpected: \"123\",\n\t\t},\n\t\t{\n\t\t\tname:     \"large value\",\n\t\t\tvalue:    math.U64(123456789),\n\t\t\texpected: \"123456789\",\n\t\t},\n\t\t{\n\t\t\tname:     \"max uint64 value\",\n\t\t\tvalue:    math.U64(^uint64(0)),\n\t\t\texpected: \"18446744073709551615\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := tt.value.Base10()\n\t\t\trequire.Equal(t, tt.expected, result,\n\t\t\t\t\"Test case: %s\", tt.name)\n\t\t})\n\t}\n}\n\nfunc TestU64_UnwrapPtr(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\tvalue    math.U64\n\t\texpected uint64\n\t}{\n\t\t{\n\t\t\tname:     \"zero value\",\n\t\t\tvalue:    math.U64(0),\n\t\t\texpected: 0,\n\t\t},\n\t\t{\n\t\t\tname:     \"small value\",\n\t\t\tvalue:    math.U64(123),\n\t\t\texpected: 123,\n\t\t},\n\t\t{\n\t\t\tname:     \"large value\",\n\t\t\tvalue:    math.U64(123456789),\n\t\t\texpected: 123456789,\n\t\t},\n\t\t{\n\t\t\tname:     \"max uint64 value\",\n\t\t\tvalue:    math.U64(^uint64(0)),\n\t\t\texpected: ^uint64(0),\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := tt.value.UnwrapPtr()\n\t\t\trequire.NotNil(t, result)\n\t\t\trequire.Equal(t, tt.expected, *result,\n\t\t\t\t\"Test case: %s\", tt.name)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "primitives/merkle/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle\n\nimport \"github.com/berachain/beacon-kit/errors\"\n\nvar (\n\t// ErrNegativeIndex indicates that a negative index was provided.\n\tErrNegativeIndex = errors.New(\"negative index provided\")\n\n\t// ErrEmptyLeaves indicates that no items were provided to generate a Merkle\n\t// tree.\n\tErrEmptyLeaves = errors.New(\"no items provided to generate Merkle tree\")\n\n\t// ErrInsufficientDepthForLeaves indicates that the depth provided for the\n\t// Merkle tree is insufficient to store the provided leaves.\n\tErrInsufficientDepthForLeaves = errors.New(\n\t\t\"insufficient depth to store leaves\",\n\t)\n\n\t// ErrZeroDepth indicates that the depth provided for the Merkle tree is\n\t// zero, which is invalid.\n\tErrZeroDepth = errors.New(\"depth must be greater than 0\")\n\n\t// ErrDepthExceedsLimitDepth indicates that the depth provided for the\n\t// Merkle\n\t// tree exceeds the specified limit depth.\n\tErrDepthExceedsLimitDepth = errors.New(\n\t\t\"depth exceeds the specified limit depth\",\n\t)\n\n\t// ErrExceededDepth indicates that the provided depth exceeds the supported\n\t// maximum depth for a Merkle tree.\n\tErrExceededDepth = errors.New(\"supported merkle tree depth exceeded\")\n\n\t// ErrOddLengthTreeRoots is returned when the input list length must be\n\t// even.\n\tErrOddLengthTreeRoots = errors.New(\"input list length must be even\")\n\n\t// ErrMaxRootsExceeded is returned when the number of roots exceeds the\n\t// maximum allowed.\n\tErrMaxRootsExceeded = errors.New(\n\t\t\"number of roots exceeds the maximum allowed\",\n\t)\n\n\t// ErrLeavesExceedsLimit is returned when the number of leaves exceeds the\n\t// maximum allowed.\n\tErrLeavesExceedsLimit = errors.New(\n\t\t\"number of leaves exceeds the maximum allowed\",\n\t)\n)\n"
  },
  {
    "path": "primitives/merkle/hasher.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle\n\nimport (\n\t\"encoding/binary\"\n)\n\n// Hasher can be re-used for efficiently conducting multiple rounds of hashing.\ntype Hasher[T ~[32]byte] interface {\n\tHash(a []byte) T\n\tCombi(a, b T) T\n\tMixIn(a T, i uint64) T\n}\n\n// HashFn is the generic hash function signature.\ntype HashFn func(input []byte) [32]byte\n\n// hasher holds a underlying byte buffers to efficiently conduct\n// multiple rounds of hashing.\ntype hasher[T ~[32]byte] struct {\n\tbuffer     [64]byte\n\thashFunc   HashFn\n\temptyBytes [24]byte\n}\n\n// NewHasher is the constructor for the object that fulfills\n// the Hasher interface.\nfunc NewHasher[T ~[32]byte](h HashFn) Hasher[T] {\n\treturn &hasher[T]{\n\t\tbuffer:   [64]byte{},\n\t\thashFunc: h,\n\t}\n}\n\n// Hash utilizes the provided hash function for the object.\nfunc (h *hasher[T]) Hash(a []byte) T {\n\treturn T(h.hashFunc(a))\n}\n\n// Combi appends the two inputs and hashes them.\nfunc (h *hasher[T]) Combi(a, b T) T {\n\tcopy(h.buffer[:32], a[:])\n\tcopy(h.buffer[32:], b[:])\n\treturn h.Hash(h.buffer[:])\n}\n\n// MixIn works like Combi, but using an integer as the second input.\nfunc (h *hasher[T]) MixIn(a T, i uint64) T {\n\tcopy(h.buffer[:32], a[:])\n\tbinary.LittleEndian.PutUint64(h.buffer[32:40], i)\n\tcopy(h.buffer[40:], h.emptyBytes[:])\n\treturn h.Hash(h.buffer[:])\n}\n"
  },
  {
    "path": "primitives/merkle/hasher_fuzz_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/merkle\"\n)\n\nfunc FuzzHashTreeRoot(f *testing.F) {\n\t// Seed corpus with a variety of sizes, including edge cases\n\t//\n\t// Test with empty slice\n\tf.Add(make([]byte, 0), true, merkle.MinParallelizationSize)\n\t// Just below a single block size\n\tf.Add(\n\t\tmake([]byte, 31), true, merkle.MinParallelizationSize,\n\t)\n\t// Exactly one block size\n\tf.Add(\n\t\tmake([]byte, 32), true, merkle.MinParallelizationSize,\n\t)\n\t// Just above a single block size\n\tf.Add(\n\t\tmake([]byte, 33), true, merkle.MinParallelizationSize,\n\t)\n\t// Multiple blocks\n\tf.Add(\n\t\tmake([]byte, 64), true, merkle.MinParallelizationSize,\n\t)\n\t// Larger input\n\tf.Add(\n\t\tmake([]byte, 1024), true, merkle.MinParallelizationSize,\n\t)\n\t// Just below MinParallelizationSize leaves\n\tf.Add(\n\t\tmake([]byte, merkle.MinParallelizationSize-2), false,\n\t\tmerkle.MinParallelizationSize,\n\t)\n\t// Exactly MinParallelizationSize leaves\n\tf.Add(\n\t\tmake([]byte, merkle.MinParallelizationSize), false,\n\t\tmerkle.MinParallelizationSize,\n\t)\n\t// Just above MinParallelizationSize leaves\n\tf.Add(\n\t\tmake([]byte, merkle.MinParallelizationSize+2), false,\n\t\tmerkle.MinParallelizationSize,\n\t)\n\t// Double MinParallelizationSize leaves\n\tf.Add(\n\t\tmake([]byte, 2*merkle.MinParallelizationSize), false,\n\t\tmerkle.MinParallelizationSize,\n\t)\n\t// Max Txs leaves\n\tf.Add(\n\t\tmake([]byte, int(constants.MaxTxsPerPayload)), false,\n\t\tmerkle.MinParallelizationSize,\n\t)\n\n\tf.Fuzz(func(\n\t\tt *testing.T,\n\t\toriginal []byte, isLeaves bool, minParallelizationSize int,\n\t) {\n\t\t// Extend the fuzzed input to 32 byte leaves if not in leaves format.\n\t\tif !isLeaves {\n\t\t\tleavesBytes := make([]byte, len(original)*32)\n\t\t\tfor i := range 32 {\n\t\t\t\tcopy(\n\t\t\t\t\tleavesBytes[i*len(original):(i+1)*len(original)],\n\t\t\t\t\toriginal,\n\t\t\t\t)\n\t\t\t}\n\t\t\toriginal = leavesBytes\n\t\t}\n\n\t\t// Convert []byte to [][32]byte as required by HashTreeRoot.\n\t\tvar input [][32]byte\n\t\tfor i := 0; i < len(original); i += 32 {\n\t\t\tvar block [32]byte\n\t\t\tcopy(block[:], original[i:min(i+32, len(original))])\n\t\t\tinput = append(input, block)\n\t\t}\n\n\t\t// Ensure an even number of chunks for HashTreeRoot.\n\t\texpectError := false\n\t\tif len(input)%2 != 0 {\n\t\t\texpectError = true\n\t\t}\n\n\t\trequireGoHashTreeEquivalence(\n\t\t\tt, input, minParallelizationSize, expectError,\n\t\t)\n\t})\n}\n"
  },
  {
    "path": "primitives/merkle/hasher_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle_test\n\nimport (\n\t\"crypto/md5\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/merkle\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestCombi(t *testing.T) {\n\tt.Parallel()\n\t// Initialize the hasher function\n\thashFunc := func(data []byte) [32]byte {\n\t\tvar result [32]byte\n\t\thash := md5.Sum(data)\n\t\tcopy(result[:], hash[:])\n\t\treturn result\n\t}\n\thasher := merkle.NewHasher[[32]byte](hashFunc)\n\n\ttests := []struct {\n\t\tname     string\n\t\ta, b     [32]byte\n\t\texpected [32]byte\n\t}{\n\t\t{\n\t\t\tname: \"Simple combination\",\n\t\t\ta:    [32]byte{1, 2, 3, 4},\n\t\t\tb:    [32]byte{5, 6, 7, 8},\n\t\t\texpected: [32]uint8{0xa3, 0x56, 0x78, 0x7f, 0x44, 0x4f, 0x5c, 0xa3,\n\t\t\t\t0x51, 0x4a, 0xfd, 0x73, 0x23, 0x18, 0xa7, 0x40},\n\t\t},\n\t\t{\n\t\t\tname: \"Another combination\",\n\t\t\ta:    [32]byte{9, 10, 11, 12},\n\t\t\tb:    [32]byte{13, 14, 15, 16},\n\t\t\texpected: [32]uint8{0xa, 0x63, 0x9a, 0x14, 0x35, 0xed, 0x3d, 0x9a,\n\t\t\t\t0x39, 0xfa, 0x9a, 0xa4, 0x60, 0xdd, 0xda},\n\t\t},\n\t}\n\n\tfor _, tc := range tests {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tresult := hasher.Combi(tc.a, tc.b)\n\t\t\trequire.Equal(t, tc.expected, result,\n\t\t\t\t\"TestCase %s\", tc.name)\n\t\t})\n\t}\n}\n\nfunc TestMixIn(t *testing.T) {\n\tt.Parallel()\n\t// Initialize the hasher function\n\thashFunc := func(data []byte) [32]byte {\n\t\tvar result [32]byte\n\t\thash := md5.Sum(data)\n\t\tcopy(result[:], hash[:])\n\t\treturn result\n\t}\n\thasher := merkle.NewHasher[[32]byte](hashFunc)\n\n\ttests := []struct {\n\t\tname     string\n\t\ta        [32]byte\n\t\ti        uint64\n\t\texpected [32]byte\n\t}{\n\t\t{\n\t\t\tname: \"MixIn with integer 1\",\n\t\t\ta:    [32]byte{1, 2, 3, 4},\n\t\t\ti:    1,\n\t\t\texpected: [32]uint8{0x90, 0xde, 0x5, 0xc9, 0x96, 0x7a, 0xc0, 0xdb,\n\t\t\t\t0x74, 0xf2, 0x8e, 0xf1, 0xd4, 0x62, 0xaf, 0x4d},\n\t\t},\n\t\t{\n\t\t\tname: \"MixIn with integer 2\",\n\t\t\ta:    [32]byte{5, 6, 7, 8},\n\t\t\ti:    2,\n\t\t\texpected: [32]uint8{0xaa, 0x93, 0x16, 0x9f, 0x1c, 0x2d, 0xc5, 0xb8,\n\t\t\t\t0xaa, 0x40, 0x39, 0x5, 0xd7, 0x80, 0x6f, 0xa9},\n\t\t},\n\t}\n\n\tfor _, tc := range tests {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tresult := hasher.MixIn(tc.a, tc.i)\n\t\t\trequire.Equal(t, tc.expected, result,\n\t\t\t\t\"TestCase %s\", tc.name)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "primitives/merkle/index.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle\n\nimport (\n\t\"slices\"\n\n\t\"github.com/berachain/beacon-kit/primitives/math/log\"\n\t\"github.com/berachain/beacon-kit/primitives/math/pow\"\n)\n\n// Inspired by the Ethereum 2.0 spec:\n// https://github.com/ethereum/consensus-specs/blob/dev/ssz/merkle-proofs.md#helpers-for-generalized-indices\ntype (\n\t// GeneralizedIndex is a generalized index.\n\tGeneralizedIndex uint64\n\n\t// GeneralizedIndices is a list of generalized indices.\n\tGeneralizedIndices []GeneralizedIndex\n)\n\n// NewGeneralizedIndex calculates the generalized index from the depth and\n// index. Inspired by:\n// https://github.com/protolambda/remerkleable/blob/master/remerkleable/tree.py#L20\nfunc NewGeneralizedIndex(\n\tdepth uint8,\n\tindex uint64,\n) GeneralizedIndex {\n\treturn GeneralizedIndex((1 << depth) | index)\n}\n\n// Unwrap returns the underlying uint64 value of the GeneralizedIndex.\nfunc (g GeneralizedIndex) Unwrap() uint64 {\n\treturn uint64(g)\n}\n\n// Length returns the length of the generalized index.\nfunc (g GeneralizedIndex) Length() int {\n\t//#nosec:G701 // uint8 cannot overflow int.\n\treturn int(log.ILog2Floor(g))\n}\n\n// IndexBit returns the bit at the specified position in a generalized index.\nfunc (g GeneralizedIndex) IndexBit(position int) bool {\n\treturn (g & (1 << position)) > 0\n}\n\n// Sibling returns the sibling index of the current generalized index.\nfunc (g GeneralizedIndex) Sibling() GeneralizedIndex {\n\treturn g ^ 1\n}\n\n// LeftChild returns the left child index of the current generalized index.\n//\n//nolint:mnd // from spec.\nfunc (g GeneralizedIndex) LeftChild() GeneralizedIndex {\n\treturn 2 * g\n}\n\n// RightChild returns the right child index of the current generalized index.\nfunc (g GeneralizedIndex) RightChild() GeneralizedIndex {\n\treturn 2*g + 1\n}\n\n// Parent returns the parent index of the current generalized index.\n//\n//nolint:mnd // from spec.\nfunc (g GeneralizedIndex) Parent() GeneralizedIndex {\n\treturn g / 2\n}\n\n// GetBranchIndices returns the generalized indices of the nodes on the path\n// from the root to the leaf.\nfunc (g GeneralizedIndex) GetBranchIndices() GeneralizedIndices {\n\t// Get the generalized indices of the sister chunks along the path from the\n\t// chunk with the given tree index to the root.\n\to := GeneralizedIndices{g.Sibling()}\n\tfor o[len(o)-1] > 1 {\n\t\to = append(o, o[len(o)-1].Parent().Sibling())\n\t}\n\treturn o[:len(o)-1]\n}\n\n// GetPathIndices returns the generalized indices of the nodes on the path from\n// the leaf to the root.\nfunc (g GeneralizedIndex) GetPathIndices() GeneralizedIndices {\n\t// Get the generalized indices of the sister chunks along the path from the\n\t// chunk with the given tree index to the root.\n\to := GeneralizedIndices{g}\n\tfor o[len(o)-1] > 1 {\n\t\to = append(o, o[len(o)-1].Parent())\n\t}\n\treturn o[:len(o)-1]\n}\n\n// Concat multiple generalized indices into a single generalized index\n// representing the path from the first to the last node.\nfunc (gs GeneralizedIndices) Concat() GeneralizedIndex {\n\to := GeneralizedIndex(1)\n\tfor _, i := range gs {\n\t\tfloorPower := pow.PrevPowerOfTwo(i)\n\t\to *= floorPower\n\t\to += i - floorPower\n\t}\n\treturn o\n}\n\n// GetHelperIndices returns the generalized indices of all \"extra\" chunks in the\n// tree needed to prove the chunks with the given generalized indices. The\n// decreasing order is chosen deliberately to ensure equivalence to the order of\n// hashes in a regular single-item Merkle proof in the single-item case.\nfunc (gs GeneralizedIndices) GetHelperIndices() GeneralizedIndices {\n\tallHelperIndices := make(map[GeneralizedIndex]struct{})\n\tallPathIndices := make(map[GeneralizedIndex]struct{})\n\n\tfor _, index := range gs {\n\t\tfor _, helperIndex := range index.GetBranchIndices() {\n\t\t\tallHelperIndices[helperIndex] = struct{}{}\n\t\t}\n\t\tfor _, pathIndex := range index.GetPathIndices() {\n\t\t\tallPathIndices[pathIndex] = struct{}{}\n\t\t}\n\t}\n\n\tdifference := make(GeneralizedIndices, 0, len(allHelperIndices))\n\tfor helperIndex := range allHelperIndices {\n\t\tif _, exists := allPathIndices[helperIndex]; !exists {\n\t\t\tdifference = append(difference, helperIndex)\n\t\t}\n\t}\n\n\t// Sort in decreasing order.\n\tslices.SortFunc(difference, GeneralizedIndexReverseComparator)\n\n\treturn difference\n}\n\n// Comparator function used to sort generalized indices in reverse order.\nfunc GeneralizedIndexReverseComparator(i, j GeneralizedIndex) int {\n\tswitch {\n\tcase i < j:\n\t\treturn 1\n\tcase i == j:\n\t\treturn 0\n\tcase i > j:\n\t\treturn -1\n\tdefault:\n\t\tpanic(\"unreachable\")\n\t}\n}\n"
  },
  {
    "path": "primitives/merkle/index_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/merkle\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestNewGeneralizedIndex(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tdepth  uint8\n\t\tindex  uint64\n\t\texpect merkle.GeneralizedIndex\n\t}{\n\t\t{depth: 0, index: 0, expect: 1},\n\t\t{depth: 1, index: 1, expect: 3},\n\t\t{depth: 2, index: 2, expect: 6},\n\t\t{depth: 3, index: 5, expect: 13},\n\t}\n\n\tfor _, tt := range tests {\n\t\tresult := merkle.NewGeneralizedIndex(\n\t\t\ttt.depth,\n\t\t\ttt.index,\n\t\t)\n\t\trequire.Equal(\n\t\t\tt,\n\t\t\ttt.expect,\n\t\t\tresult,\n\t\t\t\"Failed at depth %d and index %d\",\n\t\t\ttt.depth,\n\t\t\ttt.index,\n\t\t)\n\t}\n}\n\nfunc TestConcatGeneralizedIndices(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tindices merkle.GeneralizedIndices\n\t\texpect  merkle.GeneralizedIndex\n\t}{\n\t\t{indices: []merkle.GeneralizedIndex{1, 2, 3}, expect: 0x05},\n\t\t{indices: []merkle.GeneralizedIndex{4, 5, 6}, expect: 0x46},\n\t}\n\n\tfor _, tt := range tests {\n\t\tresult := tt.indices.Concat()\n\t\trequire.Equal(\n\t\t\tt,\n\t\t\ttt.expect,\n\t\t\tresult,\n\t\t\t\"Failed with indices %v\",\n\t\t\ttt.indices,\n\t\t)\n\t}\n}\n\nfunc TestGeneralizedIndexMethods(t *testing.T) {\n\tt.Parallel()\n\tgi := merkle.GeneralizedIndex(12) // Example index\n\n\trequire.Equal(\n\t\tt,\n\t\t3,\n\t\tgi.Length(),\n\t\t\"Incorrect length for GeneralizedIndex\",\n\t)\n\trequire.True(\n\t\tt,\n\t\tgi.IndexBit(2),\n\t\t\"IndexBit should return true for bit position 2\",\n\t)\n\trequire.False(\n\t\tt,\n\t\tgi.IndexBit(1),\n\t\t\"IndexBit should return false for bit position 1\",\n\t)\n\trequire.Equal(\n\t\tt,\n\t\tmerkle.GeneralizedIndex(13),\n\t\tgi.Sibling(),\n\t\t\"Incorrect sibling index\",\n\t)\n\trequire.Equal(\n\t\tt,\n\t\tmerkle.GeneralizedIndex(24),\n\t\tgi.LeftChild(),\n\t\t\"Incorrect right child index\",\n\t)\n\trequire.Equal(\n\t\tt,\n\t\tmerkle.GeneralizedIndex(25),\n\t\tgi.RightChild(),\n\t\t\"Incorrect left child index\",\n\t)\n\trequire.Equal(\n\t\tt,\n\t\tmerkle.GeneralizedIndex(6),\n\t\tgi.Parent(),\n\t\t\"Incorrect parent index\",\n\t)\n}\n\nfunc TestGetBranchIndices(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname   string\n\t\tindex  merkle.GeneralizedIndex\n\t\texpect merkle.GeneralizedIndices\n\t}{\n\t\t{name: \"Single Branch\", index: 1, expect: []merkle.GeneralizedIndex{}},\n\t\t{name: \"Two Branches\", index: 3, expect: []merkle.GeneralizedIndex{2}},\n\t\t{name: \"Multiple Branches\", index: 5,\n\t\t\texpect: []merkle.GeneralizedIndex{4, 3}},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := tt.index.GetBranchIndices()\n\t\t\trequire.Equal(\n\t\t\t\tt,\n\t\t\t\ttt.expect,\n\t\t\t\tresult,\n\t\t\t\t\"Failed for index %d\",\n\t\t\t\ttt.index,\n\t\t\t)\n\t\t})\n\t}\n}\n\nfunc TestGetPathIndices(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname   string\n\t\tindex  merkle.GeneralizedIndex\n\t\texpect merkle.GeneralizedIndices\n\t}{\n\t\t{\n\t\t\tname:   \"No Path\",\n\t\t\tindex:  1,\n\t\t\texpect: []merkle.GeneralizedIndex{},\n\t\t},\n\t\t{name: \"Single Path\", index: 3, expect: []merkle.GeneralizedIndex{3}},\n\t\t{\n\t\t\tname:   \"Multiple Paths\",\n\t\t\tindex:  5,\n\t\t\texpect: []merkle.GeneralizedIndex{5, 2},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := tt.index.GetPathIndices()\n\t\t\trequire.Equal(\n\t\t\t\tt,\n\t\t\t\ttt.expect,\n\t\t\t\tresult,\n\t\t\t\t\"Failed for index %d\",\n\t\t\t\ttt.index,\n\t\t\t)\n\t\t})\n\t}\n}\n\nfunc TestGetHelperIndices(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\tindices merkle.GeneralizedIndices\n\t\texpect  merkle.GeneralizedIndices\n\t}{\n\t\t{\n\t\t\tname:    \"No Indices\",\n\t\t\tindices: []merkle.GeneralizedIndex{},\n\t\t\texpect:  []merkle.GeneralizedIndex{},\n\t\t},\n\t\t{\n\t\t\tname:    \"Single Index\",\n\t\t\tindices: []merkle.GeneralizedIndex{1},\n\t\t\texpect:  []merkle.GeneralizedIndex{},\n\t\t},\n\t\t{\n\t\t\tname:    \"Multiple Indices\",\n\t\t\tindices: []merkle.GeneralizedIndex{3, 5},\n\t\t\texpect:  []merkle.GeneralizedIndex{4},\n\t\t},\n\t\t{\n\t\t\tname:    \"Overlapping Indices\",\n\t\t\tindices: []merkle.GeneralizedIndex{3, 7},\n\t\t\texpect:  []merkle.GeneralizedIndex{6, 2},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := tt.indices.GetHelperIndices()\n\t\t\trequire.Equal(t, tt.expect, result,\n\t\t\t\t\"Failed for indices %v\", tt.indices)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "primitives/merkle/object_path.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle\n\nimport (\n\t\"errors\"\n\t\"strings\"\n\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz/schema\"\n\t\"github.com/berachain/beacon-kit/primitives/math/pow\"\n)\n\n// ObjectPath represents a path to an object in a Merkle tree.\ntype ObjectPath string\n\n// Split returns the path split by \"/\".\nfunc (p ObjectPath) Split() []string {\n\treturn strings.Split(string(p), \"/\")\n}\n\n// GetGeneralizedIndex converts a path to a generalized index representing its\n// position in the Merkle tree.\n//\n//\t\"\"\"\n//\n// Converts a path (eg. `[7, \"foo\", 3]` for `x[7].foo[3]`, `[12, \"bar\",\n// \"__len__\"]` for `len(x[12].bar)`) into the generalized index representing its\n// position in the Merkle tree.\n// \"\"\"\n// root = GeneralizedIndex(1)\n// for p in path:\n//\n//\tassert not issubclass(typ, BasicValue)  # If we descend to a basic type, the\n//\n// path cannot continue further\n//\n//\tif p == '__len__':\n//\t\ttyp = uint64\n//\t\tassert issubclass(typ, (List, ByteList))\n//\t\troot = GeneralizedIndex(root * 2 + 1)\n//\telse:\n//\t\tpos, _, _ = get_item_position(typ, p)\n//\t\tbase_index = (GeneralizedIndex(2) if issubclass(typ, (List, ByteList)) else\n//\n// GeneralizedIndex(1)) \t\troot = GeneralizedIndex(root * base_index *\n// get_power_of_two_ceil(chunk_count(typ)) + pos)\n//\n//\ttyp = get_elem_type(typ, p)\n//\n// return root.\nfunc (p ObjectPath) GetGeneralizedIndex(\n\ttyp schema.SSZType,\n) (schema.SSZType, uint64, uint8, error) {\n\tgIndex := uint64(1)\n\toffset := uint8(0)\n\tfor _, part := range p.Split() {\n\t\t// If we descend to a basic type, the path cannot continue further\n\t\tif typ.ID().IsBasic() {\n\t\t\treturn nil, 0, 0, errors.New(\n\t\t\t\t\"cannot descend further from basic type\",\n\t\t\t)\n\t\t}\n\n\t\tif part == \"__len__\" {\n\t\t\tif !typ.ID().IsList() {\n\t\t\t\treturn nil, 0, 0, errors.New(\n\t\t\t\t\t\"__len__ is only valid for List types\",\n\t\t\t\t)\n\t\t\t}\n\t\t\ttyp = schema.U64()\n\t\t\t//nolint:mnd // from spec.\n\t\t\tgIndex = gIndex*2 + 1\n\t\t} else {\n\t\t\tpos, start, _, err := typ.ItemPosition(part)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, 0, 0, err\n\t\t\t}\n\n\t\t\tgIndex = gIndex*getBaseIndex(typ)*\n\t\t\t\tpow.NextPowerOfTwo(typ.HashChunkCount()) + pos\n\t\t\ttyp = typ.ElementType(part)\n\t\t\toffset = start\n\t\t}\n\t}\n\n\treturn typ, gIndex, offset, nil\n}\n\n// getBaseIndex returns the base index for a given SSZ type.\n// For list types, it returns 2, for all other types it returns 1.\nfunc getBaseIndex(typ schema.SSZType) uint64 {\n\tif typ.ID().IsList() {\n\t\t//nolint:mnd // 2 is allowed.\n\t\treturn 2\n\t}\n\treturn 1\n}\n"
  },
  {
    "path": "primitives/merkle/object_path_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle_test\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz/schema\"\n\t\"github.com/berachain/beacon-kit/primitives/merkle\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc Test_ObjectPath(t *testing.T) {\n\tt.Parallel()\n\tnested := schema.DefineContainer(\n\t\tschema.NewField(\"bytes32\", schema.B32()),\n\t\tschema.NewField(\"uint64\", schema.U64()),\n\t\tschema.NewField(\"list_bytes32\", schema.DefineList(schema.B32(), 10)),\n\t\tschema.NewField(\"bytes256\", schema.DefineVector(schema.U8(), 256)),\n\t)\n\troot := schema.DefineContainer(\n\t\tschema.NewField(\"bytes32\", schema.B32()),\n\t\tschema.NewField(\"uint32\", schema.U32()),\n\t\tschema.NewField(\"list_uint64\", schema.DefineList(schema.U64(), 1000)),\n\t\tschema.NewField(\"list_nested\", schema.DefineList(nested, 1000)),\n\t\tschema.NewField(\"nested\", nested),\n\t\tschema.NewField(\"vector_uint64\", schema.DefineVector(schema.U64(), 40)),\n\t)\n\n\tcases := []struct {\n\t\tpath   string\n\t\tgindex uint64\n\t\toffset uint8\n\t\terror  string\n\t}{\n\t\t// happy paths\n\t\t{path: \"bytes32\", gindex: 8},\n\t\t{path: \"bytes32/3\", gindex: 8, offset: 3},\n\t\t{path: \"uint32\", gindex: 9},\n\t\t{path: \"list_nested\", gindex: 11},\n\t\t{path: \"list_nested/__len__\", gindex: 2*11 + 1},\n\t\t{path: \"list_nested/12\", gindex: 11*2*1024 + 12},\n\t\t{path: \"list_nested/12/uint64\", gindex: (11*2*1024+12)*4 + 1},\n\t\t{path: \"nested\", gindex: 12},\n\t\t{path: \"nested/uint64\", gindex: 12*4 + 1},\n\t\t{path: \"nested/bytes256\", gindex: 12*4 + 3},\n\t\t{path: \"nested/bytes256/30\", gindex: (12*4 + 3) * 8, offset: 30},\n\t\t{path: \"vector_uint64\", gindex: 13},\n\t\t// 40 64-bit ints occupy 320 bytes (10 chunks), nextPowerOfTwo(10) = 16\n\t\t{path: \"vector_uint64/5\", gindex: 13*16 + (5 / 4), offset: 8},\n\n\t\t// error cases\n\t\t{path: \"nested/__len__\", error: \"__len__ is only valid\"},\n\t}\n\tfor _, tc := range cases {\n\t\tt.Run(strings.ReplaceAll(tc.path, \"/\", \".\"), func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tobjectPath := merkle.ObjectPath(tc.path)\n\t\t\ttyp, gindex, offset, err := objectPath.GetGeneralizedIndex(root)\n\n\t\t\tif tc.error != \"\" {\n\t\t\t\trequire.ErrorContains(t, err, tc.error)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.NotNil(\n\t\t\t\tt, typ, \"Type should not be nil\")\n\t\t\trequire.Equal(\n\t\t\t\tt, tc.gindex, gindex, \"Unexpected generalized index\",\n\t\t\t)\n\t\t\trequire.Equal(t, tc.offset, offset, \"Unexpected offset\")\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "primitives/merkle/proof.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle\n\nimport \"github.com/berachain/beacon-kit/primitives/crypto/sha256\"\n\n// VerifyProof given a tree root, a leaf, the generalized merkle index\n// of the leaf in the tree, and the proof itself.\nfunc VerifyProof[RootT, ProofT ~[32]byte](\n\troot, leaf RootT,\n\tmerkleIndex uint64,\n\tproof []ProofT,\n) bool {\n\t//#nosec:G701 `int`` is at minimum 32-bits and thus a\n\t// uint8 will always fit.\n\tif len(proof) > int(^uint8(0)) {\n\t\treturn false\n\t}\n\treturn IsValidMerkleBranch(\n\t\tleaf,\n\t\tproof,\n\t\tuint8(len(proof)), // #nosec G115 -- we check the length of the proof above.\n\t\tmerkleIndex,\n\t\troot,\n\t)\n}\n\n// IsValidMerkleBranch as per the Ethereum 2.0 spec:\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#is_valid_merkle_branch\nfunc IsValidMerkleBranch[RootT, BranchT ~[32]byte](\n\tleaf RootT, branch []BranchT, depth uint8, index uint64, root RootT,\n) bool {\n\t//#nosec:G701 `int`` is at minimum 32-bits and thus a\n\t// uint8 will always fit.\n\tif len(branch) != int(depth) {\n\t\treturn false\n\t}\n\treturn RootFromBranch(leaf, branch, depth, index) == root\n}\n\n// RootFromBranch calculates the Merkle root from a leaf and a branch.\n// Inspired by:\n// https://github.com/sigp/lighthouse/blob/stable/consensus/merkle_proof/src/lib.rs#L372\nfunc RootFromBranch[RootT, BranchT ~[32]byte](\n\tleaf RootT,\n\tbranch []BranchT,\n\tdepth uint8,\n\tindex uint64,\n) RootT {\n\tvar (\n\t\thashInput  [64]byte\n\t\thashFn     func([]byte) [32]byte\n\t\tmerkleRoot = leaf\n\t)\n\n\t//nolint:mnd // 5 as defined by the library.\n\tif depth > 5 {\n\t\thashFn = sha256.CustomHashFn()\n\t} else {\n\t\thashFn = sha256.Hash\n\t}\n\n\tfor i := range depth {\n\t\tithBit := (index >> i) & 1\n\t\tif ithBit == 1 {\n\t\t\tcopy(hashInput[:32], branch[i][:])\n\t\t\tcopy(hashInput[32:], merkleRoot[:])\n\t\t} else {\n\t\t\tcopy(hashInput[:32], merkleRoot[:])\n\t\t\tcopy(hashInput[32:], branch[i][:])\n\t\t}\n\t\tmerkleRoot = hashFn(hashInput[:])\n\t}\n\treturn merkleRoot\n}\n"
  },
  {
    "path": "primitives/merkle/root_hasher.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle\n\nimport (\n\t\"runtime\"\n\t\"unsafe\"\n\n\t\"github.com/prysmaticlabs/gohashtree\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\nconst (\n\t// MinParallelizationSize is the minimum size of the input list that\n\t// should be hashed using the default method. If the input list is smaller\n\t// than this size, the overhead of parallelizing the hashing process is.\n\t//\n\t// TODO: This value is arbitrary and should be benchmarked to find the\n\t// optimal value.\n\tMinParallelizationSize = 5000\n\t// two is a constant to make the linter happy.\n\ttwo = 2\n)\n\n// BuildParentTreeRoots calls BuildParentTreeRootsWithNRoutines to\n// parallelize the hashing process.\nfunc BuildParentTreeRoots[RootT ~[32]byte](\n\toutputList, inputList []RootT,\n) error {\n\treturn BuildParentTreeRootsWithNRoutines(\n\t\t//#nosec:G103 // on purpose.\n\t\t*(*[][32]byte)(unsafe.Pointer(&outputList)),\n\t\t//#nosec:G103 // on purpose.\n\t\t*(*[][32]byte)(unsafe.Pointer(&inputList)),\n\t\tMinParallelizationSize,\n\t)\n}\n\n// BuildParentTreeRootsWithNRoutines optimizes hashing of a list of roots\n// using CPU-specific vector instructions and parallel processing. This\n// method adapts to the host machine's hardware for potential performance\n// gains over sequential hashing.\n//\n// NOTE: Currently we use `runtime.GOMAXPROCS(0)-1` as the number of\n// goroutines to use.\n//\n// TODO: We do not use generics here due to the gohashtree library not\n// supporting generics.\nfunc BuildParentTreeRootsWithNRoutines(\n\toutputList, inputList [][32]byte, minParallelizationSize int,\n) error {\n\t// Validate input list length.\n\tinputLength := len(inputList)\n\tif inputLength%2 != 0 {\n\t\treturn ErrOddLengthTreeRoots\n\t}\n\n\t// If the input list is small, hash it using the default method since\n\t// the overhead of parallelizing the hashing process is not worth it.\n\tif inputLength < minParallelizationSize {\n\t\treturn gohashtree.Hash(outputList, inputList)\n\t}\n\n\t// Get the number of goroutines to use.\n\t//\n\t// TODO: parameterize n and allow this to be specified by caller.\n\tn := runtime.GOMAXPROCS(0) - 1\n\n\t// Otherwise parallelize the hashing process for large inputs.\n\tgroupSize := inputLength / (two * (n + 1))\n\ttwiceGroupSize := two * groupSize\n\teg := new(errgroup.Group)\n\n\t// If n is 0 the parallelization is disabled and the whole inputList is\n\t// hashed in the main goroutine at the end of this function.\n\tfor j := range n {\n\t\teg.Go(func() error {\n\t\t\t// inputList:  [-------------------2*groupSize-------------------]\n\t\t\t//        ______^           ____^               ^               ^\n\t\t\t//       |                 |                    |               |\n\t\t\t// j*2*groupSize   (j+1)*2*groupSize    (j+2)*2*groupSize      End\n\t\t\t//\n\t\t\t// outputList:   [---------groupSize---------]\n\t\t\t//                ^                         ^\n\t\t\t//                |                         |\n\t\t\t//           j*groupSize             (j+1)*groupSize\n\t\t\t//\n\t\t\t// Each goroutine processes a segment of inputList that is twice as\n\t\t\t// large as the segment it fills in outputList. This is because the\n\t\t\t// hash operation reduces the size of the input by half.\n\n\t\t\t// Define the segment of the inputList each goroutine will process.\n\t\t\tsegmentStart := j * twiceGroupSize\n\t\t\tsegmentEnd := (j + 1) * twiceGroupSize\n\n\t\t\treturn gohashtree.Hash(\n\t\t\t\toutputList[j*groupSize:],\n\t\t\t\tinputList[segmentStart:segmentEnd],\n\t\t\t)\n\t\t})\n\t}\n\n\t// Hash the last segment of the inputList.\n\tif err := gohashtree.Hash(\n\t\toutputList[n*groupSize:],\n\t\tinputList[n*twiceGroupSize:],\n\t); err != nil {\n\t\treturn err\n\t}\n\n\treturn eg.Wait()\n}\n"
  },
  {
    "path": "primitives/merkle/root_hasher_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle_test\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/primitives/merkle\"\n\t\"github.com/prysmaticlabs/gohashtree\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc Test_HashTreeRootEqualInputs(t *testing.T) {\n\tt.Parallel()\n\t// Test with slices of varying sizes to ensure robustness across different\n\t// conditions\n\tsliceSizes := []int{16, 32, 64}\n\tfor _, size := range sliceSizes {\n\t\tt.Run(\n\t\t\tfmt.Sprintf(\"Size%d\", size*merkle.MinParallelizationSize),\n\t\t\tfunc(t *testing.T) {\n\t\t\t\tt.Parallel()\n\t\t\t\tlargeSlice := make(\n\t\t\t\t\t[][32]byte, size*merkle.MinParallelizationSize,\n\t\t\t\t)\n\t\t\t\tsecondLargeSlice := make(\n\t\t\t\t\t[][32]byte, size*merkle.MinParallelizationSize,\n\t\t\t\t)\n\t\t\t\thash1 := make([][32]byte, size*merkle.MinParallelizationSize)\n\t\t\t\thash2 := make([][32]byte, size*merkle.MinParallelizationSize)\n\t\t\t\tvar err error\n\n\t\t\t\terr = merkle.BuildParentTreeRoots(hash1, largeSlice)\n\t\t\t\trequire.NoError(t, err)\n\n\t\t\t\terr = merkle.BuildParentTreeRoots(hash2, secondLargeSlice)\n\t\t\t\trequire.NoError(t, err)\n\n\t\t\t\trequire.Equal(\n\t\t\t\t\tt,\n\t\t\t\t\tlen(hash1),\n\t\t\t\t\tlen(hash2),\n\t\t\t\t\t\"Hash lengths should be equal\",\n\t\t\t\t)\n\t\t\t\tfor i, r := range hash1 {\n\t\t\t\t\trequire.Equal(\n\t\t\t\t\t\tt,\n\t\t\t\t\t\tr,\n\t\t\t\t\t\thash2[i],\n\t\t\t\t\t\tfmt.Errorf(\"Hash mismatch at index %d\", i),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t},\n\t\t)\n\t}\n}\n\nfunc Test_GoHashTreeHashConformance(t *testing.T) {\n\tt.Parallel()\n\t// Define a test table with various input sizes,\n\t// including ones above and below MinParallelizationSize\n\ttestCases := []struct {\n\t\tname    string\n\t\tsize    int\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\t\"BelowMinParallelizationSize\",\n\t\t\tmerkle.MinParallelizationSize / 2,\n\t\t\tfalse,\n\t\t},\n\t\t{\"AtMinParallelizationSize\",\n\t\t\tmerkle.MinParallelizationSize, false},\n\t\t{\n\t\t\t\"AboveMinParallelizationSize\",\n\t\t\tmerkle.MinParallelizationSize * 2,\n\t\t\tfalse,\n\t\t},\n\t\t{\"SmallSize\", 16, false},\n\t\t{\"MediumSize\", 64, false},\n\t\t{\"LargeSize\", 128, false},\n\t\t{\n\t\t\t\"TestRemainderStartIndexSmall\",\n\t\t\tmerkle.MinParallelizationSize + 6,\n\t\t\tfalse,\n\t\t},\n\t\t{\n\t\t\t\"TestRemainderStartIndexBig\",\n\t\t\tmerkle.MinParallelizationSize - 2,\n\t\t\tfalse,\n\t\t},\n\t\t{\"TestOddLength\",\n\t\t\tmerkle.MinParallelizationSize + 1, true},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tinputList := make([][32]byte, tc.size)\n\t\t\t// Fill inputList with pseudo-random data\n\t\t\trandSource := rand.NewSource(time.Now().UnixNano())\n\t\t\trandGen := rand.New(randSource)\n\t\t\tfor i := range inputList {\n\t\t\t\tfor j := range inputList[i] {\n\t\t\t\t\tinputList[i][j] = byte(randGen.Intn(256))\n\t\t\t\t}\n\t\t\t}\n\t\t\trequireGoHashTreeEquivalence(\n\t\t\t\tt,\n\t\t\t\tinputList,\n\t\t\t\tmerkle.MinParallelizationSize,\n\t\t\t\ttc.wantErr,\n\t\t\t)\n\t\t})\n\t}\n}\n\n// TODO: Re-enable once N routines is parameterized.\n// func TestBuildParentTreeRootsWithNRoutines_DivisionByZero(t *testing.T) {\n// \t// Attempt to call BuildParentTreeRootsWithNRoutines with n set to 0\n// \t// to test handling of division by zero.\n// \tinputList := make([][32]byte, 10) // Arbitrary size larger than 0\n// \toutput := make([][32]byte, 8)     // Arbitrary size smaller than inputList\n// \terr := merkle.BuildParentTreeRootsWithNRoutines(\n// \t\toutput,\n// \t\tinputList,\n// \t\tmerkle.MinParallelizationSize,\n// \t)\n// \trequire.NoError(\n// \t\tt,\n// \t\terr,\n// \t\t\"BuildParentTreeRootsWithNRoutines should handle n=0 without error\",\n// \t)\n// }\n\n// requireGoHashTreeEquivalence is a helper function to ensure that the output\n// of merkle.BuildParentTreeRootsWithNRoutines is equivalent to the output of\n// gohashtree.Hash.\nfunc requireGoHashTreeEquivalence(\n\tt *testing.T,\n\tinputList [][32]byte, minParallelizationSize int, expectError bool,\n) {\n\tt.Helper()\n\n\t// Deep copy inputList\n\tinputListCopy := make([][32]byte, len(inputList))\n\tcopy(inputListCopy, inputList)\n\n\texpectedOutput := make([][32]byte, len(inputListCopy)/2)\n\toutput := make([][32]byte, len(inputListCopy)/2)\n\tvar err1, err2 error\n\n\t// Run parallel hasher.\n\terr1 = merkle.BuildParentTreeRootsWithNRoutines(\n\t\toutput,\n\t\tinputListCopy,\n\t\tminParallelizationSize,\n\t)\n\n\t// Run gohashtree.Hash\n\terr2 = gohashtree.Hash(\n\t\texpectedOutput,\n\t\tinputListCopy,\n\t)\n\n\t// Check for errors\n\tif !expectError {\n\t\trequire.NoError(t, err1,\n\t\t\t\"BuildParentTreeRootsWithNRoutines failed\")\n\t\trequire.NoError(t, err2, \"gohashtree.Hash failed\")\n\t} else {\n\t\tif err1 == nil && err2 == nil {\n\t\t\tt.Error(\"Expected error did not occur\")\n\t\t}\n\t\treturn\n\t}\n\n\t// Ensure the lengths are the same\n\trequire.Equal(t, len(expectedOutput), len(output))\n\n\t// Compare the outputs element by element\n\tfor i := range output {\n\t\trequire.Equal(t, expectedOutput[i], output[i])\n\t}\n}\n"
  },
  {
    "path": "primitives/merkle/tree.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto/sha256\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/merkle/zero\"\n)\n\n// 2^63 would overflow.\nconst MaxTreeDepth = 62\n\n// Tree[RootT] implements a Merkle tree that has been optimized to\n// handle leaves that are 32 bytes in size.\ntype Tree[RootT ~[32]byte] struct {\n\tdepth    uint8\n\tbranches [][]RootT\n\tleaves   []RootT\n\n\thasher Hasher[[32]byte]\n}\n\n// NewTreeFromLeaves constructs a Merkle tree, with the minimum\n// depth required to support the number of leaves.\nfunc NewTreeFromLeaves[RootT ~[32]byte](\n\tleaves []RootT,\n) (*Tree[RootT], error) {\n\treturn NewTreeFromLeavesWithDepth(\n\t\tleaves,\n\t\tmath.U64(len(leaves)).NextPowerOfTwo().ILog2Ceil(),\n\t)\n}\n\n// NewTreeWithMaxLeaves constructs a Merkle tree with a maximum number of\n// leaves.\nfunc NewTreeWithMaxLeaves[RootT ~[32]byte](\n\tleaves []RootT,\n\tmaxLeaves uint64,\n) (*Tree[RootT], error) {\n\treturn NewTreeFromLeavesWithDepth(\n\t\tleaves,\n\t\tmath.U64(maxLeaves).NextPowerOfTwo().ILog2Ceil(),\n\t)\n}\n\n// NewTreeFromLeavesWithDepth constructs a Merkle tree\n// from a sequence of byte slices.\n// It will fill the tree with zero hashes to create the required depth.\nfunc NewTreeFromLeavesWithDepth[RootT ~[32]byte](\n\tleaves []RootT,\n\tdepth uint8,\n) (*Tree[RootT], error) {\n\tif err := verifySufficientDepth(len(leaves), depth); err != nil {\n\t\treturn &Tree[RootT]{}, err\n\t}\n\n\tlayers := make([][]RootT, depth+1)\n\tlayers[0] = leaves\n\n\t// Preallocate layers based on depth\n\t// TODO: This should be done virtually....\n\tfor i := uint8(1); i <= depth; i++ {\n\t\tlayerSize := (len(leaves) + (1 << i) - 1) >> i\n\t\tlayers[i] = make([]RootT, layerSize)\n\t}\n\n\tfor d := range depth {\n\t\tcurrentLayer := layers[d]\n\t\tif len(currentLayer)%2 == 1 {\n\t\t\tcurrentLayer = append(currentLayer, zero.Hashes[d])\n\t\t}\n\n\t\tif err := BuildParentTreeRoots(\n\t\t\tlayers[d+1], currentLayer,\n\t\t); err != nil {\n\t\t\treturn &Tree[RootT]{}, err\n\t\t}\n\t}\n\n\treturn &Tree[RootT]{\n\t\tbranches: layers,\n\t\tleaves:   leaves,\n\t\tdepth:    depth,\n\t\thasher:   NewHasher[[32]byte](sha256.Hash),\n\t}, nil\n}\n\n// Insert an item into the tree.\nfunc (m *Tree[RootT]) Insert(item [32]byte, index int) error {\n\tif index < 0 {\n\t\treturn errors.Wrap(ErrNegativeIndex, fmt.Sprintf(\"index: %d\", index))\n\t}\n\tfor index >= len(m.branches[0]) {\n\t\tm.branches[0] = append(m.branches[0], zero.Hashes[0])\n\t}\n\tm.branches[0][index] = item\n\tif index >= len(m.leaves) {\n\t\tm.leaves = append(m.leaves, item)\n\t} else {\n\t\tm.leaves[index] = item\n\t}\n\n\tvar (\n\t\thashFn       func([]byte) [32]byte\n\t\tneighbor     = [32]byte{}\n\t\tinput        = [64]byte{}\n\t\tcurrentIndex = index\n\t\troot         = item\n\t)\n\n\t//nolint:mnd // 5 as defined by the library.\n\tif m.depth > 5 {\n\t\thashFn = sha256.CustomHashFn()\n\t} else {\n\t\thashFn = sha256.Hash\n\t}\n\n\tfor i := range m.depth {\n\t\tif neighborIdx := currentIndex ^ 1; neighborIdx >= len(m.branches[i]) {\n\t\t\tneighbor = zero.Hashes[i]\n\t\t} else {\n\t\t\tneighbor = m.branches[i][neighborIdx]\n\t\t}\n\n\t\t//nolint:mnd // 2 is allowed.\n\t\tif isLeft := currentIndex%2 == 0; isLeft {\n\t\t\tcopy(input[0:32], root[:])\n\t\t\tcopy(input[32:64], neighbor[:])\n\t\t} else {\n\t\t\tcopy(input[0:32], neighbor[:])\n\t\t\tcopy(input[32:64], root[:])\n\t\t}\n\t\troot = hashFn(input[:])\n\n\t\t//nolint:mnd // 2 is allowed.\n\t\tparentIdx := currentIndex / 2\n\t\tif len(m.branches[i+1]) == 0 || parentIdx >= len(m.branches[i+1]) {\n\t\t\tm.branches[i+1] = append(m.branches[i+1], root)\n\t\t} else {\n\t\t\tm.branches[i+1][parentIdx] = root\n\t\t}\n\t\tcurrentIndex = parentIdx\n\t}\n\treturn nil\n}\n\n// Root returns the root of the Merkle tree.\nfunc (m *Tree[RootT]) Root() [32]byte {\n\treturn m.branches[len(m.branches)-1][0]\n}\n\n// HashTreeRoot returns the Root of the Merkle tree with the\n// number of leaves mixed in.\nfunc (m *Tree[RootT]) HashTreeRoot() common.Root {\n\tnumItems := uint64(len(m.leaves))\n\tif len(m.leaves) == 1 &&\n\t\tm.leaves[0] == zero.Hashes[0] {\n\t\tnumItems = 0\n\t}\n\treturn m.hasher.MixIn(m.Root(), numItems)\n}\n\n// MerkleProof computes a proof from a tree's branches using a Merkle index.\nfunc (m *Tree[RootT]) MerkleProof(leafIndex uint64) ([]RootT, error) {\n\tnumLeaves := uint64(len(m.branches[0]))\n\tif leafIndex >= numLeaves {\n\t\treturn nil, errors.Wrapf(\n\t\t\terrors.New(\"merkle index out of range in tree\"),\n\t\t\t\"max range: %d, received: %d\",\n\t\t\tnumLeaves,\n\t\t\tleafIndex,\n\t\t)\n\t}\n\tproof := make([]RootT, m.depth)\n\tfor i := range m.depth {\n\t\tsubIndex := (leafIndex >> i) ^ 1\n\t\tif subIndex < uint64(len(m.branches[i])) {\n\t\t\tproof[i] = m.branches[i][subIndex]\n\t\t} else {\n\t\t\tproof[i] = zero.Hashes[i]\n\t\t}\n\t}\n\treturn proof, nil\n}\n\n// MerkleProofWithMixin computes a proof from a tree's branches using a Merkle\n// index.\nfunc (m *Tree[RootT]) MerkleProofWithMixin(\n\tindex uint64,\n) ([]RootT, error) {\n\tproof, err := m.MerkleProof(index)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tmixin := [32]byte{}\n\tbinary.LittleEndian.PutUint64(mixin[:8], uint64(len(m.leaves)))\n\treturn append(proof, mixin), nil\n}\n"
  },
  {
    "path": "primitives/merkle/tree_fuzz_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle_test\n\nimport (\n\t\"testing\"\n\n\tbyteslib \"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/merkle\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nconst depth = uint8(16)\n\nfunc FuzzTree_IsValidMerkleBranch(f *testing.F) {\n\tsplitProofs := func(proofRaw []byte) [][32]byte {\n\t\tvar proofs [][32]byte\n\t\tfor i := 0; i < len(proofRaw); i += 32 {\n\t\t\tend := i + 32\n\t\t\tif end >= len(proofRaw) {\n\t\t\t\tend = len(proofRaw) - 1\n\t\t\t}\n\t\t\tvar proofSegment [32]byte\n\t\t\tcopy(proofSegment[:], proofRaw[i:end])\n\t\t\tproofs = append(proofs, proofSegment)\n\t\t}\n\t\treturn proofs\n\t}\n\n\titems := make([][32]byte, 0)\n\tfor _, v := range [][]byte{\n\t\tbyteslib.ExtendToSize([]byte(\"A\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"B\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"C\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"D\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"E\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"F\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"G\"), byteslib.B32Size),\n\t} {\n\t\titem, err := byteslib.ToBytes32(v)\n\t\trequire.NoError(f, err)\n\t\titems = append(items, item)\n\t}\n\trequire.NotEmpty(f, items) // appease nilaway\n\n\tm, err := merkle.NewTreeFromLeavesWithDepth(items, depth)\n\trequire.NoError(f, err)\n\tproof, err := m.MerkleProofWithMixin(0)\n\trequire.NoError(f, err)\n\trequire.Len(f, proof, int(depth)+1)\n\troot := m.HashTreeRoot()\n\tvar proofRaw []byte\n\tfor _, p := range proof {\n\t\tproofRaw = append(proofRaw, p[:]...)\n\t}\n\tf.Add(root[:], items[0][:], uint64(0), proofRaw, depth)\n\n\tf.Fuzz(\n\t\tfunc(t *testing.T,\n\t\t\troot, item []byte, merkleIndex uint64,\n\t\t\tproofRaw []byte, depth uint8,\n\t\t) {\n\t\t\tvar r, leaf byteslib.B32\n\n\t\t\titem = byteslib.ExtendToSize(item, byteslib.B32Size)[:byteslib.B32Size]\n\t\t\tleaf, err = byteslib.ToBytes32(item)\n\t\t\trequire.NoError(t, err)\n\n\t\t\troot = byteslib.ExtendToSize(root, byteslib.B32Size)[:byteslib.B32Size]\n\t\t\tr, err = byteslib.ToBytes32(root)\n\t\t\trequire.NoError(t, err)\n\n\t\t\tmerkle.IsValidMerkleBranch(\n\t\t\t\tleaf,\n\t\t\t\tsplitProofs(proofRaw),\n\t\t\t\tdepth,\n\t\t\t\tmerkleIndex,\n\t\t\t\tr,\n\t\t\t)\n\t\t},\n\t)\n}\n"
  },
  {
    "path": "primitives/merkle/tree_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle_test\n\nimport (\n\t\"strconv\"\n\t\"testing\"\n\n\tbyteslib \"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/merkle\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestNewTreeFromLeavesWithDepth_NoItemsProvided(t *testing.T) {\n\tt.Parallel()\n\ttreeDepth := uint8(32)\n\t_, err := merkle.NewTreeFromLeavesWithDepth[[32]byte](\n\t\tnil,\n\t\ttreeDepth,\n\t)\n\trequire.ErrorIs(t, err, merkle.ErrEmptyLeaves)\n}\n\nfunc TestNewTreeFromLeavesWithDepth_DepthSupport(t *testing.T) {\n\tt.Parallel()\n\titems := make([][32]byte, 0)\n\tfor _, v := range [][]byte{\n\t\tbyteslib.ExtendToSize([]byte(\"A\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"BB\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"CCC\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"DDDD\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"EEEEE\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"FFFFFF\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"GGGGGGG\"), byteslib.B32Size),\n\t} {\n\t\titem, err := byteslib.ToBytes32(v)\n\t\trequire.NoError(t, err)\n\t\titems = append(items, item)\n\t}\n\n\t// Supported depth\n\tm1, err := merkle.NewTreeFromLeavesWithDepth(\n\t\titems,\n\t\tmerkle.MaxTreeDepth,\n\t)\n\trequire.NoError(t, err)\n\tproof, err := m1.MerkleProofWithMixin(2)\n\trequire.NoError(t, err)\n\trequire.Len(t, proof, int(merkle.MaxTreeDepth)+1)\n\t// Unsupported depth\n\t_, err = merkle.NewTreeFromLeavesWithDepth(\n\t\titems,\n\t\tmerkle.MaxTreeDepth+1,\n\t)\n\trequire.ErrorIs(t, err, merkle.ErrExceededDepth)\n}\n\nfunc TestMerkleTree_IsValidMerkleBranch(t *testing.T) {\n\tt.Parallel()\n\ttreeDepth := uint8(32)\n\titems := make([][32]byte, 0)\n\tfor _, v := range [][]byte{\n\t\tbyteslib.ExtendToSize([]byte(\"A\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"B\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"C\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"D\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"E\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"F\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"G\"), byteslib.B32Size),\n\t} {\n\t\titem, err := byteslib.ToBytes32(v)\n\t\trequire.NoError(t, err)\n\t\titems = append(items, item)\n\t}\n\trequire.NotEmpty(t, items)\n\n\tm, err := merkle.NewTreeFromLeavesWithDepth(\n\t\titems,\n\t\ttreeDepth,\n\t)\n\trequire.NoError(t, err)\n\n\tproof, err := m.MerkleProofWithMixin(0)\n\trequire.NoError(t, err)\n\trequire.Len(\n\t\tt,\n\t\tproof,\n\t\tint(treeDepth)+1,\n\t)\n\n\troot := m.HashTreeRoot()\n\trequire.True(t, merkle.VerifyProof(\n\t\troot, items[0], 0, proof,\n\t), \"First Merkle proof did not verify\")\n\n\tproof, err = m.MerkleProofWithMixin(3)\n\trequire.NoError(t, err)\n\trequire.True(\n\t\tt,\n\t\tmerkle.VerifyProof(\n\t\t\troot,\n\t\t\titems[3],\n\t\t\t3,\n\t\t\tproof,\n\t\t),\n\t)\n\n\tit := byteslib.ExtendToSize([]byte(\"buzz\"), byteslib.B32Size)\n\titem, err := byteslib.ToBytes32(it)\n\trequire.NoError(t, err)\n\trequire.False(\n\t\tt,\n\t\tmerkle.IsValidMerkleBranch(\n\t\t\tcommon.Root(item),\n\t\t\tproof,\n\t\t\ttreeDepth,\n\t\t\t3,\n\t\t\troot,\n\t\t),\n\t)\n}\n\nfunc TestMerkleTree_VerifyProof(t *testing.T) {\n\tt.Parallel()\n\ttreeDepth := uint8(32)\n\n\titems := make([][32]byte, 0)\n\tfor _, v := range [][]byte{\n\t\tbyteslib.ExtendToSize([]byte(\"A\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"B\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"C\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"D\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"E\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"F\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"G\"), byteslib.B32Size),\n\t} {\n\t\titem, err := byteslib.ToBytes32(v)\n\t\trequire.NoError(t, err)\n\t\titems = append(items, item)\n\t}\n\trequire.NotEmpty(t, items) // appease nilaway\n\n\tm, err := merkle.NewTreeFromLeavesWithDepth[[32]byte](\n\t\titems,\n\t\ttreeDepth,\n\t)\n\trequire.NoError(t, err)\n\tproof, err := m.MerkleProofWithMixin(0)\n\trequire.NoError(t, err)\n\trequire.Len(\n\t\tt,\n\t\tproof,\n\t\tint(treeDepth)+1,\n\t)\n\troot := m.HashTreeRoot()\n\tif ok := merkle.VerifyProof(root, items[0], 0, proof); !ok {\n\t\tt.Error(\"First Merkle proof did not verify\")\n\t}\n\tproof, err = m.MerkleProofWithMixin(3)\n\trequire.NoError(t, err)\n\trequire.True(t, merkle.VerifyProof(root, items[3], 3, proof))\n\n\tit := byteslib.ExtendToSize([]byte(\"buzz\"), byteslib.B32Size)\n\titem, err := byteslib.ToBytes32(it)\n\trequire.NoError(t, err)\n\trequire.False(\n\t\tt,\n\t\tmerkle.VerifyProof(\n\t\t\troot,\n\t\t\tcommon.Root(item),\n\t\t\t3,\n\t\t\tproof,\n\t\t),\n\t)\n}\n\nfunc TestMerkleTree_NegativeIndexes(t *testing.T) {\n\tt.Parallel()\n\ttreeDepth := uint8(32)\n\titems := make([][32]byte, 0)\n\tfor _, v := range [][]byte{\n\t\tbyteslib.ExtendToSize([]byte(\"A\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"B\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"C\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"D\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"E\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"F\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"G\"), byteslib.B32Size),\n\t} {\n\t\titem, err := byteslib.ToBytes32(v)\n\t\trequire.NoError(t, err)\n\t\titems = append(items, item)\n\t}\n\tm, err := merkle.NewTreeFromLeavesWithDepth(\n\t\titems,\n\t\ttreeDepth,\n\t)\n\trequire.NoError(t, err)\n\n\tit := byteslib.ExtendToSize([]byte(\"J\"), byteslib.B32Size)\n\textraItem, err := byteslib.ToBytes32(it)\n\trequire.NoError(t, err)\n\terr = m.Insert(extraItem, -1)\n\trequire.ErrorIs(t, err, merkle.ErrNegativeIndex)\n}\n\nfunc TestMerkleTree_VerifyProof_TrieUpdated(t *testing.T) {\n\tt.Parallel()\n\ttreeDepth := uint8(32)\n\titems := [][32]byte{\n\t\t{1},\n\t\t{2},\n\t\t{3},\n\t\t{4},\n\t}\n\tm, err := merkle.NewTreeFromLeavesWithDepth(\n\t\titems,\n\t\ttreeDepth+1,\n\t)\n\trequire.NoError(t, err)\n\tproof, err := m.MerkleProofWithMixin(0)\n\trequire.NoError(t, err)\n\troot := m.HashTreeRoot()\n\trequire.True(\n\t\tt,\n\t\tmerkle.VerifyProof(\n\t\t\troot,\n\t\t\titems[0],\n\t\t\t0,\n\t\t\tproof,\n\t\t),\n\t)\n\n\t// Now we update the merkle\n\tit := byteslib.ExtendToSize([]byte{5}, byteslib.B32Size)\n\titem, err := byteslib.ToBytes32(it)\n\n\trequire.NoError(t, err)\n\trequire.NoError(t, m.Insert(item, 3))\n\tproof, err = m.MerkleProofWithMixin(3)\n\trequire.NoError(t, err)\n\troot = m.HashTreeRoot()\n\trequire.True(t, merkle.VerifyProof(\n\t\troot, [32]byte{5}, 3, proof,\n\t), \"Second Merkle proof did not verify\")\n\trequire.False(t, merkle.VerifyProof(\n\t\troot, [32]byte{4}, 3, proof,\n\t), \"Old item should not verify\")\n\n\t// Now we update the tree at an index larger than the number of items.\n\tit = byteslib.ExtendToSize([]byte{6}, byteslib.B32Size)\n\titem, err = byteslib.ToBytes32(it)\n\trequire.NoError(t, err)\n\trequire.NoError(t, m.Insert(item, 15))\n}\n\nfunc BenchmarkNewTreeFromLeavesWithDepth(b *testing.B) {\n\ttreeDepth := uint8(32)\n\titems := make([][32]byte, 0)\n\tfor _, v := range [][]byte{\n\t\tbyteslib.ExtendToSize([]byte(\"A\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"BB\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"CCC\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"DDDD\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"EEEEE\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"FFFFFF\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"GGGGGGG\"), byteslib.B32Size),\n\t} {\n\t\titem, err := byteslib.ToBytes32(v)\n\t\trequire.NoError(b, err)\n\t\titems = append(items, item)\n\t}\n\tfor range b.N {\n\t\t_, err := merkle.NewTreeFromLeavesWithDepth(\n\t\t\titems,\n\t\t\ttreeDepth,\n\t\t)\n\t\trequire.NoError(b, err, \"Could not generate Merkle tree from items\")\n\t}\n}\n\nfunc BenchmarkInsertTrie_Optimized(b *testing.B) {\n\ttreeDepth := uint8(32)\n\tb.StopTimer()\n\n\tvar (\n\t\tnumDeposits = 16000\n\t\titems       = make([][32]byte, numDeposits)\n\t\terr         error\n\t)\n\n\tfor i := range numDeposits {\n\t\tit := byteslib.ExtendToSize([]byte(strconv.Itoa(i)), byteslib.B32Size)\n\t\titems[i], err = byteslib.ToBytes32(it)\n\t\trequire.NoError(b, err)\n\t}\n\ttr, err := merkle.NewTreeFromLeavesWithDepth[[32]byte](\n\t\titems,\n\t\ttreeDepth,\n\t)\n\trequire.NoError(b, err)\n\n\tit := byteslib.ExtendToSize([]byte(\"hello-world\"), byteslib.B32Size)\n\tsomeItem, err := byteslib.ToBytes32(it)\n\trequire.NoError(b, err)\n\n\tb.StartTimer()\n\tfor i := range b.N {\n\t\trequire.NoError(b, tr.Insert(someItem, i%numDeposits))\n\t}\n}\n\nfunc BenchmarkGenerateProof(b *testing.B) {\n\ttreeDepth := uint8(32)\n\tb.StopTimer()\n\n\titems := make([][32]byte, 0)\n\tfor _, v := range [][]byte{\n\t\tbyteslib.ExtendToSize([]byte(\"A\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"BB\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"CCC\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"DDDD\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"EEEEE\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"FFFFFF\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"GGGGGGG\"), byteslib.B32Size),\n\t} {\n\t\titem, err := byteslib.ToBytes32(v)\n\t\trequire.NoError(b, err)\n\t\titems = append(items, item)\n\t}\n\n\tgoodTree, err := merkle.NewTreeFromLeavesWithDepth[[32]byte](\n\t\titems,\n\t\ttreeDepth,\n\t)\n\trequire.NoError(b, err)\n\n\tb.StartTimer()\n\tfor range b.N {\n\t\t_, err = goodTree.MerkleProofWithMixin(3)\n\t\trequire.NoError(b, err)\n\t}\n}\n\nfunc BenchmarkIsValidMerkleBranch(b *testing.B) {\n\ttreeDepth := uint8(4)\n\tb.StopTimer()\n\n\titems := make([][32]byte, 0)\n\tfor _, v := range [][]byte{\n\t\tbyteslib.ExtendToSize([]byte(\"A\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"BB\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"CCC\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"DDDD\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"EEEEE\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"FFFFFF\"), byteslib.B32Size),\n\t\tbyteslib.ExtendToSize([]byte(\"GGGGGGG\"), byteslib.B32Size),\n\t} {\n\t\titem, err := byteslib.ToBytes32(v)\n\t\trequire.NoError(b, err)\n\t\titems = append(items, item)\n\t}\n\trequire.NotEmpty(b, items) // appease nilaway\n\n\tm, err := merkle.NewTreeFromLeavesWithDepth[[32]byte](\n\t\titems,\n\t\ttreeDepth,\n\t)\n\n\trequire.NoError(b, err)\n\tproof, err := m.MerkleProofWithMixin(2)\n\trequire.NoError(b, err)\n\n\tb.StartTimer()\n\tfor range b.N {\n\t\tok := merkle.IsValidMerkleBranch(\n\t\t\titems[2], proof, treeDepth+1, 2, m.HashTreeRoot(),\n\t\t)\n\t\trequire.True(b, ok, \"Merkle proof did not verify\")\n\t}\n}\n"
  },
  {
    "path": "primitives/merkle/utils.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage merkle\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n)\n\n// verifySufficientDepth ensures that the depth is sufficient to build a tree.\nfunc verifySufficientDepth(numLeaves int, depth uint8) error {\n\tswitch {\n\tcase numLeaves == 0:\n\t\treturn ErrEmptyLeaves\n\tcase depth == 0:\n\t\treturn ErrZeroDepth\n\tcase depth > MaxTreeDepth:\n\t\treturn ErrExceededDepth\n\tcase numLeaves > (1 << depth):\n\t\treturn errors.Wrap(\n\t\t\tErrInsufficientDepthForLeaves,\n\t\t\tfmt.Sprintf(\n\t\t\t\t\"attempted to build tree/root with %d leaves at depth %d\",\n\t\t\t\tnumLeaves, depth),\n\t\t)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "primitives/merkle/zero/zero.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage zero\n\nimport \"github.com/berachain/beacon-kit/primitives/crypto/sha256\"\n\n// NumZeroHashes is the number of pre-computed zero-hashes.\nconst NumZeroHashes = 64\n\n// Hashes is a pre-computed list of zero-hashes for each depth level.\n//\n//nolint:gochecknoglobals // saves recomputing.\nvar Hashes [NumZeroHashes + 1][32]byte\n\n// InitZeroHashes the zero-hashes pre-computed data\n// with the given hash-function.\nfunc InitZeroHashes(zeroHashesLevels int) {\n\tv := [64]byte{}\n\tfor i := range zeroHashesLevels {\n\t\tcopy(v[:32], Hashes[i][:])\n\t\tcopy(v[32:], Hashes[i][:])\n\t\tHashes[i+1] = sha256.Hash(v[:])\n\t}\n}\n\n//nolint:gochecknoinits // saves recomputing.\nfunc init() {\n\tInitZeroHashes(NumZeroHashes)\n}\n"
  },
  {
    "path": "primitives/net/http/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage http\n\nimport (\n\t\"errors\"\n)\n\nvar (\n\t// ErrTimeout indicates a timeout error from http.Client.\n\tErrTimeout = errors.New(\"timeout from HTTP client\")\n\n\t// ErrUnauthorized indicates an unauthorized error from http.Client.\n\tErrUnauthorized = errors.New(\"401 unauthorized request\")\n)\n\n// TimeoutError defines an interface for timeout errors.\n// It includes methods for error message retrieval and timeout status checking.\ntype TimeoutError interface {\n\t// Error returns the error message.\n\tError() string\n\t// Timeout indicates whether the error is a timeout error.\n\tTimeout() bool\n}\n\n// IsTimeoutError checks if the given error is a timeout error.\n// It asserts the error to the httpTimeoutError interface and checks its Timeout\n// status.\n// Returns true if the error is a timeout error, false otherwise.\nfunc IsTimeoutError(e error) bool {\n\tvar t TimeoutError\n\tok := errors.As(e, &t)\n\treturn ok && t != nil && t.Timeout()\n}\n"
  },
  {
    "path": "primitives/net/json-rpc/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage jsonrpc\n\nimport (\n\t\"github.com/berachain/beacon-kit/errors\"\n)\n\n// Error wraps RPC errors, which contain an error code in addition to the\n// message.\ntype Error interface {\n\t// Error returns the error message.\n\tError() string\n\n\t// ErrorCode returns the JSON-RPC error code.\n\tErrorCode() int\n}\n\n// IsPreDefinedError returns true if the given\n// error is a predefined JSON-RPC errors.\nfunc IsPreDefinedError(err error) bool {\n\treturn errors.IsAny(\n\t\terr,\n\t\tErrParse,\n\t\tErrInvalidRequest,\n\t\tErrMethodNotFound,\n\t\tErrInvalidParams,\n\t\tErrInternal,\n\t\tErrServer,\n\t\tErrServerParse,\n\t)\n}\n\nvar (\n\t// ErrParse indicates that invalid JSON was received by the server.\n\t// (code: -32700).\n\tErrParse = errors.New(\n\t\t\"invalid JSON was received by the server (code: -32700)\",\n\t)\n\n\t// ErrInvalidRequest indicates that the JSON sent is not a valid Request\n\t// object. (code: -32600).\n\tErrInvalidRequest = errors.New(\n\t\t\"the JSON sent is not a valid Request object (code: -32600)\",\n\t)\n\n\t// ErrMethodNotFound indicates that the method does not exist or is not\n\t// available. (code: -32601).\n\tErrMethodNotFound = errors.New(\n\t\t\"the method does not exist / is not available (code: -32601)\",\n\t)\n\n\t// ErrInvalidParams indicates invalid method parameters. (code: -32602).\n\tErrInvalidParams = errors.New(\"invalid method parameter(s) (code: -32602)\")\n\n\t// ErrInternal indicates an internal JSON-RPC error. (code: -32603).\n\tErrInternal = errors.New(\"internal JSON-RPC error (code: -32603)\")\n\n\t// ErrServer is reserved for implementation-defined server errors.\n\t// (code: -32000 to -32099).\n\tErrServer = errors.New(\n\t\t\"received implementation-defined server-error (code: -32000 to -32099)\",\n\t)\n\n\t// ErrServerParse indicates an error occurred on the server while\n\t// parsing the JSON text. (code: -32700).\n\tErrServerParse = errors.New(\n\t\t\"an error occurred on the server while parsing the JSON text (code: -32700)\",\n\t)\n)\n"
  },
  {
    "path": "primitives/net/jwt/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage jwt\n\nimport \"github.com/berachain/beacon-kit/errors\"\n\nvar (\n\t// ErrLengthMismatch is returned when a JWT secret length is not as\n\t// expected.\n\tErrLengthMismatch = errors.New(\n\t\t\"JWT secret length mismatch\")\n\n\t// ErrContainsIllegalCharacter is returned when a JWT secret contains\n\t// illegal characters.\n\tErrContainsIllegalCharacter = errors.New(\n\t\t\"JWT secret contains illegal character(s)\")\n\n\t// ErrCreateJWT is returned when a JWT token fails to be created.\n\tErrCreateJWT = errors.New(\"failed to create JWT token\")\n)\n"
  },
  {
    "path": "primitives/net/jwt/jwt.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage jwt\n\nimport (\n\t\"crypto/rand\"\n\t\"regexp\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\tgjwt \"github.com/golang-jwt/jwt/v5\"\n)\n\n// HexRegexp is a regular expression to match hexadecimal characters.\nvar HexRegexp = regexp.MustCompile(`^(?:0x)?[0-9a-fA-F]*$`)\n\n// EthereumJWTLength defines the length of the JWT byte array to be 32 bytes as\n// defined the Engine API specification.\n// https://github.com/ethereum/execution-apis/blob/main/src/engine/authentication.md\nconst EthereumJWTLength = 32\n\n// Secret represents a JSON Web Token as a fixed-size byte array.\ntype Secret [EthereumJWTLength]byte\n\n// NewFromHex creates a new JWT secret from a hexadecimal string.\nfunc NewFromHex(hexStr string) (*Secret, error) {\n\t// Ensure the hex string contains only hexadecimal characters.\n\tif !HexRegexp.MatchString(hexStr) {\n\t\treturn nil, ErrContainsIllegalCharacter\n\t}\n\n\t// Convert the hex string to a byte array.\n\tbz, err := hex.ToBytes(hexStr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif bz == nil || len(bz) != EthereumJWTLength {\n\t\treturn nil, ErrLengthMismatch\n\t}\n\ts := Secret(bz)\n\treturn &s, nil\n}\n\n// NewRandom creates a new random JWT secret.\nfunc NewRandom() (*Secret, error) {\n\tsecret := make([]byte, EthereumJWTLength)\n\t// We don't need to check n since:\n\t// n == len(b) if and only if err == nil.\n\t_, err := rand.Read(secret)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn NewFromHex(hex.EncodeBytes(secret))\n}\n\n// BuildSignedToken creates a signed JWT token from the secret.\nfunc (s *Secret) BuildSignedToken() (string, error) {\n\ttoken := gjwt.NewWithClaims(gjwt.SigningMethodHS256, gjwt.MapClaims{\n\t\t\"iat\": &gjwt.NumericDate{Time: time.Now()},\n\t})\n\tstr, err := token.SignedString(s[:])\n\tif err != nil {\n\t\treturn \"\", errors.Wrapf(ErrCreateJWT, \"%w\", err)\n\t}\n\treturn str, nil\n}\n\n// String returns the JWT secret as a string with the first 8 characters\n// visible and the rest masked out for security.\nfunc (s *Secret) String() string {\n\tsecret := hex.EncodeBytes(s[:])\n\treturn secret[:8] + strings.Repeat(\"*\", len(secret[8:]))\n}\n\n// Hex returns the JWT secret as a hexadecimal string.\nfunc (s *Secret) Hex() string {\n\treturn hex.EncodeBytes(s[:])\n}\n\n// Bytes returns the JWT secret as a byte array.\nfunc (s *Secret) Bytes() []byte {\n\treturn s[:]\n}\n"
  },
  {
    "path": "primitives/net/jwt/jwt_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage jwt_test\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/berachain/beacon-kit/primitives/net/jwt\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestNewFromHex(t *testing.T) {\n\tt.Parallel()\n\twantValid := jwt.Secret(\n\t\thex.MustToBytes(\n\t\t\t\"0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef\",\n\t\t),\n\t)\n\ttests := []struct {\n\t\tname    string\n\t\thexStr  string\n\t\twant    *jwt.Secret\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\tname: \"valid hex string w/ 0x prefix\",\n\n\t\t\thexStr:  \"0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef\",\n\t\t\twant:    &(wantValid),\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname: \"valid hex string no 0x prefix\",\n\n\t\t\thexStr:  \"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef\",\n\t\t\twant:    &(wantValid),\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid hex string\",\n\t\t\thexStr:  \"0x123\",\n\t\t\twant:    nil,\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"empty hex string\",\n\t\t\thexStr:  \"\",\n\t\t\twant:    nil,\n\t\t\twantErr: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot, err := jwt.NewFromHex(tt.hexStr)\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\trequire.Equal(t, tt.want, got)\n\t\t})\n\t}\n}\n\nfunc TestSecretString(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname   string\n\t\tsecret jwt.Secret\n\t\twant   string\n\t}{\n\t\t{\n\t\t\tname: \"mask secret correctly\",\n\t\t\tsecret: jwt.Secret(\n\t\t\t\thex.MustToBytes(\n\t\t\t\t\t\"0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef\",\n\t\t\t\t),\n\t\t\t),\n\t\t\twant: \"0x123456**********************************************************\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\trequire.Equal(\n\t\t\t\tt,\n\t\t\t\ttt.want,\n\t\t\t\ttt.secret.String(),\n\t\t\t\t\"Secret.String() mismatch\",\n\t\t\t)\n\t\t})\n\t}\n}\n\nfunc TestNewRandom(t *testing.T) {\n\tt.Parallel()\n\tsecret, err := jwt.NewRandom()\n\trequire.NoError(t, err, \"NewRandom() error\")\n\trequire.Len(t, secret.Bytes(), 32, \"NewRandom() length mismatch\")\n}\n\nfunc TestSecretBytes(t *testing.T) {\n\tt.Parallel()\n\texpectedLength := 32 // Assuming the secret is expected to be 32 bytes long\n\tsecret, _ := jwt.NewRandom()\n\tbytes := secret.Bytes()\n\trequire.Len(t, bytes, expectedLength, \"Bytes() length mismatch\")\n}\n\nfunc TestSecretHexWithFixedInput(t *testing.T) {\n\tt.Parallel()\n\texpectedHex := \"0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef\"\n\texpectedHexLength := 64\n\n\tsecret, err := jwt.NewFromHex(expectedHex)\n\trequire.NoError(t, err, \"NewFromHex() error\")\n\n\thexStr := secret.Hex()\n\trequire.Equal(t, expectedHex, hexStr, \"Hex() output mismatch\")\n\n\t// Check if the hex string is of the expected length and format.\n\trequire.Len(t, hexStr, expectedHexLength+2, \"Hex() length mismatch\")\n\n\t// Strip the '0x' prefix and check if the remaining string is valid hex.\n\thexStr = strings.TrimPrefix(hexStr, \"0x\")\n\trequire.Len(\n\t\tt,\n\t\thexStr,\n\t\texpectedHexLength,\n\t\t\"Hex() length after stripping '0x' mismatch\",\n\t)\n\trequire.True(\n\t\tt,\n\t\tjwt.HexRegexp.MatchString(hexStr),\n\t\t\"Hex() output does not match hexadecimal format\",\n\t)\n}\n\nfunc TestSecretRoundTripEncoding(t *testing.T) {\n\tt.Parallel()\n\toriginalSecret, err := jwt.NewRandom()\n\trequire.NoError(t, err, \"NewRandom() error\")\n\n\t// Encode the original secret to hex string\n\tencodedSecret := hex.EncodeBytes(originalSecret.Bytes())\n\n\t// Decode the hex string back to secret\n\tdecodedSecret, err := jwt.NewFromHex(encodedSecret)\n\trequire.NoError(t, err, \"NewFromHex() error\")\n\n\t// Compare the original and decoded secrets\n\trequire.Equal(\n\t\tt,\n\t\toriginalSecret,\n\t\tdecodedSecret,\n\t\t\"Round trip encoding failed\",\n\t)\n}\n\nfunc TestBuildSignedToken(t *testing.T) {\n\tt.Parallel()\n\tsecret, err := jwt.NewRandom()\n\trequire.NoError(t, err, \"NewRandom() error\")\n\n\ttoken, err := secret.BuildSignedToken()\n\trequire.NoError(t, err, \"BuildSignedToken() error\")\n\trequire.NotEmpty(t, token, \"BuildSignedToken() returned empty token\")\n\n\t// Verify the token structure (header.payload.signature)\n\tparts := strings.Split(token, \".\")\n\trequire.Len(t, parts, 3, \"Token should have three parts\")\n}\n\nfunc TestNewFromHexEdgeCases(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname    string\n\t\thexStr  string\n\t\twantErr bool\n\t}{\n\t\t{\n\t\t\tname:    \"lowercase hex string\",\n\t\t\thexStr:  \"0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890\",\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"uppercase hex string\",\n\t\t\thexStr:  \"0xABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890\",\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"mixed case hex string\",\n\t\t\thexStr:  \"0xaBcDeF1234567890aBcDeF1234567890aBcDeF1234567890aBcDeF1234567890\",\n\t\t\twantErr: false,\n\t\t},\n\t\t{\n\t\t\tname:    \"invalid characters\",\n\t\t\thexStr:  \"0x123G567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef\",\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"too short\",\n\t\t\thexStr:  \"0x1234567890abcdef\",\n\t\t\twantErr: true,\n\t\t},\n\t\t{\n\t\t\tname:    \"too long\",\n\t\t\thexStr:  \"0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef00\",\n\t\t\twantErr: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\t_, err := jwt.NewFromHex(tt.hexStr)\n\t\t\tif tt.wantErr {\n\t\t\t\trequire.Error(t, err)\n\t\t\t} else {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestHexRegexp(t *testing.T) {\n\tt.Parallel()\n\tvalidHexStrings := []string{\n\t\t\"0x1234567890abcdef\",\n\t\t\"1234567890ABCDEF\",\n\t\t\"0xABCDEF1234567890\",\n\t\t\"abcdef1234567890\",\n\t}\n\n\tinvalidHexStrings := []string{\n\t\t\"0x123G567890abcdef\",\n\t\t\"GHIJKLMNOPQRSTUV\",\n\t\t\"0xABCDEF12345678@0\",\n\t\t\"abcdef123456789g\",\n\t}\n\n\tfor _, validHex := range validHexStrings {\n\t\trequire.True(\n\t\t\tt,\n\t\t\tjwt.HexRegexp.MatchString(validHex),\n\t\t\t\"Valid hex string not matched: %s\",\n\t\t\tvalidHex,\n\t\t)\n\t}\n\n\tfor _, invalidHex := range invalidHexStrings {\n\t\trequire.False(\n\t\t\tt,\n\t\t\tjwt.HexRegexp.MatchString(invalidHex),\n\t\t\t\"Invalid hex string matched: %s\",\n\t\t\tinvalidHex,\n\t\t)\n\t}\n}\n\nfunc TestSecretComparison(t *testing.T) {\n\tt.Parallel()\n\tsecret1, err := jwt.NewRandom()\n\trequire.NoError(t, err, \"NewRandom() error for secret1\")\n\n\tsecret2, err := jwt.NewRandom()\n\trequire.NoError(t, err, \"NewRandom() error for secret2\")\n\n\trequire.NotEqual(\n\t\tt,\n\t\tsecret1,\n\t\tsecret2,\n\t\t\"Two random secrets should not be equal\",\n\t)\n\n\tsecret3 := *secret1\n\trequire.Equal(\n\t\tt,\n\t\tsecret1,\n\t\t&secret3,\n\t\t\"Copied secret should be equal to original\",\n\t)\n}\n"
  },
  {
    "path": "primitives/net/url/url.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage url\n\nimport \"net/url\"\n\n// ConnectionURL is a URL struct that is used to dial the execution client.\ntype ConnectionURL struct {\n\t*url.URL\n}\n\n// NewDialURL creates a new DialURL.\nfunc NewDialURL(u *url.URL) *ConnectionURL {\n\treturn &ConnectionURL{u}\n}\n\nfunc NewFromRaw(raw string) (*ConnectionURL, error) {\n\tu, err := url.Parse(raw)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn NewDialURL(u), nil\n}\n\n// IsHTTP checks if the DialURL scheme is HTTP.\nfunc (d *ConnectionURL) IsHTTP() bool {\n\treturn d.Scheme == \"http\"\n}\n\n// IsHTTPS checks if the DialURL scheme is HTTPS.\nfunc (d *ConnectionURL) IsHTTPS() bool {\n\treturn d.Scheme == \"https\"\n}\n\n// IsIPC checks if the DialURL scheme is IPC.\nfunc (d *ConnectionURL) IsIPC() bool {\n\treturn d.Scheme == \"ipc\"\n}\n"
  },
  {
    "path": "primitives/transition/context.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage transition\n\nimport (\n\t\"context\"\n\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// Context is the context for the state transition.\ntype Context struct {\n\t// consensusCtx is the context passed by CometBFT callbacks\n\t// We pass it down to be able to cancel processing (although\n\t// currently CometBFT context is set to TODO)\n\tconsensusCtx context.Context\n\t// consensusTime returns the timestamp of current consensus request.\n\t// It is used to build next payload and to validate currentpayload.\n\tconsensusTime math.U64\n\t// Address of current block proposer\n\tproposerAddress []byte\n\n\t// verifyPayload indicates whether to call NewPayload on the\n\t// execution client. This can be done when the node is not\n\t// syncing, and the payload is already known to the execution client.\n\tverifyPayload bool\n\t// verifyRandao indicates whether to validate the Randao mix.\n\tverifyRandao bool\n\t// verifyResult indicates whether to validate the result of\n\t// the state transition.\n\tverifyResult bool\n\n\t// meterGas controls whether gas data related to the execution\n\t// layer payload should be meter or not. We currently meter only\n\t// finalized blocks.\n\tmeterGas bool\n}\n\nfunc NewTransitionCtx(\n\tconsensusCtx context.Context,\n\ttime math.U64,\n\taddress []byte,\n) *Context {\n\treturn &Context{\n\t\tconsensusCtx:    consensusCtx,\n\t\tconsensusTime:   time,\n\t\tproposerAddress: address,\n\n\t\t// by default we don't meter gas\n\t\t// (we care only about finalized blocks gas)\n\t\tmeterGas: false,\n\n\t\t// by default we keep all verification\n\t\tverifyPayload: true,\n\t\tverifyRandao:  true,\n\t\tverifyResult:  true,\n\t}\n}\n\n// Setters to control context attributes.\nfunc (c *Context) WithMeterGas(meter bool) *Context {\n\tc.meterGas = meter\n\treturn c\n}\n\nfunc (c *Context) WithVerifyPayload(verifyPayload bool) *Context {\n\tc.verifyPayload = verifyPayload\n\treturn c\n}\n\nfunc (c *Context) WithVerifyRandao(verifyRandao bool) *Context {\n\tc.verifyRandao = verifyRandao\n\treturn c\n}\n\nfunc (c *Context) WithVerifyResult(verifyResult bool) *Context {\n\tc.verifyResult = verifyResult\n\treturn c\n}\n\n// Getters of context attributes.\nfunc (c *Context) ConsensusCtx() context.Context {\n\treturn c.consensusCtx\n}\n\nfunc (c *Context) ConsensusTime() math.U64 {\n\treturn c.consensusTime\n}\n\nfunc (c *Context) ProposerAddress() []byte {\n\treturn c.proposerAddress\n}\n\nfunc (c *Context) VerifyPayload() bool {\n\treturn c.verifyPayload\n}\n\nfunc (c *Context) VerifyRandao() bool {\n\treturn c.verifyRandao\n}\n\nfunc (c *Context) VerifyResult() bool {\n\treturn c.verifyResult\n}\n\nfunc (c *Context) MeterGas() bool {\n\treturn c.meterGas\n}\n"
  },
  {
    "path": "primitives/transition/validator_update.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage transition\n\nimport (\n\t\"sort\"\n\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// ValidatorUpdates is a list of validator updates.\ntype ValidatorUpdates []*ValidatorUpdate\n\n// ValidatorUpdate is a struct that holds the validator update.\ntype ValidatorUpdate struct {\n\t// Pubkey is the public key of the validator. PubKey identifies\n\t// updates, meaning that two validator updates are considered equal\n\t// if they refer to the same PubKey\n\tPubkey crypto.BLSPubkey\n\t// EffectiveBalance is the effective balance of the validator.\n\tEffectiveBalance math.Gwei\n}\n\n// CanonicalSort sorts validator updates in the canonical order.\n// Canonical order requires validators updates being sorted\n// by their PubKey, with no duplicates. In case of duplicates\n// the latest is preferred.\nfunc (vu ValidatorUpdates) CanonicalSort() ValidatorUpdates {\n\treturn vu.removeDuplicates().sort()\n}\n\n// removeDuplicates removes duplicate validator updates. We\n// iterate through the list backwards since we want the last\n// update to be the one that is kept.\nfunc (vu ValidatorUpdates) removeDuplicates() ValidatorUpdates {\n\tduplicateCheck := make(map[crypto.BLSPubkey]struct{})\n\tj := len(vu) - 1\n\tfor i := j; i >= 0; i-- {\n\t\tupdate := vu[i]\n\t\tif _, exists := duplicateCheck[update.Pubkey]; !exists {\n\t\t\tduplicateCheck[update.Pubkey] = struct{}{}\n\t\t\tvu[j] = vu[i]\n\t\t\tj--\n\t\t}\n\t}\n\tvu = vu[j+1:]\n\treturn vu\n}\n\n// sort sorts the validator updates.\nfunc (vu ValidatorUpdates) sort() ValidatorUpdates {\n\tsort.SliceStable(vu, func(i, j int) bool {\n\t\treturn string((vu)[i].Pubkey[:]) < string((vu)[j].Pubkey[:])\n\t})\n\treturn vu\n}\n"
  },
  {
    "path": "primitives/transition/validator_update_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage transition_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestValidatorUpdate_CanonicalSort(t *testing.T) {\n\tt.Parallel()\n\tpubkey1 := crypto.BLSPubkey{1}\n\tpubkey2 := crypto.BLSPubkey{2}\n\tpubkey3 := crypto.BLSPubkey{3}\n\n\ttype test struct {\n\t\tname  string\n\t\tinput transition.ValidatorUpdates\n\t\twant  transition.ValidatorUpdates\n\t}\n\n\ttests := []test{\n\t\t{\n\t\t\tname: \"RemoveDuplicates-PickLatest\",\n\t\t\tinput: transition.ValidatorUpdates{\n\t\t\t\t&transition.ValidatorUpdate{\n\t\t\t\t\tPubkey:           pubkey1,\n\t\t\t\t\tEffectiveBalance: math.Gwei(1000),\n\t\t\t\t},\n\t\t\t\t&transition.ValidatorUpdate{\n\t\t\t\t\tPubkey:           pubkey1,\n\t\t\t\t\tEffectiveBalance: math.Gwei(500),\n\t\t\t\t},\n\t\t\t\t&transition.ValidatorUpdate{\n\t\t\t\t\tPubkey:           pubkey2,\n\t\t\t\t\tEffectiveBalance: math.Gwei(2000),\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: transition.ValidatorUpdates{\n\t\t\t\t&transition.ValidatorUpdate{\n\t\t\t\t\tPubkey:           pubkey1,\n\t\t\t\t\tEffectiveBalance: math.Gwei(500),\n\t\t\t\t},\n\t\t\t\t&transition.ValidatorUpdate{\n\t\t\t\t\tPubkey:           pubkey2,\n\t\t\t\t\tEffectiveBalance: math.Gwei(2000),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"SortByPubKey\",\n\t\t\tinput: transition.ValidatorUpdates{\n\t\t\t\t&transition.ValidatorUpdate{\n\t\t\t\t\tPubkey:           pubkey3,\n\t\t\t\t\tEffectiveBalance: math.Gwei(2000),\n\t\t\t\t},\n\t\t\t\t&transition.ValidatorUpdate{\n\t\t\t\t\tPubkey:           pubkey1,\n\t\t\t\t\tEffectiveBalance: math.Gwei(5000),\n\t\t\t\t},\n\t\t\t\t&transition.ValidatorUpdate{\n\t\t\t\t\tPubkey:           pubkey2,\n\t\t\t\t\tEffectiveBalance: math.Gwei(1000),\n\t\t\t\t},\n\t\t\t},\n\t\t\twant: transition.ValidatorUpdates{\n\t\t\t\t&transition.ValidatorUpdate{\n\t\t\t\t\tPubkey:           pubkey1,\n\t\t\t\t\tEffectiveBalance: math.Gwei(5000),\n\t\t\t\t},\n\t\t\t\t&transition.ValidatorUpdate{\n\t\t\t\t\tPubkey:           pubkey2,\n\t\t\t\t\tEffectiveBalance: math.Gwei(1000),\n\t\t\t\t},\n\t\t\t\t&transition.ValidatorUpdate{\n\t\t\t\t\tPubkey:           pubkey3,\n\t\t\t\t\tEffectiveBalance: math.Gwei(2000),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range tests {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tgot := tc.input.CanonicalSort()\n\t\t\trequire.Equal(t, tc.want, got)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "primitives/version/comparable.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage version\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                Comparable                                  */\n/* -------------------------------------------------------------------------- */\n\n// NOTE: IsBefore and Equals are implemented to set a canonical sorting\n// algorithm for the common.Version type. A standard cmp function would require\n// IsBefore and Equals and could be implemented as:\n//\n//\tfunc cmp(a, b common.Version) int {\n//      // a is before b\n//\t\tif version.IsBefore(a, b) {\n//\t\t\treturn -1\n//\t\t}\n//      // a is the same version as b\n//\t\tif version.Equals(a, b) {\n//\t\t\treturn 0\n//\t\t}\n//      // a is after b\n//\t\treturn 1\n//\t}\n\n// IsBefore returns true if a is before b. This compares bytes from most significant\n// to least significant in \"little-endian\" order.\nfunc IsBefore(a, b common.Version) bool {\n\t// Iterate in order of significance.\n\tfor i := range bytes.B4Size {\n\t\t// We short-circuit if a[i] != b[i] since we are iterating in order of significance.\n\t\tif a[i] < b[i] {\n\t\t\treturn true\n\t\t} else if a[i] > b[i] {\n\t\t\treturn false\n\t\t}\n\t}\n\n\t// If we reach this point, a and b are the same version.\n\treturn false\n}\n\n// IsBeforeOrEquals returns true if a is before or at the same version as b.\nfunc IsBeforeOrEquals(a, b common.Version) bool {\n\treturn IsBefore(a, b) || Equals(a, b)\n}\n\n// Equals returns true if a and b are equal (each byte in the 4-byte vector is the same).\nfunc Equals(a, b common.Version) bool {\n\treturn a == b\n}\n\n// IsAfter returns true if a is after b. This compares bytes from most significant\n// to least significant in \"little-endian\" order.\nfunc IsAfter(a, b common.Version) bool {\n\treturn !IsBefore(a, b) && !Equals(a, b)\n}\n\n// EqualsOrIsAfter returns true if a is the same version as b or after.\nfunc EqualsOrIsAfter(a, b common.Version) bool {\n\treturn !IsBefore(a, b)\n}\n"
  },
  {
    "path": "primitives/version/comparable_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage version_test\n\nimport (\n\t\"slices\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestIsBefore(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\ta, b     common.Version\n\t\texpected bool\n\t}{\n\t\t{\n\t\t\tname:     \"equal versions\",\n\t\t\ta:        common.Version{1, 0, 0, 0},\n\t\t\tb:        common.Version{1, 0, 0, 0},\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"clearly before\",\n\t\t\ta:        common.Version{1, 0, 0, 0},\n\t\t\tb:        common.Version{2, 0, 0, 0},\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"clearly after\",\n\t\t\ta:        common.Version{2, 0, 0, 0},\n\t\t\tb:        common.Version{1, 0, 0, 0},\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"minor version before\",\n\t\t\ta:        common.Version{1, 1, 0, 0},\n\t\t\tb:        common.Version{1, 2, 0, 0},\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"patch version before\",\n\t\t\ta:        common.Version{1, 1, 1, 0},\n\t\t\tb:        common.Version{1, 1, 2, 0},\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"beacon version before\",\n\t\t\ta:        version.Phase0(),\n\t\t\tb:        version.Altair(),\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"beacon version before minor\",\n\t\t\ta:        version.Deneb(),\n\t\t\tb:        version.Deneb1(),\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"beacon version after minor\",\n\t\t\ta:        common.Version{0x05, 0x00, 0x00, 0x00},\n\t\t\tb:        common.Version{0x04, 0x01, 0x00, 0x00},\n\t\t\texpected: false,\n\t\t},\n\t}\n\n\tfor _, tc := range tests {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := version.IsBefore(tc.a, tc.b)\n\t\t\trequire.Equal(t, tc.expected, result)\n\t\t})\n\t}\n}\n\nfunc TestIsBeforeOrEquals(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\ta, b     common.Version\n\t\texpected bool\n\t}{\n\t\t{\n\t\t\tname:     \"equal versions\",\n\t\t\ta:        common.Version{1, 2, 1, 0},\n\t\t\tb:        common.Version{1, 2, 1, 0},\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"clearly after\",\n\t\t\ta:        common.Version{2, 0, 0, 0},\n\t\t\tb:        common.Version{1, 0, 0, 0},\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"minor version before\",\n\t\t\ta:        common.Version{1, 1, 0, 0},\n\t\t\tb:        common.Version{1, 2, 0, 0},\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"patch version before\",\n\t\t\ta:        common.Version{1, 1, 1, 0},\n\t\t\tb:        common.Version{1, 1, 2, 0},\n\t\t\texpected: true,\n\t\t},\n\t}\n\n\tfor _, tc := range tests {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := version.IsBeforeOrEquals(tc.a, tc.b)\n\t\t\trequire.Equal(t, tc.expected, result)\n\t\t})\n\t}\n}\n\nfunc TestEquals(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\ta, b     common.Version\n\t\texpected bool\n\t}{\n\t\t{\n\t\t\tname:     \"empty versions\",\n\t\t\ta:        common.Version{},\n\t\t\tb:        common.Version{},\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"equal versions\",\n\t\t\ta:        common.Version{1, 0, 0, 0},\n\t\t\tb:        common.Version{1, 0, 0, 0},\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"different major version\",\n\t\t\ta:        common.Version{1, 0, 0, 0},\n\t\t\tb:        common.Version{2, 0, 0, 0},\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"different minor version\",\n\t\t\ta:        common.Version{1, 1, 0, 0},\n\t\t\tb:        common.Version{1, 2, 0, 0},\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"different patch version\",\n\t\t\ta:        common.Version{1, 1, 1, 0},\n\t\t\tb:        common.Version{1, 1, 2, 0},\n\t\t\texpected: false,\n\t\t},\n\t}\n\n\tfor _, tc := range tests {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := version.Equals(tc.a, tc.b)\n\t\t\trequire.Equal(t, tc.expected, result)\n\t\t})\n\t}\n}\n\nfunc TestIsAfter(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\ta, b     common.Version\n\t\texpected bool\n\t}{\n\t\t{\n\t\t\tname:     \"equal versions\",\n\t\t\ta:        common.Version{1, 0, 0, 0},\n\t\t\tb:        common.Version{1, 0, 0, 0},\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"clearly after\",\n\t\t\ta:        common.Version{2, 0, 0, 0},\n\t\t\tb:        common.Version{1, 0, 0, 0},\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"clearly before\",\n\t\t\ta:        common.Version{1, 0, 0, 0},\n\t\t\tb:        common.Version{2, 0, 0, 0},\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"minor version after\",\n\t\t\ta:        common.Version{1, 2, 0, 0},\n\t\t\tb:        common.Version{1, 1, 0, 0},\n\t\t\texpected: true,\n\t\t},\n\t}\n\n\tfor _, tc := range tests {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := version.IsAfter(tc.a, tc.b)\n\t\t\trequire.Equal(t, tc.expected, result)\n\t\t})\n\t}\n}\n\nfunc TestEqualsOrIsAfter(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname     string\n\t\ta, b     common.Version\n\t\texpected bool\n\t}{\n\t\t{\n\t\t\tname:     \"equal versions\",\n\t\t\ta:        common.Version{1, 2, 1, 0},\n\t\t\tb:        common.Version{1, 2, 1, 0},\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"clearly after\",\n\t\t\ta:        common.Version{2, 0, 0, 0},\n\t\t\tb:        common.Version{1, 0, 0, 0},\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"minor version before\",\n\t\t\ta:        common.Version{1, 1, 0, 0},\n\t\t\tb:        common.Version{1, 2, 0, 0},\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"patch version before\",\n\t\t\ta:        common.Version{1, 1, 1, 0},\n\t\t\tb:        common.Version{1, 1, 2, 0},\n\t\t\texpected: false,\n\t\t},\n\t}\n\n\tfor _, tc := range tests {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tresult := version.EqualsOrIsAfter(tc.a, tc.b)\n\t\t\trequire.Equal(t, tc.expected, result)\n\t\t})\n\t}\n}\n\nfunc TestSort(t *testing.T) {\n\tt.Parallel()\n\t// Recommended function implementing cmp from the comments.\n\tcmp := func(a, b common.Version) int {\n\t\tif version.IsBefore(a, b) {\n\t\t\treturn -1\n\t\t}\n\t\tif version.Equals(a, b) {\n\t\t\treturn 0\n\t\t}\n\t\treturn 1\n\t}\n\n\ttests := []struct {\n\t\tname     string\n\t\tinput    []common.Version\n\t\texpected []common.Version\n\t}{\n\t\t{\n\t\t\tname: \"already sorted\",\n\t\t\tinput: []common.Version{\n\t\t\t\tversion.Phase0(),\n\t\t\t\tversion.Altair(),\n\t\t\t\tversion.Bellatrix(),\n\t\t\t\tversion.Capella(),\n\t\t\t},\n\t\t\texpected: []common.Version{\n\t\t\t\tversion.Phase0(),\n\t\t\t\tversion.Altair(),\n\t\t\t\tversion.Bellatrix(),\n\t\t\t\tversion.Capella(),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"reverse sorted\",\n\t\t\tinput: []common.Version{\n\t\t\t\tversion.Capella(),\n\t\t\t\tversion.Bellatrix(),\n\t\t\t\tversion.Altair(),\n\t\t\t\tversion.Phase0(),\n\t\t\t},\n\t\t\texpected: []common.Version{\n\t\t\t\tversion.Phase0(),\n\t\t\t\tversion.Altair(),\n\t\t\t\tversion.Bellatrix(),\n\t\t\t\tversion.Capella(),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"mixed versions with minors\",\n\t\t\tinput: []common.Version{\n\t\t\t\tversion.Deneb1(),\n\t\t\t\tversion.Deneb(),\n\t\t\t\tversion.Phase0(),\n\t\t\t\tversion.Electra(),\n\t\t\t\tversion.Capella(),\n\t\t\t},\n\t\t\texpected: []common.Version{\n\t\t\t\tversion.Phase0(),\n\t\t\t\tversion.Capella(),\n\t\t\t\tversion.Deneb(),\n\t\t\t\tversion.Deneb1(),\n\t\t\t\tversion.Electra(),\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range tests {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\t// Sort the input slice using the cmp function\n\t\t\tslices.SortFunc(tc.input, cmp)\n\t\t\trequire.Equal(t, tc.expected, tc.input)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "primitives/version/name.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage version\n\nimport \"github.com/berachain/beacon-kit/primitives/common\"\n\n// Name returns the name of the fork version.\nfunc Name(v common.Version) string {\n\tswitch v {\n\tcase phase0:\n\t\treturn \"phase0\"\n\tcase altair:\n\t\treturn \"altair\"\n\tcase bellatrix:\n\t\treturn \"bellatrix\"\n\tcase capella:\n\t\treturn \"capella\"\n\tcase deneb:\n\t\treturn \"deneb\"\n\tcase deneb1:\n\t\treturn \"deneb1\"\n\tcase electra:\n\t\treturn \"electra\"\n\tcase electra1:\n\t\treturn \"electra1\"\n\tcase fulu:\n\t\treturn \"fulu\"\n\tdefault:\n\t\treturn \"unknown\"\n\t}\n}\n"
  },
  {
    "path": "primitives/version/supported.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage version\n\nimport \"github.com/berachain/beacon-kit/primitives/common\"\n\n//nolint:gochecknoglobals // used for testing\nvar supportedVersions = []common.Version{\n\tdeneb,\n\tdeneb1,\n\telectra,\n\telectra1,\n\tfulu,\n}\n\n// GetSupportedVersions returns the supported versions of beacon-kit.\n// Primarily for testing so that we can easily extend test case coverage\n// with new versions by modifying the return value rather than each test.\nfunc GetSupportedVersions() []common.Version {\n\treturn supportedVersions\n}\n"
  },
  {
    "path": "primitives/version/versions.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage version\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n)\n\n// These are the versions of the Beacon Chain.\n//\n//nolint:gochecknoglobals // Kept as private to avoid modification of these variables at runtime.\nvar (\n\t// phase0 is the first version of the Beacon Chain.\n\tphase0 = common.Version{0x00, 0x00, 0x00, 0x00}\n\t// altair is the first hardfork of the Beacon Chain.\n\taltair = common.Version{0x01, 0x00, 0x00, 0x00}\n\t// bellatrix is the second hardfork of the Beacon Chain.\n\tbellatrix = common.Version{0x02, 0x00, 0x00, 0x00}\n\t// capella is the third hardfork of the Beacon Chain.\n\tcapella = common.Version{0x03, 0x00, 0x00, 0x00}\n\t// deneb is the first version of the Deneb hardfork, used for genesis of Berachain mainnet.\n\tdeneb = common.Version{0x04, 0x00, 0x00, 0x00}\n\t// deneb1 is the first hardfork of Deneb on Berachain mainnet.\n\tdeneb1 = common.Version{0x04, 0x01, 0x00, 0x00}\n\t// electra is the first version of the Electra hardfork on Berachain mainnet.\n\telectra = common.Version{0x05, 0x00, 0x00, 0x00}\n\t// electra1 is the first hardfork of Electra on Berachain mainnet.\n\telectra1 = common.Version{0x05, 0x01, 0x00, 0x00}\n\t// fulu is the first version of the Fulu hardfork on Berachain mainnet.\n\tfulu = common.Version{0x06, 0x00, 0x00, 0x00}\n)\n\n// Phase0 returns phase0 as a common.Version.\nfunc Phase0() common.Version {\n\treturn phase0\n}\n\n// Altair returns altair as a common.Version.\nfunc Altair() common.Version {\n\treturn altair\n}\n\n// Bellatrix returns bellatrix as a common.Version.\nfunc Bellatrix() common.Version {\n\treturn bellatrix\n}\n\n// Capella returns capella as a common.Version.\nfunc Capella() common.Version {\n\treturn capella\n}\n\n// Deneb returns deneb as a common.Version. Deneb is the genesis fork version for Berachain\n// mainnet and Bepolia testnet.\nfunc Deneb() common.Version {\n\treturn deneb\n}\n\n// Deneb1 returns deneb1 as a common.Version.\nfunc Deneb1() common.Version {\n\treturn deneb1\n}\n\n// Electra returns electra as a common.Version.\nfunc Electra() common.Version {\n\treturn electra\n}\n\n// Electra1 returns electra1 as a common.Version.\nfunc Electra1() common.Version {\n\treturn electra1\n}\n\n// Fulu returns fulu as a common.Version. Fulu is the CL component of the\n// Fusaka hardfork on Berachain mainnet.\nfunc Fulu() common.Version {\n\treturn fulu\n}\n"
  },
  {
    "path": "scripts/build/build.mk",
    "content": "#!/usr/bin/make -f\nifeq ($(VERSION),)\n  VERSION := $(shell git describe --tags --always --match \"v*\")\nendif\n\nCOMMIT = $(shell git log -1 --format='%H')\nCURRENT_DIR = $(shell pwd)\nOUT_DIR ?= $(CURDIR)/build/bin\nTESTNAME = beacon\nTESTAPP = beacond\nTESTAPP_FILES_DIR = testing/files\nTESTAPP_CMD_DIR = cmd/$(TESTAPP)\nPROJECT_NAME = $(shell git remote get-url origin | xargs basename -s .git)\n\n# process build tags\nbuild_tags = netgo\n\nifeq (legacy,$(findstring legacy,$(COSMOS_BUILD_OPTIONS)))\n  build_tags += app_v1\nendif\n\n# DB backend selection\nifeq (cleveldb,$(findstring cleveldb,$(COSMOS_BUILD_OPTIONS)))\n  build_tags += gcc\nendif\nifeq (badgerdb,$(findstring badgerdb,$(COSMOS_BUILD_OPTIONS)))\n  build_tags += badgerdb\nendif\n# handle rocksdb\nifeq (rocksdb,$(findstring rocksdb,$(COSMOS_BUILD_OPTIONS)))\n  CGO_ENABLED=1\n  build_tags += rocksdb grocksdb_clean_link\nendif\n# handle boltdb\nifeq (boltdb,$(findstring boltdb,$(COSMOS_BUILD_OPTIONS)))\n  build_tags += boltdb\nendif\n\n# always include pebble\nbuild_tags += pebbledb\n\n# always include blst\nbuild_tags += blst\nbuild_tags += bls12381\n\n# always include cgo\nbuild_tags += cgo\n\nwhitespace :=\nwhitespace += $(whitespace)\ncomma := ,\nbuild_tags_comma_sep := $(subst $(whitespace),$(comma),$(build_tags))\n\n# process linker flags\nldflags = -X github.com/cosmos/cosmos-sdk/version.Name=$(TESTNAME) \\\n\t\t-X github.com/cosmos/cosmos-sdk/version.AppName=$(TESTAPP) \\\n\t\t-X github.com/cosmos/cosmos-sdk/version.Version=$(VERSION) \\\n\t\t-X github.com/cosmos/cosmos-sdk/version.Commit=$(COMMIT) \\\n\t\t-X \"github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep)\"\n\nifeq (,$(findstring nostrip,$(COSMOS_BUILD_OPTIONS)))\n  ldflags += -w -s\nendif\nldflags += $(LDFLAGS)\nldflags := $(strip $(ldflags))\n\nbuild_tags += $(BUILD_TAGS)\n\nBUILD_FLAGS := -tags \"$(build_tags)\" -ldflags '$(ldflags)'\n# check for nostrip option\nifeq (,$(findstring nostrip,$(COSMOS_BUILD_OPTIONS)))\n  BUILD_FLAGS += -trimpath\nendif\n\n# Check for debug option\nifeq (debug,$(findstring debug,$(COSMOS_BUILD_OPTIONS)))\n  BUILD_FLAGS += -gcflags \"all=-N -l\"\nendif\n\n# This allows us to reuse the build target steps for both go build and go install\nBUILD_TARGETS := build install\n\n## Build:\nbuild: BUILD_ARGS=-o $(OUT_DIR)/$(TESTAPP) ## build `beacond`\n\n$(BUILD_TARGETS): $(OUT_DIR)/\n\t@echo \"Building ${TESTAPP_CMD_DIR}\"\n\t@go $@ -mod=readonly $(BUILD_FLAGS) $(BUILD_ARGS) $(TESTAPP_CMD_DIR)/*.go\n\n$(OUT_DIR)/:\n\tmkdir -p $(OUT_DIR)/\n\n# Variables\nARCH ?= $(shell uname -m)\nifeq ($(ARCH),)\n\tARCH = arm64\nendif\nIMAGE_NAME ?= $(TESTAPP)\n\n# Docker Paths\nDOCKERFILE = ./Dockerfile\n\n# Go version extracted from go.mod (single source of truth).\nGO_VERSION := $(or \\\n  $(shell awk '/^go /{print $$2}' $(CURDIR)/go.mod 2>/dev/null), \\\n  $(shell sed -n 's/^go \\(.*\\)/\\1/p' $(CURDIR)/go.mod 2>/dev/null))\nifeq ($(GO_VERSION),)\n  $(error GO_VERSION could not be parsed from $(CURDIR)/go.mod)\nendif\n\nbuild-docker: ## build a docker image containing `beacond`\n\t@echo \"Build a release docker image for the Cosmos SDK chain...\"\n\tdocker build \\\n\t--platform linux/$(ARCH) \\\n\t--build-arg GO_VERSION=$(GO_VERSION) \\\n\t--build-arg GIT_COMMIT=$(shell git rev-parse HEAD) \\\n\t--build-arg GIT_VERSION=$(VERSION) \\\n\t--build-arg GIT_BRANCH=$(shell git rev-parse --abbrev-ref HEAD) \\\n\t--build-arg GOOS=linux \\\n\t--build-arg GOARCH=$(ARCH) \\\n\t-f ${DOCKERFILE} \\\n\t-t $(IMAGE_NAME):$(VERSION) \\\n\t.\n\npush-docker-github: ## push the docker image to the ghcr registry\n\t@echo \"Push the release docker image to the ghcr registry...\"\n\tdocker tag $(IMAGE_NAME):$(VERSION) ghcr.io/berachain/beacon-kit:$(VERSION)\n\tdocker push ghcr.io/berachain/beacon-kit:$(VERSION)\n"
  },
  {
    "path": "scripts/build/codegen.mk",
    "content": "#!usr/bin/make -f\n\nGETH_GO_GENERATE_VERSION := $(shell grep 'github.com/ethereum/go-ethereum' go.mod | awk '{print $$2}')\nGOPATH = $(shell go env GOPATH)\nGETH_PKG_INCLUDE := $(GOPATH)/pkg/mod/github.com/ethereum/go-ethereum@$(GETH_GO_GENERATE_VERSION)\n\n## Codegen:\ngenerate: ## generate all the code\n\t@$(MAKE) forge-build\n\t@for module in $(MODULES); do \\\n\t\techo \"Running go generate in $$module\"; \\\n\t\t(cd $$module && \\\n\t\t\tGETH_PKG_INCLUDE=$(GETH_PKG_INCLUDE) go generate ./...) || exit 1; \\\n\tdone\n\t@go run github.com/vektra/mockery/v2@v2.53.5\n\nabigen-install:\n\t@go install github.com/ethereum/go-ethereum/cmd/abigen@latest\n\ngenerate-check: abigen-install\n\t@$(MAKE) forge-build\n\t@$(MAKE) generate\n\t@if [ -n \"$$(git status --porcelain | grep -vE '\\.ssz\\.go$$')\" ]; then \\\n\t\techo \"Generated files are not up to date\"; \\\n\t\tgit status -s | grep -vE '\\.ssz\\.go$$'; \\\n\t\tgit diff -- . ':(exclude)*.ssz.go'; \\\n\t\texit 1; \\\n\tfi\n"
  },
  {
    "path": "scripts/build/constants.mk",
    "content": "#!/usr/bin/make -f\nMODULES := $(shell find . -type f -name 'go.mod' -exec dirname {} \\;)\n# Exclude root module\nMODULES := $(filter-out ./,$(MODULES))\n\nCONTRACTS_DIR := ./contracts\n"
  },
  {
    "path": "scripts/build/devtools.mk",
    "content": "#!/usr/bin/make -f\n\nrepo-rinse: | ## dangerous!!! make sure you know what you are doing\n\tgit clean -xfd\n\tgit submodule foreach --recursive git clean -xfd\n\tgit submodule foreach --recursive git reset --hard\n\tgit submodule update --init --recursive\n\n# tidy-sync-check runs `go mod tidy` and checks if go.mod/go.sum files are in sync with\n# the dependencies in the codebase. If they are not in sync, it will exit with a\n# non-zero status code.\ntidy-sync-check:\n\t@{ \\\n\tpre_tidy_diff=$$(git diff --ignore-space-change go.mod go.sum); \\\n\tgo mod tidy; \\\n\tpost_tidy_diff=$$(git diff --ignore-space-change go.mod go.sum); \\\n\tif [ \"$$pre_tidy_diff\" != \"$$post_tidy_diff\" ]; then \\\n\t\techo \"go.mod or go.sum changed after running 'go mod tidy'\"; \\\n\t\tgit diff go.mod go.sum; \\\n\t\texit 1; \\\n\tfi; \\\n\t}\n"
  },
  {
    "path": "scripts/build/golines.sh",
    "content": "#!/usr/bin/env bash\n# SPDX-License-Identifier: MIT\n#\n# Copyright (c) 2025 Berachain Foundation\n#\n# Permission is hereby granted, free of charge, to any person\n# obtaining a copy of this software and associated documentation\n# files (the \"Software\"), to deal in the Software without\n# restriction, including without limitation the rights to use,\n# copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the\n# Software is furnished to do so, subject to the following\n# conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n# OTHER DEALINGS IN THE SOFTWARE.\n\n\n# Define the root directory of your Go project\nROOT_DIR=\".\"\n\n# Find all .go files in the project directory and its subdirectories, ignoring .pb.go and .pb_encoding.go files\nfind \"${ROOT_DIR}\" -type f -name \"*.go\" ! -name \"*.pb.go\" ! -name \"*_test.go\" ! -name \"*.pb_encoding.go\" | while read -r file; do\n    echo \"Processing $file...\"\n    golines --reformat-tags --shorten-comments --write-output --max-len=140 \"$file\"\ndone\n\necho \"✅ All files processed.\"\n"
  },
  {
    "path": "scripts/build/help.mk",
    "content": "#!/usr/bin/make -f\n\nGREEN  := $(shell tput -Txterm setaf 2)\nYELLOW := $(shell tput -Txterm setaf 3)\nWHITE  := $(shell tput -Txterm setaf 7)\nCYAN   := $(shell tput -Txterm setaf 6)\nRESET  := $(shell tput -Txterm sgr0)\n\n## Help:\nhelp: ## Show this help.\n\t@echo ''\n\t@echo ' ${CYAN}🌈  Welcome to the BeaconKit Makefile Help Page  🌈${RESET}'\n\t@echo ''\n\t@echo 'Usage:'\n\t@echo '  ${YELLOW}make${RESET} ${GREEN}<target>${RESET}'\n\t@echo ''\n\t@echo 'Targets:'\n\t@awk 'BEGIN {FS = \":.*?## \"} { \\\n\t\tif (/^[a-zA-Z_-]+:.*?##.*$$/) {printf \"    ${YELLOW}%-20s${GREEN}%s${RESET}\\n\", $$1, $$2} \\\n\t\telse if (/^## .*$$/) {printf \"  ${CYAN}%s${RESET}\\n\", substr($$1,4)} \\\n\t\t}' $(MAKEFILE_LIST)"
  },
  {
    "path": "scripts/build/linting.mk",
    "content": "#!/usr/bin/make -f\n\n## Linting:\nformat: ## run all configured formatters\n\t@$(MAKE) license-fix forge-lint-fix golines golangci-fix star-fix\n\nlint: ## run all configured linters\n\t@$(MAKE) license markdownlint forge-lint golangci star-lint\n\n\n#################\n# golangci-lint #\n#################\n\ngolangci-install:\n\t@go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest\n\n# TODO: Remove GODEBUG override once: https://github.com/golang/go/issues/68877 is resolved.\ngolangci: golangci-install\n\t@echo \"--> Running linter on all modules\"\n\t(GODEBUG=gotypesalias=0 golangci-lint run --config $(ROOT_DIR)/.golangci.yaml --timeout=10m --concurrency 8) || exit 1;\n\t@printf \"All modules complete\\n\"\n\n\n# TODO: Remove GODEBUG override once: https://github.com/golang/go/issues/68877 is resolved.\ngolangci-fix: golangci-install\n\t@echo \"--> Running linter with fixes on all modules\"\n\t(GODEBUG=gotypesalias=0 golangci-lint run --config $(ROOT_DIR)/.golangci.yaml --timeout=10m --fix --concurrency 8) || exit 1;\n\t@printf \"All modules complete\\n\"\n\n#################\n#    golines    #\n#################\n\ngolines-install:\n\t@go install github.com/segmentio/golines@latest\n\ngolines: golines-install\n\t@echo \"--> Running golines\"\n\t@./scripts/build/golines.sh\n\n#################\n#    license    #\n#################\n\nlicense-install:\n\t@go install github.com/google/addlicense@latest\n\nlicense: license-install\n\t@echo \"--> Running addlicense with -check\"\n\t(addlicense -check -v -f $(ROOT_DIR)/LICENSE.header -ignore \"**/*.toml\" -ignore \"contracts/**\" -ignore \".idea/**\" .) || exit 1;\n\t@printf \"License check complete\\n\"\n\nlicense-fix: license-install\n\techo \"--> Running addlicense\"\n\t(addlicense -v -f $(ROOT_DIR)/LICENSE.header -ignore \"**/*.toml\" -ignore \"contracts/**\" -ignore \".idea/**\" .) || exit 1;\n\t@printf \"License check complete\\n\"\n\n#################\n#    nilaway    #\n#################\n\nnilaway-install:\n\t@go install go.uber.org/nilaway/cmd/nilaway@latest\n\nnilaway: nilaway-install\n\t@echo \"--> Running nilaway\"\n\t(nilaway -test=false -exclude-errors-in-files \"gethlib/deposit/\",\"gethlib/ssztest/\" -v ./...) || exit 1;\n\t@printf \"Nilaway check complete\\n\"\n\n#################\n#     gosec     #\n#################\n\ngosec-install:\n\t@go install github.com/securego/gosec/v2/cmd/gosec@latest\n\ngosec: gosec-install\n\t@echo \"--> Running gosec\"\n\t@gosec ./...\n\n#################\n#   vulncheck   #\n#################\n\nvulncheck:\n\t@echo \"--> Running govulncheck\"\n\t@export GOTOOLCHAIN=go$$(sed -n 's/^go //p' go.mod) && \\\n\t\tgo run golang.org/x/vuln/cmd/govulncheck@latest $$(go list ./... | grep -v '/testing/')\n\n#################\n#    slither    #\n#################\n\nslither:\n\tchmod -R o+rw ./contracts\n\tdocker run \\\n\t-t \\\n\t--platform linux/amd64 \\\n\t-v ./contracts:/contracts:rw \\\n\ttrailofbits/eth-security-toolbox:edge \\\n\t/bin/bash -c \"cd /contracts/ && slither ./.\"\n\n#################\n# markdown-lint #\n#################\n\nmarkdownlint:\n\t@echo \"--> Running markdownlint\"\n\t@docker run --rm -v $(ROOT_DIR):/workspace -w /workspace -t markdownlint/markdownlint:latest --git-recurse **/**.md\n\n#################\n# all ci linters #\n#################\n\nlint-ci: lint slither gosec vulncheck nilaway markdownlint generate-check \\\n    tidy-sync-check test-unit-cover test-unit-bench test-unit-fuzz \\\n\ttest-forge-cover test-forge-fuzz\n"
  },
  {
    "path": "scripts/build/proto_generate_pulsar.sh",
    "content": "# SPDX-License-Identifier: MIT\n#\n# Copyright (c) 2025 Berachain Foundation\n#\n# Permission is hereby granted, free of charge, to any person\n# obtaining a copy of this software and associated documentation\n# files (the \"Software\"), to deal in the Software without\n# restriction, including without limitation the rights to use,\n# copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the\n# Software is furnished to do so, subject to the following\n# conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n# OTHER DEALINGS IN THE SOFTWARE.\n\n\n# this script is for generating protobuf files for the new google.golang.org/protobuf API\n\nset -eo pipefail\n\nprotoc_install_gopulsar() {\n  go install github.com/cosmos/cosmos-proto/cmd/protoc-gen-go-pulsar@latest\n  go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest\n}\n\nprotoc_install_gopulsar\n\necho \"Cleaning API directory\"\nmkdir -p cosmos/api\n(cd cosmos/api; find ./ -type f \\( -iname \\*.pulsar.go -o -iname \\*.pb.go -o -iname \\*.cosmos_orm.go -o -iname \\*.pb.gw.go \\) -delete; find . -empty -type d -delete; cd ../../..)\n\necho \"Generating API module\"\n(cd node-core/components/module/proto; buf generate --template buf.gen.pulsar.yaml; cd ../)\n\n# # cp -r api cosmos\n# cp -r api/mod/node-core/pkg/components/module/* mod/node-core/pkg/components/module/api\n# rm -rf api\n# # rm -rf cosmos/api/ethereum\n# # rm -rf cosmos/api/types"
  },
  {
    "path": "scripts/build/protobuf.mk",
    "content": "#!/usr/bin/make -f\n\nprotoImageName    := \"ghcr.io/cosmos/proto-builder\"\nprotoImageVersion := \"0.14.0\"\nmodulesProtoDir := \"node-core/components/module/proto\"\n\n## Protobuf:\nproto: ## run all the proto tasks\n\t@$(MAKE) proto-build\n\nproto-build: ## build the proto files\n\t@docker run --rm -v ${CURRENT_DIR}:/workspace --workdir /workspace $(protoImageName):$(protoImageVersion) sh ./scripts/build/proto_generate_pulsar.sh\n\nproto-clean: ## clean the proto files\n\t@find . -name '*.pb.go' -delete\n\t@find . -name '*.pb.gw.go' -delete\n"
  },
  {
    "path": "scripts/build/release.mk",
    "content": "#!/usr/bin/make -f\n\nRELEASE_TARGETS := build-linux-amd64 build-linux-arm64 build-darwin-arm64\n\ndefine build_release\n\techo \"Building beacond for $(shell echo $(4) | tr '/' '-')-$(1)-$(2)-...\"\n\tGOOS=$(1) GOARCH=$(2) CGO_ENABLED=$(3) \\\n\tcd ${CURRENT_DIR}/$(TESTAPP_CMD_DIR) && \\\n\tgo build -mod=readonly $(BUILD_FLAGS) -o $(OUT_DIR)/beacond-$(shell echo $(4) | tr '/' '-')-$(1)-$(2) ./.\nendef\n\nbuild-linux-amd64-%:\n\t$(call build_release,linux,amd64,1,$*)\n\nbuild-linux-arm64-%:\n\t$(call build_release,linux,arm64,1,$*)\n\nbuild-darwin-arm64-%:\n\t$(call build_release,darwin,arm64,1,$*)\n\n\n"
  },
  {
    "path": "scripts/build/testing.mk",
    "content": "#!/usr/bin/make -f\n\n###############################################################################\n###                           Tests & Simulation                            ###\n###############################################################################\n\n# ask_reset_dir_func checks if the directory passed in exists, and if so asks the user whether it\n# should delete it. Note that on linux, docker may have created the directory with root\n# permissions, so we may need to ask the user to delete it with sudo\ndefine ask_reset_dir_func\n\t@abs_path=$(abspath $(1)); \\\n\tif test -d \"$$abs_path\"; then \\\n\t\tread -p \"Directory '$$abs_path' exists. Do you want to delete it? (y/n): \" confirm && \\\n\t\tif [ \"$$confirm\" = \"y\" ]; then \\\n\t\t\techo \"Deleting directory '$$abs_path'...\"; \\\n\t\t\trm -rf \"$$abs_path\" 2>/dev/null || sudo rm -rf \"$$abs_path\"; \\\n\t\t\tif test -d \"$$abs_path\"; then \\\n\t\t\t\techo \"Failed to delete directory '$$abs_path'.\"; \\\n\t\t\t\texit 1; \\\n\t\t\tfi; \\\n\t\tfi \\\n\telse \\\n\t\techo \"Directory '$$abs_path' does not exist.\"; \\\n\tfi\nendef\n\n#################\n#     Local     #\n#################\n\n# Use the genesis file from the beacond folder as it has been modified by \n# beacond genesis set-deposit-storage.\nETH_GENESIS_PATH = ${HOMEDIR}/eth-genesis.json\n\nHOMEDIR = .tmp/beacond\nJWT_PATH = ${TESTAPP_FILES_DIR}/jwt.hex\nETH_DATA_DIR = .tmp/eth-home\n\n## Start an ephemeral `beacond` node. Must be run before running the EL to\n## configure the deposit contract storage slots pre-genesis.\nstart: \n\t@JWT_SECRET_PATH=$(JWT_PATH) \\\n\t${TESTAPP_FILES_DIR}/entrypoint.sh devnet\n\n# URLs used for dialing the eth client\nIPC_PATH = .tmp/eth-home/eth-engine.ipc\nIPC_PREFIX = ipc://\n\n## Start an ephemeral `beacond` node with a custom chain spec. The path to the chain spec\n## file must be passed as an argument. Usage: make start-custom /path/to/chain/spec.toml\nstart-custom:\n\t@JWT_SECRET_PATH=$(JWT_PATH) \\\n\t${TESTAPP_FILES_DIR}/entrypoint.sh file $(word 2,$(MAKECMDGOALS))\n\n## Start an ephemeral `reth` node\nstart-reth: \n\t$(call ask_reset_dir_func, $(ETH_DATA_DIR))\n\t@docker run \\\n\t-p 30303:30303 \\\n\t-p 8545:8545 \\\n\t-p 8551:8551 \\\n\t--rm -v $(PWD)/${TESTAPP_FILES_DIR}:/${TESTAPP_FILES_DIR} \\\n\t-v $(PWD)/.tmp:/.tmp \\\n\tghcr.io/berachain/bera-reth:nightly node \\\n\t--chain ${ETH_GENESIS_PATH} \\\n\t--http \\\n\t--http.addr \"0.0.0.0\" \\\n\t--http.api eth,net \\\n\t--authrpc.addr \"0.0.0.0\" \\\n\t--authrpc.jwtsecret $(JWT_PATH) \\\n\t--datadir ${ETH_DATA_DIR} \\\n\t--ipcpath ${IPC_PATH} \\\n\t--engine.persistence-threshold 0 \\\n\t--engine.memory-block-buffer-target 0\n\n## Start an ephemeral `geth` node with docker\nstart-geth: \n\t$(call ask_reset_dir_func, $(ETH_DATA_DIR))\n\tdocker run \\\n\t--rm -v $(PWD)/${TESTAPP_FILES_DIR}:/${TESTAPP_FILES_DIR} \\\n\t-v $(PWD)/.tmp:/.tmp \\\n\tghcr.io/berachain/bera-geth:latest init \\\n\t--datadir ${ETH_DATA_DIR} \\\n\t${ETH_GENESIS_PATH}\n\n\tdocker run \\\n\t-p 30303:30303 \\\n\t-p 8545:8545 \\\n\t-p 8551:8551 \\\n\t--rm -v $(PWD)/${TESTAPP_FILES_DIR}:/${TESTAPP_FILES_DIR} \\\n\t-v $(PWD)/.tmp:/.tmp \\\n\tghcr.io/berachain/bera-geth:latest \\\n\t--syncmode=full \\\n\t--http \\\n\t--http.addr 0.0.0.0 \\\n\t--http.api eth,net \\\n\t--authrpc.addr 0.0.0.0 \\\n\t--authrpc.jwtsecret $(JWT_PATH) \\\n\t--authrpc.vhosts \"*\" \\\n\t--datadir ${ETH_DATA_DIR} \\\n\t--ipcpath ${IPC_PATH}\n\n\n#################\n#    Bepolia    #\n#################\n\nBEPOLIA_NETWORK_FILES_DIR = ${TESTAPP_FILES_DIR}/../networks/80069\nBEPOLIA_ETH_GENESIS_PATH = ${BEPOLIA_NETWORK_FILES_DIR}/eth-genesis.json\n\nstart-bepolia:\n\t@JWT_SECRET_PATH=$(JWT_PATH) \\\n\t${TESTAPP_FILES_DIR}/entrypoint.sh testnet\n\nstart-geth-bepolia:\n\t$(call ask_reset_dir_func, $(ETH_DATA_DIR))\n\tdocker run \\\n\t--rm -v $(PWD)/${TESTAPP_FILES_DIR}:/${TESTAPP_FILES_DIR} \\\n\t--rm -v $(PWD)/${BEPOLIA_NETWORK_FILES_DIR}:/${BEPOLIA_NETWORK_FILES_DIR} \\\n\t-v $(PWD)/.tmp:/.tmp \\\n\tghcr.io/berachain/bera-geth:latest init \\\n\t--datadir ${ETH_DATA_DIR} \\\n\t${BEPOLIA_ETH_GENESIS_PATH}\n\n\t@# Read bootnodes from the file; the file is mounted into the container.\n\t@bootnodes=`cat $(PWD)/$(BEPOLIA_NETWORK_FILES_DIR)/el-bootnodes.txt`; \\\n\techo \"Using bootnodes: $$bootnodes\"; \\\n\tdocker run \\\n\t-p 30303:30303 \\\n\t-p 8545:8545 \\\n\t-p 8551:8551 \\\n\t--rm -v $(PWD)/${TESTAPP_FILES_DIR}:/${TESTAPP_FILES_DIR} \\\n\t--rm -v $(PWD)/${BEPOLIA_NETWORK_FILES_DIR}:/${BEPOLIA_NETWORK_FILES_DIR} \\\n\t-v $(PWD)/.tmp:/.tmp \\\n\tghcr.io/berachain/bera-geth:latest \\\n\t--http \\\n\t--http.addr 0.0.0.0 \\\n\t--http.api eth,net \\\n\t--authrpc.addr 0.0.0.0 \\\n\t--authrpc.jwtsecret $(JWT_PATH) \\\n\t--authrpc.vhosts \"*\" \\\n\t--datadir ${ETH_DATA_DIR} \\\n\t--ipcpath ${IPC_PATH} \\\n\t--syncmode=full \\\n\t--bootnodes $$bootnodes\n\nstart-reth-bepolia:\n\t$(call ask_reset_dir_func, $(ETH_DATA_DIR))\n\t@trustedpeers=`cat $(PWD)/$(BEPOLIA_NETWORK_FILES_DIR)/el-peers.txt`; \\\n\techo \"Using truted peers: $$trustedpeers\"; \\\n\tdocker run \\\n\t-p 30303:30303 \\\n\t-p 8545:8545 \\\n\t-p 8551:8551 \\\n\t--rm -v $(PWD)/${TESTAPP_FILES_DIR}:/${TESTAPP_FILES_DIR} \\\n\t--rm -v $(PWD)/${BEPOLIA_NETWORK_FILES_DIR}:/${BEPOLIA_NETWORK_FILES_DIR} \\\n\t-v $(PWD)/.tmp:/.tmp \\\n\tghcr.io/berachain/bera-reth:nightly node \\\n\t--chain ${BEPOLIA_ETH_GENESIS_PATH} \\\n\t--http \\\n\t--http.addr \"0.0.0.0\" \\\n\t--http.api eth,net \\\n\t--authrpc.addr \"0.0.0.0\" \\\n\t--authrpc.jwtsecret $(JWT_PATH) \\\n\t--datadir ${ETH_DATA_DIR} \\\n\t--ipcpath ${IPC_PATH} \\\n\t--trusted-peers $$trustedpeers\n\n#################\n#    Mainnet    #\n#################\n\nMAINNET_NETWORK_FILES_DIR = ${TESTAPP_FILES_DIR}/../networks/80094\nMAINNET_ETH_GENESIS_PATH = ${MAINNET_NETWORK_FILES_DIR}/eth-genesis.json\n\nstart-mainnet:\n\t@JWT_SECRET_PATH=$(JWT_PATH) \\\n\t${TESTAPP_FILES_DIR}/entrypoint.sh mainnet\n\n# NOTE: By default this will use the EL peers as your bootnodes. If you want specific \n# discovery bootnodes by region, refer to testing/networks/80094/el-bootnodes.txt\nstart-geth-mainnet:\n\t$(call ask_reset_dir_func, $(ETH_DATA_DIR))\n\tdocker run \\\n\t--rm -v $(PWD)/${TESTAPP_FILES_DIR}:/${TESTAPP_FILES_DIR} \\\n\t--rm -v $(PWD)/${MAINNET_NETWORK_FILES_DIR}:/${MAINNET_NETWORK_FILES_DIR} \\\n\t-v $(PWD)/.tmp:/.tmp \\\n\tghcr.io/berachain/bera-geth:latest init \\\n\t--datadir ${ETH_DATA_DIR} \\\n\t${MAINNET_ETH_GENESIS_PATH}\n\n\t@# Read bootnodes from the file; the file is mounted into the container.\n\t@bootnodes=`cat $(PWD)/$(MAINNET_NETWORK_FILES_DIR)/el-peers.txt`; \\\n\techo \"Using bootnodes: $$bootnodes\"; \\\n\tdocker run \\\n\t-p 30303:30303 \\\n\t-p 8545:8545 \\\n\t-p 8551:8551 \\\n\t--rm -v $(PWD)/${TESTAPP_FILES_DIR}:/${TESTAPP_FILES_DIR} \\\n\t--rm -v $(PWD)/${MAINNET_NETWORK_FILES_DIR}:/${MAINNET_NETWORK_FILES_DIR} \\\n\t-v $(PWD)/.tmp:/.tmp \\\n\tghcr.io/berachain/bera-geth:latest \\\n\t--http \\\n\t--http.addr 0.0.0.0 \\\n\t--http.api eth,net \\\n\t--authrpc.addr 0.0.0.0 \\\n\t--authrpc.jwtsecret $(JWT_PATH) \\\n\t--authrpc.vhosts \"*\" \\\n\t--datadir ${ETH_DATA_DIR} \\\n\t--ipcpath ${IPC_PATH} \\\n\t--syncmode=full \\\n\t--bootnodes $$bootnodes\n\nstart-reth-mainnet:\n\t$(call ask_reset_dir_func, $(ETH_DATA_DIR))\n\t@trustedpeers=`cat $(PWD)/$(MAINNET_NETWORK_FILES_DIR)/el-peers.txt`; \\\n\techo \"Using truted peers: $$trustedpeers\"; \\\n\tdocker run \\\n\t-p 30303:30303 \\\n\t-p 8545:8545 \\\n\t-p 8551:8551 \\\n\t--rm -v $(PWD)/${TESTAPP_FILES_DIR}:/${TESTAPP_FILES_DIR} \\\n\t--rm -v $(PWD)/${MAINNET_NETWORK_FILES_DIR}:/${MAINNET_NETWORK_FILES_DIR} \\\n\t-v $(PWD)/.tmp:/.tmp \\\n\tghcr.io/berachain/bera-reth:nightly node \\\n\t--chain ${MAINNET_ETH_GENESIS_PATH} \\\n\t--http \\\n\t--http.addr \"0.0.0.0\" \\\n\t--http.api eth,net \\\n\t--authrpc.addr \"0.0.0.0\" \\\n\t--authrpc.jwtsecret $(JWT_PATH) \\\n\t--datadir ${ETH_DATA_DIR} \\\n\t--ipcpath ${IPC_PATH} \\\n\t--trusted-peers $$trustedpeers\n\n#################\n#    Testing    #\n#################\n\nSHORT_FUZZ_TIME=10s\nMEDIUM_FUZZ_TIME=30s\nLONG_FUZZ_TIME=3m\n\n# Define a function to filter out lines with \"/testing/\", \"/mock/\", \"/mocks/\", or \".mock.go\"\ndefine FILTER_COVERAGE\n\tgrep -Ev '(/testing/|/mock/|/mocks/|\\.mock\\.go)' $(1) > $(2)\nendef\n\ntest:\n\t@$(MAKE) test-unit test-forge-fuzz\n\ntest-unit-no-coverage: ## run golang unit tests\n\t@echo \"Running unit tests...\"\n\t@go list -f '{{.Dir}}/...' -m | xargs \\\n\t\tgo test -race -tags bls12381,test\n\ncoverage-summary: test-unit test-simulated\n\t@echo \"Merging coverage reports...\"\n\t@go install github.com/wadey/gocovmerge@latest\n\t@gocovmerge test-unit-cover.txt test-simulated.txt > coverage-merged.txt\n\t@echo \"Coverage Summary:\"\n\t@go tool cover -html=coverage-merged.txt\n\ntest-unit-cover: test-unit test-simulated test-unit-quick ## run golang unit tests with coverage\n\ntest-unit:\n\t@echo \"Running unit tests with coverage and race checks...\"\n\t@go list -f '{{.Dir}}/...' -m | xargs \\\n\t\tgo test -race -covermode=atomic -coverpkg=github.com/berachain/beacon-kit/... -coverprofile=temp-test-unit-cover.txt -tags bls12381,test\n\t# Filter out any coverage lines from the testing directory\n\t$(call FILTER_COVERAGE, temp-test-unit-cover.txt, test-unit-cover.txt)\n\t@rm temp-test-unit-cover.txt\n\ntest-unit-quick: ## run quick tests. We run these without coverage as covermode=atomic is too slow and coverage here provides little value\n\t@echo \"Running 'quick' tests...\"\n\t@go list -f '{{.Dir}}/testing/quick' -m | xargs \\\n\t\tgo test -v -tags quick\n\ntest-simulated: ## run simulation tests\n\t@echo \"Running simulation tests with coverage\"\n\t@go list -f '{{.Dir}}/testing/simulated' -m | xargs \\\n\t\tgo test -cover -covermode=atomic -coverpkg=github.com/berachain/beacon-kit/... -coverprofile=temp-test-simulated.txt -tags simulated -v\n\t# Filter out any coverage lines from the testing directory\n\t$(call FILTER_COVERAGE, temp-test-simulated.txt, test-simulated.txt)\n\t@rm temp-test-simulated.txt\n\ntest-unit-bench: ## run golang unit benchmarks\n\t@echo \"Running unit tests with benchmarks...\"\n\t@go list -f '{{.Dir}}/...' -m | xargs \\\n\t\tgo test -bench=. -run=^$ -benchmem -tags bls12381,test\n\n# On MacOS, if there is a linking issue on the fuzz tests,\n# use the old linker with flags -ldflags=-extldflags=-Wl,-ld_classic\ntest-unit-fuzz: ## run fuzz tests\n\t@echo \"Running fuzz tests with coverage...\"\n\tgo test -run ^FuzzPayloadIDCacheBasic -fuzztime=${SHORT_FUZZ_TIME} github.com/berachain/beacon-kit/payload/cache\n\tgo test -run ^FuzzPayloadIDInvalidInput -fuzztime=${SHORT_FUZZ_TIME} github.com/berachain/beacon-kit/payload/cache\n\tgo test -run ^FuzzPayloadIDCacheConcurrency -fuzztime=${SHORT_FUZZ_TIME} github.com/berachain/beacon-kit/payload/cache\n\tgo test -run ^FuzzHashTreeRoot -fuzztime=${MEDIUM_FUZZ_TIME} github.com/berachain/beacon-kit/primitives/merkle\n\ntest-e2e: ## run all e2e tests (standard)\n\t@$(MAKE) build-docker VERSION=kurtosis-local test-e2e-no-build\n\ntest-e2e-no-build:\n\t@$(MAKE) test-e2e-standard-no-build\n\ntest-e2e-standard: ## run standard e2e tests\n\t@$(MAKE) build-docker VERSION=kurtosis-local test-e2e-standard-no-build\n\ntest-e2e-standard-no-build:\n\tgo test -timeout 0 -tags e2e,bls12381,test ./testing/e2e/standard/. -v\n\ntest-e2e-4844: ## run e2e blob tests\n\t@$(MAKE) build-docker VERSION=kurtosis-local test-e2e-4844-no-build\n\ntest-e2e-4844-no-build:\n\tgo test -timeout 0 -tags e2e,bls12381,test ./testing/e2e/standard/. -v -testify.m Test4844Live\n\ntest-e2e-deposits: ## run e2e deposit tests\n\t@$(MAKE) build-docker VERSION=kurtosis-local test-e2e-deposits-no-build\n\ntest-e2e-deposits-no-build:\n\tgo test -timeout 0 -tags e2e,bls12381,test ./testing/e2e/standard/. -v -testify.m TestDepositRobustness\n"
  },
  {
    "path": "scripts/rollback_cl.sh",
    "content": "#!/usr/bin/env bash\n# SPDX-License-Identifier: MIT\n#\n# Copyright (c) 2025 Berachain Foundation\n#\n# Permission is hereby granted, free of charge, to any person\n# obtaining a copy of this software and associated documentation\n# files (the \"Software\"), to deal in the Software without\n# restriction, including without limitation the rights to use,\n# copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the\n# Software is furnished to do so, subject to the following\n# conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n# OTHER DEALINGS IN THE SOFTWARE.\n\n# fail immediately on errors including any commands in a pipeline\nset -Eeuo pipefail\n# include linenumber and command if an error occurs\ntrap 'echo \"Script failed at line $LINENO when running command: \\\"$BASH_COMMAND\\\"\"' ERR\n\nusage() {\n    echo \"Usage: $(basename \"$0\")\"\n    echo \"\"\n    echo \"This script compares the Consensus Layer (CL) height with the Execution Layer (EL) height,\"\n    echo \"and performs rollbacks on CL until it is at or below the EL height.\"\n    echo \"\"\n    echo \"Environment Variables:\"\n    echo \"  BEACOND_BIN      (default: 'beacond') - Path to the beacon-kit binary.\"\n    echo \"  BEACOND_HOME     (default: '~/.beacond') - Path to the beacon-kit home directory.\"\n    echo \"  EL_RPC_URL       (default: '127.0.0.1:8545') - Execution Layer RPC endpoint.\"\n    echo \"\"\n    echo \"Example usage:\"\n    echo \"  BEACOND_HOME=/data/.beacond ./$(basename \"$0\")\"\n    echo \"  BEACOND_BIN=/custom/path/beacond ./$(basename \"$0\")\"\n    exit 0\n}\n\nif [[ \"${1:-}\" == \"--help\" || \"${1:-}\" == \"-h\" ]]; then\n    usage\nfi\n\n\nBEACOND_BIN=\"${BEACOND_BIN:-beacond}\"\nBEACOND_HOME=\"${BEACOND_HOME:-$HOME/.beacond}\"\nEL_RPC_URL=\"${EL_RPC_URL:-127.0.0.1:8545}\"\n\necho \"Starting rollback process:\"\necho \"- BEACOND_BIN: $BEACOND_BIN\"\necho \"- BEACOND_HOME: $BEACOND_HOME\"\necho \"- EL_RPC_URL: $EL_RPC_URL\"\n\n# Validate BEACOND_HOME already exists\nif [[ ! -d \"$BEACOND_HOME\" ]]; then\n    echo \"Error: BEACOND_HOME is not a valid directory.\"\n    exit 1\nfi\n\n# Validate BEACOND_BIN (must be in PATH or specified)\nif ! \"$BEACOND_BIN\" version &>/dev/null; then\n    echo \"Error: BEACOND_BIN is not a valid executable or not found.\"\n    exit 1\nfi\n\necho \"[Fetching EL height...]\"\nEL_HEX=$(curl -s -X POST --location \"$EL_RPC_URL\" --header 'Content-Type: application/json' --data '{\n    \"jsonrpc\":\"2.0\",\n    \"method\":\"eth_getBlockByNumber\",\n    \"params\":[\"latest\", false],\n    \"id\":1\n}' | jq -r .result.number)\n[[ -z \"$EL_HEX\" || \"$EL_HEX\" == \"null\" || \"$EL_HEX\" -le 0 ]] && echo \"Error: Invalid Execution Layer height (EL). EL must be greater than zero.\" && exit 1\nEL=$((${EL_HEX}))\necho \"-> EL height: $EL ($EL_HEX)\"\n\necho \"[Fetching CL height...]\"\nROLLBACK_OUTPUT=$(\"$BEACOND_BIN\" rollback --home=\"$BEACOND_HOME\")\nCL=$(echo \"$ROLLBACK_OUTPUT\" | sed -n 's/.*height=\\([0-9][0-9]*\\).*/\\1/p')\necho \"-> CL height: $CL\"\n\n# Check if CL is already at or below EL\nif (( CL <= EL )); then\n    echo \"No rollback needed. Consensus Layer height is already at or below Execution Layer height.\"\n    exit 0\nfi\n\n# Start the rollback loop from CL down to EL\necho \"[Starting rolling back of CL]\"\nwhile true; do\n    echo \"Rolling back CL height $CL...\"\n\n    ROLLBACK_OUTPUT=$(\"$BEACOND_BIN\" rollback --hard --home=\"$BEACOND_HOME\")\n    CL=$(echo \"$ROLLBACK_OUTPUT\" | sed -n 's/.*height=\\([0-9][0-9]*\\).*/\\1/p')\n    echo \"New CL height after rollback: $CL (required height: $EL)\"\n\n    if (( CL <= EL )); then\n        echo \"Reached target Execution Layer height. Exiting.\"\n        break\n    fi\ndone\n\necho \"Rollback process completed successfully.\"\n"
  },
  {
    "path": "state-transition/core/README.md",
    "content": "# State Processor\n\n## Validators handling\n\nAs a general principle, BeaconKit strives to keep validators handling aligned with Ethereum 2.0 specs. There currently two notable exceptions to this principle:\n\n- BeaconKit **does not** enforce a cap on validators churn, neither in the activation nor in the exit queue.\n- BeaconKit **does** enforce an explicit cap on the validators set.\n- BeaconKit **does not** currently support voluntary withdrawals.\n\nWe list below a few relevant facts.\n\n## `Balance` and `EffectiveBalance`\n\nBeaconKit distingishes a validator `Balance` and a validator `EffectiveBalance`.\n\n- `Balance` is updated slot by slot, when a deposit in made over the deposit contract and events are subsequently processed by BeaconKit.\n- `Balance` can increase only in multiples of `MinDepositAmount`, which is specified in the deposit contract. There is no cap on the `Balance`.\n- `EffectiveBalance` is updated at the turn of every epoch.\n- `EffectiveBalance` is enforced to be a multiple of `EffectiveBalanceIncrement`\n- `EffectiveBalance` is capped at `MaxEffectiveBalance`. Any `Balance` in excess of `MaxEffectiveBalance` is automatically withdrawn.\n- `EffectiveBalance` is aligned to `Balance`, within the constrains listed above, and accounting for hysteresys, at the turn of every epoch, via [`processEffectiveBalanceUpdates`](./state_processor.go#L491)\n\n## Validator lifecycle\n\nValidators are created by a deposit made to the deposit contract, as soon as the corresponding event is emitted.\n\nSay a deposit is made at slot `S`, epoch `N`, that creates a validator.\n\nThe funds deposited will be locked and the validator will stay inactive until the a minimum staking balance is hit. The minimum staking balance is set to `EjectionBalance + EffectiveBalanceIncrement` to account for hysteresys. However if the active validator set has already reached the `ValidatorSetCap`, a new prospective validator must deposit more funds than the effective balance of the active validator with the lowest stake.\n\nSo let's assumed that `S`, epoch `N`, is the slot where finally the validator `Balance` equals the minimum required for staking (one or multiple deposits may have been done to get there). Then:\n\n- The validator is marked as `EligibleForActivationQueue` as soon as epoch `N+1` starts. This is guaranteed since there is no cap on the activation queue size.\n- The validator is marked as active as soon as epoch `N+2` starts. However\n  - if the size of validator set goes beyond the `ValidatorSetCap` enough validators with the lowest stake are marked for eviction, to make the cap be fullfilled. Validators are sorted by increasing `EffectiveBalance` and ties are broken ordering their pub keys alphabetically.\n- BeaconKit does not currently support voluntary withdrawals, nor slashing or inactivity leaks. Therefore a validator keeps validating indefinitely.\n  - The only case in which a validator may be evicted from the validator set (and its funds returned) is when `ValidatorSetCap` is hit and a validator with greater priority is added (i.e. with larger `EffectiveBalance` or equal `EffectiveBalance` and larger PubKey in alphabetical order).\n- Once a validator is marked as active, `CometBFT` consensus will reach it out for block proposals, validations and voting. The higher a validator `EffectiveBalance`, the higher its voting power the frequency it is polled for block proposal.\n\nNow say the validator is marked for exit (i.e. a result of validator set cap being hit or a full withdrawal request), at epoch `M`. Then its funds will be fully withdrawn at epoch `M+MinValidatorWithdrawabilityDelay` during and after electra, at epoch `M+1` before electra. BeaconKit does not currently enforce a cap on validators churn.\n"
  },
  {
    "path": "state-transition/core/core_test.go",
    "content": "//go:build test\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core_test\n\nimport (\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\tgethtypes \"github.com/berachain/beacon-kit/gethlib/types\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/berachain/beacon-kit/state-transition/core\"\n\tstatetransition \"github.com/berachain/beacon-kit/testing/state-transition\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc setupChain(t *testing.T) chain.Spec {\n\tt.Helper()\n\tchainSpec, err := spec.DevnetChainSpec()\n\trequire.NoError(t, err)\n\treturn chainSpec\n}\n\n//nolint:unused // may be used in the future.\nfunc progressStateToSlot(\n\tt *testing.T,\n\tbeaconState *statetransition.TestBeaconStateT,\n\tslot math.U64,\n) {\n\tt.Helper()\n\n\tif slot == math.U64(0) {\n\t\tt.Fatal(\"for genesis slot, use InitializeBeaconStateFromEth1\")\n\t}\n\n\terr := beaconState.SetSlot(slot)\n\trequire.NoError(t, err)\n\terr = beaconState.SetLatestBlockHeader(types.NewBeaconBlockHeader(\n\t\tslot,\n\t\tmath.U64(0),\n\t\tcommon.Root{},\n\t\tcommon.Root{},\n\t\tcommon.Root{},\n\t))\n\trequire.NoError(t, err)\n}\n\nfunc buildNextBlock(\n\tt *testing.T,\n\tcs chain.Spec,\n\tbeaconState *statetransition.TestBeaconStateT,\n\teth1Data *types.Eth1Data,\n\ttimestamp math.U64,\n\tblockDeposits types.Deposits,\n\texecutionRequests *types.ExecutionRequests,\n\twithdrawals ...*engineprimitives.Withdrawal,\n) *types.BeaconBlock {\n\tt.Helper()\n\trequire.NotNil(t, cs)\n\t// first update state root, similarly to what we do in processSlot\n\tparentBlkHeader, err := beaconState.GetLatestBlockHeader()\n\trequire.NoError(t, err)\n\troot := beaconState.HashTreeRoot()\n\tparentBlkHeader.SetStateRoot(root)\n\n\t// build the block\n\tfv := cs.ActiveForkVersionForTimestamp(timestamp)\n\tversionable := types.NewVersionable(fv)\n\tblk, err := types.NewBeaconBlockWithVersion(\n\t\tparentBlkHeader.GetSlot()+1,\n\t\tparentBlkHeader.GetProposerIndex(),\n\t\tparentBlkHeader.HashTreeRoot(),\n\t\tfv,\n\t)\n\trequire.NoError(t, err)\n\n\t// build the payload\n\tpayload := &types.ExecutionPayload{\n\t\tVersionable:   versionable,\n\t\tTimestamp:     timestamp,\n\t\tExtraData:     []byte(\"testing\"),\n\t\tTransactions:  [][]byte{},\n\t\tWithdrawals:   withdrawals,\n\t\tBaseFeePerGas: math.NewU256(0),\n\t}\n\tparentBeaconBlockRoot := parentBlkHeader.HashTreeRoot()\n\n\tvar ethBlk *gethtypes.Block\n\tif version.IsBefore(fv, version.Electra()) {\n\t\tethBlk, _, err = types.MakeEthBlock(payload, parentBeaconBlockRoot, nil, nil)\n\t\trequire.NoError(t, err)\n\t} else {\n\t\tencodedER, erErr := types.GetExecutionRequestsList(executionRequests)\n\t\trequire.NoError(t, erErr)\n\t\trequire.NotNil(t, encodedER)\n\n\t\tparentProposerPubkey, errPk := beaconState.ParentProposerPubkey(timestamp)\n\t\trequire.NoError(t, errPk)\n\n\t\tethBlk, _, err = types.MakeEthBlock(payload, parentBeaconBlockRoot, encodedER, parentProposerPubkey)\n\t\trequire.NoError(t, err)\n\t}\n\tpayload.BlockHash = common.ExecutionHash(ethBlk.Hash())\n\n\trequire.NoError(t, err)\n\tblk.Body = &types.BeaconBlockBody{\n\t\tVersionable:      versionable,\n\t\tExecutionPayload: payload,\n\t\tEth1Data:         eth1Data,\n\t\tDeposits:         blockDeposits,\n\t}\n\tif version.EqualsOrIsAfter(fv, version.Electra()) {\n\t\terr = blk.Body.SetExecutionRequests(executionRequests)\n\t\trequire.NoError(t, err)\n\t}\n\treturn blk\n}\n\nfunc generateTestExecutionAddress(\n\tt *testing.T,\n\trndSeed int,\n) (types.WithdrawalCredentials, int) {\n\tt.Helper()\n\n\taddrStr := strconv.Itoa(rndSeed)\n\taddrBytes := bytes.ExtendToSize([]byte(addrStr), bytes.B20Size)\n\texecAddr, err := bytes.ToBytes20(addrBytes)\n\trequire.NoError(t, err)\n\trndSeed++\n\treturn types.NewCredentialsFromExecutionAddress(\n\t\tcommon.ExecutionAddress(execAddr),\n\t), rndSeed\n}\n\nfunc generateTestPK(t *testing.T, rndSeed int) (bytes.B48, int) {\n\tt.Helper()\n\tkeyStr := strconv.Itoa(rndSeed)\n\tkeyBytes := bytes.ExtendToSize([]byte(keyStr), bytes.B48Size)\n\tkey, err := bytes.ToBytes48(keyBytes)\n\trequire.NoError(t, err)\n\trndSeed++\n\treturn key, rndSeed\n}\n\nfunc moveToEndOfEpoch(\n\tt *testing.T,\n\ttip *types.BeaconBlock,\n\tcs chain.Spec,\n\tsp *statetransition.TestStateProcessorT,\n\tst *statetransition.TestBeaconStateT,\n\tctx core.ReadOnlyContext,\n\tdepRoot common.Root,\n) *types.BeaconBlock {\n\tt.Helper()\n\tblk := tip\n\tcurrEpoch := cs.SlotToEpoch(blk.GetSlot())\n\tfor currEpoch == cs.SlotToEpoch(blk.GetSlot()+1) {\n\t\ttimestamp := blk.Body.ExecutionPayload.Timestamp + 1\n\t\tblk = buildNextBlock(\n\t\t\tt,\n\t\t\tcs,\n\t\t\tst,\n\t\t\ttypes.NewEth1Data(depRoot),\n\t\t\ttimestamp,\n\t\t\t[]*types.Deposit{},\n\t\t\t&types.ExecutionRequests{},\n\t\t\tst.EVMInflationWithdrawal(timestamp),\n\t\t)\n\n\t\tvals, err := sp.Transition(ctx, st, blk)\n\t\trequire.NoError(t, err)\n\t\trequire.Empty(t, vals) // no vals changes expected before next epoch\n\t}\n\treturn blk\n}\n"
  },
  {
    "path": "state-transition/core/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core\n\nimport \"github.com/berachain/beacon-kit/errors\"\n\nvar (\n\t// ErrValSetCapExceeded is returned when the number of genesis deposits\n\t// exceeds the validator set cap.\n\tErrValSetCapExceeded = errors.New(\"validator set cap exceeded at genesis\")\n\n\t// ErrBlockSlotTooLow is returned when the block slot is too low.\n\tErrBlockSlotTooLow = errors.New(\"block slot too low\")\n\n\t// ErrSlotMismatch is returned when the slot in a block header does not\n\t// match the expected value.\n\tErrSlotMismatch = errors.New(\"slot mismatch\")\n\n\t// ErrProposerMismatch is returned when block builder does not match\n\t// with the proposer reported by consensus.\n\tErrProposerMismatch = errors.New(\"proposer key mismatch\")\n\n\tErrDepositsRootMismatch = errors.New(\"deposits root mismatch\")\n\n\t// ErrDepositsLengthMismatch is returned when length of deposits\n\t// listed in block is different from deposits from store.\n\tErrDepositsLengthMismatch = errors.New(\"deposits lengths mismatched\")\n\n\t// ErrDepositMismatch is returned when a specific deposit listed in\n\t// block is different from the correspondent one from store.\n\tErrDepositMismatch = errors.New(\"deposit mismatched\")\n\n\t// ErrDepositIndexOutOfOrder is returned when deposits are not in\n\t// contiguous order.\n\tErrDepositIndexOutOfOrder = errors.New(\"deposit index out of order\")\n\n\t// ErrParentRootMismatch is returned when the parent root in an execution\n\t// payload does not match the expected value.\n\tErrParentRootMismatch = errors.New(\"parent root mismatch\")\n\n\t// ErrParentPayloadHashMismatch is returned when the parent hash of an\n\t// execution payload does not match the expected value.\n\tErrParentPayloadHashMismatch = errors.New(\"payload parent hash mismatch\")\n\n\t// ErrRandaoMixMismatch is returned when the randao mix in an execution\n\t// payload does not match the expected value.\n\tErrRandaoMixMismatch = errors.New(\"randao mix mismatch\")\n\n\t// ErrExceedsBlockDepositLimit is returned when the block exceeds the\n\t// deposit limit.\n\tErrExceedsBlockDepositLimit = errors.New(\"block exceeds deposit limit\")\n\n\t// ErrRewardsLengthMismatch is returned when the length of the rewards\n\t// in a block does not match the expected value.\n\tErrRewardsLengthMismatch = errors.New(\"rewards length mismatch\")\n\n\t// ErrPenaltiesLengthMismatch is returned when the length of the penalties\n\t// in a block does not match the expected value.\n\tErrPenaltiesLengthMismatch = errors.New(\"penalties length mismatch\")\n\n\t// ErrExceedsBlockBlobLimit is returned when the block exceeds the blob\n\t// limit.\n\tErrExceedsBlockBlobLimit = errors.New(\"block exceeds blob limit\")\n\n\t// ErrSlashedProposer is returned when a block is processed in which\n\t// the proposer is slashed.\n\tErrSlashedProposer = errors.New(\n\t\t\"attempted to process a block with a slashed proposer\")\n\n\t// ErrStateRootMismatch is returned when the state root in a block header\n\t// does not match the expected value.\n\tErrStateRootMismatch = errors.New(\"state root mismatch\")\n\n\t// ErrExceedMaximumWithdrawals is returned when the number of withdrawals\n\t// in a block exceeds the maximum allowed.\n\tErrExceedMaximumWithdrawals = errors.New(\"exceeds maximum withdrawals\")\n\n\t// ErrZeroWithdrawals is returned when the number of withdrawals in a\n\t// block is zero. At least the EVM inflation withdrawal is always expected.\n\tErrZeroWithdrawals = errors.New(\"zero withdrawals\")\n\n\t// ErrNumWithdrawalsMismatch is returned when the number of withdrawals\n\t// in a block does not match the expected value.\n\tErrNumWithdrawalsMismatch = errors.New(\"number of withdrawals mismatch\")\n\n\t// ErrFirstWithdrawalNotEVMInflation is returned when the first withdrawal\n\t// in a block is not the EVM inflation withdrawal.\n\tErrFirstWithdrawalNotEVMInflation = errors.New(\n\t\t\"first withdrawal is not the EVM inflation withdrawal\",\n\t)\n\n\t// ErrWithdrawalMismatch is returned when the withdrawals in a payload do\n\t// not match the local state's expected value.\n\tErrWithdrawalMismatch = errors.New(\n\t\t\"withdrawal mismatch between local state and payload\")\n)\n"
  },
  {
    "path": "state-transition/core/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core\n\nimport (\n\t\"context\"\n\n\t\"github.com/berachain/beacon-kit/chain\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/delay\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\ntype ReadOnlyBeaconState interface {\n\tGetLatestExecutionPayloadHeader() (*ctypes.ExecutionPayloadHeader, error)\n\tGetSlot() (math.Slot, error)\n\tGetEpoch() (math.Epoch, error)\n\tGetRandaoMixAtIndex(uint64) (common.Bytes32, error)\n}\n\n// ReadOnlyContext defines an interface for managing state transition context.\ntype ReadOnlyContext interface {\n\tConsensusCtx() context.Context\n\tConsensusTime() math.U64\n\tProposerAddress() []byte\n\tVerifyPayload() bool\n\tVerifyRandao() bool\n\tVerifyResult() bool\n\tMeterGas() bool\n}\n\n// ExecutionEngine is the interface for the execution engine.\ntype ExecutionEngine interface {\n\tNotifyForkchoiceUpdate( // added to simplify mocks\n\t\tctx context.Context,\n\t\treq *ctypes.ForkchoiceUpdateRequest,\n\t) (*engineprimitives.PayloadID, error)\n\t// NotifyNewPayload notifies the execution client of the new payload.\n\tNotifyNewPayload(\n\t\tctx context.Context,\n\t\treq ctypes.NewPayloadRequest,\n\t\tretryOnSyncingStatus bool,\n\t) error\n}\n\n// TelemetrySink is an interface for sending metrics to a telemetry backend.\ntype TelemetrySink interface {\n\tSetGauge(key string, value int64, args ...string)\n\t// IncrementCounter increments the counter identified by\n\t// the provided key.\n\tIncrementCounter(key string, args ...string)\n}\n\ntype ChainSpec interface {\n\tchain.HysteresisSpec\n\tchain.BalancesSpec\n\tchain.DepositSpec\n\tchain.ForkSpec\n\tchain.DomainTypeSpec\n\tchain.WithdrawalsSpec\n\tdelay.ConfigGetter\n\n\tSlotsPerEpoch() uint64\n\tSlotToEpoch(slot math.Slot) math.Epoch\n\tSlotsPerHistoricalRoot() uint64\n\tEpochsPerHistoricalVector() uint64\n\tGenesisForkVersion() common.Version\n\tActiveForkVersionForTimestamp(timestamp math.U64) common.Version\n\tValidatorSetCap() uint64\n\tHistoricalRootsLimit() uint64\n\tIsMainnet() bool\n}\n"
  },
  {
    "path": "state-transition/core/metrics.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\ntype stateProcessorMetrics struct {\n\t// sink is the sink for the metrics.\n\tsink TelemetrySink\n}\n\n// newStateProcessorMetrics creates a new stateProcessorMetrics.\nfunc newStateProcessorMetrics(sink TelemetrySink) *stateProcessorMetrics {\n\treturn &stateProcessorMetrics{\n\t\tsink: sink,\n\t}\n}\n\nfunc (s *stateProcessorMetrics) gaugeBlockGasUsed(blockNumber, txGasUsed, blobGasUsed math.U64) {\n\tblockNumberStr := blockNumber.Base10()\n\ts.sink.SetGauge(\n\t\t\"beacon_kit.state.block_tx_gas_used\",\n\t\tint64(txGasUsed.Unwrap()), // #nosec G115\n\t\t\"block_number\",\n\t\tblockNumberStr,\n\t)\n\ts.sink.SetGauge(\n\t\t\"beacon_kit.state.block_blob_gas_used\",\n\t\tint64(blobGasUsed.Unwrap()), // #nosec G115\n\t\t\"block_number\",\n\t\tblockNumberStr,\n\t)\n}\n\nfunc (s *stateProcessorMetrics) gaugePartialWithdrawalsEnqueued(count int) {\n\ts.sink.SetGauge(\"beacon_kit.state.partial_withdrawals_enqueued\", int64(count))\n}\n\nfunc (s *stateProcessorMetrics) gaugeTimestamps(payloadTimestamp, consensusTimestamp uint64) {\n\t// the diff can be positive or negative depending on whether the payload\n\t// timestamp is ahead or behind the consensus timestamp\n\tdiff := int64(payloadTimestamp) - int64(consensusTimestamp) // #nosec G115\n\ts.sink.SetGauge(\"beacon_kit.state.payload_consensus_timestamp_diff\", diff)\n}\n\nfunc (s *stateProcessorMetrics) incrementDepositStakeLost() {\n\ts.sink.IncrementCounter(\"beacon_kit.state.deposit_stake_lost\")\n}\n\nfunc (s *stateProcessorMetrics) incrementPartialWithdrawalRequestDropped() {\n\ts.sink.IncrementCounter(\"beacon_kit.state.partial_withdrawal_request_dropped\")\n}\n\nfunc (s *stateProcessorMetrics) incrementPartialWithdrawalRequestInvalid() {\n\ts.sink.IncrementCounter(\"beacon_kit.state.partial_withdrawal_request_invalid\")\n}\n\nfunc (s *stateProcessorMetrics) incrementValidatorNotWithdrawable() {\n\ts.sink.IncrementCounter(\"beacon_kit.state.validator_not_withdrawable\")\n}\n"
  },
  {
    "path": "state-transition/core/mocks/execution_engine.mock.go",
    "content": "// Code generated by mockery v2.53.5. DO NOT EDIT.\n\npackage mocks\n\nimport (\n\tcontext \"context\"\n\n\ttypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\tmock \"github.com/stretchr/testify/mock\"\n)\n\n// ExecutionEngine is an autogenerated mock type for the ExecutionEngine type\ntype ExecutionEngine struct {\n\tmock.Mock\n}\n\ntype ExecutionEngine_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *ExecutionEngine) EXPECT() *ExecutionEngine_Expecter {\n\treturn &ExecutionEngine_Expecter{mock: &_m.Mock}\n}\n\n// NotifyForkchoiceUpdate provides a mock function with given fields: ctx, req\nfunc (_m *ExecutionEngine) NotifyForkchoiceUpdate(ctx context.Context, req *types.ForkchoiceUpdateRequest) (*engineprimitives.PayloadID, error) {\n\tret := _m.Called(ctx, req)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for NotifyForkchoiceUpdate\")\n\t}\n\n\tvar r0 *engineprimitives.PayloadID\n\tvar r1 error\n\tif rf, ok := ret.Get(0).(func(context.Context, *types.ForkchoiceUpdateRequest) (*engineprimitives.PayloadID, error)); ok {\n\t\treturn rf(ctx, req)\n\t}\n\tif rf, ok := ret.Get(0).(func(context.Context, *types.ForkchoiceUpdateRequest) *engineprimitives.PayloadID); ok {\n\t\tr0 = rf(ctx, req)\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).(*engineprimitives.PayloadID)\n\t\t}\n\t}\n\n\tif rf, ok := ret.Get(1).(func(context.Context, *types.ForkchoiceUpdateRequest) error); ok {\n\t\tr1 = rf(ctx, req)\n\t} else {\n\t\tr1 = ret.Error(1)\n\t}\n\n\treturn r0, r1\n}\n\n// ExecutionEngine_NotifyForkchoiceUpdate_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'NotifyForkchoiceUpdate'\ntype ExecutionEngine_NotifyForkchoiceUpdate_Call struct {\n\t*mock.Call\n}\n\n// NotifyForkchoiceUpdate is a helper method to define mock.On call\n//   - ctx context.Context\n//   - req *types.ForkchoiceUpdateRequest\nfunc (_e *ExecutionEngine_Expecter) NotifyForkchoiceUpdate(ctx interface{}, req interface{}) *ExecutionEngine_NotifyForkchoiceUpdate_Call {\n\treturn &ExecutionEngine_NotifyForkchoiceUpdate_Call{Call: _e.mock.On(\"NotifyForkchoiceUpdate\", ctx, req)}\n}\n\nfunc (_c *ExecutionEngine_NotifyForkchoiceUpdate_Call) Run(run func(ctx context.Context, req *types.ForkchoiceUpdateRequest)) *ExecutionEngine_NotifyForkchoiceUpdate_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(context.Context), args[1].(*types.ForkchoiceUpdateRequest))\n\t})\n\treturn _c\n}\n\nfunc (_c *ExecutionEngine_NotifyForkchoiceUpdate_Call) Return(_a0 *engineprimitives.PayloadID, _a1 error) *ExecutionEngine_NotifyForkchoiceUpdate_Call {\n\t_c.Call.Return(_a0, _a1)\n\treturn _c\n}\n\nfunc (_c *ExecutionEngine_NotifyForkchoiceUpdate_Call) RunAndReturn(run func(context.Context, *types.ForkchoiceUpdateRequest) (*engineprimitives.PayloadID, error)) *ExecutionEngine_NotifyForkchoiceUpdate_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NotifyNewPayload provides a mock function with given fields: ctx, req, retryOnSyncingStatus\nfunc (_m *ExecutionEngine) NotifyNewPayload(ctx context.Context, req types.NewPayloadRequest, retryOnSyncingStatus bool) error {\n\tret := _m.Called(ctx, req, retryOnSyncingStatus)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for NotifyNewPayload\")\n\t}\n\n\tvar r0 error\n\tif rf, ok := ret.Get(0).(func(context.Context, types.NewPayloadRequest, bool) error); ok {\n\t\tr0 = rf(ctx, req, retryOnSyncingStatus)\n\t} else {\n\t\tr0 = ret.Error(0)\n\t}\n\n\treturn r0\n}\n\n// ExecutionEngine_NotifyNewPayload_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'NotifyNewPayload'\ntype ExecutionEngine_NotifyNewPayload_Call struct {\n\t*mock.Call\n}\n\n// NotifyNewPayload is a helper method to define mock.On call\n//   - ctx context.Context\n//   - req types.NewPayloadRequest\n//   - retryOnSyncingStatus bool\nfunc (_e *ExecutionEngine_Expecter) NotifyNewPayload(ctx interface{}, req interface{}, retryOnSyncingStatus interface{}) *ExecutionEngine_NotifyNewPayload_Call {\n\treturn &ExecutionEngine_NotifyNewPayload_Call{Call: _e.mock.On(\"NotifyNewPayload\", ctx, req, retryOnSyncingStatus)}\n}\n\nfunc (_c *ExecutionEngine_NotifyNewPayload_Call) Run(run func(ctx context.Context, req types.NewPayloadRequest, retryOnSyncingStatus bool)) *ExecutionEngine_NotifyNewPayload_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].(context.Context), args[1].(types.NewPayloadRequest), args[2].(bool))\n\t})\n\treturn _c\n}\n\nfunc (_c *ExecutionEngine_NotifyNewPayload_Call) Return(_a0 error) *ExecutionEngine_NotifyNewPayload_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *ExecutionEngine_NotifyNewPayload_Call) RunAndReturn(run func(context.Context, types.NewPayloadRequest, bool) error) *ExecutionEngine_NotifyNewPayload_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewExecutionEngine creates a new instance of ExecutionEngine. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewExecutionEngine(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *ExecutionEngine {\n\tmock := &ExecutionEngine{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "state-transition/core/state/constants.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage state\n\nimport (\n\t\"math\"\n)\n\nconst (\n\t// EVMInflationWithdrawalIndex is the fixed withdrawal index to be used for\n\t// the EVM inflation withdrawal in every block. It should remain unused\n\t// during processing.\n\tEVMInflationWithdrawalIndex = math.MaxUint64\n\n\t// EVMInflationWithdrawalValidatorIndex is the fixed validator index to be\n\t// used for the EVM inflation withdrawal in every block. It should remain\n\t// unused during processing.\n\tEVMInflationWithdrawalValidatorIndex = math.MaxUint64\n)\n"
  },
  {
    "path": "state-transition/core/state/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage state\n\nimport (\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\ntype ChainSpec interface {\n\tchain.BerachainSpec\n\tchain.WithdrawalsSpec\n\tSlotToEpoch(slot math.Slot) math.Epoch\n\tSlotsPerHistoricalRoot() uint64\n\tMaxEffectiveBalance() math.Gwei\n\tEpochsPerHistoricalVector() uint64\n\tActiveForkVersionForTimestamp(timestamp math.U64) common.Version\n\tMinActivationBalance() math.Gwei\n}\n\n// TelemetrySink is an interface for sending metrics to a telemetry backend.\ntype TelemetrySink interface {\n\tIncrementCounter(key string, args ...string)\n}\n"
  },
  {
    "path": "state-transition/core/state/metrics.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage state\n\nfunc (s *StateDB) incrementPartialWithdrawalRequestInvalid() {\n\ts.telemetrySink.IncrementCounter(\"beacon_kit.statedb.partial_withdrawal_request_invalid\")\n}\n\n// incrementExcessStakePartialWithdrawal increments the telemetry counter when a withdrawal is created\n// because a validator's stake went over the MaxEffectiveBalance.\nfunc (s *StateDB) incrementExcessStakePartialWithdrawal() {\n\ts.telemetrySink.IncrementCounter(\"beacon_kit.statedb.excess_stake_partial_withdrawal\")\n}\n"
  },
  {
    "path": "state-transition/core/state/parent_proposer_pubkey.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage state\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n)\n\n// ParentProposerPubkey returns the parent proposer pubkey for the given timestamp.\n// It must return nil if we are before Electra1.\n//\n//nolint:nilnil // TODO: consider addressing this\nfunc (s *StateDB) ParentProposerPubkey(timestamp math.U64) (*crypto.BLSPubkey, error) {\n\tif version.IsBefore(s.cs.ActiveForkVersionForTimestamp(timestamp), version.Electra1()) {\n\t\treturn nil, nil\n\t}\n\n\tlatestBlockHeader, err := s.GetLatestBlockHeader()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed retrieving latest block header: %w\", err)\n\t}\n\tprevProposer, err := s.ValidatorByIndex(latestBlockHeader.GetProposerIndex())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed retrieving prev proposer: %w\", err)\n\t}\n\tp := prevProposer.GetPubkey()\n\treturn &p, nil\n}\n"
  },
  {
    "path": "state-transition/core/state/statedb.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage state\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/berachain/beacon-kit/storage/beacondb\"\n)\n\n// StateDB is the underlying struct behind the BeaconState interface.\n//\n//nolint:revive // todo fix somehow\ntype StateDB struct {\n\tbeacondb.KVStore\n\n\tcs            ChainSpec\n\tlogger        log.Logger\n\ttelemetrySink TelemetrySink\n}\n\n// NewBeaconStateFromDB creates a new beacon state from an underlying state db.\nfunc NewBeaconStateFromDB(\n\tbdb *beacondb.KVStore, cs ChainSpec, logger log.Logger, telemetrySink TelemetrySink,\n) *StateDB {\n\treturn &StateDB{\n\t\tKVStore:       *bdb,\n\t\tcs:            cs,\n\t\tlogger:        logger,\n\t\ttelemetrySink: telemetrySink,\n\t}\n}\n\n// Protect returns an almost copy of stateDB. Specifically Protect guarantees that:\n// - No changes done on the returned state will affect the original state\n// - However, changes done on the original state will be carried over to the returned state.\n// The behaviour is probably best understood by considering the context hosts a stack of cache layers.\n// So write operations to the top cache won't be flushed to the lower layer but read operations will walk\n// through the cache stack, so bubbling up changes from the lower layers to the top ones.\nfunc (s *StateDB) Protect(ctx context.Context) *StateDB {\n\treturn NewBeaconStateFromDB(s.KVStore.Copy(ctx), s.cs, s.logger, s.telemetrySink)\n}\n\n// GetEpoch returns the current epoch.\nfunc (s *StateDB) GetEpoch() (math.Epoch, error) {\n\tslot, err := s.GetSlot()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn s.cs.SlotToEpoch(slot), nil\n}\n\n// IncreaseBalance increases the balance of a validator.\nfunc (s *StateDB) IncreaseBalance(idx math.ValidatorIndex, delta math.Gwei) error {\n\tbalance, err := s.GetBalance(idx)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn s.SetBalance(idx, balance+delta)\n}\n\n// DecreaseBalance decreases the balance of a validator.\nfunc (s *StateDB) DecreaseBalance(idx math.ValidatorIndex, delta math.Gwei) error {\n\tbalance, err := s.GetBalance(idx)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn s.SetBalance(idx, balance-min(balance, delta))\n}\n\n// ExpectedWithdrawals is modified from the ETH2.0 spec:\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/electra/beacon-chain.md#new-get_expected_withdrawals\n// to allow a fixed withdrawal (as the first withdrawal) used for EVM inflation.\n//\n// NOTE for caller: ProcessSlots must be called before this function as the \"current\" slot is\n// retrieved from the state in this function.\n//\n//nolint:gocognit,funlen // Spec aligned.\nfunc (s *StateDB) ExpectedWithdrawals(timestamp math.U64) (engineprimitives.Withdrawals, uint64, error) {\n\tvar (\n\t\tvalidator         *ctypes.Validator\n\t\tbalance           math.Gwei\n\t\twithdrawalAddress common.ExecutionAddress\n\t)\n\n\tprocessedPartialWithdrawals := uint64(0)\n\n\tepoch, err := s.GetEpoch()\n\tif err != nil {\n\t\treturn nil, 0, err\n\t}\n\tmaxWithdrawals := s.cs.MaxWithdrawalsPerPayload()\n\twithdrawals := make([]*engineprimitives.Withdrawal, 0, maxWithdrawals)\n\n\t// The first withdrawal is fixed to be the EVM inflation withdrawal.\n\twithdrawals = append(withdrawals, s.EVMInflationWithdrawal(timestamp))\n\n\twithdrawalIndex, err := s.GetNextWithdrawalIndex()\n\tif err != nil {\n\t\treturn nil, 0, err\n\t}\n\n\tvalidatorIndex, err := s.GetNextWithdrawalValidatorIndex()\n\tif err != nil {\n\t\treturn nil, 0, err\n\t}\n\n\ttotalValidators, err := s.GetTotalValidators()\n\tif err != nil {\n\t\treturn nil, 0, err\n\t}\n\n\t// [New in Electra:EIP7251] Consume pending partial withdrawals\n\tforkVersion := s.cs.ActiveForkVersionForTimestamp(timestamp)\n\tif version.EqualsOrIsAfter(forkVersion, version.Electra()) {\n\t\twithdrawals, withdrawalIndex, processedPartialWithdrawals, err =\n\t\t\ts.consumePendingPartialWithdrawals(epoch, withdrawals, withdrawalIndex)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t}\n\n\tbound := min(totalValidators, s.cs.MaxValidatorsPerWithdrawalsSweep())\n\n\t// Iterate through indices to find the next validators to withdraw.\n\tfor range bound {\n\t\tvalidator, err = s.ValidatorByIndex(validatorIndex)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\n\t\tbalance, err = s.GetBalance(validatorIndex)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\n\t\tif version.EqualsOrIsAfter(forkVersion, version.Electra()) {\n\t\t\tvar totalWithdrawn math.Gwei\n\t\t\tfor _, withdrawal := range withdrawals {\n\t\t\t\tif withdrawal.Validator == validatorIndex {\n\t\t\t\t\ttotalWithdrawn += withdrawal.Amount\n\t\t\t\t}\n\t\t\t}\n\t\t\t// After electra, partiallyWithdrawnBalance can be non-zero, which we must account for.\n\t\t\tbalance -= totalWithdrawn\n\t\t}\n\n\t\t// Set the amount of the withdrawal depending on the balance of the validator.\n\t\tif validator.IsFullyWithdrawable(balance, epoch) {\n\t\t\twithdrawalAddress, err = validator.GetWithdrawalCredentials().ToExecutionAddress()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, 0, err\n\t\t\t}\n\n\t\t\twithdrawals = append(withdrawals, engineprimitives.NewWithdrawal(\n\t\t\t\tmath.U64(withdrawalIndex),\n\t\t\t\tvalidatorIndex,\n\t\t\t\twithdrawalAddress,\n\t\t\t\tbalance,\n\t\t\t))\n\n\t\t\t// Increment the withdrawal index to process the next withdrawal.\n\t\t\twithdrawalIndex++\n\t\t} else if validator.IsPartiallyWithdrawable(balance, s.cs.MaxEffectiveBalance()) {\n\t\t\twithdrawalAddress, err = validator.GetWithdrawalCredentials().ToExecutionAddress()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, 0, err\n\t\t\t}\n\n\t\t\twithdrawals = append(withdrawals, engineprimitives.NewWithdrawal(\n\t\t\t\tmath.U64(withdrawalIndex),\n\t\t\t\tvalidatorIndex,\n\t\t\t\twithdrawalAddress,\n\t\t\t\tbalance-s.cs.MaxEffectiveBalance(),\n\t\t\t))\n\n\t\t\ts.logger.Info(\"expectedWithdrawals: validator withdrawal due to excess balance\",\n\t\t\t\t\"validator_pubkey\", validator.GetPubkey().String(),\n\t\t\t\t\"balance\", balance,\n\t\t\t\t\"effective_balance\", validator.GetEffectiveBalance(),\n\t\t\t\t\"exit_epoch\", validator.GetExitEpoch(),\n\t\t\t\t\"withdrawal_credentials\", validator.GetWithdrawalCredentials().String(),\n\t\t\t)\n\t\t\ts.incrementExcessStakePartialWithdrawal()\n\n\t\t\t// Increment the withdrawal index to process the next withdrawal.\n\t\t\twithdrawalIndex++\n\t\t}\n\n\t\t// Cap the number of withdrawals to the maximum allowed per payload.\n\t\tif uint64(len(withdrawals)) == maxWithdrawals {\n\t\t\tbreak\n\t\t}\n\n\t\t// Increment the validator index to process the next validator.\n\t\tvalidatorIndex = (validatorIndex + 1) % totalValidators\n\t}\n\n\treturn withdrawals, processedPartialWithdrawals, nil\n}\n\n//nolint:gocognit // Spec aligned.\nfunc (s *StateDB) consumePendingPartialWithdrawals(\n\tepoch math.Epoch,\n\twithdrawals engineprimitives.Withdrawals,\n\twithdrawalIndex uint64,\n) (\n\tengineprimitives.Withdrawals,\n\tuint64, // withdrawalIndex\n\tuint64, // processedPartialWithdrawals\n\terror,\n) {\n\t// By this point, if we're post-Electra, the fork version on the BeaconState will have been set as part of `PrepareStateForFork`.\n\t// This will fail if the state has not been prepared for a post-Electra fork version.\n\tppWithdrawals, getErr := s.GetPendingPartialWithdrawals()\n\tif getErr != nil {\n\t\treturn nil, 0, 0, fmt.Errorf(\"consumePendingPartialWithdrawals: failed retrieving pending partial withdrawals: %w\", getErr)\n\t}\n\n\tprocessedPartialWithdrawals := uint64(0)\n\tminActivationBalance := s.cs.MinActivationBalance()\n\n\tfor _, withdrawal := range ppWithdrawals {\n\t\tif withdrawal.WithdrawableEpoch > epoch || len(withdrawals) == constants.MaxPendingPartialsPerWithdrawalsSweep {\n\t\t\t// If the first withdrawal in the queue is not withdrawable, then all subsequent withdrawals will also be in later\n\t\t\t// epochs and hence are not withdrawable, so we can break early.\n\t\t\ts.logger.Debug(\"consumePendingPartialWithdrawals: early break for partial withdrawals\",\n\t\t\t\t\"current_epoch\", epoch,\n\t\t\t\t\"next_withdrawable_epoch\", withdrawal.WithdrawableEpoch,\n\t\t\t)\n\t\t\tbreak\n\t\t}\n\n\t\tvalidator, err := s.ValidatorByIndex(withdrawal.ValidatorIndex)\n\t\tif err != nil {\n\t\t\treturn nil, 0, 0, err\n\t\t}\n\t\thasSufficientEffectiveBalance := validator.GetEffectiveBalance() >= minActivationBalance\n\t\tbalance, err := s.GetBalance(withdrawal.ValidatorIndex)\n\t\tif err != nil {\n\t\t\treturn nil, 0, 0, err\n\t\t}\n\n\t\tvar totalWithdrawn math.Gwei\n\t\tfor _, w := range withdrawals {\n\t\t\tif w.Validator == withdrawal.ValidatorIndex {\n\t\t\t\ttotalWithdrawn += w.Amount\n\t\t\t}\n\t\t}\n\t\tbalance -= totalWithdrawn\n\n\t\thasExcessBalance := balance > minActivationBalance\n\t\tisWithdrawable := validator.GetExitEpoch() == constants.FarFutureEpoch && hasSufficientEffectiveBalance && hasExcessBalance\n\t\tif isWithdrawable {\n\t\t\t// A validator can only partial withdraw an amount such that:\n\t\t\t// 1. never withdraw more than what the validator asked for.\n\t\t\t// 2. never withdraw so much that the validator’s remaining balance would drop below MIN_ACTIVATION_BALANCE.\n\t\t\twithdrawableBalance := min(balance-minActivationBalance, withdrawal.Amount)\n\n\t\t\twithdrawalAddress, addrErr := validator.WithdrawalCredentials.ToExecutionAddress()\n\t\t\tif addrErr != nil {\n\t\t\t\treturn nil, 0, 0, addrErr\n\t\t\t}\n\t\t\twithdrawals = append(\n\t\t\t\twithdrawals,\n\t\t\t\tengineprimitives.NewWithdrawal(\n\t\t\t\t\tmath.U64(withdrawalIndex),\n\t\t\t\t\twithdrawal.ValidatorIndex,\n\t\t\t\t\twithdrawalAddress,\n\t\t\t\t\twithdrawableBalance,\n\t\t\t\t),\n\t\t\t)\n\t\t\t// Increment the withdrawal index to process the next withdrawal.\n\t\t\twithdrawalIndex++\n\t\t} else {\n\t\t\ts.logger.Info(\"consumePendingPartialWithdrawals: validator not withdrawable\",\n\t\t\t\t\"validator_index\", withdrawal.ValidatorIndex,\n\t\t\t\t\"validator_pubkey\", validator.GetPubkey().String(),\n\t\t\t\t\"balance\", balance,\n\t\t\t\t\"effective_balance\", validator.GetEffectiveBalance(),\n\t\t\t\t\"exit_epoch\", validator.GetExitEpoch(),\n\t\t\t\t\"withdrawable_epoch\", withdrawal.WithdrawableEpoch,\n\t\t\t)\n\t\t\ts.incrementPartialWithdrawalRequestInvalid()\n\t\t}\n\t\t// Even if a withdrawal was not created, e.g. the validator did not have sufficient balance, we will consider\n\t\t// this withdrawal processed (spec defined) and hence increment the processedPartialWithdrawals count.\n\t\tprocessedPartialWithdrawals++\n\t}\n\treturn withdrawals, withdrawalIndex, processedPartialWithdrawals, nil\n}\n\n// EVMInflationWithdrawal returns the withdrawal used for EVM balance inflation.\n//\n// NOTE: The withdrawal index and validator index are both set to max(uint64) as\n// they are not used during processing.\nfunc (s *StateDB) EVMInflationWithdrawal(timestamp math.U64) *engineprimitives.Withdrawal {\n\treturn engineprimitives.NewWithdrawal(\n\t\tEVMInflationWithdrawalIndex,\n\t\tEVMInflationWithdrawalValidatorIndex,\n\t\ts.cs.EVMInflationAddress(timestamp),\n\t\ts.cs.EVMInflationPerBlock(timestamp),\n\t)\n}\n\n// GetMarshallable is the interface for the beacon store.\n//\n//nolint:funlen,gocognit // todo fix somehow\nfunc (s *StateDB) GetMarshallable() (*ctypes.BeaconState, error) {\n\tslot, err := s.GetSlot()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfork, err := s.GetFork()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tgenesisValidatorsRoot, err := s.GetGenesisValidatorsRoot()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlatestBlockHeader, err := s.GetLatestBlockHeader()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tblockRoots := make([]common.Root, s.cs.SlotsPerHistoricalRoot())\n\tfor i := range s.cs.SlotsPerHistoricalRoot() {\n\t\tblockRoots[i], err = s.GetBlockRootAtIndex(i)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tstateRoots := make([]common.Root, s.cs.SlotsPerHistoricalRoot())\n\tfor i := range s.cs.SlotsPerHistoricalRoot() {\n\t\tstateRoots[i], err = s.StateRootAtIndex(i)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tlatestExecutionPayloadHeader, err := s.GetLatestExecutionPayloadHeader()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\teth1Data, err := s.GetEth1Data()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\teth1DepositIndex, err := s.GetEth1DepositIndex()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvalidators, err := s.GetValidators()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tbalances, err := s.GetBalances()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\trandaoMixes := make([]common.Bytes32, s.cs.EpochsPerHistoricalVector())\n\tfor i := range s.cs.EpochsPerHistoricalVector() {\n\t\trandaoMixes[i], err = s.GetRandaoMixAtIndex(i)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tnextWithdrawalIndex, err := s.GetNextWithdrawalIndex()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tnextWithdrawalValidatorIndex, err := s.GetNextWithdrawalValidatorIndex()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tslashings, err := s.GetSlashings()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttotalSlashings, err := s.GetTotalSlashing()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tbeaconState := ctypes.NewEmptyBeaconStateWithVersion(fork.CurrentVersion)\n\tbeaconState.Slot = slot\n\tbeaconState.GenesisValidatorsRoot = genesisValidatorsRoot\n\tbeaconState.Fork = fork\n\tbeaconState.LatestBlockHeader = latestBlockHeader\n\tbeaconState.BlockRoots = blockRoots\n\tbeaconState.StateRoots = stateRoots\n\tbeaconState.LatestExecutionPayloadHeader = latestExecutionPayloadHeader\n\tbeaconState.Eth1Data = eth1Data\n\tbeaconState.Eth1DepositIndex = eth1DepositIndex\n\tbeaconState.Validators = validators\n\tbeaconState.Balances = balances\n\tbeaconState.RandaoMixes = randaoMixes\n\tbeaconState.NextWithdrawalIndex = nextWithdrawalIndex\n\tbeaconState.NextWithdrawalValidatorIndex = nextWithdrawalValidatorIndex\n\tbeaconState.Slashings = slashings\n\tbeaconState.TotalSlashing = totalSlashings\n\n\tif version.EqualsOrIsAfter(beaconState.GetForkVersion(), version.Electra()) {\n\t\tpendingPartialWithdrawals, getErr := s.GetPendingPartialWithdrawals()\n\t\tif getErr != nil {\n\t\t\treturn nil, getErr\n\t\t}\n\t\tbeaconState.PendingPartialWithdrawals = pendingPartialWithdrawals\n\t}\n\n\treturn beaconState, nil\n}\n\n// HashTreeRoot is the interface for the beacon store.\nfunc (s *StateDB) HashTreeRoot() common.Root {\n\tst, err := s.GetMarshallable()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn st.HashTreeRoot()\n}\n"
  },
  {
    "path": "state-transition/core/state/statedb_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage state_test\n\nimport (\n\t\"testing\"\n\n\t\"cosmossdk.io/collections\"\n\t\"cosmossdk.io/log\"\n\t\"cosmossdk.io/store\"\n\tsdkmetrics \"cosmossdk.io/store/metrics\"\n\tstoretypes \"cosmossdk.io/store/types\"\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/node-core/components/metrics\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/state-transition/core/state\"\n\t\"github.com/berachain/beacon-kit/storage\"\n\t\"github.com/berachain/beacon-kit/storage/beacondb\"\n\t\"github.com/berachain/beacon-kit/storage/db\"\n\tdbm \"github.com/cosmos/cosmos-db\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestStateProtect(t *testing.T) {\n\tt.Parallel()\n\n\tdb, err := db.OpenDB(\"\", dbm.MemDBBackend)\n\trequire.NoError(t, err)\n\n\tcs, errSpec := spec.MainnetChainSpec()\n\trequire.NoError(t, errSpec)\n\n\tvar (\n\t\tnopLog     = log.NewNopLogger()\n\t\tnopMetrics = sdkmetrics.NewNoOpMetrics()\n\t)\n\n\tcms := store.NewCommitMultiStore(db, nopLog, nopMetrics)\n\tcms.MountStoreWithDB(testStoreKey, storetypes.StoreTypeIAVL, nil)\n\trequire.NoError(t, cms.LoadLatestVersion())\n\n\tbackendStoreService := &storage.KVStoreService{Key: testStoreKey}\n\tkvStore := beacondb.New(backendStoreService)\n\n\tms := cms.CacheMultiStore()\n\tsdkCtx := sdk.NewContext(ms, true, nopLog)\n\toriginalState := state.NewBeaconStateFromDB(\n\t\tkvStore.WithContext(sdkCtx),\n\t\tcs,\n\t\tsdkCtx.Logger(),\n\t\tmetrics.NewNoOpTelemetrySink(),\n\t)\n\n\tprotectingState := originalState.Protect(sdkCtx)\n\n\t// 1- set an attribute in the original state and show\n\t// that value is carried over the protecting state\n\twantSlot := math.Slot(1234)\n\trequire.NoError(t, originalState.SetSlot(wantSlot))\n\n\tgotSlot, err := protectingState.GetSlot()\n\trequire.NoError(t, err)\n\trequire.Equal(t, wantSlot, gotSlot)\n\n\t// 2- Show that modifying the protecting state\n\t// does not affect the original state\n\twantFork := &ctypes.Fork{\n\t\tPreviousVersion: common.Version{0x11, 0x22, 0x33, 0x44},\n\t\tCurrentVersion:  common.Version{0xff, 0xff, 0xff, 0xff},\n\t\tEpoch:           math.Epoch(1234),\n\t}\n\trequire.NoError(t, protectingState.SetFork(wantFork))\n\n\t_, err = originalState.GetFork()\n\trequire.ErrorIs(t, err, collections.ErrNotFound)\n\n\t// 3- Show that changes made to original state after protection\n\t// are carried over the protecting state\n\twantEthIdx := uint64(1987)\n\trequire.NoError(t, originalState.SetEth1DepositIndex(wantEthIdx))\n\n\tgotEthIdx, err := protectingState.GetEth1DepositIndex()\n\trequire.NoError(t, err)\n\trequire.Equal(t, wantEthIdx, gotEthIdx)\n}\n\nvar testStoreKey = storetypes.NewKVStoreKey(\"test-stateDB\")\n"
  },
  {
    "path": "state-transition/core/state_processor.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"sync\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/cache\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n\t\"github.com/berachain/beacon-kit/state-transition/core/state\"\n\t\"github.com/berachain/beacon-kit/storage/deposit\"\n)\n\n// StateProcessor is a basic Processor, which takes care of the\n// main state transition for the beacon chain.\ntype StateProcessor struct {\n\t// logger is used for logging information and errors.\n\tlogger log.Logger\n\t// cs is the chain specification for the beacon chain.\n\tcs ChainSpec\n\t// signer is the BLS signer used for cryptographic operations.\n\tsigner crypto.BLSSigner\n\t// fGetAddressFromPubKey verifies that a validator public key\n\t// matches with the proposer address passed by the consensus\n\t// Injected via ctor to simplify testing.\n\tfGetAddressFromPubKey func(crypto.BLSPubkey) ([]byte, error)\n\t// executionEngine is the engine responsible for executing transactions.\n\texecutionEngine ExecutionEngine\n\t// ds allows checking payload deposits against the deposit contract\n\tds deposit.StoreManager\n\t// metrics is the metrics for the service.\n\tmetrics *stateProcessorMetrics\n\t// logDeneb1Once enforces logging the Deneb1 fork information at most once.\n\tlogDeneb1Once sync.Once\n}\n\n// NewStateProcessor creates a new state processor.\nfunc NewStateProcessor(\n\tlogger log.Logger,\n\tcs ChainSpec,\n\texecutionEngine ExecutionEngine,\n\tds deposit.StoreManager,\n\tsigner crypto.BLSSigner,\n\tfGetAddressFromPubKey func(crypto.BLSPubkey) ([]byte, error),\n\ttelemetrySink TelemetrySink,\n) *StateProcessor {\n\treturn &StateProcessor{\n\t\tlogger:                logger,\n\t\tcs:                    cs,\n\t\texecutionEngine:       executionEngine,\n\t\tsigner:                signer,\n\t\tfGetAddressFromPubKey: fGetAddressFromPubKey,\n\t\tds:                    ds,\n\t\tmetrics:               newStateProcessorMetrics(telemetrySink),\n\t}\n}\n\n// Transition is the main function for processing a state transition.\nfunc (sp *StateProcessor) Transition(\n\tctx ReadOnlyContext,\n\tst *state.StateDB,\n\tblk *ctypes.BeaconBlock,\n) (transition.ValidatorUpdates, error) {\n\tif blk == nil {\n\t\treturn nil, nil\n\t}\n\n\t// Process the next slot.\n\tvalidatorUpdates, err := sp.ProcessSlots(st, blk.GetSlot())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Prepare the state for the next block's fork version.\n\t// Ideally we want to log only in case we are processing the\n\t// block to be finalized. Pre cache activation this is easy.\n\t// Post activation we log every time we verify a block\n\tlogForkProcessing := ctx.VerifyPayload() && !ctx.VerifyRandao()\n\n\tif cache.IsStateCachingActive(sp.cs, blk.Slot) {\n\t\tlogForkProcessing = ctx.VerifyPayload()\n\t}\n\tif err = sp.ProcessFork(st, blk.GetTimestamp(), logForkProcessing); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Process the block.\n\tif err = sp.ProcessBlock(ctx, st, blk); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn validatorUpdates, nil\n}\n\n// ProcessSlots deviates from the ethereum consensus specs `process_slots`. The `process_slots` function must\n// iterate and process slots in which the target `slot` can be several slots ahead of the `stateSlot`. This is because\n// the beacon chain can miss blocks for a given slot, resulting in not processing the slot. For example, the current\n// slot is 100, and no blocks were proposed for slots 101 and 102. Upon receiving a block at slot 103, the beacon state\n// must \"catch up\" the state and trigger slot and epoch transitions that may have happened during slot 101 and 102.\n//\n// Beacon-kit does not allow missed slots. Each height from cometBFT will always correspond to a beacon block slot, so\n// `ProcessSlots` will always be called at every slot. Thus, we will only process the state up to the next slot.\n// The reasoning behind this deviation is to be explicit in this behavior and also to better support the usage of fork\n// logic in the `processEpoch` function. Since we do not fork by slot but instead fork by timestamp, we must be able to\n// strictly tie each call of `processSlot` and `processEpoch` to a timestamp. Since we don't have beacon blocks during\n// each iteration of the slot loop, we cannot correlate each slot to a timestamp. We instead identify that we process\n// only one slot, allowing us to simply use the fork version from the state.\nfunc (sp *StateProcessor) ProcessSlots(\n\tst *state.StateDB, slot math.Slot,\n) (transition.ValidatorUpdates, error) {\n\tvar res transition.ValidatorUpdates\n\n\tstateSlot, err := st.GetSlot()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif slot == stateSlot {\n\t\treturn res, nil\n\t}\n\tif slot != stateSlot+1 {\n\t\treturn nil, fmt.Errorf(\"slot %d does not match expected slot %d\", slot, stateSlot+1)\n\t}\n\n\tif err = sp.processSlot(st); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Process the Epoch Boundary.\n\tif slot.Unwrap()%sp.cs.SlotsPerEpoch() == 0 {\n\t\tvar epochUpdates transition.ValidatorUpdates\n\t\tif epochUpdates, err = sp.processEpoch(st); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tres = append(res, epochUpdates...)\n\t}\n\n\t// Update the state slot.\n\tif err = st.SetSlot(slot); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn res, nil\n}\n\n// processSlot as defined in the Ethereum 2.0 Specification:\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#beacon-chain-state-transition-function\nfunc (sp *StateProcessor) processSlot(st *state.StateDB) error {\n\tstateSlot, err := st.GetSlot()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Before we make any changes, we calculate the previous state root.\n\tprevStateRoot := st.HashTreeRoot()\n\tif err = st.UpdateStateRootAtIndex(\n\t\tstateSlot.Unwrap()%sp.cs.SlotsPerHistoricalRoot(), prevStateRoot,\n\t); err != nil {\n\t\treturn err\n\t}\n\n\t// We get the latest block header, this will not have\n\t// a state root on it.\n\tlatestHeader, err := st.GetLatestBlockHeader()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// We set the \"rawHeader\" in the StateProcessor, but cannot fill in\n\t// the StateRoot until the following block.\n\tif (latestHeader.GetStateRoot() == common.Root{}) {\n\t\tlatestHeader.SetStateRoot(prevStateRoot)\n\t\tif err = st.SetLatestBlockHeader(latestHeader); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// We update the block root.\n\treturn st.UpdateBlockRootAtIndex(\n\t\tstateSlot.Unwrap()%sp.cs.SlotsPerHistoricalRoot(), latestHeader.HashTreeRoot(),\n\t)\n}\n\n// ProcessBlock processes the block, it optionally verifies the\n// state root.\nfunc (sp *StateProcessor) ProcessBlock(\n\tctx ReadOnlyContext,\n\tst *state.StateDB,\n\tblk *ctypes.BeaconBlock,\n) error {\n\t// Before processing block header, we need to retrieve public key of\n\t// parent block proposer to be able to inform the EL client.\n\tparentProposerPubkey, err := st.ParentProposerPubkey(blk.GetTimestamp())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err = sp.processBlockHeader(ctx, st, blk); err != nil {\n\t\treturn err\n\t}\n\n\tif err = sp.processExecutionPayload(ctx, st, blk, parentProposerPubkey); err != nil {\n\t\treturn err\n\t}\n\n\tif err = sp.processWithdrawals(st, blk); err != nil {\n\t\treturn err\n\t}\n\n\tif err = sp.processRandaoReveal(ctx, st, blk); err != nil {\n\t\treturn err\n\t}\n\n\tif err = sp.processOperations(ctx, st, blk); err != nil {\n\t\treturn err\n\t}\n\n\t// If we are skipping validate, we can skip calculating the state\n\t// root to save compute.\n\tif !ctx.VerifyResult() {\n\t\treturn nil\n\t}\n\n\t// Ensure the calculated state root matches the state root on\n\t// the block.\n\tstateRoot := st.HashTreeRoot()\n\tif blk.GetStateRoot() != stateRoot {\n\t\treturn errors.Wrapf(\n\t\t\tErrStateRootMismatch, \"expected %s, got %s\",\n\t\t\tstateRoot, blk.GetStateRoot(),\n\t\t)\n\t}\n\n\treturn nil\n}\n\n// processEpoch processes the epoch and ensures it matches the local state.\n// Currently, beacon-kit does not enforce rewards, penalties, and slashing for validators.\n// Extra caution is required when any fork-specific logic is added within the scope of this method\n// as epochs and fork slots may not always neatly overlap.\nfunc (sp *StateProcessor) processEpoch(st *state.StateDB) (transition.ValidatorUpdates, error) {\n\tcurrentEpoch, err := st.GetEpoch()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// track validators set before updating it, to be able to\n\t// inform consensus of the validators set changes\n\tcurrentActiveVals, err := getActiveVals(st, currentEpoch)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// if err = sp.processRewardsAndPenalties(st); err != nil {\n\t// \treturn nil, err\n\t// }\n\tif err = sp.processRegistryUpdates(st); err != nil {\n\t\treturn nil, err\n\t}\n\tif err = sp.processEffectiveBalanceUpdates(st); err != nil {\n\t\treturn nil, err\n\t}\n\t// if err = sp.processSlashingsReset(st); err != nil {\n\t// \treturn nil, err\n\t// }\n\tif err = sp.processRandaoMixesReset(st); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// only after we have fully updated validators, we enforce a cap on the validators set\n\tif err = sp.processValidatorSetCap(st); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// finally compute diffs in validator set to duly update consensus\n\tnextEpoch := currentEpoch + 1\n\tnextActiveVals, err := getActiveVals(st, nextEpoch)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn validatorSetsDiffs(currentActiveVals, nextActiveVals), nil\n}\n\n// processBlockHeader processes the header and ensures it matches the local state.\nfunc (sp *StateProcessor) processBlockHeader(\n\tctx ReadOnlyContext,\n\tst *state.StateDB,\n\tblk *ctypes.BeaconBlock,\n) error {\n\t// Ensure the block slot matches the state slot.\n\tslot, err := st.GetSlot()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif blk.GetSlot() != slot {\n\t\treturn errors.Wrapf(ErrSlotMismatch, \"expected: %d, got: %d\", slot, blk.GetSlot())\n\t}\n\n\t// Verify that the block is newer than latest block header\n\tlatestBlockHeader, err := st.GetLatestBlockHeader()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif blk.GetSlot() <= latestBlockHeader.GetSlot() {\n\t\treturn errors.Wrapf(\n\t\t\tErrBlockSlotTooLow, \"expected: > %d, got: %d\",\n\t\t\tlatestBlockHeader.GetSlot(), blk.GetSlot(),\n\t\t)\n\t}\n\n\t// Verify that proposer matches with what consensus declares as proposer\n\tproposer, err := st.ValidatorByIndex(blk.GetProposerIndex())\n\tif err != nil {\n\t\treturn err\n\t}\n\tstateProposerAddress, err := sp.fGetAddressFromPubKey(proposer.GetPubkey())\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !bytes.Equal(stateProposerAddress, ctx.ProposerAddress()) {\n\t\treturn errors.Wrapf(\n\t\t\tErrProposerMismatch, \"store key: %s, consensus key: %s\",\n\t\t\tstateProposerAddress, ctx.ProposerAddress(),\n\t\t)\n\t}\n\n\t// Verify that the parent matches\n\tparentBlockRoot := latestBlockHeader.HashTreeRoot()\n\tif parentBlockRoot != blk.GetParentBlockRoot() {\n\t\treturn errors.Wrapf(\n\t\t\tErrParentRootMismatch, \"expected: %s, got: %s\",\n\t\t\tparentBlockRoot.String(), blk.GetParentBlockRoot().String(),\n\t\t)\n\t}\n\n\t// Verify proposer is not slashed\n\tif proposer.IsSlashed() {\n\t\treturn errors.Wrapf(\n\t\t\tErrSlashedProposer, \"index: %d\",\n\t\t\tblk.GetProposerIndex(),\n\t\t)\n\t}\n\n\t// Cache current block as the new latest block\n\tbodyRoot := blk.GetBody().HashTreeRoot()\n\n\tlbh := &ctypes.BeaconBlockHeader{\n\t\tSlot:            blk.GetSlot(),\n\t\tProposerIndex:   blk.GetProposerIndex(),\n\t\tParentBlockRoot: blk.GetParentBlockRoot(),\n\t\t// state_root is zeroed and overwritten in the next `process_slot` call.\n\t\tStateRoot: common.Root{},\n\t\tBodyRoot:  bodyRoot,\n\t}\n\treturn st.SetLatestBlockHeader(lbh)\n}\n\n// processEffectiveBalanceUpdates as defined in the Ethereum 2.0 specification.\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#effective-balances-updates\nfunc (sp *StateProcessor) processEffectiveBalanceUpdates(st *state.StateDB) error {\n\t// Update effective balances with hysteresis\n\tvalidators, err := st.GetValidators()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Get the timestamp from the latest execution payload header to determine the active fork\n\t// version for fork-gated hysteresis parameters (BRIP-0008).\n\t//\n\t// Note: this uses the previous block's payload timestamp because processEpoch runs\n\t// inside ProcessSlots, before ProcessFork updates the state. If Fulu activates exactly\n\t// at an epoch boundary, the new hysteresis values take effect one epoch later. This is\n\t// acceptable because hysteresis only affects capital efficiency (not consensus safety),\n\t// and is consistent with how all fork-gated logic in processEpoch operates.\n\tlph, err := st.GetLatestExecutionPayloadHeader()\n\tif err != nil {\n\t\treturn err\n\t}\n\ttimestamp := lph.GetTimestamp()\n\n\tvar (\n\t\teffectiveBalanceIncrement = sp.cs.EffectiveBalanceIncrement()\n\t\thysteresisIncrement       = effectiveBalanceIncrement / sp.cs.HysteresisQuotient(timestamp)\n\t\tdownwardThreshold         = hysteresisIncrement * sp.cs.HysteresisDownwardMultiplier()\n\t\tupwardThreshold           = hysteresisIncrement * sp.cs.HysteresisUpwardMultiplier(timestamp)\n\n\t\tidx     math.U64\n\t\tbalance math.Gwei\n\t)\n\n\tfor _, val := range validators {\n\t\tidx, err = st.ValidatorIndexByPubkey(val.GetPubkey())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tbalance, err = st.GetBalance(idx)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif balance+downwardThreshold < val.GetEffectiveBalance() ||\n\t\t\tval.GetEffectiveBalance()+upwardThreshold < balance {\n\t\t\tupdatedBalance := ctypes.ComputeEffectiveBalance(\n\t\t\t\tbalance, effectiveBalanceIncrement, sp.cs.MaxEffectiveBalance(),\n\t\t\t)\n\t\t\tval.SetEffectiveBalance(updatedBalance)\n\t\t\tif err = st.UpdateValidatorAtIndex(idx, val); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "state-transition/core/state_processor_exits.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n)\n\n// InitiateValidatorExit initiates the exit of the validator with index `idx`. Modified from ETH 2.0 spec:\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#initiate-validator-exit\n// to handle pre-Electra validator exit logic.\nfunc (sp *StateProcessor) InitiateValidatorExit(st *statedb.StateDB, idx math.ValidatorIndex) error {\n\tvalidator, err := st.ValidatorByIndex(idx)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// We will use the fork version from the state to determine how to exit the validator.\n\tfork, err := st.GetFork()\n\tif err != nil {\n\t\treturn err\n\t}\n\tcurrentEpoch, err := st.GetEpoch()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// We still have no cap on validator churn, choosing not to adopt any churn-related\n\t// Electra changes, so exit epoch is at the next epoch.\n\texitEpoch := currentEpoch + 1\n\n\t// The withdrawable epoch is `MinValidatorWithdrawabilityDelay` epoch's after `exitEpoch`.\n\tvar withdrawableEpoch math.Epoch\n\tif version.IsBefore(fork.CurrentVersion, version.Electra()) {\n\t\t// Before Electra, this was the logic for exiting a validator: only trigger if the validator\n\t\t// set cap was reached. The withdrawable epoch does not include\n\t\t// `MinValidatorWithdrawabilityDelay`, but is instead the next epoch after exiting.\n\t\twithdrawableEpoch = exitEpoch + 1\n\t} else {\n\t\t// Return if the validator already initiated an exit, so that we only exit validators once.\n\t\tif validator.GetExitEpoch() != constants.FarFutureEpoch {\n\t\t\treturn nil\n\t\t}\n\n\t\t// The withdrawable Epoch is `MinValidatorWithdrawabilityDelay` epoch's after `exitEpoch`.\n\t\twithdrawableEpoch = exitEpoch + sp.cs.MinValidatorWithdrawabilityDelay()\n\t}\n\n\t// Set validator exit epoch and withdrawable epoch.\n\tvalidator.SetExitEpoch(exitEpoch)\n\tvalidator.SetWithdrawableEpoch(withdrawableEpoch)\n\treturn st.UpdateValidatorAtIndex(idx, validator)\n}\n"
  },
  {
    "path": "state-transition/core/state_processor_fixes.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core\n\nimport (\n\t\"fmt\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/berachain/beacon-kit/state-transition/core/state\"\n\t\"github.com/ethereum/go-ethereum/params\"\n)\n\n// TODO: confirm data\nconst (\n\tluganodesPubKey = \"0xafd0ad061f698eae0d483098948e26e254f4b7089244bda897895257c668196ffd5e2ddf458fdf8bcea295b7d47a5b37\"\n\tluganodesCreds  = \"0x010000000000000000000000b0c615224a053236ac7d1c239f6c1b5fbf8f0617\"\n\tluganodesAmount = 901_393_690_000_000 * params.Wei // 901_393.69 Gwei\n\n\tfixSmileePubKey = \"0x84acfd38a13af12add8d82e1ef0842c4dfc1e4175fae5b8ab73770f9050cbf673cafdbf6d8ab679fe9ea13208f50b485\"\n)\n\n//nolint:gochecknoglobals // unexported\nvar (\n\tluganodesCredentials = ctypes.WithdrawalCredentials(hex.MustToBytes(luganodesCreds))\n\tluganodesPubKeyBytes = crypto.BLSPubkey(hex.MustToBytes(luganodesPubKey))\n\n\tsmileePubKey = crypto.BLSPubkey(hex.MustToBytes(fixSmileePubKey))\n)\n\n// processElectra1Fixes handles some fixes made necessary by accidents or wrong validator choices in mainnet\nfunc (sp *StateProcessor) processElectra1Fixes(st *state.StateDB) error {\n\tif !sp.cs.IsMainnet() {\n\t\treturn nil\n\t}\n\n\tif err := sp.processLuganodesRecovery(st); err != nil {\n\t\treturn err\n\t}\n\n\treturn sp.processSmileeFix(st)\n}\n\nfunc (sp *StateProcessor) processLuganodesRecovery(st *state.StateDB) error {\n\tsp.logger.Info(\"Luganodes recovery - creating deposit\")\n\n\t// Make a one-time hardcoded deposit\n\tdeposit := ctypes.Deposit{\n\t\tPubkey:      luganodesPubKeyBytes,\n\t\tCredentials: luganodesCredentials,\n\t\tAmount:      luganodesAmount,\n\t}\n\tsp.logger.Info(\n\t\t\"Luganodes deposit\",\n\t\t\"pubkey\", deposit.GetPubkey().String(),\n\t\t\"amount\", deposit.GetAmount().Unwrap(),\n\t\t\"credentials\", deposit.GetWithdrawalCredentials().String(),\n\t)\n\n\tif err := sp.addValidatorToRegistry(st, &deposit); err != nil {\n\t\treturn fmt.Errorf(\"failed to add Luganodes validator: %w\", err)\n\t}\n\n\tsp.logger.Info(\"Luganodes recovery - created deposit\")\n\treturn nil\n}\n\nfunc (sp *StateProcessor) processSmileeFix(st *state.StateDB) error {\n\tsp.logger.Info(\"smilee fix - forcing validator exit\")\n\n\tidx, err := st.ValidatorIndexByPubkey(smileePubKey)\n\tif err != nil {\n\t\t// Post fork activation, we skip the processing in case of errors.\n\t\t// This simplifies some UTs where we pick mainnet specs and activate\n\t\t// the fork during the test\n\t\tsp.logger.Warn(\"smilee fix - failed retrieving validator by pub key\", \"err\", err)\n\t\treturn nil\n\t}\n\tval, err := st.ValidatorByIndex(idx)\n\tif err != nil {\n\t\t// Skipping error here as well.\n\t\tsp.logger.Warn(\"smilee fix - failed retrieving validator\", \"err\", err)\n\t\treturn nil\n\t}\n\n\tif err = sp.InitiateValidatorExit(st, idx); err != nil {\n\t\t// We never want to skip this error instead. If the validator is\n\t\t// available we must succeed in kicking it out.\n\t\treturn fmt.Errorf(\"smilee fix - failed initiating validator exit: %w\", err)\n\t}\n\tsp.logger.Info(\n\t\t\"smilee validator\",\n\t\t\"pubkey\", val.Pubkey.String(),\n\t\t\"amount\", val.EffectiveBalance.Unwrap(),\n\t\t\"credentials\", val.WithdrawalCredentials.String(),\n\t)\n\tsp.logger.Info(\"smilee fix - successfully forced validator exit\")\n\treturn nil\n}\n"
  },
  {
    "path": "state-transition/core/state_processor_forks.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t\"cosmossdk.io/collections\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n)\n\n// ProcessFork prepares the state for the fork version at the given timestamp.\n//   - If this function is called for the same version as the state's current version,\n//     it will do nothing. Unless it is the genesis slot, in which case we want to\n//     prepare the state for the genesis fork version.\n//   - If this function is called for a version before the state's current version,\n//     it will return error as this is not allowed.\n//   - If this function is called for a version after the state's current version,\n//     it will upgrade the state to the new version.\n//\n// NOTE for caller: `ProcessSlots` must be called before this function. If we are\n// crossing into a new fork, the first slot of the new fork will be retrieved from\n// the state. The state must be prepared for this new slot.\n//\n//nolint:gocognit // switch-case is unavoidable here.\nfunc (sp *StateProcessor) ProcessFork(\n\tst *statedb.StateDB, timestamp math.U64, logUpgrade bool,\n) error {\n\tstateFork, err := st.GetFork()\n\tif err != nil {\n\t\treturn err\n\t}\n\tslot, err := st.GetSlot()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Return early if the given fork version is before or equal to the current state fork version.\n\tforkVersion := sp.cs.ActiveForkVersionForTimestamp(timestamp)\n\tif version.IsBefore(forkVersion, stateFork.CurrentVersion) {\n\t\treturn fmt.Errorf(\n\t\t\t\"cannot downgrade state from %s to %s\", stateFork.CurrentVersion, forkVersion,\n\t\t)\n\t} else if slot > 0 && version.Equals(forkVersion, stateFork.CurrentVersion) {\n\t\t// If we are past genesis and the fork version remains consistent, do nothing.\n\t\treturn nil\n\t}\n\n\t// If we are at genesis or moving to a new fork version, upgrade the state.\n\tswitch forkVersion {\n\tcase version.Deneb():\n\t\t// Do nothing to the state. NOTE: Deneb is the genesis version of Berachain mainnet and\n\t\t// Bepolia testnet.\n\n\t\t// Log the upgrade to Deneb if requested.\n\t\tif logUpgrade {\n\t\t\tsp.logDenebFork(timestamp)\n\t\t}\n\tcase version.Deneb1():\n\t\t// Do nothing to the state. NOTE: Deneb1 is the first hard fork of Berachain mainnet and\n\t\t// Bepolia testnet. In this fork, the Fork struct on BeaconState is NOT updated. In\n\t\t// future hard forks, the Fork struct should be updated.\n\n\t\t// Log the upgrade to Deneb1 if requested.\n\t\tif logUpgrade {\n\t\t\tsp.logDeneb1Fork(stateFork.PreviousVersion, timestamp, slot)\n\t\t}\n\tcase version.Electra():\n\t\tif err = sp.upgradeToElectra(st, stateFork, slot); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Log the upgrade to Electra if requested.\n\t\tif logUpgrade {\n\t\t\tsp.logElectraFork(stateFork.PreviousVersion, timestamp, slot)\n\t\t}\n\tcase version.Electra1():\n\t\tif err = sp.upgradeToElectra1(st, stateFork, slot); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif err = sp.processElectra1Fixes(st); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Log the upgrade to Electra1 if requested.\n\t\tif logUpgrade {\n\t\t\tsp.logElectra1Fork(stateFork.PreviousVersion, timestamp, slot)\n\t\t}\n\tcase version.Fulu():\n\t\tif err = sp.upgradeToFulu(st, stateFork, slot); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Log the upgrade to Fulu if requested.\n\t\tif logUpgrade {\n\t\t\tsp.logFuluFork(stateFork.PreviousVersion, timestamp, slot)\n\t\t}\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unsupported fork version: %s\", forkVersion))\n\t}\n\n\treturn nil\n}\n\n// logDenebFork logs information about the Deneb fork.\nfunc (sp *StateProcessor) logDenebFork(timestamp math.U64) {\n\t// Since Deneb is the earliest fork version supported by beacon-kit, if we are\n\t// entering Deneb it must be at genesis, which means the fork time of Deneb is\n\t// the timestamp of the genesis block itself.\n\tdenebForkTime := timestamp.Unwrap()\n\n\tsp.logger.Info(fmt.Sprintf(`\n\n\n\t⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️\n\n\t+ ✅  welcome to the deneb (0x04000000) fork! 🎉\n\t+ ⏱️   deneb fork time: %d\n\t+ 🍴  first slot / timestamp of deneb: %d / %d\n\t+ ⛓️   current beacon epoch: %d\n\n\t⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️\n\n\n`,\n\t\tdenebForkTime,\n\t\tconstants.GenesisSlot.Unwrap(), denebForkTime,\n\t\tconstants.GenesisEpoch.Unwrap(),\n\t))\n}\n\n// logDeneb1Fork logs information about the Deneb1 fork.\nfunc (sp *StateProcessor) logDeneb1Fork(\n\tpreviousVersion common.Version, timestamp math.U64, slot math.Slot,\n) {\n\t// Since state fork is not updating to Deneb1, every block observes Deneb1 as \"new fork\" during\n\t// Deneb1. Hence, we must wrap this in a OnceFunc to ensure it is logged only the first time\n\t// we process a Deneb1 block.\n\tsp.logDeneb1Once.Do(func() {\n\t\tsp.logger.Info(fmt.Sprintf(`\n\n\n\t⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️\n\n\t+ ✅  welcome to the deneb1 (0x04010000) fork! 🎉\n\t+ 🚝  previous fork: %s (%s)\n\t+ ⏱️   deneb1 fork time: %d\n\t+ 🍴  first slot / timestamp of deneb1: %d / %d\n\t+ ⛓️   current beacon epoch: %d\n\n\t⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️\n\n\n`,\n\t\t\tversion.Name(previousVersion), previousVersion.String(),\n\t\t\tsp.cs.Deneb1ForkTime(),\n\t\t\tslot.Unwrap(), timestamp.Unwrap(),\n\t\t\tsp.cs.SlotToEpoch(slot).Unwrap(),\n\t\t))\n\t})\n}\n\n// upgradeToElectra upgrades the state to the Electra fork version. It is modified from the ETH 2.0\n// spec (https://ethereum.github.io/consensus-specs/specs/electra/fork/#upgrading-the-state) to:\n//   - update the Fork struct in the BeaconState\n//   - initialize the pending partial withdrawals to an empty array\nfunc (sp *StateProcessor) upgradeToElectra(\n\tst *statedb.StateDB, fork *types.Fork, slot math.Slot,\n) error {\n\t// Set the fork on BeaconState.\n\tfork.PreviousVersion = fork.CurrentVersion\n\tfork.CurrentVersion = version.Electra()\n\tfork.Epoch = sp.cs.SlotToEpoch(slot)\n\tif err := st.SetFork(fork); err != nil {\n\t\treturn err\n\t}\n\n\t// Initialize the pending partial withdrawals to an empty array.\n\tsp.metrics.gaugePartialWithdrawalsEnqueued(0)\n\treturn st.SetPendingPartialWithdrawals([]*types.PendingPartialWithdrawal{})\n}\n\n// logElectraFork logs information about the Electra fork.\nfunc (sp *StateProcessor) logElectraFork(\n\tpreviousVersion common.Version, timestamp math.U64, slot math.Slot,\n) {\n\tsp.logger.Info(fmt.Sprintf(`\n\n\n\t⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️\n\n\t+ ✅  welcome to the electra (0x05000000) fork! 🎉\n\t+ 🚝  previous fork: %s (%s)\n\t+ ⏱️   electra fork time: %d\n\t+ 🍴  first slot / timestamp of electra: %d / %d\n\t+ ⛓️   current beacon epoch: %d\n\n\t⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️\n\n\n`,\n\t\tversion.Name(previousVersion), previousVersion.String(),\n\t\tsp.cs.ElectraForkTime(),\n\t\tslot.Unwrap(), timestamp.Unwrap(),\n\t\tsp.cs.SlotToEpoch(slot).Unwrap(),\n\t))\n}\n\n// upgradeToElectra1 upgrades the state to the Electra1 fork version. It is modified from the ETH\n// 2.0 spec (https://ethereum.github.io/consensus-specs/specs/electra/fork/#upgrading-the-state) to:\n//   - update the Fork struct in the BeaconState\n//   - initialize the pending partial withdrawals to an empty array (if not already initialized)\nfunc (sp *StateProcessor) upgradeToElectra1(\n\tst *statedb.StateDB, fork *types.Fork, slot math.Slot,\n) error {\n\t// Set the fork on BeaconState.\n\tfork.PreviousVersion = fork.CurrentVersion\n\tfork.CurrentVersion = version.Electra1()\n\tfork.Epoch = sp.cs.SlotToEpoch(slot)\n\tif err := st.SetFork(fork); err != nil {\n\t\treturn err\n\t}\n\n\t// Initialize the pending partial withdrawals to an empty array if not already initialized.\n\tif _, err := st.GetPendingPartialWithdrawals(); errors.Is(err, collections.ErrNotFound) {\n\t\tsp.metrics.gaugePartialWithdrawalsEnqueued(0)\n\t\treturn st.SetPendingPartialWithdrawals([]*types.PendingPartialWithdrawal{})\n\t}\n\n\treturn nil\n}\n\n// logElectra1Fork logs information about the Electra1 fork.\nfunc (sp *StateProcessor) logElectra1Fork(\n\tpreviousVersion common.Version, timestamp math.U64, slot math.Slot,\n) {\n\tsp.logger.Info(fmt.Sprintf(`\n\n\n\t⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️\n\n\t+ ✅  welcome to the electra1 (0x05010000) fork! 🎉\n\t+ 🚝  previous fork: %s (%s)\n\t+ ⏱️   electra1 fork time: %d\n\t+ 🍴  first slot / timestamp of electra1: %d / %d\n\t+ ⛓️   current beacon epoch: %d\n\n\t⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️\n\n`,\n\t\tversion.Name(previousVersion), previousVersion.String(),\n\t\tsp.cs.Electra1ForkTime(),\n\t\tslot.Unwrap(), timestamp.Unwrap(),\n\t\tsp.cs.SlotToEpoch(slot).Unwrap(),\n\t))\n}\n\n// upgradeToFulu upgrades the state to the Fulu fork version.\nfunc (sp *StateProcessor) upgradeToFulu(\n\tst *statedb.StateDB, fork *types.Fork, slot math.Slot,\n) error {\n\t// Set the fork on BeaconState.\n\tfork.PreviousVersion = fork.CurrentVersion\n\tfork.CurrentVersion = version.Fulu()\n\tfork.Epoch = sp.cs.SlotToEpoch(slot)\n\tif err := st.SetFork(fork); err != nil {\n\t\treturn err\n\t}\n\n\t// Initialize the pending partial withdrawals to an empty array if not already initialized.\n\t// This handles the case where the chain starts directly on Fulu (e.g., devnet).\n\tif _, err := st.GetPendingPartialWithdrawals(); errors.Is(err, collections.ErrNotFound) {\n\t\tsp.metrics.gaugePartialWithdrawalsEnqueued(0)\n\t\treturn st.SetPendingPartialWithdrawals([]*types.PendingPartialWithdrawal{})\n\t}\n\n\treturn nil\n}\n\n// logFuluFork logs information about the Fulu fork.\nfunc (sp *StateProcessor) logFuluFork(\n\tpreviousVersion common.Version, timestamp math.U64, slot math.Slot,\n) {\n\tsp.logger.Info(fmt.Sprintf(`\n\n\n\t⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️\n\n\t+ ✅  welcome to the fulu (0x06000000) fork! 🎉\n\t+ 🚝  previous fork: %s (%s)\n\t+ ⏱️   fulu fork time: %d\n\t+ 🍴  first slot / timestamp of fulu: %d / %d\n\t+ ⛓️   current beacon epoch: %d\n\n\t⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️⏭️\n\n`,\n\t\tversion.Name(previousVersion), previousVersion.String(),\n\t\tsp.cs.FuluForkTime(),\n\t\tslot.Unwrap(), timestamp.Unwrap(),\n\t\tsp.cs.SlotToEpoch(slot).Unwrap(),\n\t))\n}\n"
  },
  {
    "path": "state-transition/core/state_processor_genesis.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core\n\nimport (\n\t\"fmt\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n)\n\n// InitializeBeaconStateFromEth1 initializes the beacon state. Modified from the ETH 2.0 spec:\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#genesis\nfunc (sp *StateProcessor) InitializeBeaconStateFromEth1(\n\tst *statedb.StateDB,\n\tdeposits ctypes.Deposits,\n\texecPayloadHeader *ctypes.ExecutionPayloadHeader,\n\tgenesisVersion common.Version,\n) (transition.ValidatorUpdates, error) {\n\tif err := st.SetSlot(constants.GenesisSlot); err != nil {\n\t\treturn nil, err\n\t}\n\n\tfork := ctypes.NewFork(genesisVersion, genesisVersion, constants.GenesisEpoch)\n\tif err := st.SetFork(fork); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := sp.ProcessFork(st, execPayloadHeader.GetTimestamp(), true); err != nil {\n\t\treturn nil, err\n\t}\n\n\teth1Data := &ctypes.Eth1Data{\n\t\tDepositRoot:  deposits.HashTreeRoot(),\n\t\tDepositCount: 0,\n\t\tBlockHash:    execPayloadHeader.GetBlockHash(),\n\t}\n\tif err := st.SetEth1Data(eth1Data); err != nil {\n\t\treturn nil, err\n\t}\n\n\tblkHeader := GenesisBlockHeader(genesisVersion)\n\tif err := st.SetLatestBlockHeader(blkHeader); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := sp.seedRandaoMix(\n\t\tst,\n\t\texecPayloadHeader.GetBlockHash(),\n\t); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// ingest deposits & do genesis‐activation\n\tif err := sp.processGenesisDepositsAndActivations(st, deposits); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvalidators, err := st.GetValidators()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err = st.SetGenesisValidatorsRoot(validators.HashTreeRoot()); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err = st.SetLatestExecutionPayloadHeader(execPayloadHeader); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// seed historical block‑ and state‑roots\n\tif err = sp.seedHistoricalRoots(st); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err = st.SetNextWithdrawalIndex(0); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err = st.SetNextWithdrawalValidatorIndex(0); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err = st.SetTotalSlashing(0); err != nil {\n\t\treturn nil, err\n\t}\n\n\tactiveVals, err := getActiveVals(st, constants.GenesisEpoch)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn validatorSetsDiffs(nil, activeVals), nil\n}\n\n// seedRandaoMix writes the initial RANDAO mixes.\nfunc (sp *StateProcessor) seedRandaoMix(\n\tst *statedb.StateDB,\n\thash common.ExecutionHash,\n) error {\n\tfor i := range sp.cs.EpochsPerHistoricalVector() {\n\t\tif err := st.UpdateRandaoMixAtIndex(\n\t\t\ti, common.Bytes32(hash),\n\t\t); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// seedHistoricalRoots zero‑primes the block and state‐roots.\nfunc (sp *StateProcessor) seedHistoricalRoots(st *statedb.StateDB) error {\n\tfor i := range sp.cs.HistoricalRootsLimit() {\n\t\tif err := st.UpdateBlockRootAtIndex(i, common.Root{}); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := st.UpdateStateRootAtIndex(i, common.Root{}); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// processGenesisDepositsAndActivations handles the eth1 deposit index,\n// validates and ingests each deposit, then does the genesis activation pass.\nfunc (sp *StateProcessor) processGenesisDepositsAndActivations(\n\tst *statedb.StateDB,\n\tdeposits ctypes.Deposits,\n) error {\n\t// Before processing deposits, set the eth1 deposit index to 0.\n\tif err := st.SetEth1DepositIndex(constants.FirstDepositIndex); err != nil {\n\t\treturn err\n\t}\n\tif err := validateGenesisDeposits(\n\t\tst, deposits, sp.cs.ValidatorSetCap(),\n\t); err != nil {\n\t\treturn err\n\t}\n\tfor _, dep := range deposits {\n\t\tif err := sp.processDeposit(st, dep); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn sp.processGenesisActivation(st)\n}\n\nfunc (sp *StateProcessor) processGenesisActivation(st *statedb.StateDB) error {\n\tvals, err := st.GetValidators()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"genesis activation, failed listing validators: %w\", err)\n\t}\n\tminEffectiveBalance := sp.cs.MinActivationBalance()\n\n\tvar idx math.ValidatorIndex\n\tfor _, val := range vals {\n\t\tif val.GetEffectiveBalance() < minEffectiveBalance {\n\t\t\tcontinue\n\t\t}\n\t\tval.SetActivationEligibilityEpoch(constants.GenesisEpoch)\n\t\tval.SetActivationEpoch(constants.GenesisEpoch)\n\t\tidx, err = st.ValidatorIndexByPubkey(val.GetPubkey())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err = st.UpdateValidatorAtIndex(idx, val); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc GenesisBlockHeader(genesisVersion common.Version) *ctypes.BeaconBlockHeader {\n\tversionable := ctypes.NewVersionable(genesisVersion)\n\tblkBody := &ctypes.BeaconBlockBody{\n\t\tVersionable: versionable,\n\t\tEth1Data:    &ctypes.Eth1Data{},\n\t\tExecutionPayload: &ctypes.ExecutionPayload{\n\t\t\tVersionable: versionable,\n\t\t\tExtraData:   make([]byte, ctypes.ExtraDataSize),\n\t\t},\n\t}\n\n\tblkHeader := &ctypes.BeaconBlockHeader{\n\t\tSlot:            constants.GenesisSlot,\n\t\tProposerIndex:   0,\n\t\tParentBlockRoot: common.Root{},\n\t\tStateRoot:       common.Root{},\n\t\tBodyRoot:        blkBody.HashTreeRoot(),\n\t}\n\treturn blkHeader\n}\n"
  },
  {
    "path": "state-transition/core/state_processor_genesis_test.go",
    "content": "//go:build test\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core_test\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tstatetransition \"github.com/berachain/beacon-kit/testing/state-transition\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n//nolint:paralleltest // uses envars\nfunc TestInitialize(t *testing.T) {\n\tcsDevnet := setupChain(t)\n\tcsTestnet, specErr := spec.TestnetChainSpec()\n\trequire.NoError(t, specErr)\n\tcsMainnet, specErr := spec.MainnetChainSpec()\n\trequire.NoError(t, specErr)\n\n\tspecs := []chain.Spec{csDevnet, csTestnet, csMainnet}\n\tfor i, cs := range specs {\n\t\tt.Run(fmt.Sprintf(\"TestInitialize-%d\", i), func(t *testing.T) {\n\t\t\tsp, st, _, _, _, _ := statetransition.SetupTestState(t, cs)\n\n\t\t\tvar (\n\t\t\t\tmaxBalance = cs.MaxEffectiveBalance()\n\t\t\t\tincrement  = cs.EffectiveBalanceIncrement()\n\t\t\t\tminBalance = cs.MinActivationBalance() - increment\n\t\t\t)\n\n\t\t\t// create test inputs\n\t\t\tvar (\n\t\t\t\tgenDeposits = []*types.Deposit{\n\t\t\t\t\t{\n\t\t\t\t\t\tPubkey: [48]byte{0x01},\n\t\t\t\t\t\tAmount: maxBalance,\n\t\t\t\t\t\tCredentials: types.NewCredentialsFromExecutionAddress(\n\t\t\t\t\t\t\tcommon.ExecutionAddress{0x01},\n\t\t\t\t\t\t),\n\t\t\t\t\t\tIndex: uint64(0),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tPubkey: [48]byte{0x02},\n\t\t\t\t\t\tAmount: minBalance + increment,\n\t\t\t\t\t\tCredentials: types.NewCredentialsFromExecutionAddress(\n\t\t\t\t\t\t\tcommon.ExecutionAddress{0x02},\n\t\t\t\t\t\t),\n\t\t\t\t\t\tIndex: uint64(1),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tPubkey: [48]byte{0x03},\n\t\t\t\t\t\tAmount: minBalance,\n\t\t\t\t\t\tCredentials: types.NewCredentialsFromExecutionAddress(\n\t\t\t\t\t\t\tcommon.ExecutionAddress{0x03},\n\t\t\t\t\t\t),\n\t\t\t\t\t\tIndex: uint64(2),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tPubkey: [48]byte{0x04},\n\t\t\t\t\t\tAmount: 2 * maxBalance,\n\t\t\t\t\t\tCredentials: types.NewCredentialsFromExecutionAddress(\n\t\t\t\t\t\t\tcommon.ExecutionAddress{0x04},\n\t\t\t\t\t\t),\n\t\t\t\t\t\tIndex: uint64(3),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tPubkey: [48]byte{0x05},\n\t\t\t\t\t\tAmount: minBalance - increment,\n\t\t\t\t\t\tCredentials: types.NewCredentialsFromExecutionAddress(\n\t\t\t\t\t\t\tcommon.ExecutionAddress{0x05},\n\t\t\t\t\t\t),\n\t\t\t\t\t\tIndex: uint64(4),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tPubkey: [48]byte{0x06},\n\t\t\t\t\t\tAmount: minBalance + increment*3/2,\n\t\t\t\t\t\tCredentials: types.NewCredentialsFromExecutionAddress(\n\t\t\t\t\t\t\tcommon.ExecutionAddress{0x06},\n\t\t\t\t\t\t),\n\t\t\t\t\t\tIndex: uint64(5),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tPubkey: [48]byte{0x07},\n\t\t\t\t\t\tAmount: maxBalance + increment/10,\n\t\t\t\t\t\tCredentials: types.NewCredentialsFromExecutionAddress(\n\t\t\t\t\t\t\tcommon.ExecutionAddress{0x07},\n\t\t\t\t\t\t),\n\t\t\t\t\t\tIndex: uint64(6),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tPubkey: [48]byte{0x08},\n\t\t\t\t\t\tAmount: minBalance + increment*99/100,\n\t\t\t\t\t\tCredentials: types.NewCredentialsFromExecutionAddress(\n\t\t\t\t\t\t\tcommon.ExecutionAddress{0x08},\n\t\t\t\t\t\t),\n\t\t\t\t\t\tIndex: uint64(7),\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t\tgoodDeposits = []*types.Deposit{\n\t\t\t\t\tgenDeposits[0], genDeposits[1], genDeposits[3],\n\t\t\t\t\tgenDeposits[5], genDeposits[6],\n\t\t\t\t}\n\t\t\t\texecutionPayloadHeader = &types.ExecutionPayloadHeader{\n\t\t\t\t\tVersionable: types.NewVersionable(cs.GenesisForkVersion()),\n\t\t\t\t}\n\t\t\t\tfork = &types.Fork{\n\t\t\t\t\tPreviousVersion: cs.GenesisForkVersion(),\n\t\t\t\t\tCurrentVersion:  cs.GenesisForkVersion(),\n\t\t\t\t\tEpoch:           constants.GenesisEpoch,\n\t\t\t\t}\n\t\t\t)\n\n\t\t\t// run test\n\t\t\tgenVals, initErr := sp.InitializeBeaconStateFromEth1(\n\t\t\t\tst, genDeposits, executionPayloadHeader, fork.CurrentVersion,\n\t\t\t)\n\n\t\t\t// check outputs\n\t\t\trequire.NoError(t, initErr)\n\t\t\trequire.Len(t, genVals, len(goodDeposits))\n\n\t\t\t// check beacon state changes\n\t\t\tresSlot, err := st.GetSlot()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, constants.GenesisSlot, resSlot)\n\n\t\t\tresFork, err := st.GetFork()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, fork, resFork)\n\n\t\t\tfor _, dep := range goodDeposits {\n\t\t\t\tcheckValidator(t, cs, st, dep)\n\t\t\t}\n\n\t\t\t// check that deposit index is duly set. On devnet\n\t\t\t// deposit index is set to the last accepted deposit.\n\t\t\tlatestValIdx, err := st.GetEth1DepositIndex()\n\t\t\trequire.NoError(t, err)\n\t\t\trequire.Equal(t, uint64(len(genDeposits)), latestValIdx)\n\t\t})\n\t}\n}\n\nfunc checkValidator(\n\tt *testing.T,\n\tcs chain.Spec,\n\tbs *statetransition.TestBeaconStateT,\n\tdep *types.Deposit,\n) {\n\tt.Helper()\n\n\tidx, err := bs.ValidatorIndexByPubkey(dep.Pubkey)\n\trequire.NoError(t, err)\n\n\tval, err := bs.ValidatorByIndex(idx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, dep.Pubkey, val.Pubkey)\n\n\tvar (\n\t\tmaxBalance = cs.MaxEffectiveBalance()\n\t\tincrement  = cs.EffectiveBalanceIncrement()\n\t\tminBalance = cs.MinActivationBalance() - increment\n\t)\n\tswitch {\n\tcase dep.Amount >= maxBalance:\n\t\trequire.Equal(t, maxBalance, val.EffectiveBalance)\n\tcase dep.Amount > minBalance && dep.Amount < maxBalance:\n\t\t// Effective balance must be a multiple of increment.\n\t\t// If balance is not, effective balance is rounded down\n\t\tif dep.Amount%increment == 0 {\n\t\t\trequire.Equal(t, dep.Amount, val.EffectiveBalance)\n\t\t} else {\n\t\t\trequire.Less(t, val.EffectiveBalance, dep.Amount)\n\t\t\trequire.Greater(t, val.EffectiveBalance, dep.Amount-increment)\n\t\t\trequire.Zero(t, val.EffectiveBalance%increment)\n\t\t}\n\tcase dep.Amount <= minBalance:\n\t\trequire.Equal(t, math.Gwei(0), val.EffectiveBalance)\n\t}\n\n\trequire.Equal(t, constants.GenesisEpoch, val.GetActivationEligibilityEpoch())\n\trequire.Equal(t, constants.GenesisEpoch, val.GetActivationEpoch())\n\n\tvalBal, err := bs.GetBalance(idx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, dep.Amount, valBal)\n}\n"
  },
  {
    "path": "state-transition/core/state_processor_payload.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core\n\nimport (\n\t\"context\"\n\n\tpayloadtime \"github.com/berachain/beacon-kit/beacon/payload-time\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\n// processExecutionPayload processes the execution payload and ensures it\n// matches the local state.\nfunc (sp *StateProcessor) processExecutionPayload(\n\ttxCtx ReadOnlyContext,\n\tst *statedb.StateDB,\n\tblk *ctypes.BeaconBlock,\n\tparentProposerPubkey *crypto.BLSPubkey,\n) error {\n\tvar (\n\t\tbody    = blk.GetBody()\n\t\tpayload = body.GetExecutionPayload()\n\t\theader  = &ctypes.ExecutionPayloadHeader{} // appeases nilaway\n\t\tg, ctx  = errgroup.WithContext(txCtx.ConsensusCtx())\n\t)\n\n\tpayloadTimestamp := payload.GetTimestamp().Unwrap()\n\tconsensusTimestamp := txCtx.ConsensusTime().Unwrap()\n\n\tsp.metrics.gaugeTimestamps(payloadTimestamp, consensusTimestamp)\n\n\tsp.logger.Info(\"processExecutionPayload\",\n\t\t\"consensus height\", blk.GetSlot().Unwrap(),\n\t\t\"payload height\", payload.GetNumber().Unwrap(),\n\t\t\"payload timestamp\", payloadTimestamp,\n\t\t\"consensus timestamp\", consensusTimestamp,\n\t\t\"verify payload\", txCtx.VerifyPayload(),\n\t)\n\n\tif version.EqualsOrIsAfter(blk.GetForkVersion(), version.Electra()) {\n\t\trequests, getErr := blk.GetBody().GetExecutionRequests()\n\t\tif getErr != nil {\n\t\t\treturn getErr\n\t\t}\n\t\tsp.logger.Info(\n\t\t\t\"Processing execution requests\",\n\t\t\t\"deposits\", len(requests.Deposits),\n\t\t\t\"withdrawals\", len(requests.Withdrawals),\n\t\t\t\"consolidations\", len(requests.Consolidations),\n\t\t)\n\t}\n\n\t// Perform payload verification only if the context is configured as such.\n\tif txCtx.VerifyPayload() {\n\t\tg.Go(func() error {\n\t\t\treturn sp.validateExecutionPayload(ctx, txCtx.ConsensusTime(), st, blk, parentProposerPubkey)\n\t\t})\n\t}\n\n\t// Get the execution payload header.\n\tg.Go(func() error {\n\t\tvar err error\n\t\theader, err = payload.ToHeader()\n\t\treturn err\n\t})\n\n\tif err := g.Wait(); err != nil {\n\t\treturn err\n\t}\n\n\tif txCtx.MeterGas() {\n\t\tsp.metrics.gaugeBlockGasUsed(\n\t\t\tpayload.GetNumber(), payload.GetGasUsed(), payload.GetBlobGasUsed(),\n\t\t)\n\t}\n\n\t// Set the latest execution payload header.\n\treturn st.SetLatestExecutionPayloadHeader(header)\n}\n\n// validateExecutionPayload validates the execution payload against both local\n// state and the execution engine.\nfunc (sp *StateProcessor) validateExecutionPayload(\n\tctx context.Context,\n\tconsensusTime math.U64,\n\tst ReadOnlyBeaconState,\n\tblk *ctypes.BeaconBlock,\n\tparentProposerPubkey *crypto.BLSPubkey,\n) error {\n\tif err := sp.validateStatelessPayload(blk); err != nil {\n\t\treturn err\n\t}\n\treturn sp.validateStatefulPayload(ctx, consensusTime, st, blk, parentProposerPubkey)\n}\n\n// validateStatelessPayload performs stateless checks on the execution payload.\nfunc (sp *StateProcessor) validateStatelessPayload(blk *ctypes.BeaconBlock) error {\n\tbody := blk.GetBody()\n\tpayload := body.GetExecutionPayload()\n\n\t// Verify the number of withdrawals.\n\twithdrawals := payload.GetWithdrawals()\n\tif uint64(len(withdrawals)) > sp.cs.MaxWithdrawalsPerPayload() {\n\t\treturn errors.Wrapf(\n\t\t\tErrExceedMaximumWithdrawals,\n\t\t\t\"too many withdrawals, expected: %d, got: %d\",\n\t\t\tsp.cs.MaxWithdrawalsPerPayload(), len(withdrawals),\n\t\t)\n\t}\n\n\t// No need to verify bounded number of commitments here, since it is\n\t// verified early on in ProcessProposal.\n\treturn nil\n}\n\n// validateStatefulPayload performs stateful checks on the execution payload.\nfunc (sp *StateProcessor) validateStatefulPayload(\n\tctx context.Context,\n\tconsensusTime math.U64,\n\tst ReadOnlyBeaconState,\n\tblk *ctypes.BeaconBlock,\n\tparentProposerPubkey *crypto.BLSPubkey,\n) error {\n\tbody := blk.GetBody()\n\tpayload := body.GetExecutionPayload()\n\n\tlph, err := st.GetLatestExecutionPayloadHeader()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Check chain canonicity\n\tsafeHash := lph.GetBlockHash()\n\tif safeHash != payload.GetParentHash() {\n\t\treturn errors.Wrapf(\n\t\t\tErrParentPayloadHashMismatch,\n\t\t\t\"parent block with hash %x is not finalized, expected finalized hash %x\",\n\t\t\tpayload.GetParentHash(),\n\t\t\tsafeHash,\n\t\t)\n\t}\n\n\t// Verify that the payload stamp is within a reasonable bound\n\tif err = payloadtime.Verify(\n\t\tconsensusTime,\n\t\tlph.GetTimestamp(),\n\t\tpayload.GetTimestamp(),\n\t); err != nil {\n\t\treturn err\n\t}\n\n\tpayloadReq, err := ctypes.BuildNewPayloadRequestFromFork(blk, parentProposerPubkey)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// First we verify the block hash and versioned hashes are valid.\n\t// TODO: is this required? Or will the EL handle this for us during\n\t// new payload?\n\tif err = payloadReq.HasValidVersionedAndBlockHashes(); err != nil {\n\t\treturn err\n\t}\n\n\t// TODO: set retryOnSyncingStatus to false if we are in FinalizeBlock.\n\t// Otherwise leave as true. This is ok to leave this way for now.\n\tif err = sp.executionEngine.NotifyNewPayload(ctx, payloadReq, true); err != nil {\n\t\treturn err\n\t}\n\n\t// Verify RANDAO\n\tepoch, err := st.GetEpoch()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\texpectedMix, err := st.GetRandaoMixAtIndex(epoch.Unwrap() % sp.cs.EpochsPerHistoricalVector())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif payload.GetPrevRandao() != expectedMix {\n\t\treturn errors.Wrapf(\n\t\t\tErrRandaoMixMismatch,\n\t\t\t\"prev randao does not match, expected: %x, got: %x\",\n\t\t\texpectedMix, payload.GetPrevRandao(),\n\t\t)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "state-transition/core/state_processor_payload_test.go",
    "content": "//go:build test\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core_test\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"cosmossdk.io/log\"\n\tstoretypes \"cosmossdk.io/store/types\"\n\tpayloadtime \"github.com/berachain/beacon-kit/beacon/payload-time\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/node-core/components/metrics\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n\tstatetransition \"github.com/berachain/beacon-kit/testing/state-transition\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n\t\"github.com/stretchr/testify/mock\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// TestPayloadTimestampVerification ensures that payload timestamp\n// is properly validated\n//\n//nolint:paralleltest // uses envars\nfunc TestPayloadTimestampVerification(t *testing.T) {\n\t// Create state processor to test\n\tcs := setupChain(t)\n\tsp, st, ds, ctx, cms, mockEngine := statetransition.SetupTestState(t, cs)\n\n\t// process genesis before any other block\n\tgenesisTime := time.Now().Truncate(time.Second)\n\tgenesisFork := cs.ActiveForkVersionForTimestamp(math.U64(genesisTime.Unix()))\n\trequire.Equal(t, genesisFork, cs.GenesisForkVersion())\n\tvar (\n\t\tgenDeposits = types.Deposits{\n\t\t\t{\n\t\t\t\tPubkey:      [48]byte{0x00},\n\t\t\t\tCredentials: types.NewCredentialsFromExecutionAddress(common.ExecutionAddress{}),\n\t\t\t\tAmount:      cs.MaxEffectiveBalance(),\n\t\t\t\tIndex:       0,\n\t\t\t},\n\t\t}\n\t\tgenPayloadHeader = &types.ExecutionPayloadHeader{\n\t\t\tVersionable: types.NewVersionable(genesisFork),\n\t\t}\n\t)\n\tgenPayloadHeader.Timestamp = math.U64(genesisTime.Unix())\n\n\t_, err := sp.InitializeBeaconStateFromEth1(st, genDeposits, genPayloadHeader, genesisFork)\n\trequire.NoError(t, err)\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), genDeposits))\n\n\t// write genesis changes to make them available for next blocks\n\t//nolint:errcheck // false positive as this has no return value\n\tctx.ConsensusCtx().(sdk.Context).MultiStore().(storetypes.CacheMultiStore).Write()\n\n\t// Test cases\n\tconsensusBlkTime := genesisTime.Add(time.Second)\n\ttests := []struct {\n\t\tname        string\n\t\tsetupMocksF func()\n\t\tpayloadTime time.Time\n\t\texpectedErr error\n\t}{\n\t\t{\n\t\t\tname: \"Payload timestamp < consensus timestamp\",\n\t\t\tsetupMocksF: func() {\n\t\t\t\tmockEngine.EXPECT().NotifyNewPayload(mock.Anything, mock.Anything, mock.Anything).Return(nil)\n\t\t\t},\n\t\t\tpayloadTime: consensusBlkTime.Add(-10 * time.Second),\n\t\t\texpectedErr: nil,\n\t\t},\n\t\t{\n\t\t\tname: \"Payload timestamp == consensus timestamp\",\n\t\t\tsetupMocksF: func() {\n\t\t\t\tmockEngine.EXPECT().NotifyNewPayload(mock.Anything, mock.Anything, mock.Anything).Return(nil)\n\t\t\t},\n\t\t\tpayloadTime: consensusBlkTime,\n\t\t\texpectedErr: nil,\n\t\t},\n\t\t{\n\t\t\tname: \"Payload timestamp > consensus timestamp\",\n\t\t\tsetupMocksF: func() {\n\t\t\t\tmockEngine.EXPECT().NotifyNewPayload(mock.Anything, mock.Anything, mock.Anything).Return(nil)\n\t\t\t},\n\t\t\tpayloadTime: consensusBlkTime.Add(time.Second),\n\t\t\texpectedErr: nil,\n\t\t},\n\t\t{\n\t\t\tname: \"Payload timestamp >> consensus timestamp\",\n\t\t\tsetupMocksF: func() {\n\t\t\t\t// no mock here, since timestamp validation fails\n\t\t\t},\n\t\t\tpayloadTime: consensusBlkTime.Add(2 * time.Second),\n\t\t\texpectedErr: payloadtime.ErrTooFarInTheFuture,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t// these test cases should not be run in parallel\n\t\t\t// since state processors is shared by them\n\t\t\ttt.setupMocksF()\n\n\t\t\t// create independent states per each test\n\t\t\tsdkCtx := sdk.NewContext(cms.CacheMultiStore(), true, log.NewNopLogger())\n\t\t\ttestSt := statedb.NewBeaconStateFromDB(\n\t\t\t\tst.KVStore.WithContext(sdkCtx), cs, sdkCtx.Logger(), metrics.NewNoOpTelemetrySink(),\n\t\t\t)\n\n\t\t\ttCtx := transition.NewTransitionCtx(\n\t\t\t\tsdkCtx,\n\t\t\t\tmath.U64(consensusBlkTime.Unix()),\n\t\t\t\tstatetransition.DummyProposerAddr,\n\t\t\t).\n\t\t\t\tWithVerifyPayload(true).\n\t\t\t\tWithVerifyRandao(false).\n\t\t\t\tWithVerifyResult(false).\n\t\t\t\tWithMeterGas(false)\n\n\t\t\tvar depRoot common.Root\n\t\t\t_, depRoot, err = ds.GetDepositsByIndex(\n\t\t\t\tctx.ConsensusCtx(),\n\t\t\t\tconstants.FirstDepositIndex,\n\t\t\t\tuint64(len(genDeposits))+cs.MaxDepositsPerBlock(),\n\t\t\t)\n\t\t\trequire.NoError(t, err)\n\n\t\t\tblk := buildNextBlock(\n\t\t\t\tt,\n\t\t\t\tcs,\n\t\t\t\ttestSt,\n\t\t\t\ttypes.NewEth1Data(depRoot),\n\t\t\t\tmath.U64(tt.payloadTime.Unix()),\n\t\t\t\tnil,\n\t\t\t\t&types.ExecutionRequests{},\n\t\t\t\ttestSt.EVMInflationWithdrawal(math.U64(tt.payloadTime.Unix())),\n\t\t\t)\n\n\t\t\t_, err = sp.Transition(tCtx, testSt, blk)\n\t\t\tif tt.expectedErr == nil {\n\t\t\t\trequire.NoError(t, err)\n\t\t\t} else {\n\t\t\t\trequire.ErrorIs(t, err, tt.expectedErr)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "state-transition/core/state_processor_randao.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core\n\nimport (\n\t\"fmt\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto/sha256\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n\t\"github.com/go-faster/xor\"\n)\n\n// processRandaoReveal processes the randao reveal and\n// ensures it matches the local state.\nfunc (sp *StateProcessor) processRandaoReveal(\n\tctx ReadOnlyContext,\n\tst *statedb.StateDB,\n\tblk *ctypes.BeaconBlock,\n) error {\n\tepoch, err := st.GetEpoch()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Ensure the proposer index is valid.\n\tproposer, err := st.ValidatorByIndex(blk.GetProposerIndex())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tgenesisValidatorsRoot, err := st.GetGenesisValidatorsRoot()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbody := blk.GetBody()\n\ttimestamp := blk.GetTimestamp()\n\tfd := ctypes.NewForkData(sp.cs.ActiveForkVersionForTimestamp(timestamp), genesisValidatorsRoot)\n\n\tif ctx.VerifyRandao() {\n\t\tsigningRoot := fd.ComputeRandaoSigningRoot(sp.cs.DomainTypeRandao(), epoch)\n\t\treveal := body.GetRandaoReveal()\n\t\tif err = sp.signer.VerifySignature(\n\t\t\tproposer.GetPubkey(),\n\t\t\tsigningRoot[:],\n\t\t\treveal,\n\t\t); err != nil {\n\t\t\treturn fmt.Errorf(\"state processor failed randao checks: %w\", err)\n\t\t}\n\t}\n\n\tprevMix, err := st.GetRandaoMixAtIndex(epoch.Unwrap() % sp.cs.EpochsPerHistoricalVector())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn st.UpdateRandaoMixAtIndex(\n\t\tepoch.Unwrap()%sp.cs.EpochsPerHistoricalVector(),\n\t\tsp.buildRandaoMix(prevMix, body.GetRandaoReveal()),\n\t)\n}\n\n// processRandaoMixesReset as defined in the Ethereum 2.0 specification.\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#randao-mixes-updates\nfunc (sp *StateProcessor) processRandaoMixesReset(\n\tst *statedb.StateDB,\n) error {\n\tepoch, err := st.GetEpoch()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tmix, err := st.GetRandaoMixAtIndex(epoch.Unwrap() % sp.cs.EpochsPerHistoricalVector())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn st.UpdateRandaoMixAtIndex((epoch.Unwrap()+1)%sp.cs.EpochsPerHistoricalVector(), mix)\n}\n\n// buildRandaoMix as defined in the Ethereum 2.0 specification.\nfunc (sp *StateProcessor) buildRandaoMix(\n\tmix common.Bytes32,\n\treveal crypto.BLSSignature,\n) common.Bytes32 {\n\tnewMix := make([]byte, constants.RootLength)\n\trevealHash := sha256.Hash(reveal[:])\n\t// Apparently this library giga fast? Good project? lmeow.\n\t// It is safe to ignore this error, since it is guaranteed that\n\t// mix[:] and revealHash[:] are both Bytes32.\n\t_ = xor.Bytes(\n\t\tnewMix, mix[:], revealHash[:],\n\t)\n\treturn common.Bytes32(newMix)\n}\n"
  },
  {
    "path": "state-transition/core/state_processor_signature.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core\n\nimport (\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n)\n\nfunc (sp *StateProcessor) GetSignatureVerifierFn(st *statedb.StateDB) (\n\tfunc(blk *ctypes.BeaconBlock, signature crypto.BLSSignature) error,\n\terror,\n) {\n\tgenesisValidatorsRoot, err := st.GetGenesisValidatorsRoot()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn func(blk *ctypes.BeaconBlock, signature crypto.BLSSignature) error {\n\t\tfd := ctypes.NewForkData(\n\t\t\tsp.cs.ActiveForkVersionForTimestamp(blk.GetTimestamp()),\n\t\t\tgenesisValidatorsRoot,\n\t\t)\n\t\tdomain := fd.ComputeDomain(sp.cs.DomainTypeProposer())\n\n\t\t//nolint:govet // shadow\n\t\tproposer, err := st.ValidatorByIndex(blk.GetProposerIndex())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tsigningRoot := ctypes.ComputeSigningRoot(blk, domain)\n\t\treturn sp.signer.VerifySignature(proposer.GetPubkey(), signingRoot[:], signature)\n\t}, nil\n}\n"
  },
  {
    "path": "state-transition/core/state_processor_staking.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core\n\nimport (\n\t\"fmt\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/berachain/beacon-kit/state-transition/core/state\"\n\t\"github.com/ethereum/go-ethereum/params\"\n)\n\n// processOperations processes the operations and ensures they match the local state.\nfunc (sp *StateProcessor) processOperations(\n\tctx ReadOnlyContext,\n\tst *state.StateDB,\n\tblk *ctypes.BeaconBlock,\n) error {\n\t// Verify that outstanding deposits are processed up to the maximum number of deposits.\n\t//\n\t// Unlike Eth 2.0 specs we don't check that\n\t// `len(body.deposits) ==  min(MAX_DEPOSITS, state.eth1_data.deposit_count - state.eth1_deposit_index)`\n\tdeposits := blk.GetBody().GetDeposits()\n\tif uint64(len(deposits)) > sp.cs.MaxDepositsPerBlock() {\n\t\treturn errors.Wrapf(\n\t\t\tErrExceedsBlockDepositLimit, \"expected: %d, got: %d\",\n\t\t\tsp.cs.MaxDepositsPerBlock(), len(deposits),\n\t\t)\n\t}\n\n\t// Instead we directly compare block deposits with our local store ones.\n\tif err := ValidateNonGenesisDeposits(\n\t\tctx.ConsensusCtx(),\n\t\tst,\n\t\tsp.ds,\n\t\tsp.cs.MaxDepositsPerBlock(),\n\t\tdeposits,\n\t\tblk.GetBody().GetEth1Data().DepositRoot,\n\t); err != nil {\n\t\treturn err\n\t}\n\n\tfor _, dep := range deposits {\n\t\tif err := sp.processDeposit(st, dep); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif version.EqualsOrIsAfter(blk.GetForkVersion(), version.Electra()) {\n\t\t// After Electra, validators can request withdrawals through execution requests which must be handled.\n\t\trequests, err := blk.GetBody().GetExecutionRequests()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tfor _, withdrawal := range requests.Withdrawals {\n\t\t\tif withdrawErr := sp.processWithdrawalRequest(st, withdrawal); withdrawErr != nil {\n\t\t\t\treturn withdrawErr\n\t\t\t}\n\t\t}\n\t}\n\n\treturn st.SetEth1Data(blk.GetBody().Eth1Data)\n}\n\n// processDeposit processes the deposit and ensures it matches the local state.\nfunc (sp *StateProcessor) processDeposit(st *state.StateDB, dep *ctypes.Deposit) error {\n\teth1DepositIndex, err := st.GetEth1DepositIndex()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err = st.SetEth1DepositIndex(eth1DepositIndex + 1); err != nil {\n\t\treturn err\n\t}\n\n\tsp.logger.Info(\n\t\t\"Processed deposit to set Eth 1 deposit index\",\n\t\t\"previous\", eth1DepositIndex, \"new\", eth1DepositIndex+1,\n\t)\n\tif err = sp.applyDeposit(st, dep); err != nil {\n\t\treturn fmt.Errorf(\"failed to apply deposit: %w\", err)\n\t}\n\treturn nil\n}\n\n// applyDeposit processes the deposit and ensures it matches the local state.\nfunc (sp *StateProcessor) applyDeposit(st *state.StateDB, dep *ctypes.Deposit) error {\n\tidx, err := st.ValidatorIndexByPubkey(dep.GetPubkey())\n\tif err != nil {\n\t\tsp.logger.Info(\"Validator does not exist so creating\",\n\t\t\t\"pubkey\", dep.GetPubkey(), \"index\", dep.GetIndex(), \"deposit_amount\", dep.GetAmount())\n\t\t// If the validator does not exist, we add the validator.\n\t\t// TODO: improve error handling by distinguishing\n\t\t// ErrNotFound from other kind of errors\n\t\treturn sp.createValidator(st, dep)\n\t}\n\n\t// if validator exist, just update its balance\n\tif err = st.IncreaseBalance(idx, dep.GetAmount()); err != nil {\n\t\treturn err\n\t}\n\n\tsp.logger.Info(\n\t\t\"Processed deposit to increase balance\",\n\t\t\"deposit_amount\", float64(dep.GetAmount().Unwrap())/params.GWei,\n\t\t\"validator_index\", idx,\n\t)\n\treturn nil\n}\n\n// createValidator creates a validator if the deposit is valid.\nfunc (sp *StateProcessor) createValidator(st *state.StateDB, dep *ctypes.Deposit) error {\n\t// Get the current slot.\n\tslot, err := st.GetSlot()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// At genesis, the validators sign over an empty root.\n\tgenesisValidatorsRoot := common.Root{}\n\tif slot != 0 {\n\t\t// Get the genesis validators root to be used to find fork data later.\n\t\tgenesisValidatorsRoot, err = st.GetGenesisValidatorsRoot()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// Check that the deposit has the ETH1 withdrawal credentials.\n\tif !dep.HasEth1WithdrawalCredentials() {\n\t\tsp.logger.Warn(\n\t\t\t\"adding validator with non-ETH1 withdrawal credentials -- NOT withdrawable\",\n\t\t\t\"pubkey\", dep.GetPubkey().String(),\n\t\t\t\"deposit_index\", dep.GetIndex(),\n\t\t\t\"amount_gwei\", dep.GetAmount().Unwrap(),\n\t\t)\n\t\tsp.metrics.incrementValidatorNotWithdrawable()\n\t}\n\n\t// Verify that the message was signed correctly.\n\terr = dep.VerifySignature(\n\t\tctypes.NewForkData(\n\t\t\t// Deposits must be signed with GENESIS_FORK_VERSION.\n\t\t\tsp.cs.GenesisForkVersion(),\n\t\t\tgenesisValidatorsRoot,\n\t\t),\n\t\tsp.cs.DomainTypeDeposit(),\n\t\tsp.signer.VerifySignature,\n\t)\n\tif err != nil {\n\t\t// Ignore deposits that fail the signature check.\n\t\tsp.logger.Warn(\n\t\t\t\"failed deposit signature verification\",\n\t\t\t\"pubkey\", dep.GetPubkey().String(),\n\t\t\t\"deposit_index\", dep.GetIndex(),\n\t\t\t\"amount_gwei\", dep.GetAmount().Unwrap(),\n\t\t\t\"error\", err,\n\t\t)\n\t\tsp.metrics.incrementDepositStakeLost()\n\t\treturn nil\n\t}\n\n\t// Add the validator to the registry.\n\treturn sp.addValidatorToRegistry(st, dep)\n}\n\n// addValidatorToRegistry adds a validator to the registry.\nfunc (sp *StateProcessor) addValidatorToRegistry(st *state.StateDB, dep *ctypes.Deposit) error {\n\tval := ctypes.NewValidatorFromDeposit(\n\t\tdep.GetPubkey(),\n\t\tdep.GetWithdrawalCredentials(),\n\t\tdep.GetAmount(),\n\t\tsp.cs.EffectiveBalanceIncrement(),\n\t\tsp.cs.MaxEffectiveBalance(),\n\t)\n\n\tif err := st.AddValidator(val); err != nil {\n\t\treturn err\n\t}\n\tidx, err := st.ValidatorIndexByPubkey(val.GetPubkey())\n\tif err != nil {\n\t\treturn err\n\t}\n\tif err = st.IncreaseBalance(idx, dep.GetAmount()); err != nil {\n\t\treturn err\n\t}\n\tsp.logger.Info(\n\t\t\"Processed deposit to create new validator\",\n\t\t\"deposit_amount\", float64(dep.GetAmount().Unwrap())/params.GWei,\n\t\t\"validator_index\", idx, \"withdrawal_epoch\", val.GetWithdrawableEpoch(),\n\t)\n\treturn nil\n}\n"
  },
  {
    "path": "state-transition/core/state_processor_staking_test.go",
    "content": "//go:build test\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n\tstatetransition \"github.com/berachain/beacon-kit/testing/state-transition\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// TestTransitionUpdateValidators shows that when validator is\n// updated (increasing amount), corresponding balance is updated.\n//\n//nolint:paralleltest // uses envars\nfunc TestTransitionUpdateValidators(t *testing.T) {\n\tcs := setupChain(t)\n\tsp, st, ds, ctx, _, _ := statetransition.SetupTestState(t, cs)\n\n\tvar (\n\t\tmaxBalance       = cs.MaxEffectiveBalance()\n\t\tincrement        = cs.EffectiveBalanceIncrement()\n\t\tminBalance       = cs.MinActivationBalance()\n\t\temptyCredentials = types.NewCredentialsFromExecutionAddress(common.ExecutionAddress{})\n\t)\n\n\t// STEP 0: Setup initial state via genesis\n\tvar (\n\t\tgenDeposits = types.Deposits{\n\t\t\t{\n\t\t\t\tPubkey:      [48]byte{0x00},\n\t\t\t\tCredentials: emptyCredentials,\n\t\t\t\tAmount:      minBalance + increment,\n\t\t\t\tIndex:       uint64(0),\n\t\t\t},\n\t\t\t{\n\t\t\t\tPubkey:      [48]byte{0x01},\n\t\t\t\tCredentials: emptyCredentials,\n\t\t\t\tAmount:      maxBalance - 6*increment,\n\t\t\t\tIndex:       uint64(1),\n\t\t\t},\n\t\t\t{\n\t\t\t\tPubkey:      [48]byte{0x03},\n\t\t\t\tCredentials: emptyCredentials,\n\t\t\t\tAmount:      maxBalance - 3*increment,\n\t\t\t\tIndex:       uint64(2),\n\t\t\t},\n\t\t}\n\t\tgenPayloadHeader = &types.ExecutionPayloadHeader{\n\t\t\tVersionable: types.NewVersionable(cs.GenesisForkVersion()),\n\t\t}\n\t\ttotalDepositsCount = uint64(len(genDeposits))\n\t)\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), genDeposits))\n\tvalDiff, err := sp.InitializeBeaconStateFromEth1(\n\t\tst,\n\t\tgenDeposits,\n\t\tgenPayloadHeader,\n\t\tcs.GenesisForkVersion(),\n\t)\n\trequire.NoError(t, err)\n\trequire.Len(t, valDiff, len(genDeposits))\n\n\t// STEP 1: top up a genesis validator balance\n\tblkDeposit := &types.Deposit{\n\t\tPubkey:      genDeposits[2].Pubkey,\n\t\tCredentials: emptyCredentials,\n\t\tAmount:      2 * increment, // twice to account for hysteresis\n\t\tIndex:       uint64(len(genDeposits)),\n\t}\n\tblkDeposits := []*types.Deposit{blkDeposit}\n\ttotalDepositsCount++\n\n\t// make sure included deposit is already available in deposit store\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), blkDeposits))\n\tvar depRoot common.Root\n\t_, depRoot, err = ds.GetDepositsByIndex(ctx.ConsensusCtx(), constants.FirstDepositIndex, totalDepositsCount)\n\trequire.NoError(t, err)\n\n\tblk1 := buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\t10,\n\t\tblkDeposits,\n\t\t&types.ExecutionRequests{},\n\t\tst.EVMInflationWithdrawal(10),\n\t)\n\n\t// run the test\n\tvalDiff, err = sp.Transition(ctx, st, blk1)\n\trequire.NoError(t, err)\n\trequire.Empty(t, valDiff) // validators set updates only at epoch turn\n\n\t// check validator balances are duly updated, that is:\n\t// - balance is updated immediately\n\t// - effective balance is updated only at the epoch turn\n\texpectedBalance := genDeposits[2].Amount + blkDeposit.Amount\n\texpectedEffectiveBalance := genDeposits[2].Amount\n\tidx, err := st.ValidatorIndexByPubkey(genDeposits[2].Pubkey)\n\trequire.NoError(t, err)\n\n\tbalance, err := st.GetBalance(idx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, expectedBalance, balance)\n\n\tval, err := st.ValidatorByIndex(idx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, expectedEffectiveBalance, val.EffectiveBalance)\n\n\t// check that validator index is still correct\n\tlatestValIdx, err := st.GetEth1DepositIndex()\n\trequire.NoError(t, err)\n\trequire.Equal(t, uint64(len(genDeposits)+1), latestValIdx)\n\n\t// STEP 2: check that effective balance is updated once next epoch arrives\n\tblk := moveToEndOfEpoch(t, blk1, cs, sp, st, ctx, depRoot)\n\n\t// finally the block turning epoch\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblk.GetTimestamp()+1,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{},\n\t\tst.EVMInflationWithdrawal(blk.GetTimestamp()+1),\n\t)\n\n\tvalDiff, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\trequire.Len(t, valDiff, 1) // just topped up one validator\n\trequire.Equal(\n\t\tt,\n\t\t&transition.ValidatorUpdate{\n\t\t\tPubkey:           blkDeposit.Pubkey,\n\t\t\tEffectiveBalance: expectedBalance,\n\t\t},\n\t\tvalDiff[0],\n\t)\n\texpectedEffectiveBalance = expectedBalance\n\n\tbalance, err = st.GetBalance(idx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, expectedBalance, balance)\n\n\tval, err = st.ValidatorByIndex(idx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, expectedEffectiveBalance, val.EffectiveBalance)\n}\n\n// TestTransitionCreateValidator shows the lifecycle\n// of a validator creation.\n//\n//nolint:paralleltest // uses envars\nfunc TestTransitionCreateValidator(t *testing.T) {\n\t// Create state processor to test\n\tcs := setupChain(t)\n\tsp, st, ds, ctx, _, _ := statetransition.SetupTestState(t, cs)\n\n\tvar (\n\t\tmaxBalance       = cs.MaxEffectiveBalance()\n\t\tincrement        = cs.EffectiveBalanceIncrement()\n\t\tminBalance       = cs.MinActivationBalance()\n\t\temptyAddress     = common.ExecutionAddress{}\n\t\temptyCredentials = types.NewCredentialsFromExecutionAddress(emptyAddress)\n\t)\n\n\t// STEP 0: Setup initial state via genesis\n\tvar (\n\t\tgenDeposits = types.Deposits{\n\t\t\t{\n\t\t\t\tPubkey:      [48]byte{0x01},\n\t\t\t\tCredentials: emptyCredentials,\n\t\t\t\tAmount:      minBalance + increment,\n\t\t\t\tIndex:       uint64(0),\n\t\t\t},\n\t\t}\n\t\tgenPayloadHeader = &types.ExecutionPayloadHeader{\n\t\t\tVersionable: types.NewVersionable(cs.GenesisForkVersion()),\n\t\t}\n\t\ttotalDepositsCount = uint64(len(genDeposits))\n\t)\n\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), genDeposits))\n\tgenVals, err := sp.InitializeBeaconStateFromEth1(\n\t\tst,\n\t\tgenDeposits,\n\t\tgenPayloadHeader,\n\t\tcs.GenesisForkVersion(),\n\t)\n\trequire.NoError(t, err)\n\trequire.Len(t, genVals, len(genDeposits))\n\n\t// STEP 1: create a new validator\n\tblkDeposit := &types.Deposit{\n\t\tPubkey:      [48]byte{0xff}, // a new key for a new validator\n\t\tCredentials: emptyCredentials,\n\t\tAmount:      maxBalance,\n\t\tIndex:       uint64(len(genDeposits)),\n\t}\n\tblkDeposits := []*types.Deposit{blkDeposit}\n\ttotalDepositsCount++\n\n\t// make sure included deposit is already available in deposit store\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), blkDeposits))\n\tvar depRoot common.Root\n\t_, depRoot, err = ds.GetDepositsByIndex(ctx.ConsensusCtx(), constants.FirstDepositIndex, totalDepositsCount)\n\trequire.NoError(t, err)\n\n\tblk1 := buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\t10,\n\t\tblkDeposits,\n\t\t&types.ExecutionRequests{},\n\t\tst.EVMInflationWithdrawal(10),\n\t)\n\n\t// run the test\n\tvalDiff, err := sp.Transition(ctx, st, blk1)\n\trequire.NoError(t, err)\n\trequire.Empty(t, valDiff) // validators set updates only at epoch turn\n\n\t// check validator balances are duly updated\n\tvar (\n\t\texpectedBalance          = blkDeposit.Amount\n\t\texpectedEffectiveBalance = expectedBalance\n\t)\n\tidx, err := st.ValidatorIndexByPubkey(blkDeposit.Pubkey)\n\trequire.NoError(t, err)\n\n\tbalance, err := st.GetBalance(idx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, expectedBalance, balance)\n\n\tval, err := st.ValidatorByIndex(idx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, expectedEffectiveBalance, val.EffectiveBalance)\n\n\t// check that validator index is still correct\n\tlatestValIdx, err := st.GetEth1DepositIndex()\n\trequire.NoError(t, err)\n\trequire.Equal(t, uint64(len(genDeposits)+1), latestValIdx)\n\n\t// STEP 2: move the chain to the next epoch and show that\n\t// the extra validator is eligible for activation\n\tblk := moveToEndOfEpoch(t, blk1, cs, sp, st, ctx, depRoot)\n\n\t// finally the block turning epoch\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblk.GetTimestamp()+1,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{},\n\t\tst.EVMInflationWithdrawal(blk.GetTimestamp()+1),\n\t)\n\n\tvalDiff, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\trequire.Empty(t, valDiff) // new validator is only eligible for activation\n\n\textraValIdx, err := st.ValidatorIndexByPubkey(blkDeposit.Pubkey)\n\trequire.NoError(t, err)\n\textraVal, err := st.ValidatorByIndex(extraValIdx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, math.Epoch(1), extraVal.ActivationEligibilityEpoch)\n\trequire.Equal(\n\t\tt,\n\t\tconstants.FarFutureEpoch,\n\t\textraVal.ActivationEpoch,\n\t)\n\trequire.Equal(t, constants.FarFutureEpoch, extraVal.ExitEpoch)\n\trequire.Equal(\n\t\tt,\n\t\tconstants.FarFutureEpoch,\n\t\textraVal.WithdrawableEpoch,\n\t)\n\n\t// STEP 3: move the chain to the next epoch and show that\n\t// the extra validator is activate\n\t_ = moveToEndOfEpoch(t, blk, cs, sp, st, ctx, depRoot)\n\n\t// finally the block turning epoch\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblk.GetTimestamp()+1,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{},\n\t\tst.EVMInflationWithdrawal(blk.GetTimestamp()+1),\n\t)\n\n\t// run the test\n\tvalDiff, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\trequire.Len(t, valDiff, 1)\n\trequire.Equal(\n\t\tt,\n\t\t&transition.ValidatorUpdate{\n\t\t\tPubkey:           blkDeposit.Pubkey,\n\t\t\tEffectiveBalance: expectedBalance,\n\t\t},\n\t\tvalDiff[0],\n\t)\n\n\textraVal, err = st.ValidatorByIndex(extraValIdx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, math.Epoch(1), extraVal.ActivationEligibilityEpoch)\n\trequire.Equal(t, math.Epoch(2), extraVal.ActivationEpoch)\n\trequire.Equal(t, constants.FarFutureEpoch, extraVal.ExitEpoch)\n\trequire.Equal(\n\t\tt,\n\t\tconstants.FarFutureEpoch,\n\t\textraVal.WithdrawableEpoch,\n\t)\n\n\texpectedBalance = blkDeposit.Amount\n\texpectedEffectiveBalance = expectedBalance\n\n\tbalance, err = st.GetBalance(idx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, expectedBalance, balance)\n\n\tval, err = st.ValidatorByIndex(idx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, expectedEffectiveBalance, val.EffectiveBalance)\n}\n\n// TestTransitionHittingValidatorsCap shows that the extra\n// validator added when validators set is at cap gets never activated\n// and its deposit is returned at after next epoch starts.\nfunc TestTransitionHittingValidatorsCap_ExtraSmall(t *testing.T) {\n\tt.Parallel()\n\tcs := setupChain(t)\n\tsp, st, ds, ctx, _, _ := statetransition.SetupTestState(t, cs)\n\n\tvar (\n\t\tmaxBalance = cs.MaxEffectiveBalance()\n\t\tminBalance = cs.MinActivationBalance()\n\t\trndSeed    = 2024 // seed used to generate unique random value\n\t)\n\n\t// STEP 0: Setup genesis with GetValidatorSetCap validators\n\t// TODO: consider instead setting state artificially\n\tvar (\n\t\tgenDeposits      = make(types.Deposits, 0, cs.ValidatorSetCap())\n\t\tgenPayloadHeader = &types.ExecutionPayloadHeader{\n\t\t\tVersionable: types.NewVersionable(cs.GenesisForkVersion()),\n\t\t}\n\t\ttotalDepositsCount = cs.ValidatorSetCap()\n\t)\n\n\t// let genesis define all available validators\n\tfor idx := range cs.ValidatorSetCap() {\n\t\tvar (\n\t\t\tkey   bytes.B48\n\t\t\tcreds types.WithdrawalCredentials\n\t\t)\n\t\tkey, rndSeed = generateTestPK(t, rndSeed)\n\t\tcreds, rndSeed = generateTestExecutionAddress(t, rndSeed)\n\n\t\tgenDeposits = append(\n\t\t\tgenDeposits,\n\t\t\t&types.Deposit{\n\t\t\t\tPubkey:      key,\n\t\t\t\tCredentials: creds,\n\t\t\t\tAmount:      maxBalance,\n\t\t\t\tIndex:       idx,\n\t\t\t},\n\t\t)\n\t}\n\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), genDeposits))\n\t_, err := sp.InitializeBeaconStateFromEth1(\n\t\tst,\n\t\tgenDeposits,\n\t\tgenPayloadHeader,\n\t\tcs.GenesisForkVersion(),\n\t)\n\trequire.NoError(t, err)\n\n\t// STEP 1: Try and add an extra validator\n\textraValKey, rndSeed := generateTestPK(t, rndSeed)\n\textraValCreds, _ := generateTestExecutionAddress(t, rndSeed)\n\tvar (\n\t\textraValDeposit = &types.Deposit{\n\t\t\tPubkey:      extraValKey,\n\t\t\tCredentials: extraValCreds,\n\t\t\tAmount:      minBalance,\n\t\t\tIndex:       uint64(len(genDeposits)),\n\t\t}\n\t\tblkDeposits = []*types.Deposit{extraValDeposit}\n\t)\n\ttotalDepositsCount++\n\n\t// make sure included deposit is already available in deposit store\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), blkDeposits))\n\tvar depRoot common.Root\n\t_, depRoot, err = ds.GetDepositsByIndex(ctx.ConsensusCtx(), constants.FirstDepositIndex, totalDepositsCount)\n\trequire.NoError(t, err)\n\n\tblk1 := buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\t10,\n\t\tblkDeposits,\n\t\t&types.ExecutionRequests{},\n\t\tst.EVMInflationWithdrawal(10),\n\t)\n\n\t// run the test\n\tvalDiff, err := sp.Transition(ctx, st, blk1)\n\trequire.NoError(t, err)\n\trequire.Empty(t, valDiff)\n\n\textraValIdx, err := st.ValidatorIndexByPubkey(extraValDeposit.Pubkey)\n\trequire.NoError(t, err)\n\textraVal, err := st.ValidatorByIndex(extraValIdx)\n\trequire.NoError(t, err)\n\trequire.Equal(\n\t\tt,\n\t\tconstants.FarFutureEpoch,\n\t\textraVal.ActivationEligibilityEpoch,\n\t)\n\trequire.Equal(\n\t\tt,\n\t\tconstants.FarFutureEpoch,\n\t\textraVal.ActivationEpoch,\n\t)\n\trequire.Equal(t, constants.FarFutureEpoch, extraVal.ExitEpoch)\n\trequire.Equal(\n\t\tt,\n\t\tconstants.FarFutureEpoch,\n\t\textraVal.WithdrawableEpoch,\n\t)\n\n\t// STEP 2: move the chain to the next epoch and show that\n\t// the extra validator is eligible for activation\n\tblk := moveToEndOfEpoch(t, blk1, cs, sp, st, ctx, depRoot)\n\n\t// finally the block turning epoch\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblk.GetTimestamp()+1,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{},\n\t\tst.EVMInflationWithdrawal(blk.GetTimestamp()+1),\n\t)\n\n\t// run the test\n\tvalDiff, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\trequire.Empty(t, valDiff)\n\n\t// check extra validator is added with Withdraw epoch duly set\n\textraVal, err = st.ValidatorByIndex(extraValIdx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, math.Epoch(1), extraVal.ActivationEligibilityEpoch)\n\trequire.Equal(\n\t\tt,\n\t\tconstants.FarFutureEpoch,\n\t\textraVal.ActivationEpoch,\n\t)\n\trequire.Equal(t, constants.FarFutureEpoch, extraVal.ExitEpoch)\n\trequire.Equal(\n\t\tt,\n\t\tconstants.FarFutureEpoch,\n\t\textraVal.WithdrawableEpoch,\n\t)\n\n\t// STEP 3: move the chain to the next epoch and show that the extra\n\t// validator is activate and immediately marked for exit\n\tblk = moveToEndOfEpoch(t, blk, cs, sp, st, ctx, depRoot)\n\n\t// finally the block turning epoch\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblk.GetTimestamp()+1,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{},\n\t\tst.EVMInflationWithdrawal(blk.GetTimestamp()+1),\n\t)\n\n\t// run the test\n\tvalDiff, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\trequire.Empty(t, valDiff)\n\n\textraVal, err = st.ValidatorByIndex(extraValIdx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, constants.GenesisEpoch+1, extraVal.ActivationEligibilityEpoch)\n\trequire.Equal(t, constants.GenesisEpoch+2, extraVal.ActivationEpoch)\n\trequire.Equal(t, constants.GenesisEpoch+2, extraVal.ExitEpoch)\n\t// After electra, the withdrawable epoch is exitEpoch + sp.cs.MinValidatorWithdrawabilityDelay())\n\trequire.Equal(t, cs.MinValidatorWithdrawabilityDelay()+extraVal.ExitEpoch, extraVal.WithdrawableEpoch)\n\n\t// STEP 4: move the chain to the MinValidatorWithdrawabilityDelay epoch and show withdrawals\n\t// for rejected validator are enqueued then\n\tepoch := cs.SlotToEpoch(blk.Slot)\n\trequire.Equal(t, math.Epoch(2), epoch)\n\n\tfor i := epoch; i < extraVal.WithdrawableEpoch; i++ {\n\t\tblk = moveToEndOfEpoch(t, blk, cs, sp, st, ctx, depRoot)\n\t\t// Epoch turning block\n\t\tblk = buildNextBlock(\n\t\t\tt,\n\t\t\tcs,\n\t\t\tst,\n\t\t\ttypes.NewEth1Data(depRoot),\n\t\t\tblk.GetTimestamp()+1,\n\t\t\t[]*types.Deposit{},\n\t\t\t&types.ExecutionRequests{},\n\t\t\tst.EVMInflationWithdrawal(blk.GetTimestamp()+1),\n\t\t)\n\t\t_, err = sp.Transition(ctx, st, blk)\n\t\trequire.NoError(t, err)\n\t}\n\n\tepoch = cs.SlotToEpoch(blk.Slot)\n\trequire.Equal(t, extraVal.ExitEpoch+cs.MinValidatorWithdrawabilityDelay(), epoch)\n\n\t// Extra validator deposits will be withdrawn within 3 blocks (#Validator / MaxValidatorsPerWithdrawalsSweep)\n\textraValAddr, err := extraValCreds.ToExecutionAddress()\n\trequire.NoError(t, err)\n\n\textraValBalance, err := st.GetBalance(extraValIdx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, extraValBalance, minBalance)\n\n\twithdrawals := []*engineprimitives.Withdrawal{\n\t\tst.EVMInflationWithdrawal(blk.GetTimestamp() + 1),\n\t\t{\n\t\t\tIndex:     0,\n\t\t\tValidator: extraValIdx,\n\t\t\tAddress:   extraValAddr,\n\t\t\tAmount:    extraValDeposit.Amount,\n\t\t},\n\t}\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblk.GetTimestamp()+1,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{},\n\t\twithdrawals...,\n\t)\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\n\textraValBalance, err = st.GetBalance(extraValIdx)\n\trequire.NoError(t, err)\n\n\trequire.Equal(t, extraValBalance, math.Gwei(0))\n}\n\n// TestTransitionHittingValidatorsCap shows that if an extra validator is added with a higher amount of stake than the lowest validator\n// when the validator set is at cap, the lowest validator is removed at the beginning of next epoch, i.e. replaced by the new validator.\n//\n//nolint:maintidx // this end‑to‑end staking‑cap scenario is inherently complex\nfunc TestTransitionHittingValidatorsCap_ExtraBig(t *testing.T) {\n\tt.Parallel()\n\tcs := setupChain(t)\n\tsp, st, ds, ctx, _, _ := statetransition.SetupTestState(t, cs)\n\n\tvar (\n\t\tmaxBalance = cs.MaxEffectiveBalance()\n\t\tminBalance = cs.MinActivationBalance()\n\t\trndSeed    = 2024 // seed used to generate unique random value\n\t)\n\n\t// STEP 0: Setup genesis with GetValidatorSetCap validators\n\t// TODO: consider instead setting state artificially\n\tvar (\n\t\tgenDeposits      = make(types.Deposits, 0, cs.ValidatorSetCap())\n\t\tgenPayloadHeader = &types.ExecutionPayloadHeader{\n\t\t\tVersionable: types.NewVersionable(cs.GenesisForkVersion()),\n\t\t}\n\t\ttotalDepositsCount = cs.ValidatorSetCap()\n\t)\n\n\t// let genesis define all available validators\n\tfor idx := range cs.ValidatorSetCap() {\n\t\tvar (\n\t\t\tkey   bytes.B48\n\t\t\tcreds types.WithdrawalCredentials\n\t\t)\n\t\tkey, rndSeed = generateTestPK(t, rndSeed)\n\t\tcreds, rndSeed = generateTestExecutionAddress(t, rndSeed)\n\n\t\tgenDeposits = append(\n\t\t\tgenDeposits,\n\t\t\t&types.Deposit{\n\t\t\t\tPubkey:      key,\n\t\t\t\tCredentials: creds,\n\t\t\t\tAmount:      maxBalance,\n\t\t\t\tIndex:       idx,\n\t\t\t},\n\t\t)\n\t}\n\t// make a deposit small to be ready for eviction\n\tgenDeposits[0].Amount = minBalance\n\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), genDeposits))\n\tgenVals, err := sp.InitializeBeaconStateFromEth1(\n\t\tst,\n\t\tgenDeposits,\n\t\tgenPayloadHeader,\n\t\tcs.GenesisForkVersion(),\n\t)\n\trequire.NoError(t, err)\n\trequire.Len(t, genVals, len(genDeposits))\n\n\t// STEP 1: Add an extra validator\n\textraValKey, rndSeed := generateTestPK(t, rndSeed)\n\textraValCreds, _ := generateTestExecutionAddress(t, rndSeed)\n\tvar (\n\t\textraValDeposit = &types.Deposit{\n\t\t\tPubkey:      extraValKey,\n\t\t\tCredentials: extraValCreds,\n\t\t\tAmount:      maxBalance,\n\t\t\tIndex:       uint64(len(genDeposits)),\n\t\t}\n\t\tblkDeposits = []*types.Deposit{extraValDeposit}\n\t)\n\ttotalDepositsCount++\n\n\t// make sure included deposit is already available in deposit store\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), blkDeposits))\n\tvar depRoot common.Root\n\t_, depRoot, err = ds.GetDepositsByIndex(ctx.ConsensusCtx(), constants.FirstDepositIndex, totalDepositsCount)\n\trequire.NoError(t, err)\n\n\tblk1 := buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\t10,\n\t\t[]*types.Deposit{extraValDeposit},\n\t\t&types.ExecutionRequests{},\n\t\tst.EVMInflationWithdrawal(10),\n\t)\n\n\t// run the test\n\tvalDiff, err := sp.Transition(ctx, st, blk1)\n\trequire.NoError(t, err)\n\trequire.Empty(t, valDiff)\n\n\textraValIdx, err := st.ValidatorIndexByPubkey(extraValDeposit.Pubkey)\n\trequire.NoError(t, err)\n\textraVal, err := st.ValidatorByIndex(extraValIdx)\n\trequire.NoError(t, err)\n\trequire.Equal(\n\t\tt,\n\t\tconstants.FarFutureEpoch,\n\t\textraVal.ActivationEligibilityEpoch,\n\t)\n\trequire.Equal(\n\t\tt,\n\t\tconstants.FarFutureEpoch,\n\t\textraVal.ActivationEpoch,\n\t)\n\trequire.Equal(t, constants.FarFutureEpoch, extraVal.ExitEpoch)\n\trequire.Equal(\n\t\tt,\n\t\tconstants.FarFutureEpoch,\n\t\textraVal.WithdrawableEpoch,\n\t)\n\n\tsmallestValIdx, err := st.ValidatorIndexByPubkey(genDeposits[0].Pubkey)\n\trequire.NoError(t, err)\n\tsmallestVal, err := st.ValidatorByIndex(smallestValIdx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, constants.GenesisEpoch, smallestVal.ActivationEligibilityEpoch)\n\trequire.Equal(t, constants.GenesisEpoch, smallestVal.ActivationEpoch)\n\trequire.Equal(\n\t\tt,\n\t\tconstants.FarFutureEpoch,\n\t\tsmallestVal.ExitEpoch,\n\t)\n\trequire.Equal(\n\t\tt,\n\t\tconstants.FarFutureEpoch,\n\t\tsmallestVal.WithdrawableEpoch,\n\t)\n\n\t// STEP 2: move the chain to the next epoch and show that\n\t// the extra validator is eligible for activation\n\tblk := moveToEndOfEpoch(t, blk1, cs, sp, st, ctx, depRoot)\n\n\t// finally the block turning epoch\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblk.GetTimestamp()+1,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{},\n\t\tst.EVMInflationWithdrawal(blk.GetTimestamp()+1),\n\t)\n\n\t// run the test\n\tvalDiff, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\trequire.Empty(t, valDiff)\n\n\t// check extra validator is added with Withdraw epoch duly set\n\textraVal, err = st.ValidatorByIndex(extraValIdx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, math.Epoch(1), extraVal.ActivationEligibilityEpoch)\n\trequire.Equal(\n\t\tt,\n\t\tconstants.FarFutureEpoch,\n\t\textraVal.ActivationEpoch,\n\t)\n\trequire.Equal(t, constants.FarFutureEpoch, extraVal.ExitEpoch)\n\trequire.Equal(\n\t\tt,\n\t\tconstants.FarFutureEpoch,\n\t\textraVal.WithdrawableEpoch,\n\t)\n\n\tsmallestVal, err = st.ValidatorByIndex(smallestValIdx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, constants.GenesisEpoch, smallestVal.ActivationEligibilityEpoch)\n\trequire.Equal(t, constants.GenesisEpoch, smallestVal.ActivationEpoch)\n\trequire.Equal(\n\t\tt,\n\t\tconstants.FarFutureEpoch,\n\t\tsmallestVal.ExitEpoch,\n\t)\n\trequire.Equal(\n\t\tt,\n\t\tconstants.FarFutureEpoch,\n\t\tsmallestVal.WithdrawableEpoch,\n\t)\n\n\t// STEP 3: move the chain to the next epoch and show that the extra\n\t// validator is activated and genesis validator immediately marked for exit\n\tblk = moveToEndOfEpoch(t, blk, cs, sp, st, ctx, depRoot)\n\n\t// finally the block turning epoch\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblk.GetTimestamp()+1,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{},\n\t\tst.EVMInflationWithdrawal(blk.GetTimestamp()+1),\n\t)\n\n\t// run the test\n\tvalDiff, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\trequire.Len(t, valDiff, 2)\n\trequire.Equal(\n\t\tt,\n\t\t&transition.ValidatorUpdate{\n\t\t\tPubkey:           extraVal.Pubkey,\n\t\t\tEffectiveBalance: extraVal.EffectiveBalance,\n\t\t},\n\t\tvalDiff[0],\n\t)\n\trequire.Equal(\n\t\tt,\n\t\t&transition.ValidatorUpdate{\n\t\t\tPubkey:           smallestVal.Pubkey,\n\t\t\tEffectiveBalance: 0,\n\t\t},\n\t\tvalDiff[1],\n\t)\n\n\textraVal, err = st.ValidatorByIndex(extraValIdx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, constants.GenesisEpoch+1, extraVal.ActivationEligibilityEpoch)\n\trequire.Equal(t, constants.GenesisEpoch+2, extraVal.ActivationEpoch)\n\trequire.Equal(t, constants.FarFutureEpoch, extraVal.ExitEpoch)\n\trequire.Equal(\n\t\tt,\n\t\tconstants.FarFutureEpoch,\n\t\textraVal.WithdrawableEpoch,\n\t)\n\n\tsmallestVal, err = st.ValidatorByIndex(smallestValIdx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, constants.GenesisEpoch, smallestVal.ActivationEligibilityEpoch)\n\trequire.Equal(t, constants.GenesisEpoch, smallestVal.ActivationEpoch)\n\trequire.Equal(t, constants.GenesisEpoch+2, smallestVal.ExitEpoch)\n\trequire.Equal(t, smallestVal.ExitEpoch+cs.MinValidatorWithdrawabilityDelay(), smallestVal.WithdrawableEpoch)\n\n\tepoch := cs.SlotToEpoch(blk.Slot)\n\trequire.Equal(t, math.Epoch(2), epoch)\n\n\t// STEP 4: move the chain to the MinValidatorWithdrawabilityDelay epoch and show withdrawals\n\t// for rejected validator are enqueued within 3 blocks\n\t// (#Validator / MaxValidatorsPerWithdrawalsSweep))\n\tfor i := epoch; i < smallestVal.WithdrawableEpoch; i++ {\n\t\tblk = moveToEndOfEpoch(t, blk, cs, sp, st, ctx, depRoot)\n\t\t// Epoch turning block\n\t\tblk = buildNextBlock(\n\t\t\tt,\n\t\t\tcs,\n\t\t\tst,\n\t\t\ttypes.NewEth1Data(depRoot),\n\t\t\tblk.GetTimestamp()+1,\n\t\t\t[]*types.Deposit{},\n\t\t\t&types.ExecutionRequests{},\n\t\t\tst.EVMInflationWithdrawal(blk.GetTimestamp()+1),\n\t\t)\n\t\t_, err = sp.Transition(ctx, st, blk)\n\t\trequire.NoError(t, err)\n\t}\n\n\tepoch = cs.SlotToEpoch(blk.Slot)\n\trequire.Equal(t, smallestVal.ExitEpoch+cs.MinValidatorWithdrawabilityDelay(), epoch)\n\n\tvalToEvict := genDeposits[0]\n\tvalToEvictAddr, err := valToEvict.Credentials.ToExecutionAddress()\n\trequire.NoError(t, err)\n\n\twithdrawals := []*engineprimitives.Withdrawal{\n\t\tst.EVMInflationWithdrawal(blk.GetTimestamp() + 1),\n\t\t{\n\t\t\tIndex:     0,\n\t\t\tValidator: smallestValIdx,\n\t\t\tAddress:   valToEvictAddr,\n\t\t\tAmount:    valToEvict.Amount,\n\t\t},\n\t}\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblk.GetTimestamp()+1,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{},\n\t\twithdrawals...,\n\t)\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n}\n"
  },
  {
    "path": "state-transition/core/state_processor_test.go",
    "content": "//go:build test\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core_test\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tstatetransition \"github.com/berachain/beacon-kit/testing/state-transition\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestStateProcessor_ProcessSlots(t *testing.T) {\n\tt.Parallel()\n\tcs := setupChain(t)\n\t//nolint:dogsled // used for testing\n\tsp, st, _, _, _, _ := statetransition.SetupTestState(t, cs)\n\n\t// Initialize state with genesis.\n\tgenesisTime := time.Now().Truncate(time.Second)\n\tvar (\n\t\tgenDeposits = types.Deposits{\n\t\t\t{\n\t\t\t\tPubkey:      [48]byte{0x00},\n\t\t\t\tCredentials: types.NewCredentialsFromExecutionAddress(common.ExecutionAddress{}),\n\t\t\t\tAmount:      cs.MaxEffectiveBalance(),\n\t\t\t\tIndex:       0,\n\t\t\t},\n\t\t}\n\t\tgenPayloadHeader = &types.ExecutionPayloadHeader{\n\t\t\tVersionable: types.NewVersionable(cs.GenesisForkVersion()),\n\t\t}\n\t)\n\tgenPayloadHeader.Timestamp = math.U64(genesisTime.Unix())\n\t_, err := sp.InitializeBeaconStateFromEth1(\n\t\tst, genDeposits, genPayloadHeader, cs.GenesisForkVersion(),\n\t)\n\trequire.NoError(t, err)\n\n\t// Grab slot that will result in epoch processing in ProcessSlots.\n\tepochSlot := math.Slot(cs.SlotsPerEpoch()) - 1\n\n\t// Setup test cases\n\ttests := []struct {\n\t\tname      string\n\t\tstateSlot math.Slot\n\t\tslot      math.Slot\n\t\twantErr   bool\n\t}{\n\t\t{\"equal-slot\", epochSlot, epochSlot, false},\n\t\t{\"correct-slot\", epochSlot, epochSlot + 1, false},\n\t\t{\"too-large-slot\", epochSlot, epochSlot + 2, true},\n\t\t{\"too-small-slot\", epochSlot, epochSlot - 1, true},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\terr = st.SetSlot(tt.stateSlot)\n\t\t\trequire.NoError(t, err)\n\t\t\t_, err = sp.ProcessSlots(st, tt.slot)\n\t\t\tif (err != nil) != tt.wantErr {\n\t\t\t\tt.Errorf(\"ProcessSlots() error = %v, wantErr %v\", err, tt.wantErr)\n\t\t\t\treturn\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "state-transition/core/state_processor_validators.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core\n\nimport (\n\tstdbytes \"bytes\"\n\t\"fmt\"\n\t\"slices\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n\t\"github.com/sourcegraph/conc/iter\"\n)\n\nfunc (sp *StateProcessor) processRegistryUpdates(st *statedb.StateDB) error {\n\tcurrEpoch, err := st.GetEpoch()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"registry update, failed loading slot: %w\", err)\n\t}\n\tactivationEpoch := currEpoch + 1\n\tminActivationBalance := sp.cs.MinActivationBalance()\n\n\tvals, err := st.GetValidators()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"registry update, failed listing validators: %w\", err)\n\t}\n\n\t// We do not currently have a cap on validator churn,\n\t// so we can process validators activations in a single loop\n\tvar idx math.ValidatorIndex\n\tfor si, val := range vals {\n\t\tvalModified := false\n\t\tif val.IsEligibleForActivationQueue(minActivationBalance) {\n\t\t\tval.SetActivationEligibilityEpoch(activationEpoch)\n\t\t\tvalModified = true\n\t\t}\n\n\t\t// Note: without slashing and voluntary withdrawals, there is no way\n\t\t// for an active validator to have its balance less or equal to EjectionBalance.\n\t\t// Even Partial Withdrawals through EIP7002 can only reduce a validator's balance to `MinActivationBalance`,\n\t\t// which is not enough to trigger a validator exit.\n\t\t// A Full Withdrawal through EIP7002 would initiate a validator exit directly and does not rely on `processRegistryUpdates`.\n\t\t// As such, we do not include the logic, but rather log an error if it is observed:\n\t\t/*\n\t\t\telif is_active_validator(validator, current_epoch) and validator.effective_balance <= config.EJECTION_BALANCE:\n\t\t\t\t\t\t\tinitiate_validator_exit(state, ValidatorIndex(index))  # [Modified in Electra:EIP7251]\n\t\t*/\n\t\tif val.IsActive(currEpoch) &&\n\t\t\tval.GetEffectiveBalance() <= minActivationBalance-sp.cs.EffectiveBalanceIncrement() {\n\t\t\tsp.logger.Error(\n\t\t\t\t\"registry update, validator is active but effective balance is too low\",\n\t\t\t\t\"validator_pub_key\", val.Pubkey.String(),\n\t\t\t\t\"effective_balance\", val.GetEffectiveBalance().Base10(),\n\t\t\t\t\"epoch\", currEpoch.Base10(),\n\t\t\t)\n\t\t}\n\n\t\tif val.IsEligibleForActivation(currEpoch) {\n\t\t\tval.SetActivationEpoch(activationEpoch)\n\t\t\tvalModified = true\n\t\t}\n\n\t\tif valModified {\n\t\t\tidx, err = st.ValidatorIndexByPubkey(val.GetPubkey())\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\n\t\t\t\t\t\"registry update, failed loading validator index, state index %d: %w\",\n\t\t\t\t\tsi,\n\t\t\t\t\terr,\n\t\t\t\t)\n\t\t\t}\n\t\t\tif err = st.UpdateValidatorAtIndex(idx, val); err != nil {\n\t\t\t\treturn fmt.Errorf(\n\t\t\t\t\t\"registry update, failed updating validator idx %d: %w\",\n\t\t\t\t\tidx,\n\t\t\t\t\terr,\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t}\n\n\t// validators registry will be possibly further modified in order to enforce\n\t// validators set cap. We will do that at the end of processEpoch, once all\n\t// Eth 2.0 like transitions has been done (notable EffectiveBalances\n\t// handling).\n\treturn nil\n}\n\nfunc (sp *StateProcessor) processValidatorSetCap(st *statedb.StateDB) error {\n\t// Enforce the validator set cap by:\n\t// 1- retrieving validators active next epoch\n\t// 2- sorting them by stake\n\t// 3- dropping enough validators to fulfill the cap\n\n\tcurrentEpoch, err := st.GetEpoch()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tnextEpochVals, err := getActiveVals(st, currentEpoch+1)\n\tif err != nil {\n\t\treturn fmt.Errorf(\n\t\t\t\"registry update, failed retrieving next epoch vals: %w\",\n\t\t\terr,\n\t\t)\n\t}\n\n\tvalidatorSetCap := sp.cs.ValidatorSetCap()\n\tif uint64(len(nextEpochVals)) <= validatorSetCap {\n\t\t// nothing to eject\n\t\treturn nil\n\t}\n\n\tslices.SortFunc(nextEpochVals, func(lhs, rhs *ctypes.Validator) int {\n\t\tvar (\n\t\t\tval1Stake = lhs.GetEffectiveBalance()\n\t\t\tval2Stake = rhs.GetEffectiveBalance()\n\t\t)\n\t\tswitch {\n\t\tcase val1Stake < val2Stake:\n\t\t\treturn -1\n\t\tcase val1Stake > val2Stake:\n\t\t\treturn 1\n\t\tdefault:\n\t\t\t// validators pks are guaranteed to be different\n\t\t\tvar (\n\t\t\t\tval1Pk = lhs.GetPubkey()\n\t\t\t\tval2Pk = rhs.GetPubkey()\n\t\t\t)\n\t\t\treturn stdbytes.Compare(val1Pk[:], val2Pk[:])\n\t\t}\n\t})\n\n\t// We do not currently have a cap on validators churn, so we exit\n\t// validators in the next epoch, and we withdraw them after a delay depending on the fork.\n\tvar idx math.ValidatorIndex\n\tfor li := range uint64(len(nextEpochVals)) - validatorSetCap {\n\t\tvalToEject := nextEpochVals[li]\n\t\tidx, err = st.ValidatorIndexByPubkey(valToEject.GetPubkey())\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"validators cap, failed loading validator index: %w\",\n\t\t\t\terr,\n\t\t\t)\n\t\t}\n\t\tif exitErr := sp.InitiateValidatorExit(st, idx); exitErr != nil {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"validator cap, failed ejecting validator idx %d: %w\",\n\t\t\t\tli,\n\t\t\t\texitErr,\n\t\t\t)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// Note: validatorSetsDiffs does not need to be a StateProcessor method\n// but it helps simplifying generic instantiation.\nfunc validatorSetsDiffs(\n\tprevEpochValidators []*ctypes.Validator,\n\tcurrEpochValidator []*ctypes.Validator,\n) transition.ValidatorUpdates {\n\tcurrentValSet := iter.Map(\n\t\tcurrEpochValidator,\n\t\tfunc(val **ctypes.Validator) *transition.ValidatorUpdate {\n\t\t\tv := (*val)\n\t\t\treturn &transition.ValidatorUpdate{\n\t\t\t\tPubkey:           v.GetPubkey(),\n\t\t\t\tEffectiveBalance: v.GetEffectiveBalance(),\n\t\t\t}\n\t\t},\n\t)\n\n\tres := make([]*transition.ValidatorUpdate, 0)\n\tprevValsSet := make(map[string]math.Gwei, len(prevEpochValidators))\n\tfor _, v := range prevEpochValidators {\n\t\tpk := v.GetPubkey()\n\t\tprevValsSet[string(pk[:])] = v.GetEffectiveBalance()\n\t}\n\n\tfor _, newVal := range currentValSet {\n\t\tkey := string(newVal.Pubkey[:])\n\t\toldBal, found := prevValsSet[key]\n\t\tif !found {\n\t\t\t// new validator, we add it with its weight\n\t\t\tres = append(res, newVal)\n\t\t\tcontinue\n\t\t}\n\t\tif oldBal != newVal.EffectiveBalance {\n\t\t\t// validator updated, we add it with new weight\n\t\t\tres = append(res, newVal)\n\t\t}\n\n\t\t// consume pre-existing validators\n\t\tdelete(prevValsSet, key)\n\t}\n\n\t// prevValsSet now contains all evicted validators (and only those)\n\tfor pkBytes := range prevValsSet {\n\t\t//#nosec:G703 // bytes comes from a pk\n\t\tpk, _ := bytes.ToBytes48([]byte(pkBytes))\n\t\tres = append(res, &transition.ValidatorUpdate{\n\t\t\tPubkey:           pk,\n\t\t\tEffectiveBalance: 0, // signal val eviction to consensus\n\t\t})\n\t}\n\treturn res\n}\n\n// nextEpochValidatorSet returns the current estimation of what next epoch\n// validator set would be.\nfunc getActiveVals(st *statedb.StateDB, epoch math.Epoch) ([]*ctypes.Validator, error) {\n\tvals, err := st.GetValidators()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tactiveVals := make([]*ctypes.Validator, 0, len(vals))\n\tfor _, val := range vals {\n\t\tif val.IsActive(epoch) {\n\t\t\tactiveVals = append(activeVals, val)\n\t\t}\n\t}\n\treturn activeVals, nil\n}\n"
  },
  {
    "path": "state-transition/core/state_processor_withdrawals.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core\n\nimport (\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/state-transition/core/state\"\n\t\"github.com/davecgh/go-spew/spew\"\n\t\"github.com/ethereum/go-ethereum/params\"\n)\n\n// processWithdrawals as per the Ethereum 2.0 specification.\n// https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#new-process_withdrawals\n//\n// NOTE: Modified from the Ethereum 2.0 specification to support EVM inflation:\n// 1. The first withdrawal MUST be a fixed EVM inflation withdrawal\n// 2. Subsequent withdrawals (if any) are processed as validator withdrawals\n// 3. This modification reduces the maximum validator withdrawals per block by one.\n//\n//nolint:gocognit,funlen // TODO: Consider refactoring\nfunc (sp *StateProcessor) processWithdrawals(\n\tst *state.StateDB, blk *ctypes.BeaconBlock,\n) error {\n\t// Dequeue and verify the logs.\n\tvar (\n\t\tbody               = blk.GetBody()\n\t\tpayload            = body.GetExecutionPayload()\n\t\tpayloadWithdrawals = payload.GetWithdrawals()\n\t)\n\n\t// Get the expected withdrawals.\n\texpectedWithdrawals, processedPartialWithdrawalsCount, err := st.ExpectedWithdrawals(blk.GetTimestamp())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Common validations\n\tif len(expectedWithdrawals) != len(payloadWithdrawals) {\n\t\treturn errors.Wrapf(\n\t\t\tErrNumWithdrawalsMismatch,\n\t\t\t\"withdrawals do not match expected length %d, got %d\",\n\t\t\tlen(expectedWithdrawals), len(payloadWithdrawals),\n\t\t)\n\t}\n\n\t// Enforce that first withdrawal is EVM inflation\n\tif len(payloadWithdrawals) == 0 {\n\t\treturn ErrZeroWithdrawals\n\t}\n\tif !payloadWithdrawals[0].Equals(st.EVMInflationWithdrawal(blk.GetTimestamp())) {\n\t\treturn ErrFirstWithdrawalNotEVMInflation\n\t}\n\tnumWithdrawals := len(expectedWithdrawals)\n\n\t// Process all subsequent validator withdrawals.\n\tfor i := 1; i < numWithdrawals; i++ {\n\t\t// Ensure the withdrawals match the local state.\n\t\tif !expectedWithdrawals[i].Equals(payloadWithdrawals[i]) {\n\t\t\treturn errors.Wrapf(\n\t\t\t\tErrWithdrawalMismatch,\n\t\t\t\t\"withdrawal at index %d does not match expected %s, got %s\",\n\t\t\t\ti,\n\t\t\t\tspew.Sdump(expectedWithdrawals[i]),\n\t\t\t\tspew.Sdump(payloadWithdrawals[i]),\n\t\t\t)\n\t\t}\n\n\t\tif err = st.DecreaseBalance(\n\t\t\texpectedWithdrawals[i].GetValidatorIndex(), expectedWithdrawals[i].GetAmount(),\n\t\t); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// Update pending partial withdrawals [Introduced in Electra:EIP7251]\n\t// This case can only be hit after electra.\n\tif processedPartialWithdrawalsCount > 0 {\n\t\tppWithdrawals, getErr := st.GetPendingPartialWithdrawals()\n\t\tif getErr != nil {\n\t\t\treturn getErr\n\t\t}\n\t\tupdatedWithdrawals := ppWithdrawals[processedPartialWithdrawalsCount:]\n\t\tsp.metrics.gaugePartialWithdrawalsEnqueued(len(updatedWithdrawals))\n\t\tif setErr := st.SetPendingPartialWithdrawals(updatedWithdrawals); setErr != nil {\n\t\t\treturn setErr\n\t\t}\n\t\tsp.logger.Info(\n\t\t\t\"pending partial withdrawals found\",\n\t\t\t\"original_count\", processedPartialWithdrawalsCount,\n\t\t\t\"updated_count\", len(updatedWithdrawals),\n\t\t)\n\t}\n\n\tif numWithdrawals > 1 {\n\t\tif err = st.SetNextWithdrawalIndex(\n\t\t\t(expectedWithdrawals[numWithdrawals-1].GetIndex() + 1).Unwrap(),\n\t\t); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\ttotalValidators, err := st.GetTotalValidators()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Update the next validator index to start the next withdrawal sweep.\n\tvar nextValidatorIndex math.ValidatorIndex\n\tif uint64(numWithdrawals) == sp.cs.MaxWithdrawalsPerPayload() {\n\t\t// Next sweep starts after the latest withdrawal's validator index.\n\t\tnextValidatorIndex = (expectedWithdrawals[numWithdrawals-1].GetValidatorIndex() + 1) % totalValidators\n\t} else {\n\t\t// Advance sweep by the max length of the sweep if there was not a full set of withdrawals.\n\t\tnextValidatorIndex, err = st.GetNextWithdrawalValidatorIndex()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tnextValidatorIndex += sp.cs.MaxValidatorsPerWithdrawalsSweep()\n\t\tnextValidatorIndex %= totalValidators\n\t}\n\n\tif err = st.SetNextWithdrawalValidatorIndex(nextValidatorIndex); err != nil {\n\t\treturn err\n\t}\n\n\tsp.logger.Debug(\n\t\t\"Processed withdrawals\",\n\t\t\"num_withdrawals\", numWithdrawals,\n\t\t\"evm_inflation\", float64(payloadWithdrawals[0].GetAmount().Unwrap())/params.GWei,\n\t)\n\n\treturn nil\n}\n\n// processWithdrawalRequest is the equivalent of process_withdrawal_request as defined in the spec.\n// It should only be called after the electra hard fork.\n// For invalid withdrawal requests, we return nil, and only return error for system errors.\nfunc (sp *StateProcessor) processWithdrawalRequest(\n\tst *state.StateDB, withdrawalRequest *ctypes.WithdrawalRequest,\n) error {\n\t// If the amount is 0, it's a full exit.\n\tisFullExitRequest := withdrawalRequest.Amount == constants.FullExitRequestAmount\n\tpendingPartialWithdrawals, err := st.GetPendingPartialWithdrawals()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// If partial withdrawal queue is full, only full exits are processed\n\tif len(pendingPartialWithdrawals) == constants.PendingPartialWithdrawalsLimit && !isFullExitRequest {\n\t\tsp.logger.Warn(\n\t\t\t\"skipping processing of withdrawal request as partial withdrawal queue is full\",\n\t\t\twithdrawalFields(withdrawalRequest, nil)...,\n\t\t)\n\t\tsp.metrics.incrementPartialWithdrawalRequestDropped()\n\t\treturn nil\n\t}\n\n\tindex, validator, err := validateWithdrawal(st, withdrawalRequest)\n\tif err != nil {\n\t\tsp.logger.Info(\"Failed to validate withdrawal\", withdrawalFields(withdrawalRequest, err)...)\n\t\t// Note that we do not return error on invalid requests as it's a user error and invalid withdrawal requests are simply skipped.\n\t\treturn nil\n\t}\n\tif validator == nil {\n\t\t// This should never occur as we check in validateWithdrawal for nil, but this is needed to appease nilaway.\n\t\tsp.logger.Warn(\"processWithdrawalRequest: nil validator\", withdrawalFields(withdrawalRequest, nil)...)\n\t\treturn errors.New(\"processWithdrawalRequest: unexpected nil validator\")\n\t}\n\n\tif err = verifyWithdrawalConditions(st, validator); err != nil {\n\t\t// Note that we do not return error on invalid requests as it's a user error and invalid withdrawal requests are simply skipped.\n\t\tsp.logger.Info(\"Failed to verify withdrawal conditions\", withdrawalFields(withdrawalRequest, err)...)\n\t\treturn nil\n\t}\n\n\t// Process full exit or partial withdrawal.\n\tif isFullExitRequest {\n\t\tsp.logger.Info(\"Processing full exit request\", withdrawalFields(withdrawalRequest, nil)...)\n\t\treturn sp.processFullExit(st, index, pendingPartialWithdrawals)\n\t}\n\tsp.logger.Info(\"Processing partial withdrawal request\", withdrawalFields(withdrawalRequest, nil)...)\n\treturn sp.processPartialWithdrawal(st, withdrawalRequest, validator, index, pendingPartialWithdrawals)\n}\n\n// processFullExit processes the full exit request is not a pending partial withdrawal\n// and has passed validation of `processWithdrawalRequest`.\nfunc (sp *StateProcessor) processFullExit(\n\tst *state.StateDB,\n\tindex math.ValidatorIndex,\n\tpendingPartialWithdrawals ctypes.PendingPartialWithdrawals,\n) error {\n\tpendingBalance := pendingPartialWithdrawals.PendingBalanceToWithdraw(index)\n\tif pendingBalance == 0 {\n\t\t// Only exit validator if it has no pending withdrawals in the queue\n\t\treturn sp.InitiateValidatorExit(st, index)\n\t}\n\tsp.logger.Info(\"validator has pending balance and cannot full exit\",\n\t\t\"validator_index\", index,\n\t\t\"pending_balance\", pendingBalance,\n\t)\n\treturn nil\n}\n\n// processPartialWithdrawal handles the partial withdrawal processing and called after\n// request has passed validation of `processWithdrawalRequest`\nfunc (sp *StateProcessor) processPartialWithdrawal(\n\tst *state.StateDB,\n\treq *ctypes.WithdrawalRequest,\n\tvalidator *ctypes.Validator,\n\tindex math.ValidatorIndex,\n\tpendingWithdrawals ctypes.PendingPartialWithdrawals,\n) error {\n\tminActivationBalance := sp.cs.MinActivationBalance()\n\thasSufficient := validator.GetEffectiveBalance() >= minActivationBalance\n\n\tbalance, err := st.GetBalance(index)\n\tif err != nil {\n\t\treturn err\n\t}\n\tpendingBalanceToWithdraw := pendingWithdrawals.PendingBalanceToWithdraw(index)\n\thasExcess := balance > minActivationBalance+pendingBalanceToWithdraw\n\n\tisWithdrawable := validator.HasCompoundingWithdrawalCredential() && hasSufficient && hasExcess\n\tif !isWithdrawable {\n\t\tsp.logger.Info(\"validator cannot withdraw partial balance\",\n\t\t\t\"validator_index\", index,\n\t\t\t\"validator_pubkey\", validator.GetPubkey().String(),\n\t\t\t\"balance\", balance,\n\t\t\t\"pending_balance_to_withdraw\", pendingBalanceToWithdraw,\n\t\t\t\"has_sufficient\", hasSufficient,\n\t\t\t\"has_excess\", hasExcess,\n\t\t)\n\t\tsp.metrics.incrementPartialWithdrawalRequestInvalid()\n\t\treturn nil\n\t}\n\n\ttoWithdraw := min(balance-minActivationBalance-pendingBalanceToWithdraw, req.Amount)\n\t// As long as `processPartialWithdrawal` is called after `processSlots`, this will always\n\t// return the correct epoch.\n\tcurrentEpoch, getErr := st.GetEpoch()\n\tif getErr != nil {\n\t\treturn getErr\n\t}\n\t// Note that we do not need to set the ExitEpoch anywhere here as Partial withdrawals do not\n\t// exit the validator as we enforce that the `toWithdraw` amount is always above the\n\t// `minActivationBalance`. For example, if a validator's balance is already at\n\t// `minActivationBalance` (250K BERA on mainnet) and they request a partial withdrawal, the\n\t// `toWithdraw` amount will always be zero.\n\tnextEpoch := currentEpoch + 1\n\twithdrawableEpoch := nextEpoch + sp.cs.MinValidatorWithdrawabilityDelay()\n\tppWithdrawal := &ctypes.PendingPartialWithdrawal{\n\t\tValidatorIndex:    index,\n\t\tAmount:            toWithdraw,\n\t\tWithdrawableEpoch: withdrawableEpoch,\n\t}\n\tpendingWithdrawals = append(pendingWithdrawals, ppWithdrawal)\n\tsp.metrics.gaugePartialWithdrawalsEnqueued(len(pendingWithdrawals))\n\treturn st.SetPendingPartialWithdrawals(pendingWithdrawals)\n}\n\n// validateWithdrawal checks that the validator exists and that the withdrawal credentials match.\nfunc validateWithdrawal(\n\tst *state.StateDB, withdrawalRequest *ctypes.WithdrawalRequest,\n) (math.ValidatorIndex, *ctypes.Validator, error) {\n\t// Verify pubkey exists\n\tindex, err := st.ValidatorIndexByPubkey(withdrawalRequest.ValidatorPubKey)\n\tif err != nil {\n\t\treturn 0, nil, err\n\t}\n\n\tvalidator, err := st.ValidatorByIndex(index)\n\tif err != nil {\n\t\treturn 0, nil, err\n\t}\n\tif validator == nil {\n\t\t// This should never occur as we expect ErrNotFound if the validator is not found.\n\t\treturn 0, nil, errors.New(\"validateWithdrawal: validator does not exist\")\n\t}\n\n\t// Verify withdrawal credentials\n\tif !validator.HasExecutionWithdrawalCredential() {\n\t\treturn 0, nil, errors.New(\"validator does not have execution withdrawal credentials\")\n\t}\n\tcorrectCred, err := validator.WithdrawalCredentials.ToExecutionAddress()\n\tif err != nil {\n\t\treturn 0, nil, err\n\t}\n\tif !withdrawalRequest.SourceAddress.Equals(correctCred) {\n\t\treturn 0, nil, errors.New(\"source address does not match execution withdrawal credential\")\n\t}\n\treturn index, validator, nil\n}\n\n// verifyWithdrawalConditions checks additional conditions like active status, exit not initiated,\n// and minimal activation period.\nfunc verifyWithdrawalConditions(st *state.StateDB, validator *ctypes.Validator) error {\n\tcurrentEpoch, err := st.GetEpoch()\n\tif err != nil {\n\t\treturn err\n\t}\n\t// Verify the validator is active\n\tif !validator.IsActive(currentEpoch) {\n\t\treturn errors.New(\"validator is not active\")\n\t}\n\t// Verify exit has not been initiated\n\tif validator.GetExitEpoch() != constants.FarFutureEpoch {\n\t\treturn errors.New(\"withdrawal already initiated\")\n\t}\n\n\t// In Ethereum specs here it's checked that\n\t// currentEpoch < validator.ActivationEpoch + config.SHARD_COMMITTEE_PERIOD\n\t// We ignore config.SHARD_COMMITTEE_PERIOD, since data shards are not relevant for us.\n\t// Moreover here validator is active so currentEpoch >= validator.ActivationEpoch\n\treturn nil\n}\n\n// withdrawalFields returns the structured fields for logging any WithdrawalRequest.\n// error is optional\nfunc withdrawalFields(req *ctypes.WithdrawalRequest, err error) []interface{} {\n\tlogFields := []interface{}{\n\t\t\"source_address\", req.SourceAddress.String(),\n\t\t\"validator_pubkey\", req.ValidatorPubKey.String(),\n\t\t\"amount\", req.Amount,\n\t}\n\tif err != nil {\n\t\tlogFields = append(logFields, \"error\", err)\n\t}\n\treturn logFields\n}\n"
  },
  {
    "path": "state-transition/core/state_processor_withdrawals_test.go",
    "content": "//go:build test\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\tstatetransition \"github.com/berachain/beacon-kit/testing/state-transition\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestPartialWithdrawalRequestGenesisValidators(t *testing.T) {\n\tt.Parallel()\n\tcs := setupChain(t)\n\tsp, st, ds, ctx, _, _ := statetransition.SetupTestState(t, cs)\n\n\t// make sure Electra is active\n\trequire.True(t, version.EqualsOrIsAfter(cs.GenesisForkVersion(), version.Electra()))\n\n\tvar (\n\t\tmaxBalance = cs.MaxEffectiveBalance()\n\t\tminBalance = cs.MinActivationBalance()\n\n\t\taddr    = common.ExecutionAddress{0x01}\n\t\tcreds   = types.NewCredentialsFromExecutionAddress(addr)\n\t\tbadAddr = common.ExecutionAddress{0x20}\n\t)\n\n\t// Add a single validator to which we will target withdrawal requests\n\tvar (\n\t\tgenDeposits = types.Deposits{\n\t\t\t{\n\t\t\t\tPubkey:      [48]byte{0x00},\n\t\t\t\tCredentials: creds,\n\t\t\t\tAmount:      maxBalance,\n\t\t\t\tIndex:       0,\n\t\t\t},\n\t\t}\n\t\tgenPayloadHeader = &types.ExecutionPayloadHeader{\n\t\t\tVersionable: types.NewVersionable(cs.GenesisForkVersion()),\n\t\t}\n\t)\n\t_, err := sp.InitializeBeaconStateFromEth1(\n\t\tst, genDeposits, genPayloadHeader, cs.GenesisForkVersion(),\n\t)\n\trequire.NoError(t, err)\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), genDeposits))\n\n\t// Send withdrawal requests and see the valid ones being carried out\n\tvals, err := st.GetValidators()\n\trequire.NoError(t, err)\n\trequire.Len(t, vals, 1)\n\tgenVal := vals[0]\n\tgenValIdx, err := st.ValidatorIndexByPubkey(genVal.GetPubkey())\n\trequire.NoError(t, err)\n\n\tgenValPubKey := genVal.GetPubkey()\n\twrs := []*types.WithdrawalRequest{\n\t\t{ // valid request\n\t\t\tSourceAddress:   addr,\n\t\t\tValidatorPubKey: genValPubKey,\n\t\t\tAmount:          1,\n\t\t},\n\t\t{ // valid request\n\t\t\tSourceAddress:   addr,\n\t\t\tValidatorPubKey: genValPubKey,\n\t\t\tAmount:          10,\n\t\t},\n\t\t{ // invalid request, invalid address\n\t\t\tSourceAddress:   badAddr,\n\t\t\tValidatorPubKey: genValPubKey,\n\t\t\tAmount:          10,\n\t\t},\n\t\t{ // invalid request, invalid pub key\n\t\t\tSourceAddress:   addr,\n\t\t\tValidatorPubKey: crypto.BLSPubkey(append([]byte{0xff}, genValPubKey[1:]...)),\n\t\t\tAmount:          10,\n\t\t},\n\t\t{ // valid request, largest withdrawable amount\n\t\t\tSourceAddress:   addr,\n\t\t\tValidatorPubKey: genValPubKey,\n\t\t\tAmount:          maxBalance - 1 - 10 - minBalance, // remaining amount to minBalance\n\t\t},\n\t\t{ // invalid request (can't go below min activation balance even by 1 bera)\n\t\t\tSourceAddress:   addr,\n\t\t\tValidatorPubKey: genValPubKey,\n\t\t\tAmount:          1,\n\t\t},\n\t\t{ // invalid request (full withdraw ignored when partial withdraws are ongoing)\n\t\t\tSourceAddress:   addr,\n\t\t\tValidatorPubKey: genValPubKey,\n\t\t\tAmount:          0,\n\t\t},\n\t}\n\n\tvar depRoot common.Root\n\t_, depRoot, err = ds.GetDepositsByIndex(ctx.ConsensusCtx(), 0, uint64(len(genDeposits)))\n\trequire.NoError(t, err)\n\n\tblk := buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\t10,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{\n\t\t\tWithdrawals: wrs,\n\t\t},\n\t\tst.EVMInflationWithdrawal(10),\n\t)\n\n\t// Run the test.\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\n\t// check withdrawal request is enqueued\n\texpectedWithdrawalEpoch := 1 + cs.MinValidatorWithdrawabilityDelay()\n\tpr, err := st.GetPendingPartialWithdrawals()\n\trequire.NoError(t, err)\n\trequire.Len(t, pr, 3)\n\trequire.Equal(t,\n\t\t[]*types.PendingPartialWithdrawal{\n\t\t\t{\n\t\t\t\tValidatorIndex:    0,\n\t\t\t\tAmount:            wrs[0].Amount,\n\t\t\t\tWithdrawableEpoch: expectedWithdrawalEpoch,\n\t\t\t},\n\t\t\t{\n\t\t\t\tValidatorIndex:    0,\n\t\t\t\tAmount:            wrs[1].Amount,\n\t\t\t\tWithdrawableEpoch: expectedWithdrawalEpoch,\n\t\t\t},\n\t\t\t{\n\t\t\t\tValidatorIndex:    0,\n\t\t\t\tAmount:            wrs[4].Amount,\n\t\t\t\tWithdrawableEpoch: expectedWithdrawalEpoch,\n\t\t\t},\n\t\t},\n\t\tpr,\n\t)\n\n\t// check that the request is eventually fulfilled\n\tfor range expectedWithdrawalEpoch - 1 {\n\t\t_ = moveToEndOfEpoch(t, blk, cs, sp, st, ctx, depRoot)\n\n\t\t// This is just because we cannot chain moveToEndOfEpoch\n\t\t// back to back. TODO: fix\n\t\ttimestamp := blk.Body.ExecutionPayload.Timestamp + 1\n\t\tblk = buildNextBlock(\n\t\t\tt,\n\t\t\tcs,\n\t\t\tst,\n\t\t\ttypes.NewEth1Data(depRoot),\n\t\t\t10,\n\t\t\t[]*types.Deposit{},\n\t\t\t&types.ExecutionRequests{},\n\t\t\tst.EVMInflationWithdrawal(timestamp),\n\t\t)\n\t\t_, err = sp.Transition(ctx, st, blk)\n\t\trequire.NoError(t, err)\n\t}\n\tfor range cs.SlotsPerEpoch() - 1 {\n\t\ttimestamp := blk.Body.ExecutionPayload.Timestamp + 1\n\t\tblk = buildNextBlock(\n\t\t\tt,\n\t\t\tcs,\n\t\t\tst,\n\t\t\ttypes.NewEth1Data(depRoot),\n\t\t\t10,\n\t\t\t[]*types.Deposit{},\n\t\t\t&types.ExecutionRequests{},\n\t\t\tst.EVMInflationWithdrawal(timestamp),\n\t\t)\n\t\t_, err = sp.Transition(ctx, st, blk)\n\t\trequire.NoError(t, err)\n\t}\n\n\t// finally the withdrawal\n\ttimestamp := blk.Body.ExecutionPayload.Timestamp + 1\n\twithdrawals := []*engineprimitives.Withdrawal{\n\t\t// The first withdrawal is always for EVM inflation.\n\t\tst.EVMInflationWithdrawal(10),\n\t\t{\n\t\t\tIndex:     0,\n\t\t\tValidator: genValIdx,\n\t\t\tAmount:    wrs[0].Amount,\n\t\t\tAddress:   wrs[0].SourceAddress,\n\t\t},\n\t\t{\n\t\t\tIndex:     1,\n\t\t\tValidator: genValIdx,\n\t\t\tAmount:    wrs[1].Amount,\n\t\t\tAddress:   wrs[1].SourceAddress,\n\t\t},\n\t\t{\n\t\t\tIndex:     2,\n\t\t\tValidator: genValIdx,\n\t\t\tAmount:    wrs[4].Amount,\n\t\t\tAddress:   wrs[4].SourceAddress,\n\t\t},\n\t}\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\ttimestamp,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{},\n\t\twithdrawals...,\n\t)\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\n\t// no more pending withdrawals\n\tpr, err = st.GetPendingPartialWithdrawals()\n\trequire.NoError(t, err)\n\trequire.Empty(t, pr)\n}\n\nfunc TestFullWithdrawalRequestGenesisValidators(t *testing.T) {\n\tt.Parallel()\n\tcs := setupChain(t)\n\tsp, st, ds, ctx, _, _ := statetransition.SetupTestState(t, cs)\n\n\t// make sure Electra is active\n\trequire.True(t, version.EqualsOrIsAfter(cs.GenesisForkVersion(), version.Electra()))\n\n\tvar (\n\t\tmaxBalance = cs.MaxEffectiveBalance()\n\n\t\taddr1  = common.ExecutionAddress{0x01}\n\t\tcreds1 = types.NewCredentialsFromExecutionAddress(addr1)\n\t\taddr2  = common.ExecutionAddress{0x01}\n\t\tcreds2 = types.NewCredentialsFromExecutionAddress(addr2)\n\t)\n\n\t// Add a couple of validators and fully withdraw one of them\n\tvar (\n\t\tgenDeposits = types.Deposits{\n\t\t\t{\n\t\t\t\tPubkey:      [48]byte{0x00},\n\t\t\t\tCredentials: creds1,\n\t\t\t\tAmount:      maxBalance,\n\t\t\t\tIndex:       0,\n\t\t\t},\n\t\t\t{\n\t\t\t\tPubkey:      [48]byte{0x01},\n\t\t\t\tCredentials: creds2,\n\t\t\t\tAmount:      maxBalance,\n\t\t\t\tIndex:       1,\n\t\t\t},\n\t\t}\n\t\tgenPayloadHeader = &types.ExecutionPayloadHeader{\n\t\t\tVersionable: types.NewVersionable(cs.GenesisForkVersion()),\n\t\t}\n\t)\n\t_, err := sp.InitializeBeaconStateFromEth1(\n\t\tst, genDeposits, genPayloadHeader, cs.GenesisForkVersion(),\n\t)\n\trequire.NoError(t, err)\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), genDeposits))\n\n\tvals, err := st.GetValidators()\n\trequire.NoError(t, err)\n\trequire.Len(t, vals, 2)\n\tvalToRm := vals[0]\n\n\twrs := []*types.WithdrawalRequest{\n\t\t{\n\t\t\tSourceAddress:   addr1,\n\t\t\tValidatorPubKey: valToRm.GetPubkey(),\n\t\t\tAmount:          0,\n\t\t},\n\t}\n\n\tvar depRoot common.Root\n\t_, depRoot, err = ds.GetDepositsByIndex(ctx.ConsensusCtx(), 0, uint64(len(genDeposits)))\n\trequire.NoError(t, err)\n\n\tblkTimestamp := math.U64(10)\n\tblk := buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblkTimestamp,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{\n\t\t\tWithdrawals: wrs,\n\t\t},\n\t\tst.EVMInflationWithdrawal(blkTimestamp),\n\t)\n\n\t// Run the test.\n\tvalDiff, err := sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\trequire.Empty(t, valDiff)\n\n\t// check that valToRm has initiated exit\n\texpectedExitEpoch := math.Epoch(1)\n\texpectedWithdrawalEpoch := expectedExitEpoch + cs.MinValidatorWithdrawabilityDelay()\n\n\tvalToRmIdx, err := st.ValidatorIndexByPubkey(valToRm.GetPubkey())\n\trequire.NoError(t, err)\n\tvalToRm, err = st.ValidatorByIndex(valToRmIdx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, expectedExitEpoch, valToRm.ExitEpoch)\n\trequire.Equal(t, expectedWithdrawalEpoch, valToRm.WithdrawableEpoch)\n\n\t// no pending withdrawals, full withdrawals are executed right away\n\tpr, err := st.GetPendingPartialWithdrawals()\n\trequire.NoError(t, err)\n\trequire.Empty(t, pr)\n\n\t// check the validator duly exits validator set\n\tblk = moveToEndOfEpoch(t, blk, cs, sp, st, ctx, depRoot)\n\tblkTimestamp = blk.GetTimestamp() + 1\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblkTimestamp,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{},\n\t\tst.EVMInflationWithdrawal(blkTimestamp),\n\t)\n\tvalDiff, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\trequire.Equal(t,\n\t\ttransition.ValidatorUpdates{\n\t\t\t{\n\t\t\t\tPubkey:           valToRm.Pubkey,\n\t\t\t\tEffectiveBalance: 0,\n\t\t\t},\n\t\t},\n\t\tvalDiff,\n\t)\n\n\t// no more partial withdrawals are possible for an exited validator\n\twrs = []*types.WithdrawalRequest{\n\t\t{\n\t\t\tSourceAddress:   addr1,\n\t\t\tValidatorPubKey: valToRm.GetPubkey(),\n\t\t\tAmount:          1,\n\t\t},\n\t}\n\tblkTimestamp = blk.GetTimestamp() + 1\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblkTimestamp,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{\n\t\t\tWithdrawals: wrs,\n\t\t},\n\t\tst.EVMInflationWithdrawal(blkTimestamp),\n\t)\n\n\t// Run the test.\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\tpr, err = st.GetPendingPartialWithdrawals()\n\trequire.NoError(t, err)\n\trequire.Empty(t, pr)\n\n\t// check that balance is still locked and it will be\n\t// returned after MinValidatorWithdrawabilityDelay epochs\n\t// check that the request is eventually fulfilled\n\tfor range expectedWithdrawalEpoch - 2 {\n\t\t_ = moveToEndOfEpoch(t, blk, cs, sp, st, ctx, depRoot)\n\n\t\t// This is just because we cannot chain moveToEndOfEpoch\n\t\t// back to back. TODO: fix\n\t\tblkTimestamp = blk.GetTimestamp() + 1\n\t\tblk = buildNextBlock(\n\t\t\tt,\n\t\t\tcs,\n\t\t\tst,\n\t\t\ttypes.NewEth1Data(depRoot),\n\t\t\tblkTimestamp,\n\t\t\t[]*types.Deposit{},\n\t\t\t&types.ExecutionRequests{},\n\t\t\tst.EVMInflationWithdrawal(blkTimestamp),\n\t\t)\n\t\t_, err = sp.Transition(ctx, st, blk)\n\t\trequire.NoError(t, err)\n\t}\n\tfor range cs.SlotsPerEpoch() - 1 {\n\t\tblkTimestamp = blk.GetTimestamp() + 1\n\t\tblk = buildNextBlock(\n\t\t\tt,\n\t\t\tcs,\n\t\t\tst,\n\t\t\ttypes.NewEth1Data(depRoot),\n\t\t\tblkTimestamp,\n\t\t\t[]*types.Deposit{},\n\t\t\t&types.ExecutionRequests{},\n\t\t\tst.EVMInflationWithdrawal(blkTimestamp),\n\t\t)\n\t\t_, err = sp.Transition(ctx, st, blk)\n\t\trequire.NoError(t, err)\n\t}\n\n\t// finally the withdrawal\n\ttimestamp := blk.Body.ExecutionPayload.Timestamp + 1\n\twithdrawals := []*engineprimitives.Withdrawal{\n\t\t// The first withdrawal is always for EVM inflation.\n\t\tst.EVMInflationWithdrawal(10),\n\t\t{\n\t\t\tIndex:     0,\n\t\t\tValidator: valToRmIdx,\n\t\t\tAmount:    valToRm.EffectiveBalance, // wrs request has zero to signal full withdrawal\n\t\t\tAddress:   wrs[0].SourceAddress,\n\t\t},\n\t}\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\ttimestamp,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{},\n\t\twithdrawals...,\n\t)\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\n\t// Check that validator balance is 0\n\tvalBalance, err := st.GetBalance(valToRmIdx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, math.U64(0), valBalance)\n\n\t// Check that effective balance has not updated yet. It will update next epoch\n\t// as part of processEffectiveBalanceUpdates\n\tvalToRm, err = st.ValidatorByIndex(valToRmIdx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, maxBalance, valToRm.GetEffectiveBalance())\n\n\t// Move forward one more epoch to trigger the effective balance update\n\t{\n\t\t_ = moveToEndOfEpoch(t, blk, cs, sp, st, ctx, depRoot)\n\t\t// This is just because we cannot chain moveToEndOfEpoch\n\t\t// back to back. TODO: fix\n\t\tblkTimestamp = blk.GetTimestamp() + 1\n\t\tblk = buildNextBlock(\n\t\t\tt,\n\t\t\tcs,\n\t\t\tst,\n\t\t\ttypes.NewEth1Data(depRoot),\n\t\t\tblkTimestamp,\n\t\t\t[]*types.Deposit{},\n\t\t\t&types.ExecutionRequests{},\n\t\t\tst.EVMInflationWithdrawal(blkTimestamp),\n\t\t)\n\t\t_, err = sp.Transition(ctx, st, blk)\n\t\trequire.NoError(t, err)\n\t}\n\n\t// Check that effective balance is now 0\n\tvalToRm, err = st.ValidatorByIndex(valToRmIdx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, math.Gwei(0), valToRm.GetEffectiveBalance())\n}\n\nfunc TestWithdrawalRequestsNonGenesisValidators(t *testing.T) {\n\tt.Parallel()\n\tcs := setupChain(t)\n\tsp, st, ds, ctx, _, _ := statetransition.SetupTestState(t, cs)\n\n\t// make sure Electra is active\n\trequire.True(t, version.EqualsOrIsAfter(cs.GenesisForkVersion(), version.Electra()))\n\n\tvar (\n\t\tmaxBalance = cs.MaxEffectiveBalance()\n\n\t\tgenAddr  = common.ExecutionAddress{0x01}\n\t\tgenCreds = types.NewCredentialsFromExecutionAddress(genAddr)\n\t\tvalAddr  = common.ExecutionAddress{0x01}\n\t\tvalCreds = types.NewCredentialsFromExecutionAddress(valAddr)\n\t)\n\n\tvar (\n\t\tgenDeposits = types.Deposits{\n\t\t\t{\n\t\t\t\tPubkey:      [48]byte{0x00},\n\t\t\t\tCredentials: genCreds,\n\t\t\t\tAmount:      maxBalance,\n\t\t\t\tIndex:       0,\n\t\t\t},\n\t\t}\n\t\tgenPayloadHeader = &types.ExecutionPayloadHeader{\n\t\t\tVersionable: types.NewVersionable(cs.GenesisForkVersion()),\n\t\t}\n\t\ttotalDepositsCount = uint64(len(genDeposits))\n\t)\n\t_, err := sp.InitializeBeaconStateFromEth1(\n\t\tst, genDeposits, genPayloadHeader, cs.GenesisForkVersion(),\n\t)\n\trequire.NoError(t, err)\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), genDeposits))\n\n\t// add a validator and test withdrawals through its lifetime\n\tblkDeposit := &types.Deposit{\n\t\tPubkey:      [48]byte{0xff},\n\t\tCredentials: valCreds,\n\t\tAmount:      maxBalance,\n\t\tIndex:       uint64(len(genDeposits)),\n\t}\n\tblkDeposits := []*types.Deposit{blkDeposit}\n\ttotalDepositsCount++\n\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), blkDeposits))\n\tvar depRoot common.Root\n\t_, depRoot, err = ds.GetDepositsByIndex(ctx.ConsensusCtx(), constants.FirstDepositIndex, totalDepositsCount)\n\trequire.NoError(t, err)\n\n\tblk := buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\t10,\n\t\tblkDeposits,\n\t\t&types.ExecutionRequests{},\n\t\tst.EVMInflationWithdrawal(10),\n\t)\n\n\t// run the test\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\n\t// assert that validator is not even eligible for activation yet\n\tidx, err := st.ValidatorIndexByPubkey(blkDeposit.Pubkey)\n\trequire.NoError(t, err)\n\tval, err := st.ValidatorByIndex(idx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, constants.FarFutureEpoch, val.ActivationEligibilityEpoch)\n\n\t// validator is not even in activation queue, any withdrawal request is dropped\n\twrs := []*types.WithdrawalRequest{\n\t\t{\n\t\t\tSourceAddress:   valAddr,\n\t\t\tValidatorPubKey: val.GetPubkey(),\n\t\t\tAmount:          1,\n\t\t},\n\t}\n\tblkTimestamp := blk.GetTimestamp() + 1\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblkTimestamp,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{\n\t\t\tWithdrawals: wrs,\n\t\t},\n\t\tst.EVMInflationWithdrawal(blkTimestamp),\n\t)\n\n\t// Show that no withdrawal is enqueued\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\tpr, err := st.GetPendingPartialWithdrawals()\n\trequire.NoError(t, err)\n\trequire.Empty(t, pr)\n\n\t// try again with full withdrawal\n\twrs = []*types.WithdrawalRequest{\n\t\t{\n\t\t\tSourceAddress:   valAddr,\n\t\t\tValidatorPubKey: val.GetPubkey(),\n\t\t\tAmount:          0,\n\t\t},\n\t}\n\tblkTimestamp = blk.GetTimestamp() + 1\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblkTimestamp,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{\n\t\t\tWithdrawals: wrs,\n\t\t},\n\t\tst.EVMInflationWithdrawal(blkTimestamp),\n\t)\n\n\t// Show that validator is not marked for exit\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\n\tval, err = st.ValidatorByIndex(idx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, constants.FarFutureEpoch, val.ActivationEligibilityEpoch)\n\trequire.Equal(t, constants.FarFutureEpoch, val.ExitEpoch)\n\n\t// make validator eligible for activation and show that withdrawals are not yet allowed\n\tblk = moveToEndOfEpoch(t, blk, cs, sp, st, ctx, depRoot)\n\tblkTimestamp = blk.GetTimestamp() + 1\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblkTimestamp,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{},\n\t\tst.EVMInflationWithdrawal(blkTimestamp),\n\t)\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\n\tval, err = st.ValidatorByIndex(idx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, math.Epoch(1), val.ActivationEligibilityEpoch)\n\trequire.Equal(t, constants.FarFutureEpoch, val.ActivationEpoch)\n\n\t// validator eligible for activation but not active yet. Requests dropped\n\twrs = []*types.WithdrawalRequest{\n\t\t{\n\t\t\tSourceAddress:   valAddr,\n\t\t\tValidatorPubKey: val.GetPubkey(),\n\t\t\tAmount:          1,\n\t\t},\n\t}\n\tblkTimestamp = blk.GetTimestamp() + 1\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblkTimestamp,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{\n\t\t\tWithdrawals: wrs,\n\t\t},\n\t\tst.EVMInflationWithdrawal(blkTimestamp),\n\t)\n\n\t// Show that no withdrawal is enqueued\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\tpr, err = st.GetPendingPartialWithdrawals()\n\trequire.NoError(t, err)\n\trequire.Empty(t, pr)\n\n\t// try again with full withdrawal\n\twrs = []*types.WithdrawalRequest{\n\t\t{\n\t\t\tSourceAddress:   valAddr,\n\t\t\tValidatorPubKey: val.GetPubkey(),\n\t\t\tAmount:          0,\n\t\t},\n\t}\n\tblkTimestamp = blk.GetTimestamp() + 1\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblkTimestamp,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{\n\t\t\tWithdrawals: wrs,\n\t\t},\n\t\tst.EVMInflationWithdrawal(blkTimestamp),\n\t)\n\n\t// Show that validator is not marked for exit\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\n\tval, err = st.ValidatorByIndex(idx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, constants.FarFutureEpoch, val.ActivationEpoch)\n\trequire.Equal(t, constants.FarFutureEpoch, val.ExitEpoch)\n\n\t// finally when validator is active withdrawals will work\n\tblk = moveToEndOfEpoch(t, blk, cs, sp, st, ctx, depRoot)\n\n\twrs = []*types.WithdrawalRequest{\n\t\t{\n\t\t\tSourceAddress:   valAddr,\n\t\t\tValidatorPubKey: val.GetPubkey(),\n\t\t\tAmount:          1,\n\t\t},\n\t}\n\tblkTimestamp = blk.GetTimestamp() + 1\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblkTimestamp,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{\n\t\t\tWithdrawals: wrs,\n\t\t},\n\t\tst.EVMInflationWithdrawal(blkTimestamp),\n\t)\n\n\t// Run the test.\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\n\tpr, err = st.GetPendingPartialWithdrawals()\n\trequire.NoError(t, err)\n\trequire.Len(t, pr, 1)\n\trequire.Equal(t,\n\t\t[]*types.PendingPartialWithdrawal{\n\t\t\t{\n\t\t\t\tValidatorIndex:    1,\n\t\t\t\tAmount:            wrs[0].Amount,\n\t\t\t\tWithdrawableEpoch: 3 + cs.MinValidatorWithdrawabilityDelay(),\n\t\t\t},\n\t\t},\n\t\tpr,\n\t)\n}\n\n// Check that if the withdrawal request comes for a validator about to\n// be evicted, this double eviction is duly handled\nfunc TestConcurrentAutomaticAndVoluntaryWithdrawalRequests(t *testing.T) {\n\tt.Parallel()\n\tcs := setupChain(t)\n\tsp, st, ds, ctx, _, _ := statetransition.SetupTestState(t, cs)\n\n\t// make sure Electra is active\n\trequire.True(t, version.EqualsOrIsAfter(cs.GenesisForkVersion(), version.Electra()))\n\n\t// Make sure we have as many validators as the cap allows\n\tvar (\n\t\tmaxBalance = cs.MaxEffectiveBalance()\n\t\trndSeed    = 2024 // seed used to generate unique random value\n\t)\n\n\tvar (\n\t\tgenDeposits      = make(types.Deposits, 0, cs.ValidatorSetCap())\n\t\tgenPayloadHeader = &types.ExecutionPayloadHeader{\n\t\t\tVersionable: types.NewVersionable(cs.GenesisForkVersion()),\n\t\t}\n\t\ttotalDepositsCount = cs.ValidatorSetCap()\n\t)\n\n\t// Step1: let blockchain have as many validators as cap allows\n\tfor idx := range cs.ValidatorSetCap() {\n\t\tvar (\n\t\t\tkey   bytes.B48\n\t\t\tcreds types.WithdrawalCredentials\n\t\t)\n\t\tkey, rndSeed = generateTestPK(t, rndSeed)\n\t\tcreds, rndSeed = generateTestExecutionAddress(t, rndSeed)\n\n\t\tgenDeposits = append(\n\t\t\tgenDeposits,\n\t\t\t&types.Deposit{\n\t\t\t\tPubkey:      key,\n\t\t\t\tCredentials: creds,\n\t\t\t\tAmount:      maxBalance,\n\t\t\t\tIndex:       idx,\n\t\t\t},\n\t\t)\n\t}\n\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), genDeposits))\n\t_, err := sp.InitializeBeaconStateFromEth1(\n\t\tst,\n\t\tgenDeposits,\n\t\tgenPayloadHeader,\n\t\tcs.GenesisForkVersion(),\n\t)\n\trequire.NoError(t, err)\n\n\t// Step 2: add a deposit which will evict one of the existing validators\n\tnewValKey, rndSeed := generateTestPK(t, rndSeed)\n\tnewValCreds, _ := generateTestExecutionAddress(t, rndSeed)\n\tvar (\n\t\tnewValDeposit = &types.Deposit{\n\t\t\tPubkey:      newValKey,\n\t\t\tCredentials: newValCreds,\n\t\t\tAmount:      maxBalance,\n\t\t\tIndex:       uint64(len(genDeposits)),\n\t\t}\n\t\tblkDeposits = []*types.Deposit{newValDeposit}\n\t)\n\ttotalDepositsCount++\n\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), blkDeposits))\n\tvar depRoot common.Root\n\t_, depRoot, err = ds.GetDepositsByIndex(ctx.ConsensusCtx(), constants.FirstDepositIndex, totalDepositsCount)\n\trequire.NoError(t, err)\n\n\tblkTimestamp := math.U64(10)\n\tblk := buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblkTimestamp,\n\t\tblkDeposits,\n\t\t&types.ExecutionRequests{},\n\t\tst.EVMInflationWithdrawal(blkTimestamp),\n\t)\n\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\n\t// check the deposit has been accepted\n\t_, err = st.ValidatorIndexByPubkey(newValDeposit.Pubkey)\n\trequire.NoError(t, err)\n\n\t// move chain on till the new validator is about to be activated\n\t_ = moveToEndOfEpoch(t, blk, cs, sp, st, ctx, depRoot)\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblk.GetTimestamp()+1,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{},\n\t\tst.EVMInflationWithdrawal(blk.GetTimestamp()+1),\n\t)\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\n\t_ = moveToEndOfEpoch(t, blk, cs, sp, st, ctx, depRoot)\n\n\t// right at the block where we a validator will be evicted\n\t// we add a full withdrawal request for it. We expect this request\n\t// to be simply dropped since the validator is evicted upon ProcessEpoch\n\tevictedValAddr, err := genDeposits[0].Credentials.ToExecutionAddress()\n\trequire.NoError(t, err)\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblk.GetTimestamp()+1,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{\n\t\t\tWithdrawals: []*types.WithdrawalRequest{\n\t\t\t\t{\n\t\t\t\t\tSourceAddress:   evictedValAddr,\n\t\t\t\t\tValidatorPubKey: genDeposits[0].Pubkey,\n\t\t\t\t\tAmount:          0,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tst.EVMInflationWithdrawal(blk.GetTimestamp()+1),\n\t)\n\tvalDiff, err := sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\trequire.Len(t, valDiff, 2)\n\trequire.Equal(\n\t\tt,\n\t\t&transition.ValidatorUpdate{\n\t\t\tPubkey:           newValDeposit.Pubkey,\n\t\t\tEffectiveBalance: newValDeposit.Amount,\n\t\t},\n\t\tvalDiff[0],\n\t)\n\trequire.Equal(\n\t\tt,\n\t\t&transition.ValidatorUpdate{\n\t\t\tPubkey:           genDeposits[0].Pubkey,\n\t\t\tEffectiveBalance: 0,\n\t\t},\n\t\tvalDiff[1],\n\t)\n\n\tevictedValIdx, err := st.ValidatorIndexByPubkey(genDeposits[0].Pubkey)\n\trequire.NoError(t, err)\n\tevictedVal, err := st.ValidatorByIndex(evictedValIdx)\n\trequire.NoError(t, err)\n\n\texpectedExitEpoch := math.Epoch(2)\n\texpectedWithdrawalEpoch := math.Epoch(2) + cs.MinValidatorWithdrawabilityDelay()\n\trequire.Equal(t, expectedExitEpoch, evictedVal.ExitEpoch)\n\trequire.Equal(t, expectedWithdrawalEpoch, evictedVal.WithdrawableEpoch)\n}\n\n// Check that two full withdrawals requests issued back to back\n// are idempotent. The second request simply dropped\nfunc TestDoubleFullWithdrawalRequests(t *testing.T) {\n\tt.Parallel()\n\tcs := setupChain(t)\n\tsp, st, ds, ctx, _, _ := statetransition.SetupTestState(t, cs)\n\n\t// make sure Electra is active\n\trequire.True(t, version.EqualsOrIsAfter(cs.GenesisForkVersion(), version.Electra()))\n\n\tvar (\n\t\tmaxBalance = cs.MaxEffectiveBalance()\n\n\t\taddr1  = common.ExecutionAddress{0x01}\n\t\tcreds1 = types.NewCredentialsFromExecutionAddress(addr1)\n\t\taddr2  = common.ExecutionAddress{0x01}\n\t\tcreds2 = types.NewCredentialsFromExecutionAddress(addr2)\n\t)\n\n\t// Add a couple of validators and fully withdraw one of them\n\tvar (\n\t\tgenDeposits = types.Deposits{\n\t\t\t{\n\t\t\t\tPubkey:      [48]byte{0x00},\n\t\t\t\tCredentials: creds1,\n\t\t\t\tAmount:      maxBalance,\n\t\t\t\tIndex:       0,\n\t\t\t},\n\t\t\t{\n\t\t\t\tPubkey:      [48]byte{0x01},\n\t\t\t\tCredentials: creds2,\n\t\t\t\tAmount:      maxBalance,\n\t\t\t\tIndex:       1,\n\t\t\t},\n\t\t}\n\t\tgenPayloadHeader = &types.ExecutionPayloadHeader{\n\t\t\tVersionable: types.NewVersionable(cs.GenesisForkVersion()),\n\t\t}\n\t)\n\t_, err := sp.InitializeBeaconStateFromEth1(\n\t\tst, genDeposits, genPayloadHeader, cs.GenesisForkVersion(),\n\t)\n\trequire.NoError(t, err)\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), genDeposits))\n\n\tvals, err := st.GetValidators()\n\trequire.NoError(t, err)\n\trequire.Len(t, vals, 2)\n\tvalToRm := vals[0]\n\n\twrs := []*types.WithdrawalRequest{\n\t\t{\n\t\t\tSourceAddress:   addr1,\n\t\t\tValidatorPubKey: valToRm.GetPubkey(),\n\t\t\tAmount:          0,\n\t\t},\n\t}\n\n\tvar depRoot common.Root\n\t_, depRoot, err = ds.GetDepositsByIndex(ctx.ConsensusCtx(), 0, uint64(len(genDeposits)))\n\trequire.NoError(t, err)\n\n\tblkTimestamp := math.U64(10)\n\tblk := buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblkTimestamp,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{\n\t\t\tWithdrawals: wrs,\n\t\t},\n\t\tst.EVMInflationWithdrawal(blkTimestamp),\n\t)\n\n\t// Run the test.\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\n\t// check that valToRm has initiated exit\n\texpectedExitEpoch := math.Epoch(1)\n\texpectedWithdrawalEpoch := expectedExitEpoch + cs.MinValidatorWithdrawabilityDelay()\n\n\tvalToRmIdx, err := st.ValidatorIndexByPubkey(valToRm.GetPubkey())\n\trequire.NoError(t, err)\n\tvalToRm, err = st.ValidatorByIndex(valToRmIdx)\n\trequire.NoError(t, err)\n\trequire.Equal(t, expectedExitEpoch, valToRm.ExitEpoch)\n\trequire.Equal(t, expectedWithdrawalEpoch, valToRm.WithdrawableEpoch)\n\n\t// issue another full withdrawal request, which should be\n\t// processed without errors and simply dropped\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblkTimestamp,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{\n\t\t\tWithdrawals: wrs,\n\t\t},\n\t\tst.EVMInflationWithdrawal(blkTimestamp),\n\t)\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n}\n\nfunc TestPartialWithdrawalsOfBalanceAboveMaxEffectiveBalance(t *testing.T) {\n\tt.Parallel()\n\tcs := setupChain(t)\n\tsp, st, ds, ctx, _, _ := statetransition.SetupTestState(t, cs)\n\n\tvar (\n\t\tmaxBalance   = cs.MaxEffectiveBalance()\n\t\tminBalance   = cs.EffectiveBalanceIncrement()\n\t\tcredentials0 = types.NewCredentialsFromExecutionAddress(common.ExecutionAddress{})\n\t\taddress1     = common.ExecutionAddress{0x01}\n\t\tcredentials1 = types.NewCredentialsFromExecutionAddress(address1)\n\t)\n\n\t// Setup initial state so that validator 1 is partially withdrawable.\n\tvar (\n\t\tgenDeposits = types.Deposits{\n\t\t\t{\n\t\t\t\tPubkey:      [48]byte{0x00},\n\t\t\t\tCredentials: credentials0,\n\t\t\t\tAmount:      maxBalance - 3*minBalance,\n\t\t\t\tIndex:       0,\n\t\t\t},\n\t\t\t{\n\t\t\t\tPubkey:      [48]byte{0x01},\n\t\t\t\tCredentials: credentials1,\n\t\t\t\tAmount:      maxBalance + minBalance,\n\t\t\t\tIndex:       1,\n\t\t\t},\n\t\t}\n\t\tgenPayloadHeader = &types.ExecutionPayloadHeader{\n\t\t\tVersionable: types.NewVersionable(cs.GenesisForkVersion()),\n\t\t}\n\t)\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), genDeposits))\n\t_, err := sp.InitializeBeaconStateFromEth1(\n\t\tst, genDeposits, genPayloadHeader, cs.GenesisForkVersion(),\n\t)\n\trequire.NoError(t, err)\n\n\t// Assert validator 1 balance before withdrawal.\n\tval1Bal, err := st.GetBalance(math.U64(1))\n\trequire.NoError(t, err)\n\trequire.Equal(t, maxBalance+minBalance, val1Bal)\n\n\t// Create test inputs.\n\twithdrawals := []*engineprimitives.Withdrawal{\n\t\t// The first withdrawal is always for EVM inflation.\n\t\tst.EVMInflationWithdrawal(10),\n\t\t// Partially withdraw validator 1 by minBalance.\n\t\t{\n\t\t\tIndex:     0,\n\t\t\tValidator: 1,\n\t\t\tAmount:    minBalance,\n\t\t\tAddress:   address1,\n\t\t},\n\t}\n\n\tvar depRoot common.Root\n\t_, depRoot, err = ds.GetDepositsByIndex(ctx.ConsensusCtx(), 0, uint64(len(genDeposits)))\n\trequire.NoError(t, err)\n\n\tblk := buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\t10,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{},\n\t\twithdrawals...,\n\t)\n\n\t// Run the test.\n\t_, err = sp.Transition(ctx, st, blk)\n\n\t// Check outputs and ensure withdrawals in payload is consistent with\n\t// statedb expected withdrawals.\n\trequire.NoError(t, err)\n\n\t// Assert validator 1 balance after withdrawal.\n\tval1BalAfter, err := st.GetBalance(math.U64(1))\n\trequire.NoError(t, err)\n\trequire.Equal(t, maxBalance, val1BalAfter)\n}\n\nfunc TestTransitionMaxWithdrawals(t *testing.T) {\n\tt.Parallel()\n\t// Use custom chain spec with max withdrawals set to 2.\n\tcsData := spec.DevnetChainSpecData()\n\tcsData.MaxWithdrawalsPerPayload = 2\n\tcsData.MaxValidatorsPerWithdrawalsSweep = 2\n\tcs, err := chain.NewSpec(csData)\n\trequire.NoError(t, err)\n\n\tsp, st, ds, ctx, _, _ := statetransition.SetupTestState(t, cs)\n\n\tvar (\n\t\tmaxBalance   = cs.MaxEffectiveBalance()\n\t\tminBalance   = cs.EffectiveBalanceIncrement()\n\t\taddress0     = common.ExecutionAddress{}\n\t\tcredentials0 = types.NewCredentialsFromExecutionAddress(address0)\n\t\taddress1     = common.ExecutionAddress{0x01}\n\t\tcredentials1 = types.NewCredentialsFromExecutionAddress(address1)\n\t)\n\n\t// Setup initial state so that both validators are partially withdrawable.\n\tvar (\n\t\tgenDeposits = types.Deposits{\n\t\t\t{\n\t\t\t\tPubkey:      [48]byte{0x00},\n\t\t\t\tCredentials: credentials0,\n\t\t\t\tAmount:      maxBalance + minBalance,\n\t\t\t\tIndex:       0,\n\t\t\t},\n\t\t\t{\n\t\t\t\tPubkey:      [48]byte{0x01},\n\t\t\t\tCredentials: credentials1,\n\t\t\t\tAmount:      maxBalance + minBalance,\n\t\t\t\tIndex:       1,\n\t\t\t},\n\t\t}\n\t\tgenPayloadHeader = &types.ExecutionPayloadHeader{\n\t\t\tVersionable: types.NewVersionable(cs.GenesisForkVersion()),\n\t\t}\n\t)\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), genDeposits))\n\t_, err = sp.InitializeBeaconStateFromEth1(\n\t\tst, genDeposits, genPayloadHeader, cs.GenesisForkVersion(),\n\t)\n\trequire.NoError(t, err)\n\n\t// Assert validator balances before withdrawal.\n\tval0Bal, err := st.GetBalance(math.U64(0))\n\trequire.NoError(t, err)\n\trequire.Equal(t, maxBalance+minBalance, val0Bal)\n\n\tval1Bal, err := st.GetBalance(math.U64(1))\n\trequire.NoError(t, err)\n\trequire.Equal(t, maxBalance+minBalance, val1Bal)\n\n\t// Create test inputs.\n\twithdrawals := []*engineprimitives.Withdrawal{\n\t\t// The first withdrawal is always for EVM inflation.\n\t\tst.EVMInflationWithdrawal(10),\n\t\t// Partially withdraw validator 0 by minBalance.\n\t\t{\n\t\t\tIndex:     0,\n\t\t\tValidator: 0,\n\t\t\tAmount:    minBalance,\n\t\t\tAddress:   address0,\n\t\t},\n\t}\n\n\tvar depRoot common.Root\n\t_, depRoot, err = ds.GetDepositsByIndex(ctx.ConsensusCtx(), 0, uint64(len(genDeposits)))\n\trequire.NoError(t, err)\n\n\tblk := buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\t10,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{},\n\t\twithdrawals...,\n\t)\n\n\t// Run the test.\n\t_, err = sp.Transition(ctx, st, blk)\n\n\t// Check outputs and ensure withdrawals in payload is consistent with\n\t// statedb expected withdrawals.\n\trequire.NoError(t, err)\n\n\t// Assert validator balances after withdrawal, ensuring only validator 0 is\n\t// withdrawn from.\n\tval0BalAfter, err := st.GetBalance(math.U64(0))\n\trequire.NoError(t, err)\n\trequire.Equal(t, maxBalance, val0BalAfter)\n\n\tval1BalAfter, err := st.GetBalance(math.U64(1))\n\trequire.NoError(t, err)\n\trequire.Equal(t, maxBalance+minBalance, val1BalAfter)\n\n\t// Process the next block, ensuring that validator 1 is also withdrawn from,\n\t// also ensuring that the state's next withdrawal (validator) index is\n\t// appropriately incremented.\n\n\twithdrawals = []*engineprimitives.Withdrawal{\n\t\t// The first withdrawal is always for EVM inflation.\n\t\tst.EVMInflationWithdrawal(blk.GetTimestamp() + 1),\n\t\t// Partially withdraw validator 1 by minBalance.\n\t\t{\n\t\t\tIndex:     1,\n\t\t\tValidator: 1,\n\t\t\tAmount:    minBalance,\n\t\t\tAddress:   address1,\n\t\t},\n\t}\n\tblk = buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\tblk.GetTimestamp()+1,\n\t\t[]*types.Deposit{},\n\t\t&types.ExecutionRequests{},\n\t\twithdrawals...,\n\t)\n\t// Run the test.\n\tvals, err := sp.Transition(ctx, st, blk)\n\n\t// Check outputs and ensure withdrawals in payload is consistent with\n\t// statedb expected withdrawals.\n\trequire.NoError(t, err)\n\trequire.Zero(t, vals)\n\n\t// Validator 1 is now withdrawn from.\n\tval1BalAfter, err = st.GetBalance(math.U64(1))\n\trequire.NoError(t, err)\n\trequire.Equal(t, maxBalance, val1BalAfter)\n}\n\nfunc TestValidatorNotWithdrawable(t *testing.T) {\n\tt.Parallel()\n\tcs := setupChain(t)\n\tsp, st, ds, ctx, _, _ := statetransition.SetupTestState(t, cs)\n\n\tvar (\n\t\tbelowActiveBalance = cs.MinActivationBalance() - cs.EffectiveBalanceIncrement()\n\t\tmaxBalance         = cs.MaxEffectiveBalance()\n\t\tvalidCredentials   = types.NewCredentialsFromExecutionAddress(common.ExecutionAddress{})\n\t)\n\n\t// Setup initial state with one validator\n\tvar (\n\t\tgenDeposits = types.Deposits{\n\t\t\t{\n\t\t\t\tPubkey:      [48]byte{0x00},\n\t\t\t\tCredentials: validCredentials,\n\t\t\t\tAmount:      maxBalance,\n\t\t\t\tIndex:       0,\n\t\t\t},\n\t\t}\n\t\tgenPayloadHeader = &types.ExecutionPayloadHeader{\n\t\t\tVersionable: types.NewVersionable(cs.GenesisForkVersion()),\n\t\t}\n\t\ttotalDepositsCount = uint64(len(genDeposits))\n\t)\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), genDeposits))\n\t_, err := sp.InitializeBeaconStateFromEth1(\n\t\tst, genDeposits, genPayloadHeader, cs.GenesisForkVersion(),\n\t)\n\trequire.NoError(t, err)\n\n\t// Create the block deposit with a non-ETH1 withdrawal credentials. This stake should not\n\t// be lost.\n\tinvalidCredentials := types.WithdrawalCredentials(validCredentials[:])\n\tinvalidCredentials[1] = 0x01\n\tblkDeposit := &types.Deposit{\n\t\tPubkey:      [48]byte{0x01},\n\t\tCredentials: invalidCredentials,\n\t\tAmount:      belowActiveBalance,\n\t\tIndex:       1,\n\t}\n\tblkDeposits := []*types.Deposit{blkDeposit}\n\ttotalDepositsCount++\n\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), blkDeposits))\n\tvar depRoot common.Root\n\t_, depRoot, err = ds.GetDepositsByIndex(ctx.ConsensusCtx(), constants.FirstDepositIndex, totalDepositsCount)\n\trequire.NoError(t, err)\n\n\tblk := buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\t10,\n\t\tblkDeposits,\n\t\t&types.ExecutionRequests{},\n\t\tst.EVMInflationWithdrawal(10),\n\t)\n\n\t// Run transition.\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n\n\t// Check that validator 0x01 is part of beacon state with below active balance.\n\tvalidator, err := st.ValidatorByIndex(1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, belowActiveBalance, validator.EffectiveBalance)\n}\n"
  },
  {
    "path": "state-transition/core/validation_deposits.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core\n\nimport (\n\t\"context\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n\t\"github.com/berachain/beacon-kit/storage/deposit\"\n)\n\nfunc validateGenesisDeposits(\n\tst *statedb.StateDB, deposits []*ctypes.Deposit, validatorSetCap uint64,\n) error {\n\teth1DepositIndex, err := st.GetEth1DepositIndex()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif eth1DepositIndex != constants.FirstDepositIndex {\n\t\treturn errors.New(\"Eth1DepositIndex should be 0 at genesis\")\n\t}\n\n\tif len(deposits) == 0 {\n\t\t// there should be at least a validator in genesis\n\t\treturn errors.Wrap(ErrDepositsLengthMismatch, \"at least one validator should be in genesis\")\n\t}\n\tfor i, deposit := range deposits {\n\t\t// deposit indices should be contiguous\n\t\t// #nosec G115\n\t\tif deposit.GetIndex() != math.U64(i) {\n\t\t\treturn errors.Wrapf(ErrDepositIndexOutOfOrder,\n\t\t\t\t\"genesis deposit index: %d, expected index: %d\", deposit.GetIndex().Unwrap(), i,\n\t\t\t)\n\t\t}\n\t}\n\n\t// BeaconKit enforces a cap on the validator set size.\n\t// If genesis deposits breaches the cap we return an error.\n\t//#nosec:G701 // can't overflow.\n\tif uint64(len(deposits)) > validatorSetCap {\n\t\treturn errors.Wrapf(\n\t\t\tErrValSetCapExceeded,\n\t\t\t\"validator set cap %d, deposits count %d\",\n\t\t\tvalidatorSetCap, len(deposits),\n\t\t)\n\t}\n\treturn nil\n}\n\nfunc ValidateNonGenesisDeposits(\n\tctx context.Context,\n\tst *statedb.StateDB,\n\tdepositStore deposit.StoreManager,\n\tmaxDepositsPerBlock uint64,\n\tblkDeposits []*ctypes.Deposit,\n\tblkDepositRoot common.Root,\n) error {\n\tdepositIndex, err := st.GetEth1DepositIndex()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Grab all previous deposits from genesis up to the current index + max deposits per block.\n\tlocalDeposits, localDepositRoot, err := depositStore.GetDepositsByIndex(\n\t\tctx,\n\t\tconstants.FirstDepositIndex,\n\t\tdepositIndex+maxDepositsPerBlock,\n\t)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// First verify that the number of block deposits matches the number of local deposits.\n\ttotalBlockDeposits := depositIndex + uint64(len(blkDeposits))\n\tif uint64(len(localDeposits)) != totalBlockDeposits {\n\t\treturn errors.Wrapf(ErrDepositsLengthMismatch,\n\t\t\t\"block deposit count: %d, expected deposit count: %d\",\n\t\t\ttotalBlockDeposits, len(localDeposits),\n\t\t)\n\t}\n\n\t// Then check that the block's deposits 1) have contiguous indices and 2) match the local\n\t// view of the block's deposits.\n\tfor i, blkDeposit := range blkDeposits {\n\t\tblkDepositIndex := blkDeposit.GetIndex().Unwrap()\n\t\t//#nosec:G115 // won't overflow in practice.\n\t\tif blkDepositIndex != depositIndex+uint64(i) {\n\t\t\treturn errors.Wrapf(ErrDepositIndexOutOfOrder,\n\t\t\t\t\"deposit index: %d, expected index: %d\", blkDepositIndex, i,\n\t\t\t)\n\t\t}\n\n\t\tif !localDeposits[blkDepositIndex].Equals(blkDeposit) {\n\t\t\treturn errors.Wrapf(ErrDepositMismatch,\n\t\t\t\t\"deposit index: %d, expected deposit: %+v, actual deposit: %+v\",\n\t\t\t\tblkDepositIndex, *localDeposits[blkDepositIndex], *blkDeposit,\n\t\t\t)\n\t\t}\n\t}\n\n\t// Finally check that the historical deposits root matches locally what's on the beacon block.\n\tif !localDepositRoot.Equals(blkDepositRoot) {\n\t\treturn ErrDepositsRootMismatch\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "state-transition/core/validation_deposits_test.go",
    "content": "//go:build test\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage core_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\tstatetransition \"github.com/berachain/beacon-kit/testing/state-transition\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n//nolint:paralleltest // uses envars\nfunc TestInvalidDeposits(t *testing.T) {\n\tcs := setupChain(t)\n\tsp, st, ds, ctx, _, _ := statetransition.SetupTestState(t, cs)\n\n\tvar (\n\t\tminBalance   = cs.MinActivationBalance()\n\t\tmaxBalance   = cs.MaxEffectiveBalance()\n\t\tcredentials0 = types.NewCredentialsFromExecutionAddress(common.ExecutionAddress{})\n\t)\n\n\t// Setup initial state with one validator\n\tvar (\n\t\tgenDeposits = types.Deposits{\n\t\t\t{\n\t\t\t\tPubkey:      [48]byte{0x00},\n\t\t\t\tCredentials: credentials0,\n\t\t\t\tAmount:      maxBalance,\n\t\t\t\tIndex:       0,\n\t\t\t},\n\t\t}\n\t\tgenPayloadHeader = &types.ExecutionPayloadHeader{\n\t\t\tVersionable: types.NewVersionable(cs.GenesisForkVersion()),\n\t\t}\n\t\ttotalDepositsCount = uint64(len(genDeposits))\n\t)\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), genDeposits))\n\t_, err := sp.InitializeBeaconStateFromEth1(\n\t\tst, genDeposits, genPayloadHeader, cs.GenesisForkVersion(),\n\t)\n\trequire.NoError(t, err)\n\n\t// Create the correct deposit for pubkey 1.\n\tcorrectDeposit := &types.Deposit{\n\t\tPubkey:      [48]byte{0x01},\n\t\tCredentials: credentials0,\n\t\tAmount:      minBalance,\n\t\tIndex:       1,\n\t}\n\ttotalDepositsCount++\n\n\t// Create an invalid deposit with extra balance going to pubkey 1\n\tinvalidDeposit := &types.Deposit{\n\t\tPubkey:      [48]byte{0x01},\n\t\tCredentials: credentials0,\n\t\tAmount:      maxBalance, // Invalid - should be minBalance\n\t\tIndex:       1,\n\t}\n\tblkDeposits := []*types.Deposit{invalidDeposit}\n\n\t// make sure included deposit is already available in deposit store\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), []*types.Deposit{correctDeposit}))\n\tvar depRoot common.Root\n\t_, depRoot, err = ds.GetDepositsByIndex(ctx.ConsensusCtx(), constants.FirstDepositIndex, totalDepositsCount)\n\trequire.NoError(t, err)\n\n\t// Create test block with invalid deposit, BUT the correct deposit for pubkey 1.\n\tblk := buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\t10,\n\t\tblkDeposits,\n\t\t&types.ExecutionRequests{},\n\t\tst.EVMInflationWithdrawal(10),\n\t)\n\n\t// Run transition - should fail due to invalid deposit amount.\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.Error(t, err)\n\trequire.ErrorContains(t, err, \"deposit mismatched\")\n}\n\n//nolint:paralleltest // uses envars\nfunc TestInvalidDepositsCount(t *testing.T) {\n\tcs := setupChain(t)\n\tsp, st, ds, ctx, _, _ := statetransition.SetupTestState(t, cs)\n\n\tvar (\n\t\tmaxBalance   = cs.MaxEffectiveBalance()\n\t\tcredentials0 = types.NewCredentialsFromExecutionAddress(common.ExecutionAddress{})\n\t)\n\n\t// Setup initial state with one validator\n\tvar (\n\t\tgenDeposits = types.Deposits{\n\t\t\t{\n\t\t\t\tPubkey:      [48]byte{0x00},\n\t\t\t\tCredentials: credentials0,\n\t\t\t\tAmount:      maxBalance,\n\t\t\t\tIndex:       0,\n\t\t\t},\n\t\t}\n\t\tgenPayloadHeader = &types.ExecutionPayloadHeader{\n\t\t\tVersionable: types.NewVersionable(cs.GenesisForkVersion()),\n\t\t}\n\t\ttotalDepositsCount = uint64(len(genDeposits))\n\t)\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), genDeposits))\n\t_, err := sp.InitializeBeaconStateFromEth1(\n\t\tst, genDeposits, genPayloadHeader, cs.GenesisForkVersion(),\n\t)\n\trequire.NoError(t, err)\n\n\t// Create the correct deposits.\n\tcorrectDeposits := types.Deposits{\n\t\t{\n\t\t\tPubkey:      [48]byte{0x01},\n\t\t\tCredentials: credentials0,\n\t\t\tAmount:      maxBalance,\n\t\t\tIndex:       1,\n\t\t},\n\t\t{\n\t\t\tPubkey:      [48]byte{0x02},\n\t\t\tCredentials: credentials0,\n\t\t\tAmount:      maxBalance,\n\t\t\tIndex:       2,\n\t\t},\n\t}\n\ttotalDepositsCount += uint64(len(correctDeposits))\n\n\t// Add JUST 1 correct deposit to local store. This node SHOULD fail to verify.\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), []*types.Deposit{correctDeposits[0]}))\n\tvar depRoot common.Root\n\t_, depRoot, err = ds.GetDepositsByIndex(ctx.ConsensusCtx(), constants.FirstDepositIndex, totalDepositsCount)\n\trequire.NoError(t, err)\n\n\t// Create test block with the correct deposits.\n\tblk := buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\t10,\n\t\tcorrectDeposits,\n\t\t&types.ExecutionRequests{},\n\t\tst.EVMInflationWithdrawal(10),\n\t)\n\n\t// Run transition.\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.Error(t, err)\n\trequire.ErrorContains(t, err, \"deposits lengths mismatched\")\n}\n\nfunc TestLocalDepositsExceedBlockDeposits(t *testing.T) {\n\tt.Parallel()\n\tcsData := spec.DevnetChainSpecData()\n\tcsData.MaxDepositsPerBlock = 1 // Set only 1 deposit allowed per block.\n\tcs, err := chain.NewSpec(csData)\n\trequire.NoError(t, err)\n\tsp, st, ds, ctx, _, _ := statetransition.SetupTestState(t, cs)\n\n\tvar (\n\t\tmaxBalance   = cs.MaxEffectiveBalance()\n\t\tcredentials0 = types.NewCredentialsFromExecutionAddress(common.ExecutionAddress{})\n\t)\n\n\t// Setup initial state with one validator\n\tvar (\n\t\tgenDeposits = types.Deposits{\n\t\t\t{\n\t\t\t\tPubkey:      [48]byte{0x00},\n\t\t\t\tCredentials: credentials0,\n\t\t\t\tAmount:      maxBalance,\n\t\t\t\tIndex:       0,\n\t\t\t},\n\t\t}\n\t\tgenPayloadHeader = &types.ExecutionPayloadHeader{\n\t\t\tVersionable: types.NewVersionable(cs.GenesisForkVersion()),\n\t\t}\n\t\ttotalDepositsCount = uint64(len(genDeposits))\n\t)\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), genDeposits))\n\t_, err = sp.InitializeBeaconStateFromEth1(\n\t\tst, genDeposits, genPayloadHeader, cs.GenesisForkVersion(),\n\t)\n\trequire.NoError(t, err)\n\n\t// Create the block deposits.\n\tblockDeposit := types.Deposit{\n\t\tPubkey:      [48]byte{0x01},\n\t\tCredentials: credentials0,\n\t\tAmount:      maxBalance,\n\t\tIndex:       1,\n\t}\n\tblkDeposits := []*types.Deposit{&blockDeposit}\n\textraLocalDeposit := &types.Deposit{\n\t\tPubkey:      [48]byte{0x01},\n\t\tCredentials: credentials0,\n\t\tAmount:      maxBalance,\n\t\tIndex:       2,\n\t}\n\ttotalDepositsCount += 2\n\n\t// make sure included deposit is already available in deposit store\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), []*types.Deposit{&blockDeposit, extraLocalDeposit}))\n\tvar depRoot common.Root\n\t_, depRoot, err = ds.GetDepositsByIndex(ctx.ConsensusCtx(), constants.FirstDepositIndex, totalDepositsCount-1)\n\trequire.NoError(t, err)\n\n\t// Create test block with the correct deposits.\n\tblk := buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(depRoot),\n\t\t10,\n\t\tblkDeposits,\n\t\t&types.ExecutionRequests{},\n\t\tst.EVMInflationWithdrawal(10),\n\t)\n\n\t// Run transition.\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.NoError(t, err)\n}\n\nfunc TestLocalDepositsExceedBlockDepositsBadRoot(t *testing.T) {\n\tt.Parallel()\n\tcsData := spec.DevnetChainSpecData()\n\tcsData.MaxDepositsPerBlock = 1 // Set only 1 deposit allowed per block.\n\tcs, err := chain.NewSpec(csData)\n\trequire.NoError(t, err)\n\tsp, st, ds, ctx, _, _ := statetransition.SetupTestState(t, cs)\n\n\tvar (\n\t\tmaxBalance   = cs.MaxEffectiveBalance()\n\t\tcredentials0 = types.NewCredentialsFromExecutionAddress(common.ExecutionAddress{})\n\t)\n\n\t// Setup initial state with one validator\n\tvar (\n\t\tgenDeposits = types.Deposits{\n\t\t\t{\n\t\t\t\tPubkey:      [48]byte{0x00},\n\t\t\t\tCredentials: credentials0,\n\t\t\t\tAmount:      maxBalance,\n\t\t\t\tIndex:       0,\n\t\t\t},\n\t\t}\n\t\tgenPayloadHeader = &types.ExecutionPayloadHeader{\n\t\t\tVersionable: types.NewVersionable(cs.GenesisForkVersion()),\n\t\t}\n\t)\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), genDeposits))\n\t_, err = sp.InitializeBeaconStateFromEth1(\n\t\tst, genDeposits, genPayloadHeader, cs.GenesisForkVersion(),\n\t)\n\trequire.NoError(t, err)\n\n\t// Create the block deposits.\n\tblockDeposits := types.Deposits{\n\t\t{\n\t\t\tPubkey:      [48]byte{0x01},\n\t\t\tCredentials: credentials0,\n\t\t\tAmount:      maxBalance,\n\t\t\tIndex:       1,\n\t\t},\n\t}\n\n\textraLocalDeposit := &types.Deposit{\n\t\tPubkey:      [48]byte{0x01},\n\t\tCredentials: credentials0,\n\t\tAmount:      maxBalance,\n\t\tIndex:       2,\n\t}\n\n\t// Now, the block proposer ends up adding the correct 1 deposit per block, BUT spoofs the\n\t// deposits root to use the entire deposits list.\n\tbadDepRoot := append(genDeposits, append(blockDeposits, extraLocalDeposit)...).HashTreeRoot()\n\tblk := buildNextBlock(\n\t\tt,\n\t\tcs,\n\t\tst,\n\t\ttypes.NewEth1Data(badDepRoot),\n\t\t10,\n\t\tblockDeposits,\n\t\t&types.ExecutionRequests{},\n\t\tst.EVMInflationWithdrawal(10),\n\t)\n\n\t// Add both deposits to local store (which includes more than what's in the block).\n\trequire.NoError(t, ds.EnqueueDeposits(ctx.ConsensusCtx(), append(blockDeposits, extraLocalDeposit)))\n\n\t// Run transition.\n\t_, err = sp.Transition(ctx, st, blk)\n\trequire.Error(t, err)\n\trequire.ErrorContains(t, err, \"deposits root mismatch\")\n}\n"
  },
  {
    "path": "storage/beacondb/eth1.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacondb\n\nimport (\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n)\n\n// GetLatestExecutionPayloadHeader retrieves the latest execution payload\n// header from the BeaconStore.\nfunc (kv *KVStore) GetLatestExecutionPayloadHeader() (\n\t*ctypes.ExecutionPayloadHeader, error,\n) {\n\t// NOTE: unmarshalling this struct is NOT affected by it's own fork version. The versioned\n\t// codec is left in for backwards compatibility.\n\tforkVersion, err := kv.latestExecutionPayloadVersion.Get(kv.ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tkv.latestExecutionPayloadCodec.SetActiveForkVersion(bytes.FromUint32(forkVersion))\n\treturn kv.latestExecutionPayloadHeader.Get(kv.ctx)\n}\n\n// SetLatestExecutionPayloadHeader sets the latest execution payload header in\n// the BeaconStore.\nfunc (kv *KVStore) SetLatestExecutionPayloadHeader(\n\tpayloadHeader *ctypes.ExecutionPayloadHeader,\n) error {\n\t// NOTE: marshalling this struct is NOT affected by it's own fork version. The versioned\n\t// codec is left in for backwards compatibility.\n\tversion := payloadHeader.GetForkVersion()\n\tif err := kv.latestExecutionPayloadVersion.Set(\n\t\tkv.ctx, version.ToUint32(),\n\t); err != nil {\n\t\treturn err\n\t}\n\tkv.latestExecutionPayloadCodec.SetActiveForkVersion(version)\n\treturn kv.latestExecutionPayloadHeader.Set(kv.ctx, payloadHeader)\n}\n\n// GetEth1DepositIndex retrieves the eth1 deposit index from the beacon state.\nfunc (kv *KVStore) GetEth1DepositIndex() (uint64, error) {\n\treturn kv.eth1DepositIndex.Get(kv.ctx)\n}\n\n// SetEth1DepositIndex sets the eth1 deposit index in the beacon state.\nfunc (kv *KVStore) SetEth1DepositIndex(index uint64) error {\n\treturn kv.eth1DepositIndex.Set(kv.ctx, index)\n}\n\n// GetEth1Data retrieves the eth1 data from the beacon state.\nfunc (kv *KVStore) GetEth1Data() (*ctypes.Eth1Data, error) {\n\treturn kv.eth1Data.Get(kv.ctx)\n}\n\n// SetEth1Data sets the eth1 data in the beacon state.\nfunc (kv *KVStore) SetEth1Data(data *ctypes.Eth1Data) error {\n\treturn kv.eth1Data.Set(kv.ctx, data)\n}\n"
  },
  {
    "path": "storage/beacondb/fork.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacondb\n\nimport ctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\n// SetFork sets the fork version for the given epoch.\nfunc (kv *KVStore) SetFork(fork *ctypes.Fork) error {\n\treturn kv.fork.Set(kv.ctx, fork)\n}\n\n// GetFork gets the fork version for the given epoch.\nfunc (kv *KVStore) GetFork() (*ctypes.Fork, error) {\n\treturn kv.fork.Get(kv.ctx)\n}\n"
  },
  {
    "path": "storage/beacondb/history.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacondb\n\nimport (\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n)\n\n// UpdateBlockRootAtIndex sets a block root in the BeaconStore.\nfunc (kv *KVStore) UpdateBlockRootAtIndex(\n\tindex uint64,\n\troot common.Root,\n) error {\n\treturn kv.blockRoots.Set(kv.ctx, index, root[:])\n}\n\n// GetBlockRootAtIndex retrieves the block root from the BeaconStore.\nfunc (kv *KVStore) GetBlockRootAtIndex(\n\tindex uint64,\n) (common.Root, error) {\n\tbz, err := kv.blockRoots.Get(kv.ctx, index)\n\tif err != nil {\n\t\treturn common.Root{}, err\n\t}\n\treturn common.Root(bz), nil\n}\n\n// SetLatestBlockHeader sets the latest block header in the BeaconStore.\nfunc (kv *KVStore) SetLatestBlockHeader(\n\theader *ctypes.BeaconBlockHeader,\n) error {\n\treturn kv.latestBlockHeader.Set(kv.ctx, header)\n}\n\n// GetLatestBlockHeader retrieves the latest block header from the BeaconStore.\nfunc (kv *KVStore) GetLatestBlockHeader() (\n\t*ctypes.BeaconBlockHeader, error,\n) {\n\treturn kv.latestBlockHeader.Get(kv.ctx)\n}\n\n// UpdateStateRootAtIndex updates the state root at the given slot.\nfunc (kv *KVStore) UpdateStateRootAtIndex(\n\tidx uint64,\n\tstateRoot common.Root,\n) error {\n\treturn kv.stateRoots.Set(kv.ctx, idx, stateRoot[:])\n}\n\n// StateRootAtIndex returns the state root at the given slot.\nfunc (kv *KVStore) StateRootAtIndex(\n\tidx uint64,\n) (common.Root, error) {\n\tbz, err := kv.stateRoots.Get(kv.ctx, idx)\n\tif err != nil {\n\t\treturn common.Root{}, err\n\t}\n\treturn common.Root(bz), nil\n}\n"
  },
  {
    "path": "storage/beacondb/index/validator.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage index\n\nimport (\n\tsdkcollections \"cosmossdk.io/collections\"\n\t\"cosmossdk.io/collections/indexes\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tcmtcrypto \"github.com/cometbft/cometbft/crypto\"\n)\n\n// Collection prefixes.\nconst (\n\tvalidatorByIndexPrefix                 = \"val_idx_to_pk\"\n\tvalidatorPubkeyToIndexPrefix           = \"val_pk_to_idx\"\n\tvalidatorConsAddrToIndexPrefix         = \"val_cons_addr_to_idx\"\n\tvalidatorEffectiveBalanceToIndexPrefix = \"val_eff_bal_to_idx\"\n)\n\n// Validator is an interface that combines the ssz.Marshaler and\n// ssz.Unmarshaler interfaces.\ntype Validator interface {\n\tconstraints.SSZMarshallable\n\t// GetPubkey returns the public key of the validator.\n\tGetPubkey() crypto.BLSPubkey\n\t// GetEffectiveBalance returns the effective balance of the validator.\n\tGetEffectiveBalance() math.Gwei\n}\n\n// ValidatorsIndex is a struct that holds a unique index for validators based\n// on their public key.\ntype ValidatorsIndex[ValidatorT Validator] struct {\n\t// Pubkey is a unique index mapping a validator's public key to their\n\t// numeric ID and vice versa.\n\tPubkey *indexes.Unique[[]byte, uint64, ValidatorT]\n\t// EffectiveBalance is a multi-index mapping a validator's effective balance\n\t// to their numeric ID.\n\tEffectiveBalance *indexes.Multi[uint64, uint64, ValidatorT]\n\t// CometBFTAddress is a unique index mapping a validator's Comet BFT address\n\t// to their numeric ID.\n\tCometBFTAddress *indexes.Unique[[]byte, uint64, ValidatorT]\n}\n\n// IndexesList returns a list of all indexes associated with the\n// validatorsIndex.\nfunc (a ValidatorsIndex[ValidatorT]) IndexesList() []sdkcollections.Index[\n\tuint64, ValidatorT,\n] {\n\treturn []sdkcollections.Index[uint64, ValidatorT]{\n\t\ta.Pubkey,\n\t\ta.EffectiveBalance,\n\t\ta.CometBFTAddress,\n\t}\n}\n\n// NewValidatorsIndex creates a new validatorsIndex with a unique index for\n// validator public keys.\nfunc NewValidatorsIndex[ValidatorT Validator](\n\tsb *sdkcollections.SchemaBuilder,\n) ValidatorsIndex[ValidatorT] {\n\treturn ValidatorsIndex[ValidatorT]{\n\t\tPubkey: indexes.NewUnique(\n\t\t\tsb,\n\t\t\tsdkcollections.NewPrefix(validatorPubkeyToIndexPrefix),\n\t\t\tvalidatorPubkeyToIndexPrefix,\n\t\t\tsdkcollections.BytesKey,\n\t\t\tsdkcollections.Uint64Key,\n\t\t\tfunc(_ uint64, validator ValidatorT) ([]byte, error) {\n\t\t\t\tpk := validator.GetPubkey()\n\t\t\t\treturn pk[:], nil\n\t\t\t},\n\t\t),\n\t\tEffectiveBalance: indexes.NewMulti(\n\t\t\tsb,\n\t\t\tsdkcollections.NewPrefix(validatorEffectiveBalanceToIndexPrefix),\n\t\t\tvalidatorEffectiveBalanceToIndexPrefix,\n\t\t\tsdkcollections.Uint64Key,\n\t\t\tsdkcollections.Uint64Key,\n\t\t\tfunc(_ uint64, validator ValidatorT) (uint64, error) {\n\t\t\t\treturn validator.GetEffectiveBalance().Unwrap(), nil\n\t\t\t},\n\t\t),\n\t\tCometBFTAddress: indexes.NewUnique(\n\t\t\tsb,\n\t\t\tsdkcollections.NewPrefix(validatorConsAddrToIndexPrefix),\n\t\t\tvalidatorConsAddrToIndexPrefix,\n\t\t\tsdkcollections.BytesKey,\n\t\t\tsdkcollections.Uint64Key,\n\t\t\tfunc(_ uint64, validator ValidatorT) ([]byte, error) {\n\t\t\t\tpk := validator.GetPubkey()\n\t\t\t\treturn cmtcrypto.AddressHash(pk[:]).Bytes(), nil\n\t\t\t},\n\t\t),\n\t}\n}\n"
  },
  {
    "path": "storage/beacondb/index/validator_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage index_test\n\nimport (\n\t\"testing\"\n)\n\nfunc TestValidatorIndexes(t *testing.T) {\n\tt.Parallel()\n\t// testName := \"test\"\n\t// logger := log.NewTestLogger(t)\n\t// keys := storetypes.NewKVStoreKeys(testName)\n\t// cms := integration.CreateMultiStore(keys, logger)\n\t// ctx := sdk.NewContext(cms, true, logger)\n\t// storeKey := keys[testName]\n\t// kvs := sdkruntime.NewKVStoreService(storeKey)\n\t// env := sdkruntime.NewEnvironment(kvs, logger)\n\n\t// beaconStore := beaconstore.NewStore(env)\n\t// // beaconStore = beaconStore.WithContext(ctx)\n\n\t// t.Run(\"add validator and replace its pubkey\", func(t *testing.T) {\n\t// \terr := beaconStore.AddValidator(ctx, []byte(\"pubkey\"))\n\t// \trequire.NoError(t, err)\n\n\t// \terr = beaconStore.AddValidator(ctx, []byte(\"pubkey2\"))\n\t// \trequire.NoError(t, err)\n\n\t// \t// get the index\n\t// \tindex, err := beaconStore.ValidatorIndexByPubkey([]byte(\"pubkey2\"))\n\t// \trequire.NoError(t, err)\n\t// \trequire.Equal(t, uint64(1), index)\n\n\t// \terr = beaconStore.UpdateValidator(\n\t// \t\tctx,\n\t// \t\t[]byte(\"pubkey2\"),\n\t// \t\t[]byte(\"newpubkey\"),\n\t// \t)\n\t// \trequire.NoError(t, err)\n\n\t// \t// get the index again, it should be the same as before\n\t// \tindex, err = beaconStore.ValidatorIndexByPubkey(\n\t// \t\t[]byte(\"newpubkey\"),\n\t// \t)\n\t// \trequire.NoError(t, err)\n\t// \trequire.Equal(t, uint64(1), index)\n\t// })\n\n\t// t.Run(\"add the same validator twice\", func(t *testing.T) {\n\t// \terr := beaconStore.AddValidator(ctx, []byte(\"pubkeyA\"))\n\t// \trequire.NoError(t, err)\n\n\t// \terr = beaconStore.AddValidator(ctx, []byte(\"pubkeyA\"))\n\t// \trequire.Error(t, err)\n\t// })\n}\n"
  },
  {
    "path": "storage/beacondb/keys/keys.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage keys\n\nconst (\n\tWithdrawalQueuePrefix byte = iota\n\tRandaoMixPrefix\n\tSlashingsPrefix\n\tTotalSlashingPrefix\n\tValidatorIndexPrefix\n\tBlockRootsPrefix\n\tStateRootsPrefix\n\tValidatorByIndexPrefix\n\tValidatorPubkeyToIndexPrefix\n\tValidatorConsAddrToIndexPrefix\n\tValidatorEffectiveBalanceToIndexPrefix\n\tLatestBeaconBlockHeaderPrefix\n\tSlotPrefix\n\tBalancesPrefix\n\tEth1BlockHashPrefix\n\tEth1DataPrefix\n\tEth1DepositIndexPrefix\n\tLatestExecutionPayloadHeaderPrefix\n\tLatestExecutionPayloadVersionPrefix\n\tGenesisValidatorsRootPrefix\n\tNextWithdrawalIndexPrefix\n\tNextWithdrawalValidatorIndexPrefix\n\tForkPrefix\n\tPendingPartialWithdrawalsPrefix\n)\n\nconst (\n\tWithdrawalQueuePrefixHumanReadable                  = \"WithdrawalQueuePrefix\"\n\tRandaoMixPrefixHumanReadable                        = \"RandaoMixPrefix\"\n\tSlashingsPrefixHumanReadable                        = \"SlashingsPrefix\"\n\tTotalSlashingPrefixHumanReadable                    = \"TotalSlashingPrefix\"\n\tValidatorIndexPrefixHumanReadable                   = \"ValidatorIndexPrefix\"\n\tBlockRootsPrefixHumanReadable                       = \"BlockRootsPrefix\"\n\tStateRootsPrefixHumanReadable                       = \"StateRootsPrefix\"\n\tValidatorByIndexPrefixHumanReadable                 = \"ValidatorByIndexPrefix\"\n\tValidatorPubkeyToIndexPrefixHumanReadable           = \"ValidatorPubkeyToIndexPrefix\"\n\tValidatorConsAddrToIndexPrefixHumanReadable         = \"ValidatorConsAddrToIndexPrefix\"\n\tValidatorEffectiveBalanceToIndexPrefixHumanReadable = \"ValidatorEffectiveBalanceToIndexPrefix\"\n\tLatestBeaconBlockHeaderPrefixHumanReadable          = \"LatestBeaconBlockHeaderPrefix\"\n\tSlotPrefixHumanReadable                             = \"SlotPrefix\"\n\tBalancesPrefixHumanReadable                         = \"BalancesPrefix\"\n\tEth1BlockHashPrefixHumanReadable                    = \"Eth1BlockHashPrefix\"\n\tEth1DataPrefixHumanReadable                         = \"Eth1DataPrefix\"\n\tEth1DepositIndexPrefixHumanReadable                 = \"Eth1DepositIndexPrefix\"\n\tLatestExecutionPayloadHeaderPrefixHumanReadable     = \"LatestExecutionPayloadHeaderPrefix\"\n\tLatestExecutionPayloadVersionPrefixHumanReadable    = \"LatestExecutionPayloadVersionPrefix\"\n\tGenesisValidatorsRootPrefixHumanReadable            = \"GenesisValidatorsRootPrefix\"\n\tNextWithdrawalIndexPrefixHumanReadable              = \"NextWithdrawalIndexPrefix\"\n\tNextWithdrawalValidatorIndexPrefixHumanReadable     = \"NextWithdrawalValidatorIndexPrefix\"\n\tForkPrefixHumanReadable                             = \"ForkPrefix\"\n\tPendingPartialWithdrawalsPrefixHumanReadable        = \"PendingPartialWithdrawalsPrefix\"\n)\n"
  },
  {
    "path": "storage/beacondb/kvstore.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacondb\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\tsdkcollections \"cosmossdk.io/collections\"\n\t\"cosmossdk.io/core/store\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/storage/beacondb/index\"\n\t\"github.com/berachain/beacon-kit/storage/beacondb/keys\"\n\t\"github.com/berachain/beacon-kit/storage/encoding\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n)\n\n// KVStore is a wrapper around an sdk.Context\n// that provides access to all beacon related data.\ntype KVStore struct {\n\tctx context.Context\n\t// Versioning\n\t// genesisValidatorsRoot is the root of the genesis validators.\n\tgenesisValidatorsRoot sdkcollections.Item[[]byte]\n\t// slot is the current slot.\n\tslot sdkcollections.Item[uint64]\n\t// fork is the current fork\n\tfork sdkcollections.Item[*ctypes.Fork]\n\t// History\n\t// latestBlockHeader stores the latest beacon block header.\n\tlatestBlockHeader sdkcollections.Item[*ctypes.BeaconBlockHeader]\n\t// blockRoots stores the block roots for the current epoch.\n\tblockRoots sdkcollections.Map[uint64, []byte]\n\t// stateRoots stores the state roots for the current epoch.\n\tstateRoots sdkcollections.Map[uint64, []byte]\n\t// Eth1\n\t// eth1Data stores the latest eth1 data.\n\teth1Data sdkcollections.Item[*ctypes.Eth1Data]\n\t// eth1DepositIndex is the index of the latest eth1 deposit.\n\teth1DepositIndex sdkcollections.Item[uint64]\n\t// latestExecutionPayloadVersion stores the latest execution payload\n\t// version.\n\tlatestExecutionPayloadVersion sdkcollections.Item[uint32]\n\t// latestExecutionPayloadCodec is the codec for the latest execution\n\t// payload, it allows us to update the codec with the latest version.\n\tlatestExecutionPayloadCodec *encoding.SSZVersionedValueCodec[*ctypes.ExecutionPayloadHeader]\n\t// latestExecutionPayloadHeader stores the latest execution payload header.\n\tlatestExecutionPayloadHeader sdkcollections.Item[*ctypes.ExecutionPayloadHeader]\n\t// Registry\n\t// validatorIndex provides the next available index for a new validator.\n\tvalidatorIndex sdkcollections.Sequence\n\t// validators stores the list of validators.\n\tvalidators *sdkcollections.IndexedMap[\n\t\tuint64, *ctypes.Validator, index.ValidatorsIndex[*ctypes.Validator],\n\t]\n\t// balances stores the list of balances.\n\tbalances sdkcollections.Map[uint64, uint64]\n\t// nextWithdrawalIndex stores the next global withdrawal index.\n\tnextWithdrawalIndex sdkcollections.Item[uint64]\n\t// nextWithdrawalValidatorIndex stores the next withdrawal validator index\n\t// for each validator.\n\tnextWithdrawalValidatorIndex sdkcollections.Item[uint64]\n\t// Randomness\n\t// randaoMix stores the randao mix for the current epoch.\n\trandaoMix sdkcollections.Map[uint64, []byte]\n\t// Slashings\n\t// slashings stores the slashings for the current epoch.\n\tslashings sdkcollections.Map[uint64, uint64]\n\t// totalSlashing stores the total slashing in the vector range.\n\ttotalSlashing sdkcollections.Item[uint64]\n\t// pendingPartialWithdrawals stores the PendingPartialWithdrawals introduced in Electra.\n\t// These are the operations done on this collection:\n\t// 1. get_pending_balance_to_withdraw -> requires iteration\n\t// 2. get_expected_withdrawals -> requires iterations\n\t// 3. process_withdrawal_request -> requires number of entries in the collection and adding new entries\n\t// 4. process_withdrawals -> requires removing entries from the collection\n\t// It is easiest to have these operations be done on an `Item` that is a list under the hood rather than\n\t// `sdkcollection` native types due to lack of support for lists.\n\t// We must use `*ctypes.PendingPartialWithdrawals` instead of `ctypes.PendingPartialWithdrawals` as marshalling\n\t// methods require a pointer receiver.\n\tpendingPartialWithdrawals sdkcollections.Item[*ctypes.PendingPartialWithdrawals]\n}\n\n// New creates a new instance of Store.\n//\n//nolint:funlen // its not overly complex.\nfunc New(kss store.KVStoreService) *KVStore {\n\tvar (\n\t\tschemaBuilder = sdkcollections.NewSchemaBuilder(kss)\n\t\tpayloadCodec  = &encoding.SSZVersionedValueCodec[*ctypes.ExecutionPayloadHeader]{\n\t\t\tNewEmptyF: ctypes.NewEmptyExecutionPayloadHeaderWithVersion,\n\t\t}\n\t)\n\n\tres := &KVStore{\n\t\tctx: nil, // set by WithContext or Copy\n\t\tgenesisValidatorsRoot: sdkcollections.NewItem(\n\t\t\tschemaBuilder,\n\t\t\tsdkcollections.NewPrefix([]byte{keys.GenesisValidatorsRootPrefix}),\n\t\t\tkeys.GenesisValidatorsRootPrefixHumanReadable,\n\t\t\tsdkcollections.BytesValue,\n\t\t),\n\t\tslot: sdkcollections.NewItem(\n\t\t\tschemaBuilder,\n\t\t\tsdkcollections.NewPrefix([]byte{keys.SlotPrefix}),\n\t\t\tkeys.SlotPrefixHumanReadable,\n\t\t\tsdkcollections.Uint64Value,\n\t\t),\n\t\tfork: sdkcollections.NewItem(\n\t\t\tschemaBuilder,\n\t\t\tsdkcollections.NewPrefix([]byte{keys.ForkPrefix}),\n\t\t\tkeys.ForkPrefixHumanReadable,\n\t\t\tencoding.SSZValueCodec[*ctypes.Fork]{\n\t\t\t\tNewEmptyF: ctypes.NewEmptyFork,\n\t\t\t},\n\t\t),\n\t\tblockRoots: sdkcollections.NewMap(\n\t\t\tschemaBuilder,\n\t\t\tsdkcollections.NewPrefix([]byte{keys.BlockRootsPrefix}),\n\t\t\tkeys.BlockRootsPrefixHumanReadable,\n\t\t\tsdkcollections.Uint64Key,\n\t\t\tsdkcollections.BytesValue,\n\t\t),\n\t\tstateRoots: sdkcollections.NewMap(\n\t\t\tschemaBuilder,\n\t\t\tsdkcollections.NewPrefix([]byte{keys.StateRootsPrefix}),\n\t\t\tkeys.StateRootsPrefixHumanReadable,\n\t\t\tsdkcollections.Uint64Key,\n\t\t\tsdkcollections.BytesValue,\n\t\t),\n\t\teth1Data: sdkcollections.NewItem(\n\t\t\tschemaBuilder,\n\t\t\tsdkcollections.NewPrefix([]byte{keys.Eth1DataPrefix}),\n\t\t\tkeys.Eth1DataPrefixHumanReadable,\n\t\t\tencoding.SSZValueCodec[*ctypes.Eth1Data]{\n\t\t\t\tNewEmptyF: ctypes.NewEmptyEth1Data,\n\t\t\t},\n\t\t),\n\t\teth1DepositIndex: sdkcollections.NewItem(\n\t\t\tschemaBuilder,\n\t\t\tsdkcollections.NewPrefix([]byte{keys.Eth1DepositIndexPrefix}),\n\t\t\tkeys.Eth1DepositIndexPrefixHumanReadable,\n\t\t\tsdkcollections.Uint64Value,\n\t\t),\n\t\tlatestExecutionPayloadVersion: sdkcollections.NewItem(\n\t\t\tschemaBuilder,\n\t\t\tsdkcollections.NewPrefix(\n\t\t\t\t[]byte{keys.LatestExecutionPayloadVersionPrefix},\n\t\t\t),\n\t\t\tkeys.LatestExecutionPayloadVersionPrefixHumanReadable,\n\t\t\tsdkcollections.Uint32Value,\n\t\t),\n\t\tlatestExecutionPayloadCodec: payloadCodec,\n\t\tlatestExecutionPayloadHeader: sdkcollections.NewItem(\n\t\t\tschemaBuilder,\n\t\t\tsdkcollections.NewPrefix(\n\t\t\t\t[]byte{keys.LatestExecutionPayloadHeaderPrefix},\n\t\t\t),\n\t\t\tkeys.LatestExecutionPayloadHeaderPrefixHumanReadable,\n\t\t\tpayloadCodec,\n\t\t),\n\t\tvalidatorIndex: sdkcollections.NewSequence(\n\t\t\tschemaBuilder,\n\t\t\tsdkcollections.NewPrefix([]byte{keys.ValidatorIndexPrefix}),\n\t\t\tkeys.ValidatorIndexPrefixHumanReadable,\n\t\t),\n\t\tvalidators: sdkcollections.NewIndexedMap(\n\t\t\tschemaBuilder,\n\t\t\tsdkcollections.NewPrefix([]byte{keys.ValidatorByIndexPrefix}),\n\t\t\tkeys.ValidatorByIndexPrefixHumanReadable,\n\t\t\tsdkcollections.Uint64Key,\n\t\t\tencoding.SSZValueCodec[*ctypes.Validator]{\n\t\t\t\tNewEmptyF: ctypes.NewEmptyValidator,\n\t\t\t},\n\t\t\tindex.NewValidatorsIndex[*ctypes.Validator](schemaBuilder),\n\t\t),\n\t\tbalances: sdkcollections.NewMap(\n\t\t\tschemaBuilder,\n\t\t\tsdkcollections.NewPrefix([]byte{keys.BalancesPrefix}),\n\t\t\tkeys.BalancesPrefixHumanReadable,\n\t\t\tsdkcollections.Uint64Key,\n\t\t\tsdkcollections.Uint64Value,\n\t\t),\n\t\trandaoMix: sdkcollections.NewMap(\n\t\t\tschemaBuilder,\n\t\t\tsdkcollections.NewPrefix([]byte{keys.RandaoMixPrefix}),\n\t\t\tkeys.RandaoMixPrefixHumanReadable,\n\t\t\tsdkcollections.Uint64Key,\n\t\t\tsdkcollections.BytesValue,\n\t\t),\n\t\tslashings: sdkcollections.NewMap(\n\t\t\tschemaBuilder,\n\t\t\tsdkcollections.NewPrefix([]byte{keys.SlashingsPrefix}),\n\t\t\tkeys.SlashingsPrefixHumanReadable,\n\t\t\tsdkcollections.Uint64Key,\n\t\t\tsdkcollections.Uint64Value,\n\t\t),\n\t\tnextWithdrawalIndex: sdkcollections.NewItem(\n\t\t\tschemaBuilder,\n\t\t\tsdkcollections.NewPrefix([]byte{keys.NextWithdrawalIndexPrefix}),\n\t\t\tkeys.NextWithdrawalIndexPrefixHumanReadable,\n\t\t\tsdkcollections.Uint64Value,\n\t\t),\n\t\tnextWithdrawalValidatorIndex: sdkcollections.NewItem(\n\t\t\tschemaBuilder,\n\t\t\tsdkcollections.NewPrefix(\n\t\t\t\t[]byte{keys.NextWithdrawalValidatorIndexPrefix},\n\t\t\t),\n\t\t\tkeys.NextWithdrawalValidatorIndexPrefixHumanReadable,\n\t\t\tsdkcollections.Uint64Value,\n\t\t),\n\t\ttotalSlashing: sdkcollections.NewItem(\n\t\t\tschemaBuilder,\n\t\t\tsdkcollections.NewPrefix([]byte{keys.TotalSlashingPrefix}),\n\t\t\tkeys.TotalSlashingPrefixHumanReadable,\n\t\t\tsdkcollections.Uint64Value,\n\t\t),\n\t\tlatestBlockHeader: sdkcollections.NewItem(\n\t\t\tschemaBuilder,\n\t\t\tsdkcollections.NewPrefix(\n\t\t\t\t[]byte{keys.LatestBeaconBlockHeaderPrefix},\n\t\t\t),\n\t\t\tkeys.LatestBeaconBlockHeaderPrefixHumanReadable,\n\t\t\tencoding.SSZValueCodec[*ctypes.BeaconBlockHeader]{\n\t\t\t\tNewEmptyF: ctypes.NewEmptyBeaconBlockHeader,\n\t\t\t},\n\t\t),\n\t\tpendingPartialWithdrawals: sdkcollections.NewItem(\n\t\t\tschemaBuilder,\n\t\t\tsdkcollections.NewPrefix([]byte{keys.PendingPartialWithdrawalsPrefix}),\n\t\t\tkeys.PendingPartialWithdrawalsPrefixHumanReadable,\n\t\t\tencoding.SSZValueCodec[*ctypes.PendingPartialWithdrawals]{\n\t\t\t\tNewEmptyF: ctypes.NewEmptyPendingPartialWithdrawals,\n\t\t\t},\n\t\t),\n\t}\n\tif _, err := schemaBuilder.Build(); err != nil {\n\t\tpanic(fmt.Errorf(\"failed building KVStore schema: %w\", err))\n\t}\n\treturn res\n}\n\n// Copy returns a copy of the Store.\nfunc (kv *KVStore) Copy(ctx context.Context) *KVStore {\n\t// TODO: Decouple the KVStore type from the Cosmos-SDK.\n\tcctx, _ := sdk.UnwrapSDKContext(ctx).CacheContext()\n\t//nolint:contextcheck // `cctx` is inherited from the parent context `ctx`.\n\tss := kv.WithContext(cctx)\n\treturn ss\n}\n\n// Context returns the context of the Store.\nfunc (kv *KVStore) Context() context.Context {\n\treturn kv.ctx\n}\n\n// WithContext returns a copy of the Store with the given context.\nfunc (kv *KVStore) WithContext(ctx context.Context) *KVStore {\n\tcpy := *kv\n\tcpy.ctx = ctx\n\treturn &cpy\n}\n"
  },
  {
    "path": "storage/beacondb/randao.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacondb\n\nimport \"github.com/berachain/beacon-kit/primitives/common\"\n\n// UpdateRandaoMixAtIndex sets the current RANDAO mix in the store.\nfunc (kv *KVStore) UpdateRandaoMixAtIndex(\n\tindex uint64,\n\tmix common.Bytes32,\n) error {\n\treturn kv.randaoMix.Set(kv.ctx, index, mix[:])\n}\n\n// GetRandaoMixAtIndex retrieves the current RANDAO mix from the store.\nfunc (kv *KVStore) GetRandaoMixAtIndex(\n\tindex uint64,\n) (common.Bytes32, error) {\n\tbz, err := kv.randaoMix.Get(kv.ctx, index)\n\tif err != nil {\n\t\treturn common.Bytes32{}, err\n\t}\n\treturn common.Bytes32(bz), nil\n}\n"
  },
  {
    "path": "storage/beacondb/registry.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacondb\n\nimport (\n\t\"errors\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// AddValidator registers a new validator in the beacon state.\nfunc (kv *KVStore) AddValidator(val *ctypes.Validator) error {\n\t// Get the next validator index from the sequence.\n\tidx, err := kv.validatorIndex.Next(kv.ctx)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Push onto the validators list.\n\tif err = kv.validators.Set(kv.ctx, idx, val); err != nil {\n\t\treturn err\n\t}\n\n\treturn kv.balances.Set(kv.ctx, idx, 0)\n}\n\n// UpdateValidatorAtIndex updates a validator at a specific index.\nfunc (kv *KVStore) UpdateValidatorAtIndex(\n\tindex math.ValidatorIndex,\n\tval *ctypes.Validator,\n) error {\n\treturn kv.validators.Set(kv.ctx, index.Unwrap(), val)\n}\n\n// ValidatorIndexByPubkey returns the validator address by index.\nfunc (kv *KVStore) ValidatorIndexByPubkey(\n\tpubkey crypto.BLSPubkey,\n) (math.ValidatorIndex, error) {\n\tidx, err := kv.validators.Indexes.Pubkey.MatchExact(\n\t\tkv.ctx,\n\t\tpubkey[:],\n\t)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn math.ValidatorIndex(idx), nil\n}\n\n// ValidatorIndexByCometBFTAddress returns the validator address by index.\nfunc (kv *KVStore) ValidatorIndexByCometBFTAddress(\n\tcometBFTAddress []byte,\n) (math.ValidatorIndex, error) {\n\tidx, err := kv.validators.Indexes.CometBFTAddress.MatchExact(\n\t\tkv.ctx,\n\t\tcometBFTAddress,\n\t)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn math.ValidatorIndex(idx), nil\n}\n\n// ValidatorByIndex returns the validator address by index.\nfunc (kv *KVStore) ValidatorByIndex(\n\tindex math.ValidatorIndex,\n) (*ctypes.Validator, error) {\n\tval, err := kv.validators.Get(kv.ctx, index.Unwrap())\n\tif err != nil {\n\t\tvar t *ctypes.Validator\n\t\treturn t, err\n\t}\n\treturn val, err\n}\n\n// GetValidators retrieves all validators from the beacon state.\nfunc (kv *KVStore) GetValidators() (\n\tctypes.Validators, error,\n) {\n\tregistrySize, err := kv.validatorIndex.Peek(kv.ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar (\n\t\tvals = make([]*ctypes.Validator, 0, registrySize)\n\t\tval  *ctypes.Validator\n\t)\n\n\titer, err := kv.validators.Iterate(kv.ctx, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer func() {\n\t\terr = errors.Join(err, iter.Close())\n\t}()\n\n\tfor ; iter.Valid(); iter.Next() {\n\t\tval, err = iter.Value()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvals = append(vals, val)\n\t}\n\n\treturn vals, err\n}\n\n// GetTotalValidators returns the total number of validators.\nfunc (kv *KVStore) GetTotalValidators() (math.U64, error) {\n\tvalidators, err := kv.GetValidators()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn math.U64(len(validators)), nil\n}\n\n// GetBalance returns the balance of a validator.\nfunc (kv *KVStore) GetBalance(\n\tidx math.ValidatorIndex,\n) (math.Gwei, error) {\n\tbalance, err := kv.balances.Get(kv.ctx, idx.Unwrap())\n\treturn math.Gwei(balance), err\n}\n\n// SetBalance sets the balance of a validator.\nfunc (kv *KVStore) SetBalance(\n\tidx math.ValidatorIndex,\n\tbalance math.Gwei,\n) error {\n\treturn kv.balances.Set(kv.ctx, idx.Unwrap(), balance.Unwrap())\n}\n\n// GetBalances returns the balancse of all validator.\nfunc (kv *KVStore) GetBalances() ([]uint64, error) {\n\tvar balances []uint64\n\titer, err := kv.balances.Iterate(kv.ctx, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer func() {\n\t\terr = errors.Join(err, iter.Close())\n\t}()\n\n\tvar balance uint64\n\tfor ; iter.Valid(); iter.Next() {\n\t\tbalance, err = iter.Value()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tbalances = append(balances, balance)\n\t}\n\treturn balances, err\n}\n\n// GetPendingPartialWithdrawals is equivalent to `pending_partial_withdrawals`\n// If called before electra, will return an error.\nfunc (kv *KVStore) GetPendingPartialWithdrawals() ([]*ctypes.PendingPartialWithdrawal, error) {\n\tpendingPartialWithdrawals, err := kv.pendingPartialWithdrawals.Get(kv.ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif pendingPartialWithdrawals == nil {\n\t\treturn nil, errors.New(\"unexpected nil pending partial withdrawals\")\n\t}\n\treturn *pendingPartialWithdrawals, err\n}\n\n// SetPendingPartialWithdrawals sets the pending partial withdrawals\nfunc (kv *KVStore) SetPendingPartialWithdrawals(pendingPartialWithdrawals []*ctypes.PendingPartialWithdrawal) error {\n\tppw := ctypes.PendingPartialWithdrawals(pendingPartialWithdrawals)\n\treturn kv.pendingPartialWithdrawals.Set(kv.ctx, &ppw)\n}\n"
  },
  {
    "path": "storage/beacondb/registry_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacondb_test\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"testing\"\n\n\tcorestore \"cosmossdk.io/core/store\"\n\t\"cosmossdk.io/log\"\n\t\"cosmossdk.io/store\"\n\t\"cosmossdk.io/store/metrics\"\n\tstoretypes \"cosmossdk.io/store/types\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/storage\"\n\t\"github.com/berachain/beacon-kit/storage/beacondb\"\n\t\"github.com/berachain/beacon-kit/storage/db\"\n\tdbm \"github.com/cosmos/cosmos-db\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n\t\"github.com/stretchr/testify/require\"\n)\n\ntype testKVStoreService struct {\n\tctx sdk.Context\n}\n\nfunc (kvs *testKVStoreService) OpenKVStore(context.Context) corestore.KVStore {\n\t//nolint:contextcheck // fine with tests\n\tstore := sdk.UnwrapSDKContext(kvs.ctx).KVStore(testStoreKey)\n\treturn storage.NewKVStore(store)\n}\n\nvar testStoreKey = storetypes.NewKVStoreKey(\"storage-tests\")\n\nfunc TestBalances(t *testing.T) {\n\tt.Parallel()\n\tstore, err := initTestStore()\n\trequire.NoError(t, err)\n\n\t// no balance to start\n\tres, err := store.GetBalances()\n\trequire.NoError(t, err)\n\trequire.Empty(t, res)\n\n\t// add balances\n\tvar (\n\t\tidx1, idx2     = math.U64(1_987), math.U64(1_989)\n\t\tinBal1, inBal2 = math.U64(8_992), math.U64(10_000)\n\t)\n\trequire.NoError(t, store.SetBalance(idx1, inBal1))\n\trequire.NoError(t, store.SetBalance(idx2, inBal2))\n\n\t// check we can query added balances\n\toutBal, err := store.GetBalance(idx1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, inBal1, outBal)\n\n\toutBal, err = store.GetBalance(idx2)\n\trequire.NoError(t, err)\n\trequire.Equal(t, inBal2, outBal)\n\n\tres, err = store.GetBalances()\n\trequire.NoError(t, err)\n\trequire.Len(t, res, 2)\n\trequire.Equal(t, inBal1.Unwrap(), res[0])\n\trequire.Equal(t, inBal2.Unwrap(), res[1])\n\n\t// update existing balances\n\tnewInBal1, newInBal2 := math.U64(0), inBal2*2\n\trequire.NoError(t, store.SetBalance(idx1, newInBal1))\n\trequire.NoError(t, store.SetBalance(idx2, newInBal2))\n\n\t// check we can query updated balances\n\toutBal, err = store.GetBalance(idx1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, newInBal1, outBal)\n\n\toutBal, err = store.GetBalance(idx2)\n\trequire.NoError(t, err)\n\trequire.Equal(t, newInBal2, outBal)\n\n\tres, err = store.GetBalances()\n\trequire.NoError(t, err)\n\trequire.Len(t, res, 2)\n\trequire.Equal(t, newInBal1.Unwrap(), res[0])\n\trequire.Equal(t, newInBal2.Unwrap(), res[1])\n}\n\nfunc TestValidators(t *testing.T) {\n\tt.Parallel()\n\tstore, err := initTestStore()\n\trequire.NoError(t, err)\n\n\t// no validators to start\n\tres, err := store.GetValidators()\n\trequire.NoError(t, err)\n\trequire.Empty(t, res)\n\n\t// add validators\n\tvar (\n\t\tinVal1 = &types.Validator{\n\t\t\tPubkey:           bytes.B48{0x01},\n\t\t\tEffectiveBalance: 31e9,\n\t\t}\n\t\tinVal2 = &types.Validator{\n\t\t\tPubkey:           bytes.B48{0x02},\n\t\t\tEffectiveBalance: 32e9,\n\t\t}\n\t)\n\trequire.NoError(t, store.AddValidator(inVal1))\n\trequire.NoError(t, store.AddValidator(inVal2))\n\n\t// check we can query added validators\n\tvalIdx1, err := store.ValidatorIndexByPubkey(inVal1.GetPubkey())\n\trequire.NoError(t, err)\n\toutVal, err := store.ValidatorByIndex(valIdx1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, inVal1, outVal)\n\n\tvalIdx2, err := store.ValidatorIndexByPubkey(inVal2.GetPubkey())\n\trequire.NoError(t, err)\n\toutVal, err = store.ValidatorByIndex(valIdx2)\n\trequire.NoError(t, err)\n\trequire.Equal(t, inVal2, outVal)\n\n\tvalCount, err := store.GetTotalValidators()\n\trequire.NoError(t, err)\n\trequire.Equal(t, math.U64(2), valCount)\n\n\tres, err = store.GetValidators()\n\trequire.NoError(t, err)\n\trequire.Len(t, res, int(valCount))\n\trequire.Equal(t, inVal1, res[0])\n\trequire.Equal(t, inVal2, res[1])\n\n\t// update existing validators balances\n\tvar (\n\t\tinUpdatedVal1 = &types.Validator{\n\t\t\tPubkey:           inVal1.GetPubkey(),\n\t\t\tEffectiveBalance: inVal1.EffectiveBalance * 2,\n\t\t}\n\t\tinUpdatedVal2 = &types.Validator{\n\t\t\tPubkey:           inVal2.GetPubkey(),\n\t\t\tEffectiveBalance: inVal1.EffectiveBalance / 2,\n\t\t}\n\t)\n\trequire.NoError(t, store.UpdateValidatorAtIndex(valIdx1, inUpdatedVal1))\n\trequire.NoError(t, store.UpdateValidatorAtIndex(valIdx2, inUpdatedVal2))\n\n\t// check we can query updated validators\n\tupValIdx1, err := store.ValidatorIndexByPubkey(inVal1.GetPubkey())\n\trequire.NoError(t, err)\n\trequire.Equal(t, valIdx1, upValIdx1)\n\toutVal, err = store.ValidatorByIndex(upValIdx1)\n\trequire.NoError(t, err)\n\trequire.Equal(t, inUpdatedVal1, outVal)\n\n\tupValIdx2, err := store.ValidatorIndexByPubkey(inVal2.GetPubkey())\n\trequire.NoError(t, err)\n\trequire.Equal(t, valIdx2, upValIdx2)\n\toutVal, err = store.ValidatorByIndex(upValIdx2)\n\trequire.NoError(t, err)\n\trequire.Equal(t, inUpdatedVal2, outVal)\n\n\tupValCount, err := store.GetTotalValidators()\n\trequire.NoError(t, err)\n\trequire.Equal(t, valCount, upValCount)\n\n\tres, err = store.GetValidators()\n\trequire.NoError(t, err)\n\trequire.Len(t, res, int(valCount))\n\trequire.Equal(t, inUpdatedVal1, res[0])\n\trequire.Equal(t, inUpdatedVal2, res[1])\n}\n\n// TestPendingPartialWithdrawals_Nil verifies that if no pending partial withdrawals\n// have been set, then GetPendingPartialWithdrawals returns an error.\nfunc TestPendingPartialWithdrawals_Nil(t *testing.T) {\n\tt.Parallel()\n\tstore, err := initTestStore()\n\trequire.NoError(t, err)\n\n\tppw, err := store.GetPendingPartialWithdrawals()\n\n\trequire.ErrorContains(t, err, \"collections: not found: key 'no_key' of type SSZMarshallable\")\n\trequire.Nil(t, ppw)\n}\n\n// TestPendingPartialWithdrawals_EmptySlice verifies that when setting an empty slice, the Set and Get operations succeed.\nfunc TestPendingPartialWithdrawals_EmptySlice(t *testing.T) {\n\tt.Parallel()\n\tstore, err := initTestStore()\n\trequire.NoError(t, err)\n\n\t// Attempt to set an empty slice.\n\terr = store.SetPendingPartialWithdrawals([]*types.PendingPartialWithdrawal{})\n\tvar ppw []*types.PendingPartialWithdrawal\n\trequire.NoError(t, err)\n\tppw, err = store.GetPendingPartialWithdrawals()\n\trequire.NoError(t, err)\n\trequire.Empty(t, ppw)\n}\n\n// TestPendingPartialWithdrawals_SetAndGetNonEmpty verifies that setting a non-empty list of pending partial withdrawals succeeds.\nfunc TestPendingPartialWithdrawals_SetAndGetNonEmpty(t *testing.T) {\n\tt.Parallel()\n\tstore, err := initTestStore()\n\trequire.NoError(t, err)\n\n\t// Create sample pending partial withdrawal entries.\n\tentry1 := &types.PendingPartialWithdrawal{\n\t\tValidatorIndex:    math.U64(1),\n\t\tAmount:            math.U64(100),\n\t\tWithdrawableEpoch: math.U64(15),\n\t}\n\tentry2 := &types.PendingPartialWithdrawal{\n\t\tValidatorIndex:    math.U64(2),\n\t\tAmount:            math.U64(200),\n\t\tWithdrawableEpoch: math.U64(20),\n\t}\n\tsampleWithdrawals := []*types.PendingPartialWithdrawal{entry1, entry2}\n\n\tvar ppw []*types.PendingPartialWithdrawal\n\t// Attempt to set the non-empty slice.\n\terr = store.SetPendingPartialWithdrawals(sampleWithdrawals)\n\n\trequire.NoError(t, err)\n\tppw, err = store.GetPendingPartialWithdrawals()\n\trequire.NoError(t, err)\n\trequire.Equal(t, sampleWithdrawals, ppw)\n}\n\n// TestPendingPartialWithdrawals_Update verifies that updating the pending partial withdrawals works correctly.\nfunc TestPendingPartialWithdrawals_Update(t *testing.T) {\n\tt.Parallel()\n\tstore, err := initTestStore()\n\trequire.NoError(t, err)\n\n\trequire.NoError(t, err)\n\t// Create initial pending partial withdrawal entries.\n\tentry1 := &types.PendingPartialWithdrawal{\n\t\tValidatorIndex:    math.U64(1),\n\t\tAmount:            math.U64(100),\n\t\tWithdrawableEpoch: math.U64(15),\n\t}\n\tentry2 := &types.PendingPartialWithdrawal{\n\t\tValidatorIndex:    math.U64(2),\n\t\tAmount:            math.U64(200),\n\t\tWithdrawableEpoch: math.U64(20),\n\t}\n\tinitialWithdrawals := []*types.PendingPartialWithdrawal{entry1, entry2}\n\tvar ppw []*types.PendingPartialWithdrawal\n\n\t// Set the initial list.\n\terr = store.SetPendingPartialWithdrawals(initialWithdrawals)\n\trequire.NoError(t, err)\n\n\t// Now update by modifying entry1's amount and dropping entry2.\n\tupdatedEntry := &types.PendingPartialWithdrawal{\n\t\tValidatorIndex:    math.U64(1),\n\t\tAmount:            math.U64(150), // Updated amount.\n\t\tWithdrawableEpoch: math.U64(15),\n\t}\n\tupdatedWithdrawals := []*types.PendingPartialWithdrawal{updatedEntry}\n\terr = store.SetPendingPartialWithdrawals(updatedWithdrawals)\n\trequire.NoError(t, err)\n\n\tppw, err = store.GetPendingPartialWithdrawals()\n\trequire.NoError(t, err)\n\trequire.Equal(t, updatedWithdrawals, ppw)\n}\n\nfunc initTestStore() (*beacondb.KVStore, error) {\n\tdb, err := db.OpenDB(\"\", dbm.MemDBBackend)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed opening mem db: %w\", err)\n\t}\n\tvar (\n\t\tnopLog     = log.NewNopLogger()\n\t\tnopMetrics = metrics.NewNoOpMetrics()\n\t)\n\n\tcms := store.NewCommitMultiStore(\n\t\tdb,\n\t\tnopLog,\n\t\tnopMetrics,\n\t)\n\n\tcms.MountStoreWithDB(testStoreKey, storetypes.StoreTypeIAVL, nil)\n\tif err = cms.LoadLatestVersion(); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to load latest version: %w\", err)\n\t}\n\n\tctx := sdk.NewContext(cms, true, nopLog)\n\ttestStoreService := &testKVStoreService{\n\t\tctx: ctx,\n\t}\n\treturn beacondb.New(testStoreService), nil\n}\n"
  },
  {
    "path": "storage/beacondb/slashing.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacondb\n\nimport (\n\t\"cosmossdk.io/collections\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\nfunc (kv *KVStore) GetSlashings() ([]math.Gwei, error) {\n\tvar slashings []math.Gwei\n\titer, err := kv.slashings.Iterate(kv.ctx, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer func() {\n\t\terr = errors.Join(err, iter.Close())\n\t}()\n\n\tfor ; iter.Valid(); iter.Next() {\n\t\tvar slashing uint64\n\t\tslashing, err = iter.Value()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslashings = append(slashings, math.Gwei(slashing))\n\t}\n\treturn slashings, err\n}\n\n// GetSlashingAtIndex retrieves the slashing amount by index from the store.\nfunc (kv *KVStore) GetSlashingAtIndex(\n\tindex uint64,\n) (math.Gwei, error) {\n\tamount, err := kv.slashings.Get(kv.ctx, index)\n\tif errors.Is(err, collections.ErrNotFound) {\n\t\treturn 0, nil\n\t} else if err != nil {\n\t\treturn 0, err\n\t}\n\treturn math.Gwei(amount), nil\n}\n\n// SetSlashingAtIndex sets the slashing amount in the store.\nfunc (kv *KVStore) SetSlashingAtIndex(\n\tindex uint64,\n\tamount math.Gwei,\n) error {\n\treturn kv.slashings.Set(kv.ctx, index, amount.Unwrap())\n}\n\n// GetTotalSlashing retrieves the total slashing amount from the store.\nfunc (kv *KVStore) GetTotalSlashing() (math.Gwei, error) {\n\ttotal, err := kv.totalSlashing.Get(kv.ctx)\n\tif errors.Is(err, collections.ErrNotFound) {\n\t\treturn 0, nil\n\t} else if err != nil {\n\t\treturn 0, err\n\t}\n\treturn math.Gwei(total), nil\n}\n\n// SetTotalSlashing sets the total slashing amount in the store.\nfunc (kv *KVStore) SetTotalSlashing(\n\tamount math.Gwei,\n) error {\n\treturn kv.totalSlashing.Set(kv.ctx, amount.Unwrap())\n}\n"
  },
  {
    "path": "storage/beacondb/staking_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacondb_test\n\n// type mockValidator struct {\n// \t*math.U64\n// }\n\n// func (m *mockValidator) IsActive(_ math.Epoch) bool {\n// \t// Assuming a simple active status check based on a condition\n// \t// This is a mock implementation and should be replaced with actual logic\n// \treturn true\n// }\n\n// func (m *mockValidator) GetPubkey() crypto.BLSPubkey {\n// \t// Return a mock BLS public key\n// \t// This is a mock implementation and should be replaced with actual logic\n// \treturn crypto.BLSPubkey{}\n// }\n\n// func (m *mockValidator) GetEffectiveBalance() math.Gwei {\n// \t// Return a mock effective balance\n// \t// This is a mock implementation and should be replaced with actual logic\n// \treturn 1000000 // 1 million Gwei as a placeholder\n// }\n\n// func testFactory() *math.U64 {\n// \treturn (*math.U64)(nil)\n// }\n\n// func TestDeposits(t *testing.T) {\n// testName := \"test\"\n// logger := log.NewTestLogger(t)\n// keys := storetypes.NewKVStoreKeys(testName)\n// cms := integration.CreateMultiStore(keys, logger)\n// ctx := sdk.NewContext(cms, true, logger)\n// storeKey := keys[testName]\n\n// sdb := beacondb.New[\n// \t*math.U64, *math.U64, *math.U64, *math.U64, *mockValidator,\n// ](\n// \tsdkruntime.NewKVStoreService(storeKey),\n// \ttestFactory,\n// )\n// _ = sdb.WithContext(ctx)\n// t.Run(\"should work with deposit\", func(t *testing.T) {\n// fakeDeposit := primitives.U64(69420)\n// err := sdb.EnqueueDeposits([]*primitives.U64{&fakeDeposit})\n// require.NoError(t, err)\n// deposits, err := sdb.DequeueDeposits(1)\n// require.NoError(t, err)\n// require.Equal(t, fakeDeposit, *deposits[0])\n// })\n// }\n"
  },
  {
    "path": "storage/beacondb/versioning.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacondb\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// SetGenesisValidatorsRoot sets the genesis validators root in the beacon\n// state.\nfunc (kv *KVStore) SetGenesisValidatorsRoot(\n\troot common.Root,\n) error {\n\treturn kv.genesisValidatorsRoot.Set(kv.ctx, root[:])\n}\n\n// GetGenesisValidatorsRoot retrieves the genesis validators root from the\n// beacon state.\nfunc (kv *KVStore) GetGenesisValidatorsRoot() (common.Root, error) {\n\tbz, err := kv.genesisValidatorsRoot.Get(kv.ctx)\n\tif err != nil {\n\t\treturn common.Root{}, err\n\t}\n\treturn common.Root(bz), nil\n}\n\n// GetSlot returns the current slot.\nfunc (kv *KVStore) GetSlot() (math.Slot, error) {\n\tslot, err := kv.slot.Get(kv.ctx)\n\treturn math.Slot(slot), err\n}\n\n// SetSlot sets the current slot.\nfunc (kv *KVStore) SetSlot(\n\tslot math.Slot,\n) error {\n\treturn kv.slot.Set(kv.ctx, slot.Unwrap())\n}\n"
  },
  {
    "path": "storage/beacondb/withdrawals.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage beacondb\n\nimport \"github.com/berachain/beacon-kit/primitives/math\"\n\n// GetNextWithdrawalIndex returns the next withdrawal index.\nfunc (kv *KVStore) GetNextWithdrawalIndex() (uint64, error) {\n\treturn kv.nextWithdrawalIndex.Get(kv.ctx)\n}\n\n// SetNextWithdrawalIndex sets the next withdrawal index.\nfunc (kv *KVStore) SetNextWithdrawalIndex(\n\tindex uint64,\n) error {\n\treturn kv.nextWithdrawalIndex.Set(kv.ctx, index)\n}\n\n// GetNextWithdrawalValidatorIndex returns the next withdrawal validator index.\nfunc (kv *KVStore) GetNextWithdrawalValidatorIndex() (\n\tmath.ValidatorIndex, error,\n) {\n\tidx, err := kv.nextWithdrawalValidatorIndex.Get(kv.ctx)\n\treturn math.ValidatorIndex(idx), err\n}\n\n// SetNextWithdrawalValidatorIndex sets the next withdrawal validator index.\nfunc (kv *KVStore) SetNextWithdrawalValidatorIndex(\n\tindex math.ValidatorIndex,\n) error {\n\treturn kv.nextWithdrawalValidatorIndex.Set(kv.ctx, index.Unwrap())\n}\n"
  },
  {
    "path": "storage/block/config.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage block\n\nconst defaultAvailabilityWindow = 8192\n\n// Config is the configuration for the block service.\ntype Config struct {\n\t// AvailabilityWindow is the number of slots to keep in the store.\n\tAvailabilityWindow int `mapstructure:\"availability-window\"`\n}\n\n// DefaultConfig returns the default configuration for the block service.\nfunc DefaultConfig() Config {\n\treturn Config{\n\t\tAvailabilityWindow: defaultAvailabilityWindow,\n\t}\n}\n"
  },
  {
    "path": "storage/block/interfaces.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage block\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\n// BeaconBlock is a block in the beacon chain that has a slot, block root (hash\n// tree root), timestamp, and state root.\ntype BeaconBlock interface {\n\tGetSlot() math.U64\n\tHashTreeRoot() common.Root\n\tGetTimestamp() math.U64\n\tGetStateRoot() common.Root\n}\n"
  },
  {
    "path": "storage/block/store.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage block\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tlru \"github.com/hashicorp/golang-lru/v2\"\n)\n\nvar ErrBlockStoreNotEnabled = errors.New(\"block store not enabled\")\n\n// KVStore is a simple memory store based implementation that stores metadata of\n// beacon blocks.\ntype KVStore[BeaconBlockT BeaconBlock] struct {\n\t// Setting availabilityWindow to zero upon construction\n\t// causes caches to not be instantiated. Setter will fail\n\t// silently while Getters will err.\n\tenabled bool\n\n\t// Beacon block root to slot mapping is injective for finalized blocks.\n\tblockRoots *lru.Cache[common.Root, math.Slot]\n\n\t// Timestamp to slot mapping is injective for finalized blocks. This is\n\t// guaranteed by CometBFT consensus. So each slot will be associated with a\n\t// different timestamp (no overwriting) as we store only finalized blocks.\n\ttimestamps *lru.Cache[math.U64, math.Slot]\n\n\t// Beacon state root to slot mapping is injective for finalized blocks.\n\tstateRoots *lru.Cache[common.Root, math.Slot]\n\n\t// Logger for the store.\n\tlogger log.Logger\n}\n\n// NewStore creates a new block store.\nfunc NewStore[BeaconBlockT BeaconBlock](\n\tlogger log.Logger,\n\tavailabilityWindow int,\n) *KVStore[BeaconBlockT] {\n\tkvStore := &KVStore[BeaconBlockT]{\n\t\tenabled: availabilityWindow != 0,\n\t\tlogger:  logger,\n\t}\n\tif !kvStore.enabled {\n\t\t// caches instantiations would fail with zero size\n\t\t// so we return early\n\t\treturn kvStore\n\t}\n\n\tvar err error\n\tkvStore.blockRoots, err = lru.New[common.Root, math.Slot](availabilityWindow)\n\tif err != nil {\n\t\tpanic(fmt.Errorf(\"failed instantiating kvStore blockRoots: %w\", err))\n\t}\n\tkvStore.timestamps, err = lru.New[math.U64, math.Slot](availabilityWindow)\n\tif err != nil {\n\t\tpanic(fmt.Errorf(\"failed instantiating kvStore timestamps: %w\", err))\n\t}\n\tkvStore.stateRoots, err = lru.New[common.Root, math.Slot](availabilityWindow)\n\tif err != nil {\n\t\tpanic(fmt.Errorf(\"failed instantiating kvStore stateRoots: %w\", err))\n\t}\n\treturn kvStore\n}\n\n// Set sets the block in the store, storing the block root, timestamp, and state root.\n// Only this function may potentially evict entries from the store if the availability\n// window is reached.\nfunc (kv *KVStore[BeaconBlockT]) Set(blk BeaconBlockT) error {\n\tif !kv.enabled {\n\t\t// nothing to do if store is disabled\n\t\tkv.logger.Debug(\"skipping set because block store is not enabled\")\n\t\treturn nil\n\t}\n\n\tslot := blk.GetSlot()\n\tkv.blockRoots.Add(blk.HashTreeRoot(), slot)\n\tkv.timestamps.Add(blk.GetTimestamp(), slot)\n\tkv.stateRoots.Add(blk.GetStateRoot(), slot)\n\treturn nil\n}\n\n// GetSlotByBlockRoot retrieves the slot by a given block root from the store.\nfunc (kv *KVStore[BeaconBlockT]) GetSlotByBlockRoot(blockRoot common.Root) (math.Slot, error) {\n\tif !kv.enabled {\n\t\treturn math.Slot(0), ErrBlockStoreNotEnabled\n\t}\n\n\tslot, ok := kv.blockRoots.Peek(blockRoot)\n\tif !ok {\n\t\treturn 0, fmt.Errorf(\"slot not found at block root: %s\", blockRoot)\n\t}\n\treturn slot, nil\n}\n\n// GetParentSlotByTimestamp retrieves the parent slot by a given timestamp from\n// the store.\nfunc (kv *KVStore[BeaconBlockT]) GetParentSlotByTimestamp(timestamp math.U64) (math.Slot, error) {\n\tif !kv.enabled {\n\t\treturn math.Slot(0), ErrBlockStoreNotEnabled\n\t}\n\n\tslot, ok := kv.timestamps.Peek(timestamp)\n\tif !ok {\n\t\treturn slot, fmt.Errorf(\"slot not found at timestamp: %d\", timestamp)\n\t}\n\tif slot == 0 {\n\t\treturn slot, errors.New(\"parent slot not supported for genesis slot 0\")\n\t}\n\n\treturn slot - 1, nil\n}\n\n// GetSlotByStateRoot retrieves the slot by a given state root from the store.\nfunc (kv *KVStore[BeaconBlockT]) GetSlotByStateRoot(stateRoot common.Root) (math.Slot, error) {\n\tif !kv.enabled {\n\t\treturn math.Slot(0), ErrBlockStoreNotEnabled\n\t}\n\n\tslot, ok := kv.stateRoots.Peek(stateRoot)\n\tif !ok {\n\t\treturn 0, fmt.Errorf(\"slot not found at state root: %s\", stateRoot)\n\t}\n\treturn slot, nil\n}\n"
  },
  {
    "path": "storage/block/store_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage block_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/log/noop\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/storage/block\"\n\t\"github.com/stretchr/testify/require\"\n)\n\ntype MockBeaconBlock struct {\n\tslot math.Slot\n}\n\nfunc (m MockBeaconBlock) GetSlot() math.Slot {\n\treturn m.slot\n}\n\nfunc (m MockBeaconBlock) HashTreeRoot() common.Root {\n\treturn [32]byte{byte(m.slot)}\n}\n\nfunc (m MockBeaconBlock) GetTimestamp() math.U64 {\n\treturn m.slot\n}\n\nfunc (m MockBeaconBlock) GetStateRoot() common.Root {\n\treturn [32]byte{byte(m.slot)}\n}\n\nfunc TestBlockStore(t *testing.T) {\n\tt.Parallel()\n\tblockStore := block.NewStore[*MockBeaconBlock](noop.NewLogger[any](), 5)\n\n\tvar (\n\t\tslot math.Slot\n\t\terr  error\n\t)\n\n\t// Set 7 blocks.\n\t// The latest block is 7 and should hold the last 5 blocks in the window.\n\tfor i := 1; i <= 7; i++ {\n\t\terr = blockStore.Set(&MockBeaconBlock{slot: math.Slot(i)})\n\t\trequire.NoError(t, err)\n\t}\n\n\t// Get the slots by roots & timestamps.\n\tfor i := math.Slot(3); i <= 7; i++ {\n\t\tslot, err = blockStore.GetSlotByBlockRoot([32]byte{byte(i)})\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, i, slot)\n\n\t\tslot, err = blockStore.GetParentSlotByTimestamp(i)\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, i-1, slot)\n\n\t\tslot, err = blockStore.GetSlotByStateRoot([32]byte{byte(i)})\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, i, slot)\n\t}\n\n\t// Try getting a slot that doesn't exist.\n\t_, err = blockStore.GetSlotByBlockRoot([32]byte{byte(8)})\n\trequire.ErrorContains(t, err, \"not found\")\n\t_, err = blockStore.GetParentSlotByTimestamp(2)\n\trequire.ErrorContains(t, err, \"not found\")\n}\n\nfunc TestBlockStoreZeroSize(t *testing.T) {\n\tt.Parallel()\n\tblockStore := block.NewStore[*MockBeaconBlock](noop.NewLogger[any](), 0)\n\n\t// If kvStore is disabled, setting any block would fail silently\n\t// Any get should fail instead.\n\tfor i := 1; i <= 7; i++ {\n\t\terr := blockStore.Set(&MockBeaconBlock{slot: math.Slot(i)})\n\t\trequire.NoError(t, err)\n\t}\n\n\t// Get the slots by roots & timestamps.\n\tfor i := math.Slot(3); i <= 7; i++ {\n\t\t_, err := blockStore.GetSlotByBlockRoot([32]byte{byte(i)})\n\t\trequire.ErrorIs(t, err, block.ErrBlockStoreNotEnabled)\n\n\t\t_, err = blockStore.GetParentSlotByTimestamp(i)\n\t\trequire.ErrorIs(t, err, block.ErrBlockStoreNotEnabled)\n\n\t\t_, err = blockStore.GetSlotByStateRoot([32]byte{byte(i)})\n\t\trequire.ErrorIs(t, err, block.ErrBlockStoreNotEnabled)\n\t}\n\n\t// Try getting a slot that doesn't exist.\n\t_, err := blockStore.GetSlotByBlockRoot([32]byte{byte(8)})\n\trequire.ErrorIs(t, err, block.ErrBlockStoreNotEnabled)\n\t_, err = blockStore.GetParentSlotByTimestamp(2)\n\trequire.ErrorIs(t, err, block.ErrBlockStoreNotEnabled)\n}\n"
  },
  {
    "path": "storage/db/db.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage db\n\nimport (\n\t\"path/filepath\"\n\n\tdbm \"github.com/cosmos/cosmos-db\"\n)\n\n// OpenDB opens the application database using the appropriate driver.\nfunc OpenDB(rootDir string, backendType dbm.BackendType) (dbm.DB, error) {\n\tdataDir := filepath.Join(rootDir, \"data\")\n\treturn dbm.NewDB(\"application\", backendType, dataDir)\n}\n"
  },
  {
    "path": "storage/deposit/common/synced_db.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage deposit\n\nimport (\n\t\"cosmossdk.io/core/store\"\n\tdbm \"github.com/cosmos/cosmos-db\"\n)\n\nvar _ store.KVStoreWithBatch = &syncedDB{}\n\n// We have verified experimentally that deposits are often *not* flushed\n// as soon as they are enqueue when pebbleDB is chosed as backend. This may\n// cause an issue with ungraceful restarts, which may lead to loss of deposits,\n// resulting in the node being unable to verify any incoming deposit.\n// SyncedDB solves the issues since it maps the Set call to a SetSync call\n// which ensure that every single deposit is flushed when enqueued.\ntype syncedDB struct {\n\tdb dbm.DB\n}\n\nfunc NewSynced(db dbm.DB) dbm.DB {\n\treturn syncedDB{db: db}\n}\n\nfunc (s syncedDB) Get(key []byte) ([]byte, error) {\n\treturn s.db.Get(key)\n}\n\nfunc (s syncedDB) Has(key []byte) (bool, error) {\n\treturn s.db.Has(key)\n}\n\nfunc (s syncedDB) Set(key, value []byte) error {\n\treturn s.db.SetSync(key, value)\n}\n\nfunc (s syncedDB) SetSync(key, value []byte) error {\n\treturn s.db.SetSync(key, value)\n}\n\nfunc (s syncedDB) Delete(key []byte) error {\n\treturn s.db.Delete(key)\n}\n\nfunc (s syncedDB) DeleteSync(key []byte) error {\n\treturn s.db.DeleteSync(key)\n}\n\nfunc (s syncedDB) Iterator(start, end []byte) (store.Iterator, error) {\n\treturn s.db.Iterator(start, end)\n}\n\nfunc (s syncedDB) ReverseIterator(start, end []byte) (store.Iterator, error) {\n\treturn s.db.ReverseIterator(start, end)\n}\n\nfunc (s syncedDB) NewBatch() store.Batch {\n\treturn s.db.NewBatch()\n}\n\nfunc (s syncedDB) NewBatchWithSize(i int) store.Batch {\n\treturn s.db.NewBatchWithSize(i)\n}\n\nfunc (s syncedDB) Close() error {\n\treturn s.db.Close()\n}\n\nfunc (s syncedDB) Print() error {\n\treturn s.db.Print()\n}\n\nfunc (s syncedDB) Stats() map[string]string {\n\treturn s.db.Stats()\n}\n"
  },
  {
    "path": "storage/deposit/store.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage deposit\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\tdepositstorev1 \"github.com/berachain/beacon-kit/storage/deposit/v1\"\n\tdbm \"github.com/cosmos/cosmos-db\"\n)\n\nconst (\n\tunset uint8 = 0\n\tv1    uint8 = 1\n)\n\ntype Store interface {\n\tGetDepositsByIndex(ctx context.Context, startIndex uint64, depRange uint64) (ctypes.Deposits, common.Root, error)\n\tEnqueueDeposits(ctx context.Context, deposits []*ctypes.Deposit) error\n\tPrune(ctx context.Context, start, end uint64) error\n\tClose() error\n}\n\ntype StoreManager interface {\n\tStore\n}\n\nvar (\n\t_ Store        = (*depositstorev1.KVStore)(nil)\n\t_ StoreManager = (*generalStore)(nil)\n\n\tErrUnknownStoreVersion = errors.New(\"unknown deposit store version\")\n)\n\n// We have changed in time the way we stored deposits. generalStore is meant to offer\n// a single way to access deposits and to handle the data migration among versions when needed\ntype generalStore struct {\n\t// mu protects storex for concurrent access\n\tmu             sync.RWMutex\n\tcurrentVersion uint8\n\tstoreV1        *depositstorev1.KVStore\n\tlogger         log.Logger\n}\n\nfunc NewStore(dbV1 dbm.DB, logger log.Logger) StoreManager {\n\tstoreV1 := depositstorev1.NewStore(dbV1, logger)\n\n\tcurrentVersion := v1\n\treturn &generalStore{\n\t\tcurrentVersion: currentVersion,\n\t\tstoreV1:        storeV1,\n\t\tlogger:         logger,\n\t}\n}\n\nfunc (gs *generalStore) GetDepositsByIndex(\n\tctx context.Context,\n\tstartIndex uint64,\n\tdepRange uint64,\n) (ctypes.Deposits, common.Root, error) {\n\tgs.mu.RLock()\n\tdefer gs.mu.RUnlock()\n\n\tswitch gs.currentVersion {\n\tcase v1:\n\t\treturn gs.storeV1.GetDepositsByIndex(ctx, startIndex, depRange)\n\tdefault:\n\t\treturn nil, common.Root{}, fmt.Errorf(\"%w, version %d\", ErrUnknownStoreVersion, gs.currentVersion)\n\t}\n}\n\nfunc (gs *generalStore) EnqueueDeposits(ctx context.Context, deposits []*ctypes.Deposit) error {\n\tgs.mu.Lock()\n\tdefer gs.mu.Unlock()\n\n\tswitch gs.currentVersion {\n\tcase v1:\n\t\treturn gs.storeV1.EnqueueDeposits(ctx, deposits)\n\tdefault:\n\t\treturn fmt.Errorf(\"%w, version %d\", ErrUnknownStoreVersion, gs.currentVersion)\n\t}\n}\n\nfunc (gs *generalStore) Close() error {\n\tgs.mu.Lock()\n\tdefer gs.mu.Unlock()\n\n\treturn gs.storeV1.Close()\n}\n\nfunc (gs *generalStore) Prune(ctx context.Context, start, end uint64) error {\n\tgs.mu.Lock()\n\tdefer gs.mu.Unlock()\n\n\tswitch gs.currentVersion {\n\tcase v1:\n\t\treturn gs.storeV1.Prune(ctx, start, end)\n\tdefault:\n\t\treturn fmt.Errorf(\"%w, version %d\", ErrUnknownStoreVersion, gs.currentVersion)\n\t}\n}\n"
  },
  {
    "path": "storage/deposit/v1/provider.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage deposit\n\nimport (\n\t\"context\"\n\n\t\"cosmossdk.io/core/store\"\n)\n\nvar _ store.KVStoreService = (*KVStoreProvider)(nil)\n\n// KVStoreProvider is a provider for a KV store.\ntype KVStoreProvider struct {\n\tstore.KVStoreWithBatch\n}\n\n// NewKVStoreProvider creates a new KV store provider.\nfunc NewKVStoreProvider(kvsb store.KVStoreWithBatch) *KVStoreProvider {\n\treturn &KVStoreProvider{\n\t\tKVStoreWithBatch: kvsb,\n\t}\n}\n\n// OpenKVStore opens a new KV store.\nfunc (p *KVStoreProvider) OpenKVStore(context.Context) store.KVStore {\n\treturn p.KVStoreWithBatch\n}\n"
  },
  {
    "path": "storage/deposit/v1/store.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage deposit\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\tsdkcollections \"cosmossdk.io/collections\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/storage\"\n\tdepositstorecommon \"github.com/berachain/beacon-kit/storage/deposit/common\"\n\t\"github.com/berachain/beacon-kit/storage/encoding\"\n\tdbm \"github.com/cosmos/cosmos-db\"\n)\n\nconst KeyDepositPrefix = \"deposit\"\n\n// KVStore is a simple KV store based implementation that assumes\n// the deposit indexes are tracked outside of the kv store.\ntype KVStore struct {\n\tstore sdkcollections.Map[uint64, *ctypes.Deposit]\n\n\t// closeFunc is a closure that closes the underlying database\n\t// used by store to ensure that all writes are flushed to disk.\n\t// We guarantee that closeFunc is called at maximum only once.\n\tcloseFunc CloseFunc\n\tonce      sync.Once\n\n\t// logger is used for logging information and errors.\n\tlogger log.Logger\n}\n\n// closure type for closing the store.\ntype CloseFunc func() error\n\n// NewStore creates a new deposit store.\nfunc NewStore(\n\tbaseDB dbm.DB,\n\tlogger log.Logger,\n) *KVStore {\n\tspdbV1 := depositstorecommon.NewSynced(baseDB)\n\tkvsp := NewKVStoreProvider(spdbV1)\n\tcloseFunc := spdbV1.Close\n\n\tschemaBuilder := sdkcollections.NewSchemaBuilder(kvsp)\n\tres := &KVStore{\n\t\tstore: sdkcollections.NewMap(\n\t\t\tschemaBuilder,\n\t\t\tsdkcollections.NewPrefix([]byte(KeyDepositPrefix)),\n\t\t\tKeyDepositPrefix,\n\t\t\tsdkcollections.Uint64Key,\n\t\t\tencoding.SSZValueCodec[*ctypes.Deposit]{\n\t\t\t\tNewEmptyF: ctypes.NewEmptyDeposit,\n\t\t\t},\n\t\t),\n\t\tcloseFunc: closeFunc,\n\t\tlogger:    logger,\n\t}\n\tif _, err := schemaBuilder.Build(); err != nil {\n\t\tpanic(errors.Wrap(err, \"failed building KVStore schema\"))\n\t}\n\treturn res\n}\n\n// Close closes the store by calling the closeFunc. It ensures that the\n// closeFunc is called at most once.\nfunc (kv *KVStore) Close() error {\n\tvar err error\n\tkv.once.Do(func() { err = kv.closeFunc() })\n\treturn err\n}\n\n// GetDepositsByIndex returns the first N deposits starting from the given\n// index. If N is greater than the number of deposits, it returns up to the\n// last deposit.\n// Note: we return the hash root of the selected deposits to simplify block\n// building pre migration to deposit store V2.\nfunc (kv *KVStore) GetDepositsByIndex(\n\tctx context.Context,\n\tstartIndex uint64,\n\tdepRange uint64,\n) (ctypes.Deposits, common.Root, error) {\n\tvar (\n\t\tdeposits = make(ctypes.Deposits, 0, depRange)\n\t\tendIdx   = startIndex + depRange\n\t)\n\n\tdone := false\n\tfor i := startIndex; i < endIdx && !done; i++ {\n\t\tdeposit, err := kv.store.Get(ctx, i)\n\t\tswitch {\n\t\tcase err == nil:\n\t\t\tdeposits = append(deposits, deposit)\n\t\tcase errors.Is(err, sdkcollections.ErrNotFound):\n\t\t\tdone = true // normal happy path, there are less than max allowed deposits\n\t\tdefault:\n\t\t\treturn deposits, common.Root{}, errors.Wrapf(\n\t\t\t\terr, \"failed to get deposit %d, start: %d, end: %d\", i, startIndex, endIdx,\n\t\t\t)\n\t\t}\n\t}\n\n\tkv.logger.Debug(\"GetDepositsByIndex\", \"start\", startIndex, \"end\", endIdx)\n\treturn deposits, deposits.HashTreeRoot(), nil\n}\n\n// EnqueueDeposits pushes multiple deposits to the queue.\nfunc (kv *KVStore) EnqueueDeposits(ctx context.Context, deposits []*ctypes.Deposit) error {\n\tfor _, deposit := range deposits {\n\t\tidx := deposit.GetIndex().Unwrap()\n\t\tif err := kv.store.Set(ctx, idx, deposit); err != nil {\n\t\t\treturn errors.Wrapf(err, \"failed to enqueue deposit %d\", idx)\n\t\t}\n\t}\n\n\tif len(deposits) > 0 {\n\t\tkv.logger.Debug(\n\t\t\t\"EnqueueDeposit\", \"enqueued\", len(deposits),\n\t\t\t\"start\", deposits[0].GetIndex(), \"end\", deposits[len(deposits)-1].GetIndex(),\n\t\t)\n\t}\n\treturn nil\n}\n\n// Prune removes the [start, end) deposits from the store.\nfunc (kv *KVStore) Prune(ctx context.Context, start, end uint64) error {\n\tif start > end {\n\t\treturn errors.Wrapf(\n\t\t\tstorage.ErrInvalidRange, \"DepositKVStore Prune start: %d, end: %d\", start, end)\n\t}\n\n\tfor i := range end {\n\t\t// This only errors if the key passed in cannot be encoded.\n\t\tif err := kv.store.Remove(ctx, start+i); err != nil {\n\t\t\treturn errors.Wrapf(err, \"failed to prune deposit %d\", start+i)\n\t\t}\n\t}\n\n\tkv.logger.Debug(\"Pruned deposits\", \"start\", start, \"end\", end)\n\treturn nil\n}\n"
  },
  {
    "path": "storage/deposit/v1/store_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage deposit_test\n\nimport (\n\t\"testing\"\n\n\t\"cosmossdk.io/log\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/storage/db\"\n\t\"github.com/berachain/beacon-kit/storage/deposit/v1\"\n\tdbm \"github.com/cosmos/cosmos-db\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc BenchmarkDepositsInsertion(b *testing.B) {\n\tbaseDB, err := db.OpenDB(\"\", dbm.MemDBBackend)\n\trequire.NoError(b, err)\n\n\tnopLog := log.NewNopLogger()\n\tdummyCtx := b.Context()\n\n\tvar store *deposit.KVStore\n\trequire.NotPanics(b, func() {\n\t\tstore = deposit.NewStore(baseDB, nopLog)\n\t})\n\n\tinputSize := 5_000\n\tinputs := make([][]*types.Deposit, 0, inputSize)\n\tfor i := range inputSize {\n\t\tb := uint8(i % 255)\n\t\td := []*types.Deposit{\n\t\t\t{ // typing just to ease up insertions\n\t\t\t\tPubkey:      [48]byte{b},\n\t\t\t\tCredentials: types.NewCredentialsFromExecutionAddress(common.ExecutionAddress{b}),\n\t\t\t\tAmount:      10_000,\n\t\t\t\tSignature:   crypto.BLSSignature{b},\n\t\t\t\tIndex:       uint64(i),\n\t\t\t},\n\t\t}\n\t\tinputs = append(inputs, d)\n\t}\n\tvar root common.Root\n\n\tb.ResetTimer()\n\tfor range b.N {\n\t\tfor i, d := range inputs {\n\t\t\trequire.NoError(b, store.EnqueueDeposits(dummyCtx, d))\n\n\t\t\t// this is why v1 is less efficient than v2. To get the historical root we need to\n\t\t\t// load all depoisits from genesis and hash them together. Here I allocate up to i+1\n\t\t\t// so as least as possible.\n\t\t\t_, root, err = store.GetDepositsByIndex(dummyCtx, constants.FirstDepositIndex, uint64(i+1))\n\t\t\trequire.NoError(b, err)\n\t\t\t_ = root // an attempt to avoid compiler optimizations\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "storage/encoding/ssz.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage encoding\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constraints\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/ssz\"\n\t\"github.com/davecgh/go-spew/spew\"\n)\n\n// SSZValueCodec provides methods to encode and decode SSZ values.\ntype SSZValueCodec[T constraints.SSZMarshallable] struct {\n\tNewEmptyF func() T // constructor\n}\n\n// Encode marshals the provided value into its SSZ encoding.\nfunc (SSZValueCodec[T]) Encode(value T) ([]byte, error) {\n\treturn value.MarshalSSZ()\n}\n\n// Decode unmarshals the provided bytes into a value of type T.\nfunc (sc SSZValueCodec[T]) Decode(bz []byte) (T, error) {\n\tdest := sc.NewEmptyF()\n\treturn dest, ssz.Unmarshal(bz, dest)\n}\n\n// EncodeJSON is not implemented and will panic if called.\nfunc (SSZValueCodec[T]) EncodeJSON(_ T) ([]byte, error) {\n\tpanic(\"not implemented\")\n}\n\n// DecodeJSON is not implemented and will panic if called.\nfunc (SSZValueCodec[T]) DecodeJSON(_ []byte) (T, error) {\n\tpanic(\"not implemented\")\n}\n\n// Stringify returns the string representation of the provided value.\nfunc (SSZValueCodec[T]) Stringify(value T) string {\n\treturn spew.Sdump(value)\n}\n\n// ValueType returns the name of the interface that this codec is intended for.\nfunc (SSZValueCodec[T]) ValueType() string {\n\treturn \"SSZMarshallable\"\n}\n\n// SSZVersionedValueCodec provides methods to encode and decode SSZ values for a specific version.\ntype SSZVersionedValueCodec[T constraints.SSZMarshallable] struct {\n\tNewEmptyF     func(common.Version) T // constructor\n\tlatestVersion common.Version\n}\n\n// SetActiveForkVersion sets the fork version for the codec.\nfunc (cdc *SSZVersionedValueCodec[T]) SetActiveForkVersion(version common.Version) {\n\tcdc.latestVersion = version\n}\n\n// Encode marshals the provided value into its SSZ encoding.\nfunc (cdc *SSZVersionedValueCodec[T]) Encode(value T) ([]byte, error) {\n\treturn value.MarshalSSZ()\n}\n\n// Decode unmarshals the provided bytes into a value of type T.\nfunc (cdc *SSZVersionedValueCodec[T]) Decode(b []byte) (T, error) {\n\tdest := cdc.NewEmptyF(cdc.latestVersion)\n\treturn dest, ssz.Unmarshal(b, dest)\n}\n\n// EncodeJSON is not implemented and will panic if called.\nfunc (cdc *SSZVersionedValueCodec[T]) EncodeJSON(_ T) ([]byte, error) {\n\tpanic(\"not implemented\")\n}\n\n// DecodeJSON is not implemented and will panic if called.\nfunc (cdc *SSZVersionedValueCodec[T]) DecodeJSON(_ []byte) (T, error) {\n\tpanic(\"not implemented\")\n}\n\n// Stringify returns the string representation of the provided value.\nfunc (cdc *SSZVersionedValueCodec[T]) Stringify(value T) string {\n\treturn spew.Sdump(value)\n}\n\n// ValueType returns the name of the interface that this codec is intended for.\nfunc (cdc *SSZVersionedValueCodec[T]) ValueType() string {\n\treturn \"SSZVersionedMarshallable\"\n}\n"
  },
  {
    "path": "storage/encoding/u64.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage encoding\n\nimport (\n\t\"cosmossdk.io/collections/codec\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n)\n\nvar (\n\t// U64Key can be used to encode math.U64 keys. Encoding is big endian to\n\t// retain ordering.\n\t//\n\t//nolint:gochecknoglobals // stateless so can be reused.\n\tU64Key = codec.NewUint64Key[math.U64]()\n\n\t// U64Value implements a ValueCodec for uint64.\n\t//\n\t//nolint:gochecknoglobals // stateless so can be reused.\n\tU64Value = codec.KeyToValueCodec(U64Key)\n)\n"
  },
  {
    "path": "storage/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage storage\n\nimport \"github.com/berachain/beacon-kit/errors\"\n\nvar ErrInvalidRange = errors.New(\"range start greater than end\")\n"
  },
  {
    "path": "storage/filedb/db.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage filedb\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/spf13/afero\"\n)\n\n// DB represents a filesystem backed key-value store.\n// It is useful for storing amounts of data that exceed what is\n// performant to store in a traditional key-value database.\ntype DB struct {\n\tfs        afero.Fs\n\tlogger    log.Logger\n\trootDir   string\n\textension string\n\tdirPerms  os.FileMode\n}\n\n// NewDB creates a new instance of the DB.\nfunc NewDB(opts ...Option) *DB {\n\tdb := &DB{}\n\tfor _, opt := range opts {\n\t\tif err := opt(db); err != nil {\n\t\t\tpanic(errors.Wrap(err, \"failed to apply option\"))\n\t\t}\n\t}\n\n\tdb.fs = afero.NewBasePathFs(afero.NewOsFs(), db.rootDir)\n\treturn db\n}\n\n// Get retrieves the value for a key.\nfunc (db *DB) Get(key []byte) ([]byte, error) {\n\treturn afero.ReadFile(db.fs, db.pathForKey(key))\n}\n\n// Has returns true if the key exists in the database.\nfunc (db *DB) Has(key []byte) (bool, error) {\n\texists, err := afero.Exists(db.fs, db.pathForKey(key))\n\tif err != nil {\n\t\treturn false, err\n\t}\n\treturn exists, nil\n}\n\n// Set stores the value for a key.\nfunc (db *DB) Set(key []byte, value []byte) error {\n\tif exists, err := afero.Exists(db.fs, db.pathForKey(key)); err != nil {\n\t\treturn err\n\t} else if exists {\n\t\tdb.logger.Warn(\"Overriding existing key\", \"key\", key)\n\t}\n\n\tif err := db.fs.MkdirAll(\n\t\tfilepath.Dir(db.pathForKey(key)), db.dirPerms,\n\t); err != nil {\n\t\treturn err\n\t}\n\n\tfile, err := db.fs.Create(db.pathForKey(key))\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to create file\")\n\t}\n\tdefer file.Close()\n\n\tn, err := file.Write(value)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to write to file\")\n\t}\n\tdb.logger.Debug(\"wrote %d bytes to %s\", n, db.pathForKey(key))\n\n\treturn nil\n}\n\n// Delete removes the value for a key.\nfunc (db *DB) Delete(key []byte) error {\n\treturn db.fs.RemoveAll(db.pathForKey(key))\n}\n\n// pathForKey returns the path for a key.\n// TODO: for efficient storage we should expand this path.\nfunc (db *DB) pathForKey(key []byte) string {\n\treturn string(key) + \".\" + db.extension\n}\n"
  },
  {
    "path": "storage/filedb/db_options.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage filedb\n\nimport (\n\t\"os\"\n\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/spf13/afero\"\n)\n\ntype Option func(*DB) error\n\n// WithAferoFS sets the filesystem for the database.\n// NOTE: Should only be used for testing.\nfunc WithAferoFS(fs afero.Fs) Option {\n\treturn func(db *DB) error {\n\t\tdb.fs = fs\n\t\treturn nil\n\t}\n}\n\n// WithDirectoryPermissions sets the permissions for the directory.\nfunc WithDirectoryPermissions(permissions os.FileMode) Option {\n\treturn func(db *DB) error {\n\t\tdb.dirPerms = permissions\n\t\treturn nil\n\t}\n}\n\n// WithFileExtension sets the file extension for the database.\nfunc WithFileExtension(extension string) Option {\n\treturn func(db *DB) error {\n\t\tdb.extension = extension\n\t\treturn nil\n\t}\n}\n\n// WithLogger sets the logger for the database.\nfunc WithLogger(logger log.Logger) Option {\n\treturn func(db *DB) error {\n\t\tdb.logger = logger\n\t\treturn nil\n\t}\n}\n\n// WithRootDirectory sets the root directory for the database.\nfunc WithRootDirectory(rootDir string) Option {\n\treturn func(db *DB) error {\n\t\tdb.rootDir = rootDir\n\t\treturn nil\n\t}\n}\n"
  },
  {
    "path": "storage/filedb/db_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage filedb_test\n\nimport (\n\t\"testing\"\n\n\t\"cosmossdk.io/log\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\tfile \"github.com/berachain/beacon-kit/storage/filedb\"\n\t\"github.com/spf13/afero\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestDB(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname          string\n\t\tsetupFunc     func(db *file.DB) error\n\t\ttestFunc      func(t *testing.T, db *file.DB)\n\t\texpectedError bool\n\t}{\n\t\t{\n\t\t\tname: \"NewDB\",\n\t\t\ttestFunc: func(t *testing.T, db *file.DB) {\n\t\t\t\tt.Helper()\n\t\t\t\trequire.NotNil(t, db)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"SetAndGet\",\n\t\t\tsetupFunc: func(db *file.DB) error {\n\t\t\t\treturn db.Set([]byte(\"key\"), []byte(\"value\"))\n\t\t\t},\n\t\t\ttestFunc: func(t *testing.T, db *file.DB) {\n\t\t\t\tt.Helper()\n\t\t\t\tretrievedValue, err := db.Get([]byte(\"key\"))\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, []byte(\"value\"), retrievedValue)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Has\",\n\t\t\tsetupFunc: func(db *file.DB) error {\n\t\t\t\treturn db.Set([]byte(\"key\"), []byte(\"value\"))\n\t\t\t},\n\t\t\ttestFunc: func(t *testing.T, db *file.DB) {\n\t\t\t\tt.Helper()\n\t\t\t\texists, err := db.Has([]byte(\"key\"))\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.True(t, exists)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Delete\",\n\t\t\tsetupFunc: func(db *file.DB) error {\n\t\t\t\treturn db.Set([]byte(\"key\"), []byte(\"value\"))\n\t\t\t},\n\t\t\ttestFunc: func(t *testing.T, db *file.DB) {\n\t\t\t\tt.Helper()\n\t\t\t\texists, err := db.Has([]byte(\"key\"))\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.True(t, exists)\n\n\t\t\t\terr = db.Delete([]byte(\"key\"))\n\t\t\t\trequire.NoError(t, err)\n\n\t\t\t\texists, err = db.Has([]byte(\"key\"))\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.False(t, exists)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"SetExistingKey\",\n\t\t\tsetupFunc: func(db *file.DB) error {\n\t\t\t\tif err := db.Set([]byte(\"key\"), []byte(\"value1\")); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\treturn db.Set([]byte(\"key\"), []byte(\"value2\"))\n\t\t\t},\n\t\t\ttestFunc: func(t *testing.T, db *file.DB) {\n\t\t\t\tt.Helper()\n\t\t\t\tretrievedValue, err := db.Get([]byte(\"key\"))\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, []byte(\"value2\"), retrievedValue)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"GetNonExistingKey\",\n\t\t\ttestFunc: func(t *testing.T, db *file.DB) {\n\t\t\t\tt.Helper()\n\t\t\t\t_, err := db.Get([]byte(\"non-existing\"))\n\t\t\t\trequire.Error(t, err)\n\t\t\t},\n\t\t\texpectedError: true,\n\t\t},\n\t\t// If the key does not exist, `Has` will return false with error as nil\n\t\t{\n\t\t\tname: \"HasNonExistingKey\",\n\t\t\ttestFunc: func(t *testing.T, db *file.DB) {\n\t\t\t\tt.Helper()\n\t\t\t\texists, err := db.Has([]byte(\"non-existing\"))\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.False(t, exists)\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tfs := afero.NewMemMapFs()\n\t\t\tdb := file.NewDB(\n\t\t\t\tfile.WithRootDirectory(\"/tmp/testdb\"),\n\t\t\t\tfile.WithFileExtension(\"txt\"),\n\t\t\t\tfile.WithDirectoryPermissions(0700),\n\t\t\t\tfile.WithLogger(log.NewNopLogger()),\n\t\t\t\tfile.WithAferoFS(fs),\n\t\t\t)\n\n\t\t\tif tt.setupFunc != nil {\n\t\t\t\tif err := tt.setupFunc(db); (err != nil) != tt.expectedError {\n\t\t\t\t\tt.Fatalf(\n\t\t\t\t\t\t\"setupFunc() error = %v, expectedError %v\",\n\t\t\t\t\t\terr,\n\t\t\t\t\t\ttt.expectedError,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif tt.testFunc != nil {\n\t\t\t\ttt.testFunc(t, db)\n\t\t\t}\n\t\t})\n\t}\n\n\tt.Run(\"NewDBWithInvalidOption\", func(t *testing.T) {\n\t\tinvalidOption := func(_ *file.DB) error {\n\t\t\treturn errors.New(\"invalid option\")\n\t\t}\n\t\trequire.Panics(t, func() { file.NewDB(invalidOption) })\n\t})\n}\n\n// Test with `etc` as root directory to cause creation failure\n// due to permission denied.\nfunc TestDB_SetExistingKey_CreateError(t *testing.T) {\n\tt.Parallel()\n\ttest := struct {\n\t\tname          string\n\t\tsetupFunc     func(db *file.DB) error\n\t\ttestFunc      func(t *testing.T, db *file.DB)\n\t\texpectedError bool\n\t}{\n\t\tname: \"SetExistingKeyWithCreateError\",\n\t\ttestFunc: func(t *testing.T, db *file.DB) {\n\t\t\tt.Helper()\n\t\t\terr := db.Set([]byte(\"key\"), []byte(\"value\"))\n\t\t\trequire.Error(t, err)\n\t\t\trequire.ErrorContains(t, err, \"failed to create file\")\n\t\t},\n\t\texpectedError: true,\n\t}\n\n\tt.Run(test.name, func(t *testing.T) {\n\t\tt.Parallel()\n\t\tfs := afero.NewMemMapFs()\n\t\tdb := file.NewDB(\n\t\t\tfile.WithRootDirectory(\"/etc\"),\n\t\t\tfile.WithFileExtension(\"txt\"),\n\t\t\tfile.WithDirectoryPermissions(0700),\n\t\t\tfile.WithLogger(log.NewNopLogger()),\n\t\t\tfile.WithAferoFS(fs),\n\t\t)\n\n\t\tif test.setupFunc != nil {\n\t\t\tif err := test.setupFunc(db); (err != nil) != test.expectedError {\n\t\t\t\trequire.Error(t, err, \"setupFunc() error = %v\", err)\n\t\t\t}\n\t\t}\n\n\t\tif test.testFunc != nil {\n\t\t\ttest.testFunc(t, db)\n\t\t}\n\t})\n}\n\n// Test with root directory as a file.\nfunc TestDB_SetHas_NotDirError(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname          string\n\t\tsetupFunc     func(db *file.DB) error\n\t\ttestFunc      func(t *testing.T, db *file.DB)\n\t\texpectedError bool\n\t}{\n\t\t{\n\t\t\tname: \"HasWithError\",\n\t\t\ttestFunc: func(t *testing.T, db *file.DB) {\n\t\t\t\tt.Helper()\n\t\t\t\tvalue, err := db.Has([]byte(\"key\"))\n\t\t\t\trequire.Error(t, err)\n\t\t\t\trequire.False(t, value)\n\t\t\t\trequire.ErrorContains(t, err, \"not a directory\")\n\t\t\t},\n\t\t\texpectedError: true,\n\t\t},\n\t\t{\n\t\t\tname: \"SetWithError\",\n\t\t\ttestFunc: func(t *testing.T, db *file.DB) {\n\t\t\t\tt.Helper()\n\t\t\t\terr := db.Set([]byte(\"key\"), []byte(\"value\"))\n\t\t\t\trequire.Error(t, err)\n\t\t\t\trequire.ErrorContains(t, err, \"not a directory\")\n\t\t\t},\n\t\t\texpectedError: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tfs := afero.NewMemMapFs()\n\t\t\tdb := file.NewDB(\n\t\t\t\tfile.WithRootDirectory(\"/etc/passwd\"),\n\t\t\t\tfile.WithFileExtension(\"txt\"),\n\t\t\t\tfile.WithDirectoryPermissions(0700),\n\t\t\t\tfile.WithLogger(log.NewNopLogger()),\n\t\t\t\tfile.WithAferoFS(fs),\n\t\t\t)\n\n\t\t\tif tt.setupFunc != nil {\n\t\t\t\tif err := tt.setupFunc(db); (err != nil) != tt.expectedError {\n\t\t\t\t\trequire.Error(t, err, \"setupFunc() error = %v\", err)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif tt.testFunc != nil {\n\t\t\t\ttt.testFunc(t, db)\n\t\t\t}\n\t\t})\n\t}\n}\n\n// Test with root directory to be created in `etc`\n// which will result in permission denied.\nfunc TestDB_Set_MkDirError(t *testing.T) {\n\tt.Parallel()\n\ttest := struct {\n\t\tname          string\n\t\tsetupFunc     func(db *file.DB) error\n\t\ttestFunc      func(t *testing.T, db *file.DB)\n\t\texpectedError bool\n\t}{\n\t\tname: \"SetWithMkdirAllError\",\n\t\ttestFunc: func(t *testing.T, db *file.DB) {\n\t\t\tt.Helper()\n\t\t\terr := db.Set([]byte(\"key\"), []byte(\"value\"))\n\t\t\trequire.Error(t, err)\n\t\t},\n\t\texpectedError: true,\n\t}\n\n\tt.Run(test.name, func(t *testing.T) {\n\t\tt.Parallel()\n\t\tfs := afero.NewMemMapFs()\n\t\tdb := file.NewDB(\n\t\t\tfile.WithRootDirectory(\"/etc/test\"),\n\t\t\tfile.WithFileExtension(\"txt\"),\n\t\t\tfile.WithDirectoryPermissions(0700),\n\t\t\tfile.WithLogger(log.NewNopLogger()),\n\t\t\tfile.WithAferoFS(fs),\n\t\t)\n\n\t\tif test.setupFunc != nil {\n\t\t\tif err := test.setupFunc(db); (err != nil) != test.expectedError {\n\t\t\t\trequire.Error(t, err, \"setupFunc() error = %v\", err)\n\t\t\t}\n\t\t}\n\n\t\tif test.testFunc != nil {\n\t\t\ttest.testFunc(t, db)\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "storage/filedb/range_db.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage filedb\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/storage\"\n\tdb \"github.com/berachain/beacon-kit/storage/interfaces\"\n\t\"github.com/spf13/afero\"\n)\n\nconst (\n\tkeyFormat  = \"%d/%s\"\n\tpathFormat = \"%d/\"\n\tkeyParts   = 2\n)\n\nvar (\n\tErrRangeNotSupported = errors.New(\"RangeDB DeleteRange: delete range not supported for this db\")\n)\n\n// RangeDB is a database that stores versioned data.\n// It prefixes keys with an index.\n// Invariant: No index below firstNonNilIndex should be populated.\ntype RangeDB struct {\n\tcoreDB *DB\n\n\trwMu sync.RWMutex\n\n\t// lowerBoundIndex is used as a loose check for stored indexes\n\t// monotonicity. The goal is to make sure we do not overwrite\n\t// indexes which have been or will be deleted eventually via pruning.\n\tlowerBoundIndex uint64\n}\n\n// NewRangeDB creates a new RangeDB.\nfunc NewRangeDB(coreDB db.DB) *RangeDB {\n\tcDB, ok := coreDB.(*DB)\n\tif !ok {\n\t\tpanic(ErrRangeNotSupported)\n\t}\n\treturn &RangeDB{\n\t\tcoreDB:          cDB,\n\t\tlowerBoundIndex: 0,\n\t}\n}\n\n// Get retrieves the value associated with the given index and key.\n// It prefixes the key with the index and a slash before querying the underlying\n// database.\nfunc (db *RangeDB) Get(index uint64, key []byte) ([]byte, error) {\n\tdb.rwMu.RLock()\n\tdefer db.rwMu.RUnlock()\n\treturn db.coreDB.Get(prefix(index, key))\n}\n\n// Has checks if the given index and key exist in the database.\n// It prefixes the key with the index and a slash before querying the underlying\n// database.\nfunc (db *RangeDB) Has(index uint64, key []byte) (bool, error) {\n\tdb.rwMu.RLock()\n\tdefer db.rwMu.RUnlock()\n\treturn db.coreDB.Has(prefix(index, key))\n}\n\n// Set stores the value with the given index and key in the database.\n// It prefixes the key with the index and a slash before storing it in the\n// underlying database.\nfunc (db *RangeDB) Set(index uint64, key []byte, value []byte) error {\n\tdb.rwMu.Lock()\n\tdefer db.rwMu.Unlock()\n\n\tindex = max(index, db.lowerBoundIndex) // enforce invariant\n\treturn db.coreDB.Set(prefix(index, key), value)\n}\n\n// Delete removes the value associated with the given index and key from the\n// database. It prefixes the key with the index and a slash before deleting it\n// from the underlying database.\nfunc (db *RangeDB) Delete(index uint64, key []byte) error {\n\tdb.rwMu.Lock()\n\tdefer db.rwMu.Unlock()\n\treturn db.coreDB.Delete(prefix(index, key))\n}\n\n// deleteRange removes all values associated with the given index from the\n// filesystem. It is INCLUSIVE of the `from` index and EXCLUSIVE of\n// the `to“ index.\nfunc (db *RangeDB) deleteRange(from, to uint64) error {\n\tif from > to {\n\t\treturn fmt.Errorf(\n\t\t\t\"RangeDB deleteRange start: %d, end: %d: %w\",\n\t\t\tfrom, to, storage.ErrInvalidRange,\n\t\t)\n\t}\n\tfor i := from; i < to; i++ {\n\t\tpath := fmt.Sprintf(pathFormat, i)\n\t\tif err := db.coreDB.fs.RemoveAll(path); err != nil {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"RangeDB DeleteRange failed RemoveAll index %d: %w\",\n\t\t\t\ti, err,\n\t\t\t)\n\t\t}\n\t}\n\treturn nil\n}\n\n// Prune removes all values in the given range [start, end) from the db.\nfunc (db *RangeDB) Prune(start, end uint64) error {\n\tdb.rwMu.Lock()\n\tdefer db.rwMu.Unlock()\n\tstart = max(start, db.lowerBoundIndex)\n\tif start > end {\n\t\treturn fmt.Errorf(\n\t\t\t\"RangeDB Prune start: %d, end: %d: %w\",\n\t\t\tstart, end, storage.ErrInvalidRange,\n\t\t)\n\t}\n\n\t// DeleteRange may fail and so some files to be pruned may have not\n\t// been removed. We *do not* retry to prune those files to avoid getting\n\t// stuck with them. Instead we update lowerBoundIndex as if deletion\n\t// was successful and we return an error.\n\terr := db.deleteRange(start, end)\n\tdb.lowerBoundIndex = end\n\treturn err\n}\n\n// DeleteByIndex removes all entries at the specified index.\nfunc (db *RangeDB) DeleteByIndex(index uint64) error {\n\tdb.rwMu.Lock()\n\tdefer db.rwMu.Unlock()\n\n\tpath := fmt.Sprintf(pathFormat, index)\n\tif err := db.coreDB.fs.RemoveAll(path); err != nil && !os.IsNotExist(err) {\n\t\treturn fmt.Errorf(\"RangeDB DeleteByIndex failed to remove index %d: %w\", index, err)\n\t}\n\n\t// Note: We intentionally do not update lowerBoundIndex here.\n\treturn nil\n}\n\n// GetByIndex takes the database index and returns all associated entries,\n// expecting database keys to follow the prefix() format. If index does not\n// exist in the DB for any reason (pruned, invalid index), an empty list is\n// returned with no error.\nfunc (db *RangeDB) GetByIndex(index uint64) ([][]byte, error) {\n\tdb.rwMu.RLock()\n\tdefer db.rwMu.RUnlock()\n\tindexDir := fmt.Sprintf(pathFormat, index)\n\tentries, err := afero.ReadDir(db.coreDB.fs, indexDir)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn [][]byte{}, nil\n\t\t}\n\t\treturn nil, err\n\t}\n\tkeys := make([][]byte, 0, len(entries))\n\tfor _, entry := range entries {\n\t\tif entry.IsDir() {\n\t\t\tcontinue\n\t\t}\n\t\tfilename := entry.Name()\n\t\tif !strings.HasSuffix(filename, db.coreDB.extension) {\n\t\t\tcontinue\n\t\t}\n\t\tvar sidecarBz []byte\n\t\tsidecarBz, err = afero.ReadFile(db.coreDB.fs, filepath.Join(indexDir, filename))\n\t\tif err != nil {\n\t\t\treturn keys, err\n\t\t}\n\t\tkeys = append(keys, sidecarBz)\n\t}\n\treturn keys, nil\n}\n\n// prefix prefixes the given key with the index and a slash.\nfunc prefix(index uint64, key []byte) []byte {\n\treturn []byte(fmt.Sprintf(keyFormat, index, hex.EncodeBytes(key)))\n}\n\n// ExtractIndex extracts the index from a prefixed key.\nfunc ExtractIndex(prefixedKey []byte) (uint64, error) {\n\tparts := bytes.SplitN(prefixedKey, []byte(\"/\"), keyParts)\n\tif len(parts) < keyParts {\n\t\treturn 0, errors.New(\"invalid key format\")\n\t}\n\n\tindexStr := string(parts[0])\n\tindex, err := math.U64FromString(indexStr)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\treturn index.Unwrap(), nil\n}\n"
  },
  {
    "path": "storage/filedb/range_db_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage filedb_test\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"cosmossdk.io/log\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\tfile \"github.com/berachain/beacon-kit/storage/filedb\"\n\t\"github.com/berachain/beacon-kit/storage/interfaces/mocks\"\n\t\"github.com/spf13/afero\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// =========================== BASIC OPERATIONS ============================\n\nfunc TestRangeDB(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname          string\n\t\tsetupFunc     func(rdb *file.RangeDB) error\n\t\ttestFunc      func(t *testing.T, rdb *file.RangeDB)\n\t\texpectedError bool\n\t}{\n\t\t{\n\t\t\tname: \"Get\",\n\t\t\tsetupFunc: func(rdb *file.RangeDB) error {\n\t\t\t\treturn rdb.Set(1, []byte(\"testKey\"), []byte(\"testValue\"))\n\t\t\t},\n\t\t\ttestFunc: func(t *testing.T, rdb *file.RangeDB) {\n\t\t\t\tt.Helper()\n\t\t\t\tgotValue, err := rdb.Get(1, []byte(\"testKey\"))\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.Equal(t, []byte(\"testValue\"), gotValue)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Has\",\n\t\t\tsetupFunc: func(rdb *file.RangeDB) error {\n\t\t\t\treturn rdb.Set(1, []byte(\"testKey\"), []byte(\"testValue\"))\n\t\t\t},\n\t\t\ttestFunc: func(t *testing.T, rdb *file.RangeDB) {\n\t\t\t\tt.Helper()\n\t\t\t\texists, err := rdb.Has(1, []byte(\"testKey\"))\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.True(t, exists)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Set\",\n\t\t\tsetupFunc: func(_ *file.RangeDB) error {\n\t\t\t\treturn nil // No setup required\n\t\t\t},\n\t\t\ttestFunc: func(t *testing.T, rdb *file.RangeDB) {\n\t\t\t\tt.Helper()\n\t\t\t\terr := rdb.Set(1, []byte(\"testKey\"), []byte(\"testValue\"))\n\t\t\t\trequire.NoError(t, err)\n\n\t\t\t\texists, err := rdb.Has(1, []byte(\"testKey\"))\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.True(t, exists)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Delete\",\n\t\t\tsetupFunc: func(rdb *file.RangeDB) error {\n\t\t\t\treturn rdb.Set(1, []byte(\"testKey\"), []byte(\"testValue\"))\n\t\t\t},\n\t\t\ttestFunc: func(t *testing.T, rdb *file.RangeDB) {\n\t\t\t\tt.Helper()\n\n\t\t\t\texists, err := rdb.Has(1, []byte(\"testKey\"))\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.True(t, exists)\n\n\t\t\t\terr = rdb.Delete(1, []byte(\"testKey\"))\n\t\t\t\trequire.NoError(t, err)\n\n\t\t\t\texists, err = rdb.Has(1, []byte(\"testKey\"))\n\t\t\t\trequire.NoError(t, err)\n\t\t\t\trequire.False(t, exists)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Prune\",\n\t\t\tsetupFunc: func(rdb *file.RangeDB) error {\n\t\t\t\tfor index := uint64(1); index <= 5; index++ {\n\t\t\t\t\tif err := rdb.Set(\n\t\t\t\t\t\tindex, []byte(\"testKey\"), []byte(\"testValue\"),\n\t\t\t\t\t); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t},\n\t\t\ttestFunc: func(t *testing.T, rdb *file.RangeDB) {\n\t\t\t\tt.Helper()\n\t\t\t\terr := rdb.Prune(1, 4)\n\t\t\t\trequire.NoError(t, err)\n\n\t\t\t\tfor index := uint64(1); index <= 3; index++ {\n\t\t\t\t\tvar exists bool\n\t\t\t\t\texists, err = rdb.Has(index, []byte(\"testKey\"))\n\t\t\t\t\trequire.NoError(t, err, \"index %d\", index)\n\t\t\t\t\trequire.False(t, exists, \"index %d\", index)\n\t\t\t\t}\n\n\t\t\t\tfor index := uint64(4); index <= 5; index++ {\n\t\t\t\t\tvar exists bool\n\t\t\t\t\texists, err = rdb.Has(index, []byte(\"testKey\"))\n\t\t\t\t\trequire.NoError(t, err, \"index %d\", index)\n\t\t\t\t\trequire.True(t, exists, \"index %d\", index)\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\trdb := file.NewRangeDB(newTestFDB(\"/tmp/testdb-1\"))\n\n\t\t\tif tt.setupFunc != nil {\n\t\t\t\trequire.NoError(t, tt.setupFunc(rdb))\n\t\t\t}\n\n\t\t\ttt.testFunc(t, rdb)\n\t\t})\n\t}\n}\n\nfunc TestExtractIndex(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname        string\n\t\tprefixedKey []byte\n\t\texpectedIdx uint64\n\t\texpectedErr error\n\t}{\n\t\t{\n\t\t\tname:        \"ValidKey\",\n\t\t\tprefixedKey: []byte(\"12345/testKey\"),\n\t\t\texpectedIdx: 12345,\n\t\t\texpectedErr: nil,\n\t\t},\n\t\t{\n\t\t\tname:        \"InvalidKeyFormat\",\n\t\t\tprefixedKey: []byte(\"testKey\"),\n\t\t\texpectedIdx: 0,\n\t\t\texpectedErr: errors.New(\"invalid key format\"),\n\t\t},\n\t\t{\n\t\t\tname:        \"InvalidIndex\",\n\t\t\tprefixedKey: []byte(\"abc/testKey\"),\n\t\t\texpectedIdx: 0,\n\t\t\texpectedErr: errors.New(\n\t\t\t\t\"strconv.ParseUint: parsing \\\"abc\\\": invalid syntax\",\n\t\t\t),\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tidx, err := file.ExtractIndex(tt.prefixedKey)\n\t\t\trequire.Equal(t, tt.expectedIdx, idx)\n\t\t\tif tt.expectedErr != nil {\n\t\t\t\trequire.ErrorContains(t, err, tt.expectedErr.Error())\n\t\t\t}\n\t\t})\n\t}\n}\n\n// =========================== PRUNING =====================================\n\nfunc TestRangeDB_DeleteRange_NotSupported(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname string\n\t\tdb   *mocks.Db\n\t}{\n\t\t{\n\t\t\tname: \"DeleteRangeNotSupported\",\n\t\t\tdb:   new(mocks.Db),\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\tt.Helper()\n\t\t\trequire.Panics(t, func() { _ = file.NewRangeDB(tt.db) })\n\t\t})\n\t}\n}\n\nfunc TestRangeDB_Prune(t *testing.T) {\n\tt.Parallel()\n\ttests := []struct {\n\t\tname          string\n\t\tsetupFunc     func(rdb *file.RangeDB) error\n\t\tstart         uint64\n\t\tend           uint64\n\t\texpectedError bool\n\t\ttestFunc      func(t *testing.T, rdb *file.RangeDB)\n\t}{\n\t\t{\n\t\t\tname: \"PruneWithDeleteRange\",\n\t\t\tsetupFunc: func(rdb *file.RangeDB) error {\n\t\t\t\treturn populateTestDB(rdb, 0, 50)\n\t\t\t},\n\t\t\tstart:         2,\n\t\t\tend:           7,\n\t\t\texpectedError: false,\n\t\t\ttestFunc: func(t *testing.T, rdb *file.RangeDB) {\n\t\t\t\tt.Helper()\n\t\t\t\trequireNotExist(t, rdb, 2, 6)\n\t\t\t\trequireExist(t, rdb, 0, 1)\n\t\t\t\trequireExist(t, rdb, 7, 50)\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"PruneWithDeleteRange-InvalidRange\",\n\t\t\tsetupFunc: func(rdb *file.RangeDB) error {\n\t\t\t\treturn populateTestDB(rdb, 0, 50)\n\t\t\t},\n\t\t\tstart:         7,\n\t\t\tend:           2,\n\t\t\texpectedError: true,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\trdb := file.NewRangeDB(newTestFDB(\"/tmp/testdb-2\"))\n\n\t\t\tif tt.setupFunc != nil {\n\t\t\t\trequire.NoError(t, tt.setupFunc(rdb))\n\t\t\t}\n\t\t\terr := rdb.Prune(tt.start, tt.end)\n\t\t\tif (err != nil) != tt.expectedError {\n\t\t\t\tt.Fatalf(\n\t\t\t\t\t\"Prune() error = %v, expectedError %v\",\n\t\t\t\t\terr,\n\t\t\t\t\ttt.expectedError,\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tif tt.testFunc != nil {\n\t\t\t\ttt.testFunc(t, rdb)\n\t\t\t}\n\t\t})\n\t}\n}\n\n// =========================== INVARIANTS ================================.\n\n// invariant: all indexes up to the firstNonNilIndex should be nil.\nfunc TestRangeDB_Invariants(t *testing.T) {\n\tt.Parallel()\n\t// we ignore errors for most of the tests below because we want to ensure\n\t// that the invariants hold in exceptional circumstances.\n\ttests := []struct {\n\t\tname      string\n\t\tsetupFunc func(rdb *file.RangeDB) error\n\t\ttestFunc  func(t *testing.T, rdb *file.RangeDB)\n\t}{\n\t\t{\n\t\t\tname: \"Populate from empty\",\n\t\t\tsetupFunc: func(rdb *file.RangeDB) error {\n\t\t\t\treturn populateTestDB(rdb, 1, 5)\n\t\t\t},\n\t\t\ttestFunc: func(t *testing.T, rdb *file.RangeDB) {\n\t\t\t\tt.Helper()\n\t\t\t\trequireNotExist(t, rdb, 0, lastConsequetiveNilIndex(rdb))\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Delete from populated\",\n\t\t\tsetupFunc: func(rdb *file.RangeDB) error {\n\t\t\t\treturn populateTestDB(rdb, 1, 5)\n\t\t\t},\n\t\t\ttestFunc: func(t *testing.T, rdb *file.RangeDB) {\n\t\t\t\tt.Helper()\n\t\t\t\t_ = rdb.Delete(2, []byte(\"key\"))\n\t\t\t\trequireNotExist(t, rdb, 0, lastConsequetiveNilIndex(rdb))\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Prune from populated\",\n\t\t\tsetupFunc: func(rdb *file.RangeDB) error {\n\t\t\t\treturn populateTestDB(rdb, 1, 10)\n\t\t\t},\n\t\t\ttestFunc: func(t *testing.T, rdb *file.RangeDB) {\n\t\t\t\tt.Helper()\n\t\t\t\t_ = rdb.Prune(0, 3)\n\t\t\t\trequireNotExist(t, rdb, 0, lastConsequetiveNilIndex(rdb))\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Populate, Prune, Set round trip\",\n\t\t\tsetupFunc: func(rdb *file.RangeDB) error {\n\t\t\t\treturn populateTestDB(rdb, 1, 30)\n\t\t\t},\n\t\t\ttestFunc: func(t *testing.T, rdb *file.RangeDB) {\n\t\t\t\tt.Helper()\n\t\t\t\tif err := rdb.Prune(0, 25); err != nil {\n\t\t\t\t\tt.Fatalf(\"Prune() error = %v\", err)\n\t\t\t\t}\n\t\t\t\t_ = populateTestDB(rdb, 5, 10)\n\t\t\t\trequireNotExist(t, rdb, 0, lastConsequetiveNilIndex(rdb))\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\trdb := file.NewRangeDB(newTestFDB(\"/tmp/testdb-3\"))\n\n\t\t\tif tt.setupFunc != nil {\n\t\t\t\tif err := tt.setupFunc(rdb); err != nil {\n\t\t\t\t\trequireNotExist(\n\t\t\t\t\t\tt,\n\t\t\t\t\t\trdb,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\tlastConsequetiveNilIndex(rdb),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif tt.testFunc != nil {\n\t\t\t\ttt.testFunc(t, rdb)\n\t\t\t}\n\t\t})\n\t}\n}\n\n// =========================== DELETE BY INDEX ================================\n\n// TestRangeDB_DeleteByIndex_DoesNotAffectLowerBound verifies the critical\n// invariant that DeleteByIndex does not modify lowerBoundIndex, unlike Prune.\nfunc TestRangeDB_DeleteByIndex_DoesNotAffectLowerBound(t *testing.T) {\n\tt.Parallel()\n\trdb := file.NewRangeDB(newTestFDB(\"/tmp/testdb-deletebyindex\"))\n\n\t// Populate indexes 1-10\n\trequire.NoError(t, populateTestDB(rdb, 1, 10))\n\n\t// Prune indexes 1-5, which sets lowerBoundIndex to 5\n\trequire.NoError(t, rdb.Prune(1, 5))\n\tlowerBoundBefore := getFirstNonNilIndex(rdb)\n\trequire.Equal(t, uint64(5), lowerBoundBefore, \"lowerBoundIndex should be 5 after pruning\")\n\n\t// Delete index 7 using DeleteByIndex\n\trequire.NoError(t, rdb.DeleteByIndex(7))\n\texists, err := rdb.Has(7, []byte(\"key\"))\n\trequire.NoError(t, err)\n\trequire.False(t, exists, \"index 7 should be deleted\")\n\n\t// Verify lowerBoundIndex was NOT changed\n\tlowerBoundAfter := getFirstNonNilIndex(rdb)\n\trequire.Equal(t, lowerBoundBefore, lowerBoundAfter, \"DeleteByIndex must not modify lowerBoundIndex\")\n\n\t// Prune again to verify DeleteByIndex didn't break the pruning mechanism\n\trequire.NoError(t, rdb.Prune(5, 8))\n\n\t// Verify the second prune worked correctly\n\tlowerBoundAfter = getFirstNonNilIndex(rdb)\n\trequire.Equal(t, uint64(8), lowerBoundAfter, \"second Prune should update lowerBoundIndex to 8\")\n}\n\n// =============================== HELPERS ==================================\n\n// newTestFDB returns a new file DB instance with an in-memory filesystem.\nfunc newTestFDB(path string) *file.DB {\n\tfs := afero.NewMemMapFs()\n\treturn file.NewDB(\n\t\t// don't reuse the same txt file for consecutive unit tests bc file\n\t\t// db slow AF\n\t\tfile.WithRootDirectory(path),\n\t\tfile.WithFileExtension(\"txt\"),\n\t\tfile.WithDirectoryPermissions(0700),\n\t\tfile.WithLogger(log.NewNopLogger()),\n\t\tfile.WithAferoFS(fs),\n\t)\n}\n\nfunc getFirstNonNilIndex(rdb *file.RangeDB) uint64 {\n\treturn reflect.ValueOf(rdb).Elem().FieldByName(\"lowerBoundIndex\").Uint()\n}\n\nfunc lastConsequetiveNilIndex(rdb *file.RangeDB) uint64 {\n\treturn uint64(max(int64(getFirstNonNilIndex(rdb))-1, 0))\n}\n\n// requireNotExist requires the indexes from `from` to `to` to be empty.\n//\n\nfunc requireNotExist(t *testing.T, rdb *file.RangeDB, from uint64, to uint64) {\n\tt.Helper()\n\tfor i := from; i <= to; i++ {\n\t\texists, err := rdb.Has(i, []byte(\"key\"))\n\t\trequire.NoError(t, err)\n\t\trequire.False(t, exists, \"Index %d should have been pruned\", i)\n\t}\n}\n\n// requireExist requires the indexes from `from` to `to` not be empty.\nfunc requireExist(t *testing.T, rdb *file.RangeDB, from uint64, to uint64) {\n\tt.Helper()\n\tfor i := from; i <= to; i++ {\n\t\texists, err := rdb.Has(i, []byte(\"key\"))\n\t\trequire.NoError(t, err)\n\t\trequire.True(t, exists, \"Index %d should not have been pruned\", i)\n\t}\n}\n\n// populateTestDB populates the test DB with indexes from `from` to `to`.\nfunc populateTestDB(rdb *file.RangeDB, from, to uint64) error {\n\tfor i := from; i <= to; i++ {\n\t\tif err := rdb.Set(i, []byte(\"key\"), []byte(\"value\")); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "storage/interfaces/db.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage interfaces\n\n// DB is the interface for a simple key-value store.\ntype DB interface {\n\tGet(key []byte) ([]byte, error)\n\tHas(key []byte) (bool, error)\n\tSet(key []byte, value []byte) error\n\tDelete(key []byte) error\n\n\t// TODO: add Batch and full DB stuff.\n}\n"
  },
  {
    "path": "storage/interfaces/mocks/db.mock.go",
    "content": "// Code generated by mockery v2.53.5. DO NOT EDIT.\n\npackage mocks\n\nimport mock \"github.com/stretchr/testify/mock\"\n\n// Db is an autogenerated mock type for the DB type\ntype Db struct {\n\tmock.Mock\n}\n\ntype Db_Expecter struct {\n\tmock *mock.Mock\n}\n\nfunc (_m *Db) EXPECT() *Db_Expecter {\n\treturn &Db_Expecter{mock: &_m.Mock}\n}\n\n// Delete provides a mock function with given fields: key\nfunc (_m *Db) Delete(key []byte) error {\n\tret := _m.Called(key)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for Delete\")\n\t}\n\n\tvar r0 error\n\tif rf, ok := ret.Get(0).(func([]byte) error); ok {\n\t\tr0 = rf(key)\n\t} else {\n\t\tr0 = ret.Error(0)\n\t}\n\n\treturn r0\n}\n\n// Db_Delete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Delete'\ntype Db_Delete_Call struct {\n\t*mock.Call\n}\n\n// Delete is a helper method to define mock.On call\n//   - key []byte\nfunc (_e *Db_Expecter) Delete(key interface{}) *Db_Delete_Call {\n\treturn &Db_Delete_Call{Call: _e.mock.On(\"Delete\", key)}\n}\n\nfunc (_c *Db_Delete_Call) Run(run func(key []byte)) *Db_Delete_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].([]byte))\n\t})\n\treturn _c\n}\n\nfunc (_c *Db_Delete_Call) Return(_a0 error) *Db_Delete_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *Db_Delete_Call) RunAndReturn(run func([]byte) error) *Db_Delete_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// Get provides a mock function with given fields: key\nfunc (_m *Db) Get(key []byte) ([]byte, error) {\n\tret := _m.Called(key)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for Get\")\n\t}\n\n\tvar r0 []byte\n\tvar r1 error\n\tif rf, ok := ret.Get(0).(func([]byte) ([]byte, error)); ok {\n\t\treturn rf(key)\n\t}\n\tif rf, ok := ret.Get(0).(func([]byte) []byte); ok {\n\t\tr0 = rf(key)\n\t} else {\n\t\tif ret.Get(0) != nil {\n\t\t\tr0 = ret.Get(0).([]byte)\n\t\t}\n\t}\n\n\tif rf, ok := ret.Get(1).(func([]byte) error); ok {\n\t\tr1 = rf(key)\n\t} else {\n\t\tr1 = ret.Error(1)\n\t}\n\n\treturn r0, r1\n}\n\n// Db_Get_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Get'\ntype Db_Get_Call struct {\n\t*mock.Call\n}\n\n// Get is a helper method to define mock.On call\n//   - key []byte\nfunc (_e *Db_Expecter) Get(key interface{}) *Db_Get_Call {\n\treturn &Db_Get_Call{Call: _e.mock.On(\"Get\", key)}\n}\n\nfunc (_c *Db_Get_Call) Run(run func(key []byte)) *Db_Get_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].([]byte))\n\t})\n\treturn _c\n}\n\nfunc (_c *Db_Get_Call) Return(_a0 []byte, _a1 error) *Db_Get_Call {\n\t_c.Call.Return(_a0, _a1)\n\treturn _c\n}\n\nfunc (_c *Db_Get_Call) RunAndReturn(run func([]byte) ([]byte, error)) *Db_Get_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// Has provides a mock function with given fields: key\nfunc (_m *Db) Has(key []byte) (bool, error) {\n\tret := _m.Called(key)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for Has\")\n\t}\n\n\tvar r0 bool\n\tvar r1 error\n\tif rf, ok := ret.Get(0).(func([]byte) (bool, error)); ok {\n\t\treturn rf(key)\n\t}\n\tif rf, ok := ret.Get(0).(func([]byte) bool); ok {\n\t\tr0 = rf(key)\n\t} else {\n\t\tr0 = ret.Get(0).(bool)\n\t}\n\n\tif rf, ok := ret.Get(1).(func([]byte) error); ok {\n\t\tr1 = rf(key)\n\t} else {\n\t\tr1 = ret.Error(1)\n\t}\n\n\treturn r0, r1\n}\n\n// Db_Has_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Has'\ntype Db_Has_Call struct {\n\t*mock.Call\n}\n\n// Has is a helper method to define mock.On call\n//   - key []byte\nfunc (_e *Db_Expecter) Has(key interface{}) *Db_Has_Call {\n\treturn &Db_Has_Call{Call: _e.mock.On(\"Has\", key)}\n}\n\nfunc (_c *Db_Has_Call) Run(run func(key []byte)) *Db_Has_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].([]byte))\n\t})\n\treturn _c\n}\n\nfunc (_c *Db_Has_Call) Return(_a0 bool, _a1 error) *Db_Has_Call {\n\t_c.Call.Return(_a0, _a1)\n\treturn _c\n}\n\nfunc (_c *Db_Has_Call) RunAndReturn(run func([]byte) (bool, error)) *Db_Has_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// Set provides a mock function with given fields: key, value\nfunc (_m *Db) Set(key []byte, value []byte) error {\n\tret := _m.Called(key, value)\n\n\tif len(ret) == 0 {\n\t\tpanic(\"no return value specified for Set\")\n\t}\n\n\tvar r0 error\n\tif rf, ok := ret.Get(0).(func([]byte, []byte) error); ok {\n\t\tr0 = rf(key, value)\n\t} else {\n\t\tr0 = ret.Error(0)\n\t}\n\n\treturn r0\n}\n\n// Db_Set_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Set'\ntype Db_Set_Call struct {\n\t*mock.Call\n}\n\n// Set is a helper method to define mock.On call\n//   - key []byte\n//   - value []byte\nfunc (_e *Db_Expecter) Set(key interface{}, value interface{}) *Db_Set_Call {\n\treturn &Db_Set_Call{Call: _e.mock.On(\"Set\", key, value)}\n}\n\nfunc (_c *Db_Set_Call) Run(run func(key []byte, value []byte)) *Db_Set_Call {\n\t_c.Call.Run(func(args mock.Arguments) {\n\t\trun(args[0].([]byte), args[1].([]byte))\n\t})\n\treturn _c\n}\n\nfunc (_c *Db_Set_Call) Return(_a0 error) *Db_Set_Call {\n\t_c.Call.Return(_a0)\n\treturn _c\n}\n\nfunc (_c *Db_Set_Call) RunAndReturn(run func([]byte, []byte) error) *Db_Set_Call {\n\t_c.Call.Return(run)\n\treturn _c\n}\n\n// NewDb creates a new instance of Db. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\n// The first argument is typically a *testing.T value.\nfunc NewDb(t interface {\n\tmock.TestingT\n\tCleanup(func())\n}) *Db {\n\tmock := &Db{}\n\tmock.Mock.Test(t)\n\n\tt.Cleanup(func() { mock.AssertExpectations(t) })\n\n\treturn mock\n}\n"
  },
  {
    "path": "storage/kv_store_service.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage storage\n\nimport (\n\t\"context\"\n\n\t\"cosmossdk.io/core/store\"\n\tstoretypes \"cosmossdk.io/store/types\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n)\n\nvar (\n\t//nolint:gochecknoglobals // storeKey is a singleton.\n\tStoreKey = storetypes.NewKVStoreKey(\"beacon\")\n\n\t_ store.KVStoreService = (*KVStoreService)(nil)\n)\n\ntype KVStoreService struct {\n\tKey *storetypes.KVStoreKey\n}\n\nfunc (k KVStoreService) OpenKVStore(ctx context.Context) store.KVStore {\n\treturn NewKVStore(sdk.UnwrapSDKContext(ctx).KVStore(k.Key))\n}\n\n// CoreKVStore is a wrapper of Core/Store kvstore interface\n// Remove after https://github.com/cosmos/cosmos-sdk/issues/14714 is closed.\ntype coreKVStore struct {\n\tkvStore storetypes.KVStore\n}\n\n// NewKVStore returns a wrapper of Core/Store kvstore interface\n// Remove once store migrates to core/store kvstore interface.\nfunc NewKVStore(store storetypes.KVStore) store.KVStore {\n\treturn coreKVStore{kvStore: store}\n}\n\n// Get returns nil iff key doesn't exist. Errors on nil key.\nfunc (store coreKVStore) Get(key []byte) ([]byte, error) {\n\treturn store.kvStore.Get(key), nil\n}\n\n// Has checks if a key exists. Errors on nil key.\nfunc (store coreKVStore) Has(key []byte) (bool, error) {\n\treturn store.kvStore.Has(key), nil\n}\n\n// Set sets the key. Errors on nil key or value.\nfunc (store coreKVStore) Set(key, value []byte) error {\n\tstore.kvStore.Set(key, value)\n\treturn nil\n}\n\n// Delete deletes the key. Errors on nil key.\nfunc (store coreKVStore) Delete(key []byte) error {\n\tstore.kvStore.Delete(key)\n\treturn nil\n}\n\n// Iterator iterates over a domain of keys in ascending order. End is exclusive.\n// Start must be less than end, or the Iterator is invalid.\n// Iterator must be closed by caller.\n// To iterate over entire domain, use store.Iterator(nil, nil)\n// CONTRACT: No writes may happen within a domain while an iterator exists over\n// it.\n// Exceptionally allowed for cachekv.Store, safe to write in the modules.\nfunc (store coreKVStore) Iterator(start, end []byte) (store.Iterator, error) {\n\treturn store.kvStore.Iterator(start, end), nil\n}\n\n// ReverseIterator iterates over a domain of keys in descending order. End is\n// exclusive.\n// Start must be less than end, or the Iterator is invalid.\n// Iterator must be closed by caller.\n// CONTRACT: No writes may happen within a domain while an iterator exists over\n// it.\n// Exceptionally allowed for cachekv.Store, safe to write in the modules.\nfunc (store coreKVStore) ReverseIterator(\n\tstart, end []byte,\n) (store.Iterator, error) {\n\treturn store.kvStore.ReverseIterator(start, end), nil\n}\n"
  },
  {
    "path": "testing/benchmarks/logger_benchmark_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage benchmarks_test\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n)\n\n/* -------------------------------------------------------------------------- */\n/*                                   Info                                     */\n/* -------------------------------------------------------------------------- */\n\n// Benchmark function for phuslu logger with pretty style.\nfunc BenchmarkPhusluLoggerPrettyInfo(b *testing.B) {\n\tlogger := newPhusluLogger().WithConfig(configWithPretty(\"info\"))\n\tb.ResetTimer()\n\tfor range b.N {\n\t\tlogger.Info(\"This is an info message\", \"key1\", \"value1\", \"key2\", 2)\n\t}\n}\n\n// Benchmark function for phuslu logger with JSON style.\nfunc BenchmarkPhusluLoggerJSONInfo(b *testing.B) {\n\tlogger := newPhusluLogger().WithConfig(configWithJSON(\"info\"))\n\tb.ResetTimer()\n\tfor range b.N {\n\t\tlogger.Info(\"This is an info message\", \"key1\", \"value1\", \"key2\", 2)\n\t}\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   Warn                                     */\n/* -------------------------------------------------------------------------- */\n\n// Benchmark function for phuslu logger Warn.\nfunc BenchmarkPhusluLoggerPrettyWarn(b *testing.B) {\n\tlogger := newPhusluLogger().WithConfig(configWithPretty(\"warn\"))\n\tb.ResetTimer()\n\tfor range b.N {\n\t\tlogger.Warn(\"This is a warning message\", \"key1\", \"value1\", \"key2\", 2)\n\t}\n}\n\n// Benchmark function for phuslu logger with JSON style.\nfunc BenchmarkPhusluLoggerJSONWarn(b *testing.B) {\n\tlogger := newPhusluLogger().WithConfig(configWithJSON(\"warn\"))\n\tb.ResetTimer()\n\tfor range b.N {\n\t\tlogger.Warn(\"This is a warning message\", \"key1\", \"value1\", \"key2\", 2)\n\t}\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   Error                                    */\n/* -------------------------------------------------------------------------- */\n\n// Benchmark function for phuslu logger Error.\nfunc BenchmarkPhusluLoggerPrettyError(b *testing.B) {\n\tlogger := newPhusluLogger().WithConfig(configWithPretty(\"error\"))\n\tb.ResetTimer()\n\tfor range b.N {\n\t\tlogger.Error(\"This is an error message\", \"key1\", \"value1\", \"key2\", 2)\n\t}\n}\n\n// Benchmark function for phuslu logger with JSON style.\nfunc BenchmarkPhusluLoggerJSONError(b *testing.B) {\n\tlogger := newPhusluLogger().WithConfig(configWithJSON(\"error\"))\n\tb.ResetTimer()\n\tfor range b.N {\n\t\tlogger.Error(\"This is an error message\", \"key1\", \"value1\", \"key2\", 2)\n\t}\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   Debug                                    */\n/* -------------------------------------------------------------------------- */\n\n// Benchmark function for phuslu logger Debug.\nfunc BenchmarkPhusluLoggerPrettyDebug(b *testing.B) {\n\tlogger := newPhusluLogger().WithConfig(configWithPretty(\"debug\"))\n\tb.ResetTimer()\n\tfor range b.N {\n\t\tlogger.Debug(\"This is a debug message\", \"key1\", \"value1\", \"key2\", 2)\n\t}\n}\n\n// Benchmark function for phuslu logger with JSON style.\nfunc BenchmarkPhusluLoggerJSONDebug(b *testing.B) {\n\tlogger := newPhusluLogger().WithConfig(configWithJSON(\"debug\"))\n\tb.ResetTimer()\n\tfor range b.N {\n\t\tlogger.Debug(\"This is a debug message\", \"key1\", \"value1\", \"key2\", 2)\n\t}\n}\n\nfunc BenchmarkPhusluLoggerPrettyDebugSilent(b *testing.B) {\n\tlogger := newPhusluLogger().WithConfig(configWithPretty(\"info\"))\n\tb.ResetTimer()\n\tfor range b.N {\n\t\tlogger.Debug(\"This is a debug message\", \"key1\", \"value1\", \"key2\", 2)\n\t}\n}\n\nfunc BenchmarkPhusluLoggerJSONDebugSilent(b *testing.B) {\n\tlogger := newPhusluLogger().WithConfig(configWithJSON(\"info\"))\n\tb.ResetTimer()\n\tfor range b.N {\n\t\tlogger.Debug(\"This is a debug message\", \"key1\", \"value1\", \"key2\", 2)\n\t}\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   With                                     */\n/* -------------------------------------------------------------------------- */\n\n// Benchmark function for phuslu logger With.\nfunc BenchmarkPhusluLoggerPrettyWith(b *testing.B) {\n\tlogger := newPhusluLogger().WithConfig(configWithPretty(\"info\"))\n\tb.ResetTimer()\n\tfor range b.N {\n\t\tnewLogger := logger.With(\"contextKey\", \"contextValue\")\n\t\tnewLogger.Info(\"This is a contextual info message\", \"key1\", \"value1\",\n\t\t\t\"key2\", 2)\n\t}\n}\n\n// Benchmark function for phuslu logger With JSON style.\nfunc BenchmarkPhusluLoggerJSONWith(b *testing.B) {\n\tlogger := newPhusluLogger().WithConfig(configWithJSON(\"info\"))\n\tb.ResetTimer()\n\tfor range b.N {\n\t\tnewLogger := logger.With(\"contextKey\", \"contextValue\")\n\t\tnewLogger.Info(\"This is a contextual info message\", \"key1\", \"value1\",\n\t\t\t\"key2\", 2)\n\t}\n}\n\n/* -------------------------------------------------------------------------- */\n/*                                   Helpers                                  */\n/* -------------------------------------------------------------------------- */\n\n// setup func to create a new phuslu logger with the given log level.\nfunc newPhusluLogger() *phuslu.Logger {\n\tcfg := phuslu.DefaultConfig() // dummy config\n\tl := phuslu.NewLogger(\n\t\t&bytes.Buffer{}, &cfg)\n\treturn l\n}\n\n// setup func to create a phuslu logger config with pretty style.\nfunc configWithPretty(level string) *phuslu.Config {\n\tcfg := phuslu.DefaultConfig()\n\tcfg.LogLevel = level\n\tcfg.Style = phuslu.StylePretty\n\treturn &cfg\n}\n\n// setup func to create a phuslu logger config with JSON style.\nfunc configWithJSON(level string) *phuslu.Config {\n\tcfg := phuslu.DefaultConfig()\n\tcfg.LogLevel = level\n\tcfg.Style = phuslu.StyleJSON\n\treturn &cfg\n}\n"
  },
  {
    "path": "testing/e2e/.gitignore",
    "content": "e2e-logs/"
  },
  {
    "path": "testing/e2e/README.md",
    "content": "# E2E Tests\n\nEnd-to-end tests for BeaconKit using [Kurtosis](https://www.kurtosis.com/), a platform for running distributed systems on Docker. Each test suite spins up a full beacon-kit network inside a Kurtosis enclave, runs tests against it, and tears it down automatically.\n\n## Directory Structure\n\n```\ntesting/e2e/\n  config/          # Network configuration structs and defaults\n    config.go      #   E2ETestConfig, NetworkConfiguration, NodeSet, etc.\n    defaults.go    #   DefaultE2ETestConfig(),\n\n  suite/           # Shared test framework (Kurtosis orchestration, lifecycle)\n    suite.go       #   KurtosisE2ESuite struct and accessors\n    setup.go       #   SetupSuite, TearDownSuite, FundAccounts, WaitForFinalizedBlockNumber\n    options.go     #   Functional options\n    logs.go        #   Log fetching, dumping on failure\n    constants.go   #   Ether, gas limits, timeouts\n    errors.go      #   Shared error variables\n    types/         #   Client wrappers (ConsensusClient, RPCClient, EthAccount, etc.)\n\n  standard/        # Standard e2e test suite (package standard_test)\n    setup_test.go  #   BeaconKitE2ESuite struct + entry point\n    *_test.go      #   One file per feature (blobs, beacon API, staking, ...)\n```\n\n## How It Works\n\n### Suite Lifecycle\n\nEach test suite (`standard/`) defines a struct that embeds `suite.KurtosisE2ESuite` and uses [testify suites](https://pkg.go.dev/github.com/stretchr/testify/suite) for lifecycle management.\n\n1. **SetupSuite** (runs once before all tests in a suite):\n   - Loads configuration from `config/defaults.go` (or applies custom options)\n   - Connects to the local Kurtosis engine\n   - Destroys any leftover `e2e-test-enclave` from a previous run\n   - Creates a fresh Kurtosis enclave named `e2e-test-enclave`\n   - Runs the `kurtosis/` Starlark package to spin up validators, full nodes, seed nodes, and EL clients\n   - Sets up consensus clients and a JSON-RPC connection to the execution layer\n   - Waits for the network to reach a minimum finalized block number\n   - Funds test accounts from the genesis account\n\n2. **Test methods** run against the live network (e.g., `TestBasicStartup`, `Test4844Live`).\n\n3. **TearDownSuite** (runs once after all tests):\n   - If any test failed, dumps all service logs to `e2e-logs/<SuiteName>/` (one `.log` file per service)\n   - Stops all consensus clients\n   - Destroys the Kurtosis enclave\n\n### Enclave = One Suite\n\nEach test suite gets its own Kurtosis enclave. The standard suite uses `DefaultE2ETestConfig()` (5 bera-reth validators. 5 bera-reth full nodes, 1 bera-reth seed node).\n\n### Build Tags\n\nAll e2e test files use `//go:build e2e`. This prevents them from running during `go test ./...`. You must explicitly pass `-tags e2e` (the Makefile targets handle this).\n\n### Log Collection on Failure\n\nWhen any test in a suite fails, `TearDownSuite` automatically calls `DumpAllServiceLogs()`, which fetches up to 100,000 log lines from every service in the enclave and writes them to:\n\n```\ne2e-logs/<TestSuiteName>/<service-name>.log\n```\n\nThis directory is git-ignored. Logs from previous runs are overwritten.\n\n## Prerequisites\n\n- **Docker** running locally\n- **Kurtosis CLI** installed ([instructions](https://docs.kurtosis.com/install)) with the engine started (`kurtosis engine start`)\n- **Go 1.26.2+**\n\n## Running Tests\n\n### With Docker Build (builds `beacond:kurtosis-local` image first)\n\n```bash\nmake test-e2e              # Run ALL e2e tests (standard, sequentially)\nmake test-e2e-standard     # Run only standard suite\nmake test-e2e-4844         # Run only blob tests\nmake test-e2e-deposits     # Run only deposit tests\n```\n\n### Without Docker Build (image must already exist)\n\n```bash\nmake test-e2e-standard-no-build\n```\n\n### Running a Specific Test\n\n```bash\ngo test -timeout 0 -tags e2e,bls12381,test ./testing/e2e/standard/. -v -testify.m TestBasicStartup\n```\n\n## Configuration\n\nNetwork topology is defined in `config/defaults.go`. Key settings:\n\n- **Validators**: 5 nodes (5 bera-reth) by default\n- **Full nodes**: 5 nodes (5 bera-reth) by default\n- **Seed nodes**: 1 node (1 bera-reth) by default\n- **Chain ID**: 80087 (devnet). To modify the chain spec, see `config/spec/devnet.go`.\n- **EL images**: Configured in `defaultExecutionSettings()` (bera-reth)\n- **CL image**: `beacond:kurtosis-local` (built from local source)\n\nTo add a new test suite configuration, create a function in `defaults.go` that returns `*E2ETestConfig` and wire it via a functional option in `suite/options.go`.\n\n## Adding New Tests\n\n1. Pick the appropriate suite directory (`standard/`).\n2. Create a new `*_test.go` file with the `//go:build e2e` tag and the matching package name (`standard_test`).\n3. Add test methods on the suite struct (e.g., `func (s *BeaconKitE2ESuite) TestMyFeature() { ... }`).\n4. Use `s.ExecutionClients()` for EL queries, `s.ConsensusClients()` for CL queries, `s.GenesisAccount()` / `s.TestAccounts()` for funded accounts.\n\n## Debugging\n\n1. Check Kurtosis engine status:\n   ```bash\n   kurtosis engine status\n   kurtosis engine restart\n   ```\n\n2. Inspect a running enclave:\n   ```bash\n   kurtosis enclave inspect e2e-test-enclave\n   ```\n\n3. If tests fail, check `e2e-logs/` for service logs.\n\n4. If the enclave wasn't cleaned up (e.g., test was killed), destroy it manually:\n   ```bash\n   kurtosis enclave rm -f e2e-test-enclave\n   ```\n"
  },
  {
    "path": "testing/e2e/config/config.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//nolint:tagliatelle // starlark uses snek case.\npackage config\n\nimport (\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n)\n\n// E2ETestConfig defines the configuration for end-to-end tests, including any\n// additional services and validators involved.\ntype E2ETestConfig struct {\n\t// NetworkConfiguration specifies the configuration for the network.\n\tNetworkConfiguration NetworkConfiguration `json:\"network_configuration\"`\n\t// NodeSettings specifies the configuration for the nodes in the test.\n\tNodeSettings NodeSettings `json:\"node_settings\"`\n\t// AdditionalServices specifies any extra services that should be included\n\t// in the test environment.\n\tAdditionalServices []AdditionalService `json:\"additional_services\"`\n}\n\ntype NetworkConfiguration struct {\n\t// Validators lists the configurations for each validator in the test.\n\tValidators NodeSet `json:\"validators\"`\n\t// FullNodes specifies the number of full nodes to include in the test.\n\tFullNodes NodeSet `json:\"full_nodes\"`\n\t// SeedNodes specifies the number of seed nodes to include in the test.\n\tSeedNodes NodeSet `json:\"seed_nodes\"`\n}\n\n// NodeSet holds nodes that have a distinct role in the network.\ntype NodeSet struct {\n\t// Type is the type of node set.\n\tType string `json:\"type\"`\n\t// Nodes is a list of nodes in the set.\n\tNodes []Node `json:\"nodes\"`\n}\n\n// Node holds the configuration for a single node in the test,\n// including client images and types.\ntype Node struct {\n\t// ElType denotes the type of execution layer client (e.g., reth).\n\tElType string `json:\"el_type\"`\n\t// Replicas specifies the number of replicas to use for the client.\n\tReplicas int `json:\"replicas\"`\n\t// KZGImpl specifies the KZG implementation to use for the client.\n\tKZGImpl string `json:\"kzg_impl\"`\n}\n\n// NodeSettings holds the configuration for a single node in the test,\n// including client images and types.\ntype NodeSettings struct {\n\t// ConsensusSettings holds the configuration for the consensus layer\n\t// clients.\n\tConsensusSettings ConsensusSettings `json:\"consensus_settings\"`\n\t// ExecutionSettings holds the configuration for the execution layer\n\t// clients.\n\tExecutionSettings ExecutionSettings `json:\"execution_settings\"`\n}\n\n// ExecutionSettings holds the configuration for the execution layer\n// clients.\ntype ExecutionSettings struct {\n\t// Specs holds the node specs for all nodes in the execution layer.\n\tSpecs NodeSpecs `json:\"specs\"`\n\t// Images specifies the images available for the execution layer.\n\tImages map[string]string `json:\"images\"`\n}\n\n// ConsensusSettings holds the configuration for the consensus layer\n// clients.\ntype ConsensusSettings struct {\n\t// Specs holds the node specs for all nodes in the consensus layer.\n\tSpecs NodeSpecs `json:\"specs\"`\n\t// Images specifies the images available for the consensus layer.\n\tImages map[string]string `json:\"images\"`\n\t// Config specifies the config.toml edits for the consensus layer nodes.\n\tConfig ConsensusConfig `json:\"config\"`\n\t// AppConfig specifies the app.toml edits for the consensus layer nodes.\n\tAppConfig AppConfig `json:\"app\"`\n}\n\n// ConsensusConfig holds the configuration for the consensus layer.\ntype ConsensusConfig struct {\n\t// TimeoutPropose specifies the timeout for proposing a block.\n\tTimeoutPropose string `json:\"timeout_propose\"`\n\t// TimeoutPrevote specifies the timeout for prevoting on a block.\n\tTimeoutPrevote string `json:\"timeout_prevote\"`\n\t// TimeoutPrecommit specifies the timeout for precommiting on a block.\n\tTimeoutPrecommit string `json:\"timeout_precommit\"`\n\t// MaxNumInboundPeers specifies the maximum number of inbound peers.\n\tMaxNumInboundPeers int `json:\"max_num_inbound_peers\"`\n\t// MaxNumOutboundPeers specifies the maximum number of outbound peers.\n\tMaxNumOutboundPeers int `json:\"max_num_outbound_peers\"`\n}\n\n// AppConfig holds the configuration for the app layer.\ntype AppConfig struct {\n\t// PayloadTimeout specifies the timeout for the payload.\n\tPayloadTimeout string `json:\"payload_timeout\"`\n}\n\n// NodeSpecs holds the node specs for all nodes in a single layer.\ntype NodeSpecs struct {\n\t// MinCPU specifies the minimum number of CPUs to use for all nodes in the\n\t// layer.\n\tMinCPU int `json:\"min_cpu\"`\n\t// MaxCPU specifies the maximum number of CPUs to use for all nodes in the\n\t// layer.\n\tMaxCPU int `json:\"max_cpu\"`\n\t// MinMemory specifies the minimum amount of memory to use for all nodes in\n\t// the layer.\n\tMinMemory int `json:\"min_memory\"`\n\t// MaxMemory specifies the maximum amount of memory to use for all nodes in\n\t// the layer.\n\tMaxMemory int `json:\"max_memory\"`\n}\n\n// AdditionalService holds the configuration for an additional service\n// to be included in the test.\ntype AdditionalService struct {\n\t// Name specifies the name of the additional service.\n\tName string `json:\"name\"`\n\t// Replicas specifies the number of replicas to use for the service.\n\tReplicas int `json:\"replicas\"`\n}\n\n// MustMarshalJSON marshals the E2ETestConfig to JSON, panicking if an error.\nfunc (c *E2ETestConfig) MustMarshalJSON() string {\n\tjsonBytes, err := json.Marshal(c)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treturn string(jsonBytes)\n}\n"
  },
  {
    "path": "testing/e2e/config/defaults.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage config\n\nimport (\n\t\"fmt\"\n\n\tcometbft \"github.com/berachain/beacon-kit/consensus/cometbft/service\"\n\t\"github.com/berachain/beacon-kit/payload/builder\"\n)\n\nconst (\n\tNumFullNodes  = 5\n\tNumValidators = 5\n\n\tconsensusClientFmt = \"cl-validator-beaconkit-%d\"\n\texecutionClientFmt = \"el-full-reth-%d\"\n)\n\nfunc ValidatorConsensusClientName(i int) string {\n\treturn fmt.Sprintf(consensusClientFmt, i)\n}\n\nfunc FullNodeExecutionClientName(i int) string {\n\treturn fmt.Sprintf(executionClientFmt, i)\n}\n\n// DefaultE2ETestConfig provides a default configuration for end-to-end tests,\n// pre-populating with a standard set of validators and no additional\n// services.\nfunc DefaultE2ETestConfig() *E2ETestConfig {\n\treturn &E2ETestConfig{\n\t\tNetworkConfiguration: defaultNetworkConfiguration(),\n\t\tNodeSettings:         defaultNodeSettings(),\n\t\tAdditionalServices:   defaultAdditionalServices(),\n\t}\n}\n\nfunc defaultNetworkConfiguration() NetworkConfiguration {\n\treturn NetworkConfiguration{\n\t\tValidators: defaultValidators(),\n\t\tFullNodes:  defaultFullNodes(),\n\t\tSeedNodes:  defaultSeedNodes(),\n\t}\n}\n\nfunc defaultValidators() NodeSet {\n\treturn NodeSet{\n\t\tType: \"validator\",\n\t\tNodes: []Node{\n\t\t\t{\n\t\t\t\tElType:   \"reth\",\n\t\t\t\tReplicas: 5, //nolint:mnd // we want 5 replicas here\n\t\t\t\tKZGImpl:  \"crate-crypto/go-kzg-4844\",\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc defaultFullNodes() NodeSet {\n\treturn NodeSet{\n\t\tType: \"full\",\n\t\tNodes: []Node{\n\t\t\t{\n\t\t\t\tElType:   \"reth\",\n\t\t\t\tReplicas: 5, //nolint:mnd // we want 5 replicas here\n\t\t\t\tKZGImpl:  \"crate-crypto/go-kzg-4844\",\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc defaultSeedNodes() NodeSet {\n\treturn NodeSet{\n\t\tType: \"seed\",\n\t\tNodes: []Node{\n\t\t\t{\n\t\t\t\tElType:   \"reth\",\n\t\t\t\tReplicas: 1,\n\t\t\t\tKZGImpl:  \"crate-crypto/go-kzg-4844\",\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc defaultNodeSettings() NodeSettings {\n\treturn NodeSettings{\n\t\tExecutionSettings: defaultExecutionSettings(),\n\t\tConsensusSettings: defaultConsensusSettings(),\n\t}\n}\n\nfunc defaultExecutionSettings() ExecutionSettings {\n\treturn ExecutionSettings{\n\t\tSpecs: NodeSpecs{\n\t\t\tMinCPU:    0,\n\t\t\tMaxCPU:    0,\n\t\t\tMinMemory: 0,\n\t\t\tMaxMemory: 2048, //nolint:mnd // 2 GB\n\t\t},\n\t\tImages: map[string]string{\n\t\t\t\"reth\": \"ghcr.io/berachain/bera-reth:nightly\",\n\t\t},\n\t}\n}\n\nfunc defaultConsensusSettings() ConsensusSettings {\n\tvar (\n\t\tbuilderCfg = builder.DefaultConfig()\n\t\tdefaultCfg = cometbft.DefaultConfig()\n\t\tconsensus  = defaultCfg.Consensus\n\t\tp2p        = defaultCfg.P2P\n\t)\n\n\treturn ConsensusSettings{\n\t\tSpecs: NodeSpecs{\n\t\t\tMinCPU:    0,\n\t\t\tMaxCPU:    2000, //nolint:mnd // 2 vCPUs\n\t\t\tMinMemory: 0,\n\t\t\tMaxMemory: 2048, //nolint:mnd // 2 GB\n\t\t},\n\t\tImages: map[string]string{\n\t\t\t\"beaconkit\": \"beacond:kurtosis-local\",\n\t\t},\n\t\tConfig: ConsensusConfig{\n\t\t\tTimeoutPropose:   consensus.TimeoutPropose.String(),\n\t\t\tTimeoutPrevote:   consensus.TimeoutPrevote.String(),\n\t\t\tTimeoutPrecommit: consensus.TimeoutPrecommit.String(),\n\n\t\t\tMaxNumInboundPeers:  p2p.MaxNumInboundPeers,\n\t\t\tMaxNumOutboundPeers: p2p.MaxNumOutboundPeers,\n\t\t},\n\t\tAppConfig: AppConfig{\n\t\t\tPayloadTimeout: builderCfg.PayloadTimeout.String(),\n\t\t},\n\t}\n}\n\nfunc defaultAdditionalServices() []AdditionalService {\n\treturn []AdditionalService{}\n}\n"
  },
  {
    "path": "testing/e2e/standard/beacon_api_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//go:build e2e\n\npackage standard_test\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\tbeaconapi \"github.com/attestantio/go-eth2-client/api\"\n\tapiv1 \"github.com/attestantio/go-eth2-client/api/v1\"\n\t\"github.com/attestantio/go-eth2-client/spec/phase0\"\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\tbeacontypes \"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/berachain/beacon-kit/testing/e2e/config\"\n\t\"github.com/berachain/beacon-kit/testing/e2e/suite/types\"\n\t\"github.com/ethereum/go-ethereum/common\"\n)\n\nconst localHost = \"localhost\"\n\n// BeaconHTTPClient wraps http.Client with baseURL.\n// This is needed to change the default baseURL of the http.Client.\ntype BeaconHTTPClient struct {\n\t*http.Client\n\tbaseURL string\n}\n\n// Get overrides http.Client.Get to use baseURL\nfunc (c *BeaconHTTPClient) Get(path string) (*http.Response, error) {\n\treturn c.Client.Get(c.baseURL + path)\n}\n\n// initHTTPBeaconTest initializes the http client for the beacon node api.\n// It gets the public ports from the consensus client and creates a http client with the baseURL.\n// This is needed where we want to test the node-api directly as\n// some of the methods are not present in go-eth2-client library.\nfunc (s *BeaconKitE2ESuite) initHTTPBeaconTest() *BeaconHTTPClient {\n\t// Initialize consensus client to get public ports.\n\tports := s.initBeaconTest().GetPublicPorts()\n\n\t// As kurtosis assigns public port randomly, we need to get the port from the consensus client.\n\t// Get node-api port and format it.\n\tportStr := ports[\"node-api\"].String()\n\tportNum := strings.Replace(portStr, \"/0\", \"\", 1)\n\n\thostPort := net.JoinHostPort(localHost, portNum)\n\t// Create client with baseURL\n\treturn &BeaconHTTPClient{\n\t\tClient: &http.Client{\n\t\t\tTimeout: time.Second * 10,\n\t\t},\n\t\tbaseURL: \"http://\" + hostPort,\n\t}\n}\n\n// initBeaconTest initializes the any tests for the beacon node api.\nfunc (s *BeaconKitE2ESuite) initBeaconTest() *types.ConsensusClient {\n\t// Wait for execution block 5.\n\terr := s.WaitForFinalizedBlockNumber(5)\n\ts.Require().NoError(err)\n\n\t// Get the consensus client.\n\tclient := s.ConsensusClients(0)\n\ts.Require().NotNil(client)\n\n\treturn client\n}\n\n// TestBeaconStateRoot tests the beacon node api for beacon state root.\nfunc (s *BeaconKitE2ESuite) TestBeaconStateRoot() {\n\tclient := s.initBeaconTest()\n\n\t// Ensure the state root is not nil.\n\tstateRootResp, err := client.BeaconStateRoot(\n\t\ts.Ctx(),\n\t\t&beaconapi.BeaconStateRootOpts{\n\t\t\tState: utils.StateIDHead,\n\t\t},\n\t)\n\ts.Require().NoError(err)\n\ts.Require().NotEmpty(stateRootResp)\n\ts.Require().False(stateRootResp.Data.IsZero())\n}\n\n// TestBeaconValidatorsWithIndices tests the beacon node api for beacon validators with indices.\nfunc (s *BeaconKitE2ESuite) TestBeaconValidatorsWithIndices() {\n\tclient := s.initBeaconTest()\n\n\tindices := []phase0.ValidatorIndex{0}\n\tvalidatorsResp, err := client.Validators(\n\t\ts.Ctx(),\n\t\t&beaconapi.ValidatorsOpts{\n\t\t\tState:   utils.StateIDHead,\n\t\t\tIndices: indices,\n\t\t},\n\t)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(validatorsResp)\n\n\tvalidatorData := validatorsResp.Data\n\ts.Require().NotNil(validatorData, \"Validator data should not be nil\")\n\ts.Require().\n\t\tLen(validatorData, len(indices), \"Number of validator responses should match number of requested indices\")\n\n\tvalidator := validatorData[0]\n\ts.Require().NotNil(validator, \"Validator should not be nil\")\n\ts.Require().Equal(phase0.ValidatorIndex(0), validator.Index, \"Should be validator index 0\")\n\n\ts.Require().\n\t\tNotEmpty(validator.Validator.PublicKey, \"Validator public key should not be empty\")\n\ts.Require().\n\t\tLen(validator.Validator.PublicKey, 48, \"Validator public key should be 48 bytes long\")\n\n\ts.Require().\n\t\tNotEmpty(validator.Validator.WithdrawalCredentials, \"Withdrawal credentials should not be empty\")\n\ts.Require().\n\t\tLen(validator.Validator.WithdrawalCredentials, 32, \"Withdrawal credentials should be 32 bytes long\")\n\n\ts.Require().\n\t\tTrue(validator.Validator.EffectiveBalance > 0, \"Effective balance should be positive\")\n\ts.Require().\n\t\tTrue(validator.Validator.EffectiveBalance <= 32e9, \"Effective balance should not exceed 32 ETH\")\n\n\ts.Require().\n\t\tFalse(validator.Validator.Slashed, \"Slashed status should not be true\")\n\n\ts.Require().\n\t\tTrue(validator.Validator.ActivationEpoch >= validator.Validator.ActivationEligibilityEpoch,\n\t\t\t\"Activation epoch should be greater than or equal to activation eligibility epoch\")\n\n\ts.Require().\n\t\tTrue(validator.Validator.WithdrawableEpoch >= validator.Validator.ExitEpoch,\n\t\t\t\"Withdrawable epoch should be greater than or equal to exit epoch\")\n\n\ts.Require().\n\t\tNotEmpty(validator.Status, \"Validator status should not be empty\")\n\n\ts.Require().\n\t\tTrue(validator.Balance > 0, \"Validator balance should be positive\")\n\ts.Require().\n\t\tTrue(validator.Balance <= 32e9, \"Validator balance should not exceed 32 ETH\")\n}\n\n// TestValidatorsEmptyIndicesAndStatuses tests that querying validators with empty indices and empty statuses returns all validators.\n// Empty indices and statuses is same as not populating the indices and statuses. Basically, querying by State.\nfunc (s *BeaconKitE2ESuite) TestValidatorsEmptyIndicesAndStatuses() {\n\tclient := s.initBeaconTest()\n\n\t// Query validators with empty indices and empty statuses\n\temptyIndices := []phase0.ValidatorIndex{}\n\temptyStatuses := []apiv1.ValidatorState{}\n\n\tvalidatorsResp, err := client.Validators(\n\t\ts.Ctx(),\n\t\t&beaconapi.ValidatorsOpts{\n\t\t\tState:           utils.StateIDHead,\n\t\t\tIndices:         emptyIndices,\n\t\t\tValidatorStates: emptyStatuses,\n\t\t},\n\t)\n\n\ts.Require().NoError(err)\n\ts.Require().NotNil(validatorsResp)\n\n\t// Verify we got all validators\n\tvalidatorData := validatorsResp.Data\n\ts.Require().NotNil(validatorData, \"Validator data should not be nil\")\n\ts.Require().Equal(config.NumValidators, len(validatorData),\n\t\t\"Should return all validators when using empty statuses and empty indices\")\n\n\t// Verify each validator has required fields\n\tfor _, validator := range validatorData {\n\t\ts.Require().NotNil(validator, \"Validator should not be nil\")\n\t\ts.Require().NotEmpty(validator.Validator.PublicKey, \"Validator public key should not be empty\")\n\t\ts.Require().Len(validator.Validator.PublicKey, 48, \"Validator public key should be 48 bytes long\")\n\t\ts.Require().NotEmpty(validator.Validator.WithdrawalCredentials,\n\t\t\t\"Withdrawal credentials should not be empty\")\n\t\ts.Require().Len(validator.Validator.WithdrawalCredentials, 32,\n\t\t\t\"Withdrawal credentials should be 32 bytes long\")\n\t\ts.Require().True(validator.Validator.EffectiveBalance > 0,\n\t\t\t\"Effective balance should be positive\")\n\t}\n}\n\n// TestValidatorsWithMultipleIndices tests querying multiple specific validator indices.\nfunc (s *BeaconKitE2ESuite) TestValidatorsWithMultipleIndices() {\n\tclient := s.initBeaconTest()\n\tindices := []phase0.ValidatorIndex{0, 1, 2}\n\n\tvalidatorsResp, err := client.Validators(s.Ctx(), &beaconapi.ValidatorsOpts{\n\t\tState:   utils.StateIDHead,\n\t\tIndices: indices,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotNil(validatorsResp)\n\ts.Require().Len(validatorsResp.Data, len(indices))\n}\n\n// TestValidatorsWithInvalidIndex tests querying a non-existent validator index\n// This should return an empty list of validators.\nfunc (s *BeaconKitE2ESuite) TestValidatorsWithInvalidIndex() {\n\tclient := s.initBeaconTest()\n\tindices := []phase0.ValidatorIndex{999999} // Invalid index\n\n\tvalidatorsResp, err := client.Validators(s.Ctx(), &beaconapi.ValidatorsOpts{\n\t\tState:   utils.StateIDHead,\n\t\tIndices: indices,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotNil(validatorsResp)\n\n\t// No validators returned\n\ts.Require().Len(validatorsResp.Data, 0)\n}\n\n// TestValidatorsWithSpecificStatus tests filtering validators by status.\nfunc (s *BeaconKitE2ESuite) TestValidatorsWithSpecificStatus() {\n\tclient := s.initBeaconTest()\n\n\tvalidatorsResp, err := client.Validators(s.Ctx(), &beaconapi.ValidatorsOpts{\n\t\tState:           utils.StateIDHead,\n\t\tValidatorStates: []apiv1.ValidatorState{apiv1.ValidatorStateActiveOngoing},\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotNil(validatorsResp)\n\n\t// Verify all returned validators have the requested status\n\tfor _, validator := range validatorsResp.Data {\n\t\ts.Require().Equal(apiv1.ValidatorStateActiveOngoing, validator.Status)\n\t}\n}\n\n// TestValidatorBalances tests querying validator balances.\nfunc (s *BeaconKitE2ESuite) TestValidatorBalances() {\n\tclient := s.initBeaconTest()\n\n\tbalancesResp, err := client.ValidatorBalances(s.Ctx(), &beaconapi.ValidatorBalancesOpts{\n\t\tState: utils.StateIDHead,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotNil(balancesResp)\n\n\t// Verify the response is not empty\n\ts.Require().NotNil(balancesResp.Data)\n\ts.Require().NotEmpty(balancesResp.Data)\n\n\tbalanceMap := balancesResp.Data\n\tfor _, balance := range balanceMap {\n\t\ts.Require().True(balance > 0, \"Validator balance should be positive\")\n\t\t// 4e12 Gwei = 4 * 10^12 Gwei = 4,000,000,000,000 Gwei = 4000 BERA\n\t\ts.Require().True(balance <= 4e12, \"Validator balance should not exceed 4e12 gwei (4000 BERA)\")\n\t}\n}\n\n// TestValidatorBalancesWithSpecificIndices tests querying validator balances with specific indices.\nfunc (s *BeaconKitE2ESuite) TestValidatorBalancesWithSpecificIndices() {\n\tclient := s.initBeaconTest()\n\n\tindices := []phase0.ValidatorIndex{0}\n\n\tbalancesResp, err := client.ValidatorBalances(s.Ctx(), &beaconapi.ValidatorBalancesOpts{\n\t\tState:   utils.StateIDHead,\n\t\tIndices: indices,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotNil(balancesResp)\n\n\t// Verify the response is not empty\n\ts.Require().NotNil(balancesResp.Data)\n\ts.Require().Len(balancesResp.Data, len(indices))\n\n\t// Verify balance data\n\tfor index, balance := range balancesResp.Data {\n\t\ts.Require().NotNil(balance)\n\t\ts.Require().Contains(indices, index)\n\t\ts.Require().True(balance > 0, \"Validator balance should be positive\")\n\t\t// 4e12 Gwei = 4 * 10^12 Gwei = 4,000,000,000,000 Gwei = 4000 BERA\n\t\ts.Require().True(balance <= 4e12, \"Validator balance should not exceed 4000 BERA\")\n\t}\n}\n\n// TestValidatorBalancesMultipleIndices tests querying balances for multiple validator indices.\nfunc (s *BeaconKitE2ESuite) TestValidatorBalancesMultipleIndices() {\n\tclient := s.initBeaconTest()\n\tindices := []phase0.ValidatorIndex{0, 1, 2}\n\n\tbalancesResp, err := client.ValidatorBalances(\n\t\ts.Ctx(),\n\t\t&beaconapi.ValidatorBalancesOpts{\n\t\t\tState:   utils.StateIDHead,\n\t\t\tIndices: indices,\n\t\t},\n\t)\n\n\ts.Require().NoError(err)\n\ts.Require().NotNil(balancesResp)\n\ts.Require().Len(balancesResp.Data, len(indices))\n\n\t// Verify all requested indices are present\n\treturnedIndices := make(map[phase0.ValidatorIndex]struct{})\n\tfor index, balance := range balancesResp.Data {\n\t\treturnedIndices[index] = struct{}{}\n\t\ts.Require().True(balance > 0)\n\t\t// 4e12 Gwei = 4 * 10^12 Gwei = 4,000,000,000,000 Gwei = 4000 BERA\n\t\ts.Require().True(balance <= 4e12, \"Validator balance should not exceed 4000 BERA\")\n\t}\n\tfor _, idx := range indices {\n\t\t_, exists := returnedIndices[idx]\n\t\ts.Require().True(exists, \"Expected validator index not found in response\")\n\t}\n}\n\n// TestValidatorBalancesWithInvalidIndex tests querying validator balances with an invalid index.\nfunc (s *BeaconKitE2ESuite) TestValidatorBalancesWithInvalidIndex() {\n\tclient := s.initBeaconTest()\n\n\tindices := []phase0.ValidatorIndex{999999} // Invalid index\n\n\tbalancesResp, err := client.ValidatorBalances(s.Ctx(), &beaconapi.ValidatorBalancesOpts{\n\t\tState:   utils.StateIDHead,\n\t\tIndices: indices,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotNil(balancesResp)\n\t// Should return an empty list of balances\n\ts.Require().Len(balancesResp.Data, 0)\n}\n\n// TestValidatorBalancesWithPubkey tests querying validator balances using a public key.\nfunc (s *BeaconKitE2ESuite) TestValidatorBalancesWithPubkey() {\n\tclient := s.initBeaconTest()\n\n\t// First call validators to get the validator public key\n\tvalidatorsResp, err := client.Validators(s.Ctx(), &beaconapi.ValidatorsOpts{\n\t\tState: utils.StateIDHead,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotNil(validatorsResp)\n\n\tvalidator := validatorsResp.Data[0]\n\ts.Require().NotNil(validator)\n\tpubkey := validator.Validator.PublicKey\n\n\tbalancesResp, err := client.ValidatorBalances(s.Ctx(), &beaconapi.ValidatorBalancesOpts{\n\t\tState:   utils.StateIDHead,\n\t\tIndices: []phase0.ValidatorIndex{},\n\t\tPubKeys: []phase0.BLSPubKey{pubkey},\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotNil(balancesResp)\n\ts.Require().Len(balancesResp.Data, 1)\n\n\t// Verify balance data\n\tfor _, balance := range balancesResp.Data {\n\t\ts.Require().NotNil(balance)\n\t\ts.Require().True(balance > 0, \"Validator balance should be positive\")\n\t\t// 4e12 Gwei = 4 * 10^12 Gwei = 4,000,000,000,000 Gwei = 4000 BERA\n\t\ts.Require().True(balance <= 4e12, \"Validator balance should not exceed 4000 BERA\")\n\t}\n}\n\n// TestValidatorBalancesWithInvalidPubkey tests querying validator balances using a public key.\nfunc (s *BeaconKitE2ESuite) TestValidatorBalancesWithInvalidPubkey() {\n\tclient := s.initBeaconTest()\n\n\t// Example validator pubkey (48 bytes with 0x prefix)\n\tnotFoundPubkey := \"0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a\"\n\n\tbalancesResp, err := client.ValidatorBalances(s.Ctx(), &beaconapi.ValidatorBalancesOpts{\n\t\tState:   utils.StateIDHead,\n\t\tIndices: []phase0.ValidatorIndex{},\n\t\tPubKeys: []phase0.BLSPubKey{phase0.BLSPubKey(common.FromHex(notFoundPubkey))},\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotNil(balancesResp)\n\t// Should return an empty list of balances\n\ts.Require().Len(balancesResp.Data, 0)\n}\n\n// Helper functions\n// decodeResponse is a generic function that decodes an HTTP response into the specified type T.\nfunc decodeResponse[T any](resp *http.Response) (T, error) {\n\tvar result T\n\n\tif resp == nil {\n\t\treturn result, errors.New(\"nil response\")\n\t}\n\tdefer resp.Body.Close()\n\n\tbodyBytes, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn result, err\n\t}\n\n\t// First decode into GenericResponse.\n\tvar genericResp beacontypes.GenericResponse\n\tif err = json.Unmarshal(bodyBytes, &genericResp); err != nil {\n\t\treturn result, err\n\t}\n\n\t// Convert the data field to JSON.\n\tdataBytes, err := json.Marshal(genericResp.Data)\n\tif err != nil {\n\t\treturn result, err\n\t}\n\n\t// Unmarshal into the target type.\n\tif err = json.Unmarshal(dataBytes, &result); err != nil {\n\t\treturn result, err\n\t}\n\n\treturn result, nil\n}\n\n// decodeValidatorResponse decodes a single validator response.\nfunc (s *BeaconKitE2ESuite) decodeValidatorResponse(resp *http.Response) (*beacontypes.ValidatorData, error) {\n\tvalidator, err := decodeResponse[beacontypes.ValidatorData](resp)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &validator, nil\n}\n\n// getStateValidator gets the state validator by index or pubkey.\nfunc (s *BeaconKitE2ESuite) getStateValidator(stateID, validatorID string) (*http.Response, error) {\n\tclient := s.initHTTPBeaconTest()\n\n\tresp, err := client.Get(fmt.Sprintf(\"/eth/v1/beacon/states/%s/validators/%s\", stateID, validatorID))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get validator: %w\", err)\n\t}\n\tif resp == nil {\n\t\treturn nil, errors.New(\"received nil response\")\n\t}\n\n\treturn resp, nil\n}\n\n// TestGetStateValidatorByIndex tests getting the state validator by index.\nfunc (s *BeaconKitE2ESuite) TestGetStateValidatorByIndex() {\n\tresp, err := s.getStateValidator(utils.StateIDHead, \"0\")\n\ts.Require().NoError(err)\n\ts.Require().NotNil(resp, \"response should not be nil\")\n\ts.Require().Equal(http.StatusOK, resp.StatusCode)\n\tdefer resp.Body.Close()\n\n\tvalidatorResp, err := s.decodeValidatorResponse(resp)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(validatorResp, \"validator response should not be nil\")\n\n\ts.Require().Equal(uint64(0), validatorResp.Index)\n\ts.Require().Equal(\"active_ongoing\", validatorResp.Status)\n}\n\n// TestGetStateValidatorBySlotAndIndex tests getting the state validator by slot and index.\nfunc (s *BeaconKitE2ESuite) TestGetStateValidatorBySlotAndIndex() {\n\t// Here the stateID is a slot number which is 10.\n\tresp, err := s.getStateValidator(\"10\", \"0\")\n\ts.Require().NoError(err)\n\ts.Require().NotNil(resp, \"response should not be nil\")\n\ts.Require().Equal(http.StatusOK, resp.StatusCode)\n\tdefer resp.Body.Close()\n\n\tvalidatorResp, err := s.decodeValidatorResponse(resp)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(validatorResp, \"validator response should not be nil\")\n\n\ts.Require().Equal(uint64(0), validatorResp.Index)\n\ts.Require().Equal(\"active_ongoing\", validatorResp.Status)\n}\n\n// TestGetStateValidatorByPubkey tests getting the state validator by pubkey.\nfunc (s *BeaconKitE2ESuite) TestGetStateValidatorByPubkey() {\n\t// First call validators to get the validator public key\n\tresp, err := s.getStateValidator(utils.StateIDHead, \"0\")\n\ts.Require().NoError(err)\n\ts.Require().NotNil(resp, \"response should not be nil\")\n\ts.Require().Equal(http.StatusOK, resp.StatusCode)\n\tdefer resp.Body.Close()\n\n\tvalidatorResp, err := s.decodeValidatorResponse(resp)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(validatorResp, \"validator response should not be nil\")\n\n\t// Retrieve the public key.\n\tpubkey := validatorResp.Validator.PublicKey\n\n\t// Actual test starts here.\n\tresp, err = s.getStateValidator(utils.StateIDHead, pubkey)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(resp, \"response should not be nil\")\n\ts.Require().Equal(http.StatusOK, resp.StatusCode)\n\tdefer resp.Body.Close()\n\n\tvalidatorResp, errInDecode := s.decodeValidatorResponse(resp)\n\ts.Require().NoError(errInDecode)\n\ts.Require().NotNil(validatorResp, \"validator response should not be nil\")\n\n\ts.Require().Equal(\"active_ongoing\", validatorResp.Status)\n}\n\n// TestGetStateValidatorInvalidID tests getting the state validator with an invalid id.\nfunc (s *BeaconKitE2ESuite) TestGetStateValidatorInvalidID() {\n\tresp, err := s.getStateValidator(utils.StateIDHead, \"invalid_id\")\n\ts.Require().NoError(err)\n\ts.Require().NotNil(resp, \"response should not be nil\")\n\ts.Require().Equal(http.StatusBadRequest, resp.StatusCode)\n\tdefer resp.Body.Close()\n}\n\n// getValidatorBalances gets the validator balances for the given stateID and optional ids.\nfunc (s *BeaconKitE2ESuite) getValidatorBalances(stateID string, ids ...string) (*http.Response, error) {\n\tclient := s.initHTTPBeaconTest()\n\n\turl := fmt.Sprintf(\"/eth/v1/beacon/states/%s/validator_balances\", stateID)\n\n\t// Add ID parameters if provided\n\tif len(ids) > 0 {\n\t\tqueryParams := make([]string, 0, len(ids))\n\t\tfor _, id := range ids {\n\t\t\tqueryParams = append(queryParams, \"id=\"+id)\n\t\t}\n\t\turl = url + \"?\" + strings.Join(queryParams, \"&\")\n\t}\n\n\tresp, err := client.Get(url)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get validator balances: %w\", err)\n\t}\n\tif resp == nil {\n\t\treturn nil, errors.New(\"received nil response\")\n\t}\n\n\treturn resp, nil\n}\n\n// decodeValidatorBalancesResponse decodes a response containing validator balances.\nfunc (s *BeaconKitE2ESuite) decodeValidatorBalancesResponse(resp *http.Response) (*[]beacontypes.ValidatorBalanceData, error) {\n\tbalances, err := decodeResponse[[]beacontypes.ValidatorBalanceData](resp)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &balances, nil\n}\n\n// TestGetValidatorBalances tests querying validator balances for state head.\nfunc (s *BeaconKitE2ESuite) TestGetValidatorBalances() {\n\tresp, err := s.getValidatorBalances(utils.StateIDHead)\n\ts.Require().NoError(err)\n\ts.Require().Equal(http.StatusOK, resp.StatusCode)\n\tdefer resp.Body.Close()\n\n\tbalancesResp, err := s.decodeValidatorBalancesResponse(resp)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(balancesResp, \"balances response should not be nil\")\n\ts.Require().NotEmpty(balancesResp, \"balances response should not be empty\")\n\n\tfor _, balance := range *balancesResp {\n\t\ts.Require().True(balance.Balance > 0, \"Validator balance should be positive\")\n\t\t// 4e12 Gwei = 4 * 10^12 Gwei = 4,000,000,000,000 Gwei = 4000 BERA\n\t\ts.Require().True(balance.Balance <= 4e12, \"Validator balance should not exceed 4000 BERA\")\n\t}\n}\n\n// TestGetValidatorBalancesWithSpecificID tests querying validator balances with specific ID.\nfunc (s *BeaconKitE2ESuite) TestGetValidatorBalancesWithSpecificID() {\n\tresp, err := s.getValidatorBalances(utils.StateIDHead, \"0\")\n\ts.Require().NoError(err)\n\ts.Require().Equal(http.StatusOK, resp.StatusCode)\n\tdefer resp.Body.Close()\n\n\tbalancesResp, err := s.decodeValidatorBalancesResponse(resp)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(balancesResp, \"balances response should not be nil\")\n\n\ts.Require().Len(*balancesResp, 1)\n\ts.Require().True((*balancesResp)[0].Balance > 0, \"Validator balance should be positive\")\n\t// 4e12 Gwei = 4 * 10^12 Gwei = 4,000,000,000,000 Gwei = 4000 BERA\n\ts.Require().True((*balancesResp)[0].Balance <= 4e12, \"Validator balance should not exceed 4000 BERA\")\n}\n\n// TestGetValidatorBalancesWithMultipleIDs tests querying validator balances with multiple IDs.\nfunc (s *BeaconKitE2ESuite) TestGetValidatorBalancesWithMultipleIDs() {\n\tresp, err := s.getValidatorBalances(utils.StateIDHead, \"0\", \"1\")\n\ts.Require().NoError(err)\n\ts.Require().Equal(http.StatusOK, resp.StatusCode)\n\tdefer resp.Body.Close()\n\n\tbalancesResp, err := s.decodeValidatorBalancesResponse(resp)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(balancesResp, \"balances response should not be nil\")\n\ts.Require().NotEmpty(balancesResp, \"balances response should not be empty\")\n\n\t// The response should contain 2 validator balances.\n\ts.Require().Len(*balancesResp, 2)\n\n\tfor _, balance := range *balancesResp {\n\t\ts.Require().True(balance.Balance > 0, \"Validator balance should be positive\")\n\t\t// 4e12 Gwei = 4 * 10^12 Gwei = 4,000,000,000,000 Gwei = 4000 BERA\n\t\ts.Require().True(balance.Balance <= 4e12, \"Validator balance should not exceed 4000 BERA\")\n\t}\n}\n\n// TestGetValidatorBalancesWithInvalidID tests querying validator balances with invalid ID.\nfunc (s *BeaconKitE2ESuite) TestGetValidatorBalancesWithInvalidID() {\n\tresp, err := s.getValidatorBalances(utils.StateIDHead, \"invalid_id\")\n\ts.Require().NoError(err)\n\ts.Require().Equal(http.StatusBadRequest, resp.StatusCode)\n\tdefer resp.Body.Close()\n\n\tbalancesResp, err := s.decodeValidatorBalancesResponse(resp)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(balancesResp, \"balances response should not be nil\")\n\ts.Require().Len(*balancesResp, 0)\n}\n\n// TestGetValidatorBalancesWithNonExistentIndex tests querying validator balances with non-existent index.\nfunc (s *BeaconKitE2ESuite) TestGetValidatorBalancesWithNonExistentIndex() {\n\tresp, err := s.getValidatorBalances(utils.StateIDHead, \"99999\")\n\ts.Require().NoError(err)\n\t// If an index does not match any validator, no balance will be returned but this will not cause an error.\n\t// The response should be 200 OK with empty data.\n\ts.Require().Equal(http.StatusOK, resp.StatusCode)\n\tdefer resp.Body.Close()\n\n\tbalancesResp, err := s.decodeValidatorBalancesResponse(resp)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(balancesResp, \"balances response should not be nil\")\n\ts.Require().Len(*balancesResp, 0)\n}\n\n// TestGetValidatorBalancesWithPublicKey tests querying validator balances with public key.\nfunc (s *BeaconKitE2ESuite) TestGetValidatorBalancesWithPublicKey() {\n\tclient := s.initBeaconTest()\n\n\t// First call validators to get the validator public key\n\tvalidatorsResp, err := client.Validators(s.Ctx(), &beaconapi.ValidatorsOpts{\n\t\tState: utils.StateIDHead,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotNil(validatorsResp)\n\n\tvalidator := validatorsResp.Data[0]\n\ts.Require().NotNil(validator)\n\tpubkey := validator.Validator.PublicKey\n\n\tresp, err := s.getValidatorBalances(utils.StateIDHead, pubkey.String())\n\ts.Require().NoError(err)\n\ts.Require().Equal(http.StatusOK, resp.StatusCode)\n\tdefer resp.Body.Close()\n\n\tbalancesResp, err := s.decodeValidatorBalancesResponse(resp)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(balancesResp, \"balances response should not be nil\")\n\ts.Require().NotEmpty(balancesResp, \"balances response should not be empty\")\n\n\ts.Require().Len(*balancesResp, 1)\n\ts.Require().True((*balancesResp)[0].Balance > 0, \"Validator balance should be positive\")\n\t// 4e12 Gwei = 4 * 10^12 Gwei = 4,000,000,000,000 Gwei = 4000 BERA\n\ts.Require().True((*balancesResp)[0].Balance <= 4e12, \"Validator balance should not exceed 4000 BERA\")\n}\n\n// TestGetValidatorBalancesWithInvalidPublicKey tests querying validator balances with invalid public key.\nfunc (s *BeaconKitE2ESuite) TestGetValidatorBalancesWithInvalidPublicKey() {\n\t// Example validator pubkey (48 bytes with 0x prefix)\n\tnotFoundPubkey := \"0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a\"\n\n\tresp, err := s.getValidatorBalances(utils.StateIDHead, notFoundPubkey)\n\ts.Require().NoError(err)\n\t// If public key does not match any validator, no balance will be returned but this will not cause an error.\n\t// The response should be 200 OK with empty data.\n\ts.Require().Equal(http.StatusOK, resp.StatusCode)\n\tdefer resp.Body.Close()\n\n\tbalancesResp, err := s.decodeValidatorBalancesResponse(resp)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(balancesResp, \"balances response should not be nil\")\n\ts.Require().Len(*balancesResp, 0)\n}\n\n// TestGetValidatorBalancesForGenesis tests querying validator balances for state genesis.\nfunc (s *BeaconKitE2ESuite) TestGetValidatorBalancesForGenesis() {\n\tresp, err := s.getValidatorBalances(utils.StateIDGenesis)\n\ts.Require().NoError(err)\n\ts.Require().Equal(http.StatusOK, resp.StatusCode)\n\tdefer resp.Body.Close()\n\n\tbalancesResp, err := s.decodeValidatorBalancesResponse(resp)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(balancesResp, \"balances response should not be nil\")\n\ts.Require().NotEmpty(balancesResp, \"balances response should not be empty\")\n\n\tfor _, balance := range *balancesResp {\n\t\ts.Require().True(balance.Balance > 0, \"Validator balance should be positive\")\n\t\t// At genesis, the validator balance is 32 BERA.\n\t\t// 32e9 Gwei = 32 * 10^9 Gwei = 32,000,000,000 Gwei = 32 BERA\n\t\ts.Require().True(balance.Balance <= 32e9, \"Validator balance should not exceed 32 BERA\")\n\t}\n}\n\n// getValidator gets the validator with the given stateID and optional options.\nfunc (s *BeaconKitE2ESuite) getValidator(stateID string, options ...map[string]string) (*http.Response, error) {\n\tclient := s.initHTTPBeaconTest()\n\n\turl := fmt.Sprintf(\"/eth/v1/beacon/states/%s/validators\", stateID)\n\n\t// Process options if provided\n\tif len(options) > 0 {\n\t\tqueryParams := []string{}\n\n\t\t// Extract options from the map\n\t\tfor _, opts := range options {\n\t\t\tfor key, value := range opts {\n\t\t\t\tqueryParams = append(queryParams, fmt.Sprintf(\"%s=%s\", key, value))\n\t\t\t}\n\t\t}\n\n\t\t// Add query parameters to URL if any exist\n\t\tif len(queryParams) > 0 {\n\t\t\turl = url + \"?\" + strings.Join(queryParams, \"&\")\n\t\t}\n\t}\n\n\tresp, err := client.Get(url)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get validator: %w\", err)\n\t}\n\tif resp == nil {\n\t\treturn nil, errors.New(\"received nil response\")\n\t}\n\treturn resp, nil\n}\n\n// decodeValidatorsResponse decodes a response containing multiple validators.\nfunc (s *BeaconKitE2ESuite) decodeValidatorsResponse(resp *http.Response) (*[]beacontypes.ValidatorData, error) {\n\tvalidators, err := decodeResponse[[]beacontypes.ValidatorData](resp)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &validators, nil\n}\n\n// TestGetValidatorsWithStateHead tests querying validators with state head.\nfunc (s *BeaconKitE2ESuite) TestGetValidatorsWithStateHead() {\n\tresp, err := s.getValidator(utils.StateIDHead)\n\ts.Require().NoError(err)\n\ts.Require().Equal(http.StatusOK, resp.StatusCode)\n\tdefer resp.Body.Close()\n\n\tvalidators, err := s.decodeValidatorsResponse(resp)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(validators)\n\n\tfor _, validator := range *validators {\n\t\ts.Require().True(validator.Status == \"active_ongoing\")\n\t\ts.Require().True(validator.Balance > 0, \"Validator balance should be positive\")\n\t\t// 4e12 Gwei = 4 * 10^12 Gwei = 4,000,000,000,000 Gwei = 4000 BERA\n\t\ts.Require().True(validator.Balance <= 4e12, \"Validator balance should not exceed 4000 BERA\")\n\t}\n}\n\n// TestGetValidatorsWithID tests querying validators with ID parameter.\nfunc (s *BeaconKitE2ESuite) TestGetValidatorsWithID() {\n\tresp, err := s.getValidator(utils.StateIDHead, map[string]string{\n\t\t\"id\": \"0\",\n\t})\n\ts.Require().NoError(err)\n\ts.Require().Equal(http.StatusOK, resp.StatusCode)\n\tdefer resp.Body.Close()\n\n\tvalidators, err := s.decodeValidatorsResponse(resp)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(validators)\n\ts.Require().Len(*validators, 1)\n\ts.Require().Equal(uint64(0), (*validators)[0].Index, \"Validator index should be 0\")\n\ts.Require().Equal(\"active_ongoing\", (*validators)[0].Status, \"Validator status should be active_ongoing\")\n\ts.Require().True((*validators)[0].Balance > 0, \"Validator balance should be positive\")\n\t// 4e12 Gwei = 4 * 10^12 Gwei = 4,000,000,000,000 Gwei = 4000 BERA\n\ts.Require().True((*validators)[0].Balance <= 4e12, \"Validator balance should not exceed 4000 BERA\")\n}\n\n// TestGetValidatorsWithStatus tests querying validators with status parameter.\nfunc (s *BeaconKitE2ESuite) TestGetValidatorsWithStatus() {\n\tresp, err := s.getValidator(utils.StateIDHead, map[string]string{\n\t\t\"status\": \"active_ongoing\",\n\t})\n\ts.Require().NoError(err)\n\ts.Require().Equal(http.StatusOK, resp.StatusCode)\n\tdefer resp.Body.Close()\n\n\tvalidators, err := s.decodeValidatorsResponse(resp)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(validators)\n\n\tfor _, validator := range *validators {\n\t\ts.Require().Equal(\"active_ongoing\", validator.Status, \"Validator status should be active_ongoing\")\n\t\ts.Require().True(validator.Balance > 0, \"Validator balance should be positive\")\n\t\t// 4e12 Gwei = 4 * 10^12 Gwei = 4,000,000,000,000 Gwei = 4000 BERA\n\t\ts.Require().True(validator.Balance <= 4e12, \"Validator balance should not exceed 4000 BERA\")\n\t}\n}\n\n// TestGetValidatorsWithIDAndStatus tests querying validators with both ID and status parameters.\nfunc (s *BeaconKitE2ESuite) TestGetValidatorsWithIDAndStatus() {\n\t// Call with both ID and status\n\tresp, err := s.getValidator(utils.StateIDHead, map[string]string{\n\t\t\"id\":     \"0\",\n\t\t\"status\": \"active_ongoing\",\n\t})\n\ts.Require().NoError(err)\n\ts.Require().Equal(http.StatusOK, resp.StatusCode)\n\tdefer resp.Body.Close()\n\n\t// Decode and verify response\n\tvalidators, err := s.decodeValidatorsResponse(resp)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(validators)\n\n\ts.Require().Len(*validators, 1)\n\t// Verify the validator has the expected ID and status\n\ts.Require().Equal(uint64(0), (*validators)[0].Index, \"Validator index should be 0\")\n\ts.Require().Equal(\"active_ongoing\", (*validators)[0].Status, \"Validator status should be active_ongoing\")\n\ts.Require().True((*validators)[0].Balance > 0, \"Validator balance should be positive\")\n\t// 4e12 Gwei = 4 * 10^12 Gwei = 4,000,000,000,000 Gwei = 4000 BERA\n\ts.Require().True((*validators)[0].Balance <= 4e12, \"Validator balance should not exceed 4000 BERA\")\n}\n\n// TestGetValidatorsWithStateGenesis tests querying validators with state genesis.\nfunc (s *BeaconKitE2ESuite) TestGetValidatorsWithStateGenesis() {\n\tresp, err := s.getValidator(utils.StateIDGenesis)\n\ts.Require().NoError(err)\n\ts.Require().Equal(http.StatusOK, resp.StatusCode)\n\tdefer resp.Body.Close()\n\n\tvalidators, err := s.decodeValidatorsResponse(resp)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(validators)\n\n\tfor _, validator := range *validators {\n\t\ts.Require().True(validator.Status == \"active_ongoing\")\n\t\ts.Require().True(validator.Balance > 0, \"Validator balance should be positive\")\n\t\t// 32e9 Gwei = 32 * 10^9 Gwei = 32,000,000,000 Gwei = 32 BERA\n\t\ts.Require().True(validator.Balance <= 32e9, \"Validator balance should not exceed 32 BERA\")\n\t}\n}\n\n// TestGenesis tests querying the genesis of the beacon node.\nfunc (s *BeaconKitE2ESuite) TestGenesis() {\n\tclient := s.initBeaconTest()\n\n\tgenesisResp, err := client.Genesis(s.Ctx(), &beaconapi.GenesisOpts{})\n\ts.Require().NoError(err)\n\ts.Require().NotNil(genesisResp)\n\ts.Require().NotEmpty(genesisResp.Data)\n\n\tgenesis := genesisResp.Data\n\n\ts.Require().NotZero(genesis.GenesisTime, \"Genesis time should not be zero\")\n\ts.Require().True(genesis.GenesisTime.Unix() < time.Now().Unix(), \"Genesis time should be in the past\")\n\n\ts.Require().NotEmpty(genesis.GenesisValidatorsRoot, \"Genesis validators root should not be empty\")\n\ts.Require().NotEmpty(genesis.GenesisForkVersion, \"Genesis fork version should not be empty\")\n\n\texpectedVersion := version.Fulu() // TODO: change this back to Deneb once devnet spec is updated.\n\ts.Require().Equal(\n\t\texpectedVersion[:],\n\t\tgenesis.GenesisForkVersion[:],\n\t\t\"Genesis fork version does not match expected value\",\n\t)\n}\n\n// TestConfigSpec tests querying the config spec.\nfunc (s *BeaconKitE2ESuite) TestConfigSpec() {\n\tclient := s.initBeaconTest()\n\n\tresp, err := client.Spec(s.Ctx(), &beaconapi.SpecOpts{})\n\ts.Require().NoError(err)\n\ts.Require().NotNil(resp)\n\n\tspecData := resp.Data\n\ts.Require().NotNil(specData)\n\n\t// TODO: make test use configurable chain spec.\n\tchainspec, err := spec.DevnetChainSpec()\n\ts.Require().NoError(err)\n\n\t// Verify essential config parameters exist and have expected types\n\ts.Require().Contains(specData, \"DEPOSIT_CONTRACT_ADDRESS\")\n\taddressBytes, ok := specData[\"DEPOSIT_CONTRACT_ADDRESS\"].([]byte)\n\ts.Require().True(ok, \"DEPOSIT_CONTRACT_ADDRESS should be a byte array\")\n\tvar executionAddress common.Address\n\tcopy(executionAddress[:], addressBytes)\n\n\t// Convert chainspec's ExecutionAddress to common.Address\n\tdepositAddr := common.Address(chainspec.DepositContractAddress())\n\ts.Require().Equal(depositAddr, executionAddress)\n\n\ts.Require().Contains(specData, \"DEPOSIT_NETWORK_ID\")\n\ts.Require().Equal(chainspec.DepositEth1ChainID(), specData[\"DEPOSIT_NETWORK_ID\"])\n\n\ts.Require().Contains(specData, \"DOMAIN_AGGREGATE_AND_PROOF\")\n\ts.Require().EqualValues(chainspec.DomainTypeAggregateAndProof(), specData[\"DOMAIN_AGGREGATE_AND_PROOF\"])\n\n\t// Check penalty quotients\n\ts.Require().Contains(specData, \"INACTIVITY_PENALTY_QUOTIENT\")\n\ts.Require().Zero(specData[\"INACTIVITY_PENALTY_QUOTIENT\"])\n\n\ts.Require().Contains(specData, \"INACTIVITY_PENALTY_QUOTIENT_ALTAIR\")\n\ts.Require().Zero(specData[\"INACTIVITY_PENALTY_QUOTIENT_ALTAIR\"])\n}\n"
  },
  {
    "path": "testing/e2e/standard/blob_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//go:build e2e\n\npackage standard_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/binary\"\n\t\"math/big\"\n\t\"sync\"\n\n\t\"github.com/attestantio/go-eth2-client/api\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/berachain/beacon-kit/testing/e2e/suite\"\n\t\"github.com/berachain/beacon-kit/testing/e2e/suite/types/tx\"\n\t\"github.com/ethereum/go-ethereum/accounts/abi/bind\"\n\t\"github.com/ethereum/go-ethereum/core/txpool\"\n\tcoretypes \"github.com/ethereum/go-ethereum/core/types\"\n)\n\nconst (\n\t// NumBlobsLoad is the number of blob-carrying transactions to submit in\n\t// the Test4844Live test. Cannot pool more than 16 txs currently.\n\tNumBlobsLoad uint64 = 16\n\n\t// BlocksToWait4844 is the number of blocks to wait for the nodes to catch up.\n\tBlocksToWait4844 = 5\n)\n\n// Test4844Live tests sending a large number of blob carrying txs over the\n// network.\nfunc (s *BeaconKitE2ESuite) Test4844Live() {\n\tctx, cancel := context.WithTimeout(s.Ctx(), suite.DefaultE2ETestTimeout)\n\tdefer cancel()\n\n\t// Connect the consensus client node-api\n\tclient0 := s.ConsensusClients(0)\n\ts.Require().NotNil(client0)\n\n\t// Grab values to plug into txs\n\telClient := s.ExecutionClients(0)\n\ts.Require().NotNil(elClient)\n\tsender := s.TestAccounts()[0]\n\tchainID, err := elClient.ChainID(ctx)\n\ts.Require().NoError(err)\n\tblkNum, err := elClient.BlockNumber(ctx)\n\ts.Require().NoError(err)\n\ttip, err := elClient.SuggestGasTipCap(ctx)\n\ts.Require().NoError(err)\n\tgasFee, err := elClient.SuggestGasPrice(ctx)\n\ts.Require().NoError(err)\n\tnonce, err := elClient.NonceAt(ctx, sender.Address(), new(big.Int).SetUint64(blkNum))\n\ts.Require().NoError(err)\n\n\t// Craft and send each blob-carrying transaction.\n\tblobTxs := make([]*coretypes.Transaction, 0, NumBlobsLoad)\n\tfor i := range NumBlobsLoad {\n\t\tblobData := make([]byte, 8)\n\n\t\t// For the first 5 transactions, submit duplicate blobs in separate\n\t\t// transactions by leaving blobData empty. This is allowed by the\n\t\t// protocol.\n\t\tif i >= 5 {\n\t\t\tbinary.LittleEndian.PutUint64(blobData, nonce+i)\n\t\t}\n\n\t\t// Craft the blob-carrying transaction.\n\t\tblobTx := tx.New4844Tx(\n\t\t\tnonce+i, nil, 1000000,\n\t\t\tchainID, tip, gasFee, big.NewInt(0),\n\t\t\t[]byte{0x01, 0x02, 0x03, 0x04},\n\t\t\tbig.NewInt(1), blobData,\n\t\t\tcoretypes.AccessList{},\n\t\t)\n\n\t\t// Sign and submit the transaction.\n\t\tblobTx, err = sender.SignTx(chainID, blobTx)\n\t\ts.Require().NoError(err)\n\t\ts.Logger().Info(\"submitting blob transaction\", \"blobTx\", blobTx.Hash().Hex())\n\t\tblobTxs = append(blobTxs, blobTx)\n\n\t\terr = elClient.SendTransaction(ctx, blobTx)\n\t\t// TODO: Figure out what is causing this to happen.\n\t\t// Also, `errors.Is(err, txpool.ErrAlreadyKnown)` doesn't catch it.\n\t\tif err != nil && err.Error() == txpool.ErrAlreadyKnown.Error() {\n\t\t\tcontinue\n\t\t}\n\t\ts.Require().NoError(err)\n\t}\n\n\t// All node-api calls and verification are asynchronous. node-api should\n\t// be able to handle async calls.\n\tvar wg sync.WaitGroup\n\tfor _, blobTx := range blobTxs {\n\t\twg.Add(1)\n\t\tgo func(blobTx *coretypes.Transaction) {\n\t\t\tdefer wg.Done()\n\n\t\t\t// Wait for the blob transaction to be mined before making request.\n\t\t\ts.Logger().\n\t\t\t\tInfo(\"waiting for blob transaction to be mined\", \"blobTx\", blobTx.Hash().Hex())\n\t\t\treceipt, errWait := bind.WaitMined(ctx, elClient, blobTx)\n\t\t\ts.Require().NoError(errWait)\n\t\t\ts.Require().Equal(coretypes.ReceiptStatusSuccessful, receipt.Status)\n\n\t\t\t// WaitMined only waits until the tx is included in a block. This\n\t\t\t// gets triggered whenever beacon-kit sends a FCU including the\n\t\t\t// block. In the optimistic builder, this happens before the block\n\t\t\t// is finalized. Meaning the data has not yet been stored. Let's\n\t\t\t// just wait 1 block.\n\t\t\t//\n\t\t\t//nolint:contextcheck // uses the service context.\n\t\t\ts.Require().NoError(s.WaitForNBlockNumbers(1))\n\n\t\t\t// Fetch blobs from node-api.\n\t\t\tresponse, errAPI := client0.BlobSidecars(ctx, &api.BlobSidecarsOpts{Block: receipt.BlockNumber.String()})\n\t\t\ts.Require().NoError(errAPI, \"unable to fetch blob sidecars from node-api\")\n\n\t\t\t// Verify blob data from each transaction is published by the node-api.\n\t\t\tsidecar := blobTx.BlobTxSidecar()\n\t\t\tfor i, commitment := range sidecar.Commitments {\n\t\t\t\tverified := false\n\t\t\t\tfor _, blob := range response.Data {\n\t\t\t\t\tif bytes.Equal(blob.KZGCommitment[:], commitment[:]) {\n\t\t\t\t\t\ts.Require().Equal(sidecar.Blobs[i][:], blob.Blob[:], \"blob data not equal\")\n\t\t\t\t\t\tverified = true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ts.Require().True(verified, \"blob data was not made available by node-api\")\n\t\t\t\ts.Logger().Info(\"verified blob data availability\", \"KzgCommitment\", hex.EncodeBytes(commitment[:]))\n\t\t\t}\n\t\t}(blobTx)\n\t}\n\n\t// Wait for DA validation to finish\n\twg.Wait()\n\n\t// Ensure Blob Tx doesn't cause liveliness issues.\n\terr = s.WaitForNBlockNumbers(BlocksToWait4844)\n\ts.Require().NoError(err)\n}\n"
  },
  {
    "path": "testing/e2e/standard/comet_api_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//go:build e2e\n\npackage standard_test\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"sync\"\n\n\tsdkcollections \"cosmossdk.io/collections\"\n\t\"github.com/berachain/beacon-kit/storage/beacondb/keys\"\n\t\"github.com/berachain/beacon-kit/testing/e2e/config\"\n\trpcclient \"github.com/cometbft/cometbft/rpc/client\"\n\tics23 \"github.com/cosmos/ics23/go\"\n)\n\n// TestABCIInfo compares the ABCI info response among all nodes and cross-checks with the EL.\nfunc (s *BeaconKitE2ESuite) TestABCIInfo() {\n\t// Wait for execution block 5 to ensure nodes have progressed.\n\ts.Require().NoError(s.WaitForFinalizedBlockNumber(5))\n\n\t// Retrieve heights from all nodes in parallel.\n\tvar (\n\t\twg         sync.WaitGroup\n\t\theightsMap sync.Map\n\t\terrorsMap  sync.Map\n\t)\n\tfor i := range config.NumValidators {\n\t\twg.Add(1)\n\t\tgo func(i int) {\n\t\t\tdefer wg.Done()\n\t\t\tclient, name := s.ConsensusClients(i), config.ValidatorConsensusClientName(i)\n\t\t\ts.Require().NotNil(client)\n\t\t\tabciInfo, err := client.ABCIInfo(s.Ctx())\n\t\t\tif err != nil {\n\t\t\t\terrorsMap.Store(name, err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\theightsMap.Store(name, abciInfo.LastBlockHeight)\n\t\t}(i)\n\t}\n\n\t// Also retrieve height from the EL client.\n\twg.Add(1)\n\tgo func() {\n\t\tdefer wg.Done()\n\t\telClient := s.ExecutionClients(0)\n\t\ts.Require().NotNil(elClient)\n\t\telHeight, err := elClient.BlockNumber(s.Ctx())\n\t\ts.Require().NoError(err)\n\t\theightsMap.Store(\"el\", int64(elHeight)) // #nosec G115\n\t}()\n\n\twg.Wait()\n\n\t// Check for errors.\n\terrorsMap.Range(func(key, value interface{}) bool {\n\t\tname := key.(string) //nolint:errcheck // Safe to ignore.\n\t\terr := value.(error) //nolint:errcheck // Safe to ignore.\n\t\ts.Require().NoError(err, \"Error getting ABCI info from node %s\", name)\n\t\treturn true\n\t})\n\n\t// Collect heights into a map for comparison.\n\theights := make(map[string]int64)\n\theightsMap.Range(func(key, value interface{}) bool {\n\t\tname := key.(string)    //nolint:errcheck // Safe to ignore.\n\t\theight := value.(int64) //nolint:errcheck // Safe to ignore.\n\t\theights[name] = height\n\t\treturn true\n\t})\n\n\t// Verify that all heights are within +/- 1 of each other.\n\tfor name1, height1 := range heights {\n\t\tfor name2, height2 := range heights {\n\t\t\tif name1 == name2 {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tdiff := height1 - height2\n\t\t\tif diff < 0 {\n\t\t\t\tdiff = -diff\n\t\t\t}\n\n\t\t\ts.Require().LessOrEqual(diff, int64(1),\n\t\t\t\t\"Height difference between nodes %s (%d) and %s (%d) exceeds 1 block\",\n\t\t\t\tname1, height1, name2, height2)\n\t\t}\n\t}\n}\n\n// TestABCIQuery checks that the ABCI query response is valid.\nfunc (s *BeaconKitE2ESuite) TestABCIQuery() {\n\t// Wait for execution block 5 to ensure nodes have progressed.\n\ts.Require().NoError(s.WaitForFinalizedBlockNumber(5))\n\n\t// Get the full node consensus client.\n\tclient := s.ConsensusClients(2)\n\ts.Require().NotNil(client)\n\n\t// membership\n\n\t// Get ABCI query with proof of the fork data from a node.\n\tkey := sdkcollections.NewPrefix([]byte{keys.ForkPrefix})\n\tabciQuery, err := client.ABCIQuery(\n\t\ts.Ctx(),\n\t\t\"store/beacon/key\",\n\t\tkey,\n\t\trpcclient.ABCIQueryOptions{\n\t\t\tProve:  true,\n\t\t\tHeight: 5,\n\t\t},\n\t)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(abciQuery)\n\ts.Require().Equal(abciQuery.Height, int64(5))\n\n\tblock := int64(6)\n\tcommit, err := client.Commit(s.Ctx(), &block)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tproofs := make([]*ics23.CommitmentProof, len(abciQuery.ProofOps.Ops))\n\n\tfor i := range abciQuery.ProofOps.Ops {\n\t\tproofs[i] = &ics23.CommitmentProof{}\n\t\terr = proofs[i].Unmarshal(abciQuery.ProofOps.Ops[i].Data)\n\t\ts.Require().NoError(err)\n\t}\n\n\tverifyChainedMembershipProof(\n\t\tics23.CommitmentRoot(commit.SignedHeader.Header.AppHash),\n\t\t[]*ics23.ProofSpec{ics23.IavlSpec, ics23.TendermintSpec},\n\t\tproofs,\n\t\t[][]byte{[]byte(\"beacon\"), key.Bytes()},\n\t\tabciQuery.Value,\n\t\t0,\n\t)\n\n\t// non-membership\n\n\t// Get ABCI query with proof of the fork data from a node.\n\tkey = []byte(\"oogabooga\")\n\tabciQuery, err = client.ABCIQuery(\n\t\ts.Ctx(),\n\t\t\"store/beacon/key\",\n\t\tkey,\n\t\trpcclient.ABCIQueryOptions{\n\t\t\tProve:  true,\n\t\t\tHeight: 5,\n\t\t},\n\t)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(abciQuery)\n\ts.Require().Equal(abciQuery.Height, int64(5))\n\n\tblock = int64(6)\n\tcommit, err = client.Commit(s.Ctx(), &block)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\ts.Assert().Empty(abciQuery.Value)\n\n\tproofs = make([]*ics23.CommitmentProof, len(abciQuery.ProofOps.Ops))\n\n\tfor i := range abciQuery.ProofOps.Ops {\n\t\tproofs[i] = &ics23.CommitmentProof{}\n\t\terr = proofs[i].Unmarshal(abciQuery.ProofOps.Ops[i].Data)\n\t\ts.Require().NoError(err)\n\t}\n\n\tverifyNonMembership(\n\t\tproofs,\n\t\t[]*ics23.ProofSpec{ics23.IavlSpec, ics23.TendermintSpec},\n\t\tcommit.SignedHeader.Header.AppHash.Bytes(),\n\t\t[][]byte{[]byte(\"beacon\"), key.Bytes()},\n\t)\n}\n\n// TestCometBFTBlock tests the /cometbft/v1/block/:height endpoint.\nfunc (s *BeaconKitE2ESuite) TestCometBFTBlock() {\n\tclient := s.initHTTPBeaconTest()\n\n\tresp, err := client.Get(\"/cometbft/v1/block/5\")\n\ts.Require().NoError(err)\n\ts.Require().NotNil(resp)\n\ts.Require().Equal(http.StatusOK, resp.StatusCode)\n\tdefer resp.Body.Close()\n\n\tblockData := s.decodeCometBFTResponse(resp)\n\n\t// Validate block structure.\n\theader, ok := blockData[\"header\"].(map[string]any)\n\ts.Require().True(ok, \"block should have a 'header' field\")\n\ts.Require().NotEmpty(header[\"chain_id\"], \"header should have chain_id\")\n\ts.Require().Equal(float64(5), header[\"height\"], \"header height should match requested height\")\n\ts.Require().NotEmpty(header[\"time\"], \"header should have time\")\n\n\t_, ok = blockData[\"data\"].(map[string]any)\n\ts.Require().True(ok, \"block should have a 'data' field\")\n\t_, ok = blockData[\"evidence\"].(map[string]any)\n\ts.Require().True(ok, \"block should have an 'evidence' field\")\n}\n\n// TestCometBFTBlockInvalidHeight tests the /cometbft/v1/block/:height endpoint with a non-numeric height.\nfunc (s *BeaconKitE2ESuite) TestCometBFTBlockInvalidHeight() {\n\tclient := s.initHTTPBeaconTest()\n\n\tresp, err := client.Get(\"/cometbft/v1/block/invalid\")\n\ts.Require().NoError(err)\n\ts.Require().NotNil(resp)\n\ts.Require().Equal(http.StatusBadRequest, resp.StatusCode)\n\tresp.Body.Close()\n}\n\n// TestCometBFTSignedHeader tests the /cometbft/v1/signed_header/:height endpoint.\nfunc (s *BeaconKitE2ESuite) TestCometBFTSignedHeader() {\n\tclient := s.initHTTPBeaconTest()\n\n\tresp, err := client.Get(\"/cometbft/v1/signed_header/5\")\n\ts.Require().NoError(err)\n\ts.Require().NotNil(resp)\n\ts.Require().Equal(http.StatusOK, resp.StatusCode)\n\tdefer resp.Body.Close()\n\n\tshData := s.decodeCometBFTResponse(resp)\n\n\t// Validate signed header structure.\n\theader, ok := shData[\"header\"].(map[string]any)\n\ts.Require().True(ok, \"signed header should have a 'header' field\")\n\ts.Require().NotEmpty(header[\"chain_id\"], \"header should have chain_id\")\n\ts.Require().Equal(float64(5), header[\"height\"], \"header height should match requested height\")\n\ts.Require().NotEmpty(header[\"time\"], \"header should have time\")\n\n\tcommit, ok := shData[\"commit\"].(map[string]any)\n\ts.Require().True(ok, \"signed header should have a 'commit' field\")\n\ts.Require().NotNil(commit[\"height\"], \"commit should have height\")\n\ts.Require().NotNil(commit[\"round\"], \"commit should have round\")\n}\n\n// TestCometBFTSignedHeaderInvalidHeight tests the /cometbft/v1/signed_header/:height endpoint with a non-numeric height.\nfunc (s *BeaconKitE2ESuite) TestCometBFTSignedHeaderInvalidHeight() {\n\tclient := s.initHTTPBeaconTest()\n\n\tresp, err := client.Get(\"/cometbft/v1/signed_header/invalid\")\n\ts.Require().NoError(err)\n\ts.Require().NotNil(resp)\n\ts.Require().Equal(http.StatusBadRequest, resp.StatusCode)\n\tresp.Body.Close()\n}\n\n// TestCometBFTSignedHeaderMatchesCommit cross-validates the CometBFT signed header API response\n// against the CometBFT RPC Commit response for the same height.\nfunc (s *BeaconKitE2ESuite) TestCometBFTSignedHeaderMatchesCommit() {\n\thttpClient := s.initHTTPBeaconTest()\n\n\t// Get signed header from the node-api.\n\tresp, err := httpClient.Get(\"/cometbft/v1/signed_header/5\")\n\ts.Require().NoError(err)\n\ts.Require().NotNil(resp)\n\ts.Require().Equal(http.StatusOK, resp.StatusCode)\n\tdefer resp.Body.Close()\n\n\tshData := s.decodeCometBFTResponse(resp)\n\tapiHeader, ok := shData[\"header\"].(map[string]any)\n\ts.Require().True(ok)\n\n\t// Get the same data via CometBFT RPC Commit.\n\tclient := s.ConsensusClients(0)\n\ts.Require().NotNil(client)\n\theight := int64(5)\n\tcommit, err := client.Commit(s.Ctx(), &height)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(commit)\n\n\t// Cross-validate chain_id and height.\n\ts.Require().Equal(\n\t\tcommit.SignedHeader.Header.ChainID,\n\t\tapiHeader[\"chain_id\"],\n\t\t\"chain_id from node-api should match CometBFT RPC\",\n\t)\n\ts.Require().Equal(\n\t\tfloat64(5),\n\t\tapiHeader[\"height\"],\n\t\t\"height from node-api should match requested height\",\n\t)\n\ts.Require().Equal(\n\t\theight,\n\t\tcommit.SignedHeader.Header.Height,\n\t\t\"height from CometBFT RPC should match requested height\",\n\t)\n}\n\n// decodeCometBFTResponse reads an HTTP response body and extracts the \"data\" field\n// from the CometBFT API response envelope.\nfunc (s *BeaconKitE2ESuite) decodeCometBFTResponse(resp *http.Response) map[string]any {\n\tbodyBytes, err := io.ReadAll(resp.Body)\n\ts.Require().NoError(err)\n\n\tvar envelope map[string]any\n\terr = json.Unmarshal(bodyBytes, &envelope)\n\ts.Require().NoError(err)\n\n\tdata, ok := envelope[\"data\"].(map[string]any)\n\ts.Require().True(ok, \"response should have a 'data' field\")\n\treturn data\n}\n\n// https://github.com/cosmos/ibc-go/blob/20326046a09330898fac90540134d8556f4506cc/modules/core/23-commitment/types/merkle.go#L143-L189\nfunc verifyChainedMembershipProof(\n\troot []byte,\n\tspecs []*ics23.ProofSpec,\n\tproofs []*ics23.CommitmentProof,\n\tkeys [][]byte,\n\tvalue []byte,\n\tindex int,\n) {\n\tvar (\n\t\tsubroot []byte\n\t\terr     error\n\t)\n\t// Initialize subroot to value since the proofs list may be empty.\n\t// This may happen if this call is verifying intermediate proofs after the lowest proof has been executed.\n\t// In this case, there may be no intermediate proofs to verify and we just check that lowest proof root equals final root\n\tsubroot = value\n\tfor i := index; i < len(proofs); i++ {\n\t\tsubroot, err = proofs[i].Calculate()\n\t\tif err != nil {\n\t\t\tpanic(fmt.Sprintf(\"could not calculate proof root at index %d, merkle tree may be empty. %v\", i, err))\n\t\t}\n\n\t\t// Since keys are passed in from highest to lowest, we must grab their indices in reverse order\n\t\t// from the proofs and specs which are lowest to highest\n\t\tkey := keys[len(keys)-1-i]\n\n\t\tep := proofs[i].GetExist()\n\t\tif ep == nil {\n\t\t\tpanic(fmt.Sprintf(\"commitment proof must be existence proof. got: %T at index %d\", i, proofs[i]))\n\t\t}\n\n\t\t// verify membership of the proof at this index with appropriate key and value\n\t\tif err = ep.Verify(specs[i], subroot, key, value); err != nil {\n\t\t\tpanic(fmt.Sprintf(\"failed to verify membership proof at index %d: %v\", i, err))\n\t\t}\n\t\t// Set value to subroot so that we verify next proof in chain commits to this subroot\n\t\tvalue = subroot\n\t}\n\n\t// Check that chained proof root equals passed-in root\n\tif !bytes.Equal(root, subroot) {\n\t\tpanic(fmt.Sprintf(\"proof did not commit to expected root: %X, got: %X.\", root, subroot))\n\t}\n}\n\n// https://github.com/cosmos/ibc-go/blob/20326046a09330898fac90540134d8556f4506cc/modules/core/23-commitment/types/merkle.go#L105-L141\nfunc verifyNonMembership(proofs []*ics23.CommitmentProof, specs []*ics23.ProofSpec, root []byte, path [][]byte) {\n\t// VerifyNonMembership will verify the absence of key in lowest subtree, and then chain inclusion proofs\n\t// of all subroots up to final root\n\tsubroot, err := proofs[0].Calculate()\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"could not calculate root for proof index 0, merkle tree is likely empty. %v\", err))\n\t}\n\n\tkey := path[uint64(len(path)-1)]\n\n\tnp := proofs[0].GetNonexist()\n\tif np == nil {\n\t\tpanic(fmt.Sprintf(\"commitment proof must be non-existence proof for verifying non-membership. got: %T\", proofs[0]))\n\t}\n\n\tif err = np.Verify(specs[0], subroot, key); err != nil {\n\t\tpanic(fmt.Sprintf(\"failed to verify non-membership proof with key %s: %v\", string(key), err))\n\t}\n\n\t// Verify chained membership proof starting from index 1 with value = subroot\n\tverifyChainedMembershipProof(root, specs, proofs, path, subroot, 1)\n}\n"
  },
  {
    "path": "testing/e2e/standard/inflation_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//go:build e2e\n\npackage standard_test\n\nimport (\n\t\"math/big\"\n\t\"sync\"\n\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\tgethcommon \"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-ethereum/params\"\n)\n\n// TestEVMInflation checks that the EVM inflation address receives the correct\n// amount of EVM inflation per block.\nfunc (s *BeaconKitE2ESuite) TestEVMInflation() {\n\t// TODO: make test use configurable chain spec.\n\tchainspec, err := spec.DevnetChainSpec()\n\ts.Require().NoError(err)\n\n\telClient := s.ExecutionClients(0)\n\ts.Require().NotNil(elClient)\n\n\tvar (\n\t\tinflationPerBlock          uint64\n\t\tinflationAddress           common.ExecutionAddress\n\t\toldInflationAddress        common.ExecutionAddress\n\t\tpreForkAddressFinalBalance *big.Int\n\t\tpreForkLatestBalance       *big.Int\n\t\tbalance                    *big.Int\n\t\texpectedBalance            *big.Int\n\t\tforkSlot                   int64\n\t\tonceOnFork                 sync.Once\n\t)\n\t// Arbitrarily run test for 2 epochs.\n\tfor blkNum := range int64(2 * chainspec.SlotsPerEpoch()) {\n\t\terr = s.WaitForFinalizedBlockNumber(uint64(blkNum))\n\t\ts.Require().NoError(err)\n\t\theader, errBlk := elClient.HeaderByNumber(s.Ctx(), big.NewInt(blkNum))\n\t\ts.Require().NoError(errBlk)\n\n\t\tpayloadTime := header.Time\n\t\tinflationPerBlock = chainspec.EVMInflationPerBlock(math.U64(payloadTime)).Unwrap()\n\t\tinflationAddress = chainspec.EVMInflationAddress(math.U64(payloadTime))\n\t\tif chainspec.Deneb1ForkTime() > 0 && payloadTime >= chainspec.Deneb1ForkTime() {\n\t\t\t// If we have passed the Deneb1 fork, do some verifications and update inflation values.\n\t\t\tonceOnFork.Do(func() {\n\t\t\t\toldInflationPerBlock := chainspec.EVMInflationPerBlock(math.U64(chainspec.Deneb1ForkTime() - 1))\n\t\t\t\toldInflationAddress = chainspec.EVMInflationAddress(math.U64(chainspec.Deneb1ForkTime() - 1))\n\n\t\t\t\t// Verify the post fork inflation changes\n\t\t\t\ts.Require().NotEqual(oldInflationPerBlock, inflationPerBlock)\n\t\t\t\ts.Require().NotEqual(oldInflationAddress, inflationAddress)\n\t\t\t\tforkSlot = blkNum\n\n\t\t\t\t// take the snapshot of balance right before the fork and check it won't change anymore\n\t\t\t\tpreForkAddressFinalBalance, err = elClient.BalanceAt(\n\t\t\t\t\ts.Ctx(), gethcommon.Address(oldInflationAddress), big.NewInt(blkNum-1),\n\t\t\t\t)\n\t\t\t\ts.Require().NoError(err)\n\t\t\t})\n\n\t\t\t// Enforce that the balance of the EVM inflation address\n\t\t\t// prior to the hardfork is the same as it is now.\n\t\t\tpreForkLatestBalance, err = elClient.BalanceAt(\n\t\t\t\ts.Ctx(), gethcommon.Address(oldInflationAddress), nil, // at the current block\n\t\t\t)\n\t\t\ts.Require().NoError(err)\n\t\t\ts.Require().Zero(preForkAddressFinalBalance.Cmp(preForkLatestBalance))\n\n\t\t\texpectedBalance = new(big.Int).Mul(\n\t\t\t\tnew(big.Int).SetUint64(inflationPerBlock*params.GWei),\n\t\t\t\tbig.NewInt(blkNum-forkSlot+1),\n\t\t\t)\n\t\t} else {\n\t\t\t// Pre-Deneb1\n\t\t\texpectedBalance = new(big.Int).Mul(\n\t\t\t\tnew(big.Int).SetUint64(inflationPerBlock*params.GWei),\n\t\t\t\tbig.NewInt(blkNum),\n\t\t\t)\n\t\t}\n\n\t\tbalance, err = elClient.BalanceAt(\n\t\t\ts.Ctx(),\n\t\t\tgethcommon.Address(inflationAddress),\n\t\t\tbig.NewInt(blkNum),\n\t\t)\n\t\ts.Require().NoError(err)\n\t\ts.Require().Zero(balance.Cmp(expectedBalance),\n\t\t\t\"height\", blkNum,\n\t\t\t\"balance\", balance,\n\t\t\t\"expectedBalance\", expectedBalance,\n\t\t)\n\t}\n}\n"
  },
  {
    "path": "testing/e2e/standard/proofs_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//go:build e2e\n\npackage standard_test\n\nimport (\n\t\"math/big\"\n\t\"strconv\"\n\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\t\"github.com/berachain/beacon-kit/gethlib/ssztest\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/proof/merkle\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/ethereum/go-ethereum/accounts/abi/bind\"\n\tcoretypes \"github.com/ethereum/go-ethereum/core/types\"\n)\n\n// TestBlockProposerProof tests the block proposer proof endpoint by fetching and verifying\n// the block proposer proofs against the SSZTest contract. Refer to\n// beacon-kit/contracts/src/eip4788/SSZ.sol for details.\nfunc (s *BeaconKitE2ESuite) TestBlockProposerProof() {\n\t// Sender account\n\tsender := s.TestAccounts()[0]\n\n\t// Get the execution client.\n\telClient := s.ExecutionClients(0)\n\ts.Require().NotNil(elClient)\n\n\t// Get the chain ID.\n\tchainID, err := elClient.ChainID(s.Ctx())\n\ts.Require().NoError(err)\n\n\t// Deploy the SSZTest contract to verify the block proposer proof.\n\taddr, tx, sszTest, err := ssztest.DeploySSZTest(&bind.TransactOpts{\n\t\tFrom:     sender.Address(),\n\t\tSigner:   sender.SignerFunc(chainID),\n\t\tGasLimit: 1000000,\n\t\tContext:  s.Ctx(),\n\t}, elClient)\n\ts.Require().NoError(err)\n\n\t// Confirm deployment.\n\treceipt, err := bind.WaitMined(s.Ctx(), elClient, tx)\n\ts.Require().NoError(err)\n\ts.Require().Equal(coretypes.ReceiptStatusSuccessful, receipt.Status)\n\ts.Logger().Info(\"SSZTest contract deployed successfully\", \"address\", addr.Hex())\n\n\t// Get the current block number.\n\tblockNumber, err := elClient.BlockNumber(s.Ctx())\n\ts.Require().NoError(err)\n\n\t// Get the block proposer proof for the parent block number.\n\tblockProposerResp, err := s.ConsensusClients(0).BlockProposerProof(\n\t\ts.Ctx(), strconv.FormatUint(blockNumber-1, 10),\n\t)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(blockProposerResp)\n\ts.Require().NotNil(blockProposerResp.BeaconBlockHeader)\n\n\t// Get the next block header.\n\tnextHeader, err := elClient.HeaderByNumber(\n\t\ts.Ctx(), new(big.Int).SetUint64(blockNumber),\n\t)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(nextHeader)\n\n\t// Get the block proposer proof for the next timestamp and enforce equality.\n\tblockProposerResp2, err := s.ConsensusClients(0).BlockProposerProof(\n\t\ts.Ctx(), \"t\"+strconv.FormatUint(nextHeader.Time, 10),\n\t)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(blockProposerResp2)\n\ts.Require().NotNil(blockProposerResp2.BeaconBlockHeader)\n\ts.Require().Equal(*blockProposerResp.BeaconBlockHeader, *blockProposerResp2.BeaconBlockHeader)\n\ts.Require().Equal(blockProposerResp.BeaconBlockRoot, blockProposerResp2.BeaconBlockRoot)\n\ts.Require().Equal(blockProposerResp.ValidatorPubkey, blockProposerResp2.ValidatorPubkey)\n\ts.Require().ElementsMatch(\n\t\tblockProposerResp.ValidatorPubkeyProof, blockProposerResp2.ValidatorPubkeyProof,\n\t)\n\ts.Require().ElementsMatch(\n\t\tblockProposerResp.ProposerIndexProof, blockProposerResp2.ProposerIndexProof,\n\t)\n\n\t// Get the parent beacon block root of the current timestamp using EIP-4788 Beacon Roots\n\t// and verify equal to what is returned by the API proof/ endpoint.\n\tparentBlockRoot4788, err := sszTest.GetParentBlockRootAt(\n\t\t&bind.CallOpts{\n\t\t\tContext: s.Ctx(),\n\t\t},\n\t\tnextHeader.Time,\n\t)\n\ts.Require().NoError(err)\n\ts.Require().Equal(common.Root(parentBlockRoot4788), blockProposerResp.BeaconBlockRoot)\n\n\t// Verify the beacon block root is equal to HTR(BeaconBlockHeader).\n\ts.Require().Equal(\n\t\tblockProposerResp.BeaconBlockRoot, blockProposerResp.BeaconBlockHeader.HashTreeRoot(),\n\t)\n\n\t// Verify the slot is equal to the requested block number.\n\ts.Require().Equal(blockProposerResp.BeaconBlockHeader.Slot.Unwrap(), blockNumber-1)\n\n\t// First verify the proposer index proof.\n\tproposerIndexProof := make([][32]byte, len(blockProposerResp.ProposerIndexProof))\n\tfor i, proofItem := range blockProposerResp.ProposerIndexProof {\n\t\tproposerIndexProof[i] = proofItem\n\t}\n\terr = sszTest.MustVerifyProof(\n\t\t&bind.CallOpts{\n\t\t\tContext: s.Ctx(),\n\t\t},\n\t\tproposerIndexProof,\n\t\tblockProposerResp.BeaconBlockRoot,\n\t\tblockProposerResp.BeaconBlockHeader.ProposerIndex.HashTreeRoot(),\n\t\tbig.NewInt(merkle.ProposerIndexGIndexBlock),\n\t)\n\ts.Require().NoError(err)\n\n\t// If the proof or leaf is modified, the proof should not verify.\n\tisVerified, err := sszTest.VerifyProof(\n\t\t&bind.CallOpts{\n\t\t\tContext: s.Ctx(),\n\t\t},\n\t\tproposerIndexProof,\n\t\tblockProposerResp.BeaconBlockRoot,\n\t\t(blockProposerResp.BeaconBlockHeader.ProposerIndex + 2).HashTreeRoot(), // malicious leaf\n\t\tbig.NewInt(merkle.ProposerIndexGIndexBlock),\n\t)\n\ts.Require().NoError(err)\n\ts.Require().False(isVerified)\n\n\t// Get the chain spec to determine the fork version.\n\t// TODO: make test use configurable chain spec.\n\tcs, err := spec.DevnetChainSpec()\n\ts.Require().NoError(err)\n\n\t// Get the fork version based on the block's timestamp.\n\theader, err := elClient.HeaderByNumber(\n\t\ts.Ctx(), new(big.Int).SetUint64(blockNumber-1),\n\t)\n\ts.Require().NoError(err)\n\tforkVersion := cs.ActiveForkVersionForTimestamp(math.U64(header.Time))\n\tzeroValidatorPubkeyGIndex, err := merkle.GetZeroValidatorPubkeyGIndexBlock(forkVersion)\n\ts.Require().NoError(err)\n\n\t// Calculate the validator pubkey GIndex based on fork version.\n\tgIndex := zeroValidatorPubkeyGIndex +\n\t\t(blockProposerResp.BeaconBlockHeader.ProposerIndex.Unwrap() * merkle.ValidatorGIndexOffset)\n\n\t// Next verify the validator pubkey proof.\n\tvalidatorPubkeyProof := make([][32]byte, len(blockProposerResp.ValidatorPubkeyProof))\n\tfor i, proofItem := range blockProposerResp.ValidatorPubkeyProof {\n\t\tvalidatorPubkeyProof[i] = proofItem\n\t}\n\terr = sszTest.MustVerifyProof(\n\t\t&bind.CallOpts{\n\t\t\tContext: s.Ctx(),\n\t\t},\n\t\tvalidatorPubkeyProof,\n\t\tblockProposerResp.BeaconBlockRoot,\n\t\tblockProposerResp.ValidatorPubkey.HashTreeRoot(),\n\t\tnew(big.Int).SetUint64(gIndex),\n\t)\n\ts.Require().NoError(err)\n}\n\n// TestValidatorBalanceProof tests the validator balance proof endpoint by fetching and verifying\n// validator balance proofs against the SSZTest contract.\nfunc (s *BeaconKitE2ESuite) TestValidatorBalanceProof() {\n\t// Sender account\n\tsender := s.TestAccounts()[0]\n\n\t// Get the execution client.\n\telClient := s.ExecutionClients(0)\n\ts.Require().NotNil(elClient)\n\n\t// Get the chain ID.\n\tchainID, err := elClient.ChainID(s.Ctx())\n\ts.Require().NoError(err)\n\n\t// Deploy the SSZTest contract to verify the validator balance proof.\n\taddr, tx, sszTest, err := ssztest.DeploySSZTest(&bind.TransactOpts{\n\t\tFrom:     sender.Address(),\n\t\tSigner:   sender.SignerFunc(chainID),\n\t\tGasLimit: 1000000,\n\t\tContext:  s.Ctx(),\n\t}, elClient)\n\ts.Require().NoError(err)\n\n\t// Confirm deployment.\n\treceipt, err := bind.WaitMined(s.Ctx(), elClient, tx)\n\ts.Require().NoError(err)\n\ts.Require().Equal(coretypes.ReceiptStatusSuccessful, receipt.Status)\n\ts.Logger().Info(\"SSZTest contract deployed successfully\", \"address\", addr.Hex())\n\n\t// Get the current block number.\n\tblockNumber, err := elClient.BlockNumber(s.Ctx())\n\ts.Require().NoError(err)\n\n\t// Get the validator balance proof for validator 0 at the parent block number.\n\tvalidatorIndex := uint64(0)\n\tbalanceResp, err := s.ConsensusClients(0).ValidatorBalanceProof(\n\t\ts.Ctx(), strconv.FormatUint(blockNumber-1, 10), strconv.FormatUint(validatorIndex, 10),\n\t)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(balanceResp)\n\ts.Require().NotNil(balanceResp.BeaconBlockHeader)\n\ts.Require().Equal(balanceResp.BeaconBlockRoot, balanceResp.BeaconBlockHeader.HashTreeRoot())\n\ts.Require().Equal(balanceResp.BeaconBlockHeader.Slot.Unwrap(), blockNumber-1)\n\n\t// Get the next block header.\n\tnextHeader, err := elClient.HeaderByNumber(s.Ctx(), new(big.Int).SetUint64(blockNumber))\n\ts.Require().NoError(err)\n\ts.Require().NotNil(nextHeader)\n\n\t// Get the block proposer proof for the next timestamp and enforce equality.\n\tbalanceResp2, err := s.ConsensusClients(0).ValidatorBalanceProof(\n\t\ts.Ctx(), \"t\"+strconv.FormatUint(nextHeader.Time, 10), strconv.FormatUint(validatorIndex, 10),\n\t)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(balanceResp2)\n\ts.Require().NotNil(balanceResp2.BeaconBlockHeader)\n\ts.Require().Equal(*balanceResp.BeaconBlockHeader, *balanceResp2.BeaconBlockHeader)\n\ts.Require().Equal(balanceResp.BeaconBlockRoot, balanceResp2.BeaconBlockRoot)\n\ts.Require().Equal(balanceResp.BalanceLeaf, balanceResp2.BalanceLeaf)\n\ts.Require().ElementsMatch(\n\t\tbalanceResp.BalanceProof, balanceResp2.BalanceProof,\n\t)\n\n\t// Get the parent beacon block root of the current timestamp using EIP-4788 Beacon Roots\n\t// and verify equal to what is returned by the API proof/ endpoint.\n\tparentBlockRoot4788, err := sszTest.GetParentBlockRootAt(\n\t\t&bind.CallOpts{\n\t\t\tContext: s.Ctx(),\n\t\t},\n\t\tnextHeader.Time,\n\t)\n\ts.Require().NoError(err)\n\ts.Require().Equal(common.Root(parentBlockRoot4788), balanceResp.BeaconBlockRoot)\n\n\t// Get the chain spec to determine the fork version.\n\tcs, err := spec.DevnetChainSpec()\n\ts.Require().NoError(err)\n\n\t// Get the fork version based on the block's timestamp.\n\theader, err := elClient.HeaderByNumber(\n\t\ts.Ctx(), new(big.Int).SetUint64(blockNumber-1),\n\t)\n\ts.Require().NoError(err)\n\tforkVersion := cs.ActiveForkVersionForTimestamp(math.U64(header.Time))\n\tzeroValidatorBalanceGIndex, err := merkle.GetZeroValidatorBalanceGIndexBlock(forkVersion)\n\ts.Require().NoError(err)\n\n\t// Calculate the balance GIndex based on fork version.\n\t// Balances are packed 4 per leaf, so we need to divide by 4.\n\tleafIndex := validatorIndex / 4\n\tgIndex := zeroValidatorBalanceGIndex + leafIndex\n\n\t// Verify the validator balance proof.\n\tbalanceProof := make([][32]byte, len(balanceResp.BalanceProof))\n\tfor i, proofItem := range balanceResp.BalanceProof {\n\t\tbalanceProof[i] = proofItem\n\t}\n\terr = sszTest.MustVerifyProof(\n\t\t&bind.CallOpts{\n\t\t\tContext: s.Ctx(),\n\t\t},\n\t\tbalanceProof,\n\t\tbalanceResp.BeaconBlockRoot,\n\t\tbalanceResp.BalanceLeaf, // The leaf contains 4 packed balances\n\t\tnew(big.Int).SetUint64(gIndex),\n\t)\n\ts.Require().NoError(err)\n}\n\n// TestValidatorCredentialsProof tests the validator withdrawal credentials proof endpoint by fetching\n// and verifying withdrawal credentials proofs against the SSZTest contract.\nfunc (s *BeaconKitE2ESuite) TestValidatorCredentialsProof() {\n\t// Sender account\n\tsender := s.TestAccounts()[0]\n\n\t// Get the execution client.\n\telClient := s.ExecutionClients(0)\n\ts.Require().NotNil(elClient)\n\n\t// Get the chain ID.\n\tchainID, err := elClient.ChainID(s.Ctx())\n\ts.Require().NoError(err)\n\n\t// Deploy the SSZTest contract to verify the validator credentials proof.\n\taddr, tx, sszTest, err := ssztest.DeploySSZTest(&bind.TransactOpts{\n\t\tFrom:     sender.Address(),\n\t\tSigner:   sender.SignerFunc(chainID),\n\t\tGasLimit: 1000000,\n\t\tContext:  s.Ctx(),\n\t}, elClient)\n\ts.Require().NoError(err)\n\n\t// Confirm deployment.\n\treceipt, err := bind.WaitMined(s.Ctx(), elClient, tx)\n\ts.Require().NoError(err)\n\ts.Require().Equal(coretypes.ReceiptStatusSuccessful, receipt.Status)\n\ts.Logger().Info(\"SSZTest contract deployed successfully\", \"address\", addr.Hex())\n\n\t// Get the current block number.\n\tblockNumber, err := elClient.BlockNumber(s.Ctx())\n\ts.Require().NoError(err)\n\n\t// Get the validator credentials proof for validator 0 at the parent block number.\n\tvalidatorIndex := uint64(0)\n\tcredsResp, err := s.ConsensusClients(0).ValidatorCredentialsProof(\n\t\ts.Ctx(), strconv.FormatUint(blockNumber-1, 10), strconv.FormatUint(validatorIndex, 10),\n\t)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(credsResp)\n\ts.Require().NotNil(credsResp.BeaconBlockHeader)\n\ts.Require().Equal(credsResp.BeaconBlockRoot, credsResp.BeaconBlockHeader.HashTreeRoot())\n\ts.Require().Equal(credsResp.BeaconBlockHeader.Slot.Unwrap(), blockNumber-1)\n\n\t// Get the next block header.\n\tnextHeader, err := elClient.HeaderByNumber(s.Ctx(), new(big.Int).SetUint64(blockNumber))\n\ts.Require().NoError(err)\n\ts.Require().NotNil(nextHeader)\n\n\t// Get the block proposer proof for the next timestamp and enforce equality.\n\tcredsResp1, err := s.ConsensusClients(0).ValidatorCredentialsProof(\n\t\ts.Ctx(), \"t\"+strconv.FormatUint(nextHeader.Time, 10), strconv.FormatUint(validatorIndex, 10),\n\t)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(credsResp1)\n\ts.Require().NotNil(credsResp1.BeaconBlockHeader)\n\ts.Require().Equal(*credsResp.BeaconBlockHeader, *credsResp1.BeaconBlockHeader)\n\ts.Require().Equal(credsResp.BeaconBlockRoot, credsResp1.BeaconBlockRoot)\n\ts.Require().Equal(credsResp.ValidatorWithdrawalCredentials, credsResp1.ValidatorWithdrawalCredentials)\n\ts.Require().ElementsMatch(credsResp.WithdrawalCredentialsProof, credsResp1.WithdrawalCredentialsProof)\n\n\t// Get the parent beacon block root of the current timestamp using EIP-4788 Beacon Roots\n\t// and verify equal to what is returned by the API proof/ endpoint.\n\tparentBlockRoot4788, err := sszTest.GetParentBlockRootAt(\n\t\t&bind.CallOpts{\n\t\t\tContext: s.Ctx(),\n\t\t},\n\t\tnextHeader.Time,\n\t)\n\ts.Require().NoError(err)\n\ts.Require().Equal(common.Root(parentBlockRoot4788), credsResp.BeaconBlockRoot)\n\n\t// Get the chain spec to determine the fork version.\n\tcs, err := spec.DevnetChainSpec()\n\ts.Require().NoError(err)\n\n\t// Get the fork version based on the block's timestamp.\n\theader, err := elClient.HeaderByNumber(\n\t\ts.Ctx(), new(big.Int).SetUint64(blockNumber-1),\n\t)\n\ts.Require().NoError(err)\n\tforkVersion := cs.ActiveForkVersionForTimestamp(math.U64(header.Time))\n\tzeroValidatorCredentialsGIndex, err := merkle.GetZeroValidatorCredentialsGIndexBlock(forkVersion)\n\ts.Require().NoError(err)\n\n\t// Calculate the credentials GIndex based on fork version.\n\tgIndex := zeroValidatorCredentialsGIndex + (validatorIndex * merkle.ValidatorGIndexOffset)\n\n\t// Verify the validator withdrawal credentials proof.\n\tcredentialsProof := make([][32]byte, len(credsResp.WithdrawalCredentialsProof))\n\tfor i, proofItem := range credsResp.WithdrawalCredentialsProof {\n\t\tcredentialsProof[i] = proofItem\n\t}\n\terr = sszTest.MustVerifyProof(\n\t\t&bind.CallOpts{\n\t\t\tContext: s.Ctx(),\n\t\t},\n\t\tcredentialsProof,\n\t\tcredsResp.BeaconBlockRoot,\n\t\tcommon.Root(credsResp.ValidatorWithdrawalCredentials),\n\t\tnew(big.Int).SetUint64(gIndex),\n\t)\n\ts.Require().NoError(err)\n\n\t// Test with a different validator index\n\tvalidatorIndex2 := uint64(1)\n\tcredsResp2, err := s.ConsensusClients(0).ValidatorCredentialsProof(\n\t\ts.Ctx(), strconv.FormatUint(blockNumber-1, 10), strconv.FormatUint(validatorIndex2, 10),\n\t)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(credsResp2)\n\n\t// Calculate the credentials GIndex for validator 1\n\tgIndex2 := zeroValidatorCredentialsGIndex + (validatorIndex2 * merkle.ValidatorGIndexOffset)\n\n\t// Verify the validator withdrawal credentials proof for validator 1\n\tcredentialsProof2 := make([][32]byte, len(credsResp2.WithdrawalCredentialsProof))\n\tfor i, proofItem := range credsResp2.WithdrawalCredentialsProof {\n\t\tcredentialsProof2[i] = proofItem\n\t}\n\terr = sszTest.MustVerifyProof(\n\t\t&bind.CallOpts{\n\t\t\tContext: s.Ctx(),\n\t\t},\n\t\tcredentialsProof2,\n\t\tcredsResp2.BeaconBlockRoot,\n\t\tcommon.Root(credsResp2.ValidatorWithdrawalCredentials),\n\t\tnew(big.Int).SetUint64(gIndex2),\n\t)\n\ts.Require().NoError(err)\n}\n\n// TestValidatorPubkeyProof tests the validator pubkey proof endpoint by fetching and verifying\n// validator pubkey proofs against the SSZTest contract.\nfunc (s *BeaconKitE2ESuite) TestValidatorPubkeyProof() {\n\t// Sender account\n\tsender := s.TestAccounts()[0]\n\n\t// Get the execution client.\n\telClient := s.ExecutionClients(0)\n\ts.Require().NotNil(elClient)\n\n\t// Get the chain ID.\n\tchainID, err := elClient.ChainID(s.Ctx())\n\ts.Require().NoError(err)\n\n\t// Deploy the SSZTest contract to verify the validator pubkey proof.\n\taddr, tx, sszTest, err := ssztest.DeploySSZTest(&bind.TransactOpts{\n\t\tFrom:     sender.Address(),\n\t\tSigner:   sender.SignerFunc(chainID),\n\t\tGasLimit: 1000000,\n\t\tContext:  s.Ctx(),\n\t}, elClient)\n\ts.Require().NoError(err)\n\n\t// Confirm deployment.\n\treceipt, err := bind.WaitMined(s.Ctx(), elClient, tx)\n\ts.Require().NoError(err)\n\ts.Require().Equal(coretypes.ReceiptStatusSuccessful, receipt.Status)\n\ts.Logger().Info(\"SSZTest contract deployed successfully\", \"address\", addr.Hex())\n\n\t// Get the current block number.\n\tblockNumber, err := elClient.BlockNumber(s.Ctx())\n\ts.Require().NoError(err)\n\n\t// Get the validator pubkey proof for validator 0 at the parent block number.\n\tvalidatorIndex := uint64(0)\n\tpubkeyResp, err := s.ConsensusClients(0).ValidatorPubkeyProof(\n\t\ts.Ctx(), strconv.FormatUint(blockNumber-1, 10), strconv.FormatUint(validatorIndex, 10),\n\t)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(pubkeyResp)\n\ts.Require().NotNil(pubkeyResp.BeaconBlockHeader)\n\ts.Require().Equal(pubkeyResp.BeaconBlockRoot, pubkeyResp.BeaconBlockHeader.HashTreeRoot())\n\ts.Require().Equal(pubkeyResp.BeaconBlockHeader.Slot.Unwrap(), blockNumber-1)\n\n\t// Get the next block header.\n\tnextHeader, err := elClient.HeaderByNumber(s.Ctx(), new(big.Int).SetUint64(blockNumber))\n\ts.Require().NoError(err)\n\ts.Require().NotNil(nextHeader)\n\n\t// Get the pubkey proof for the next timestamp and enforce equality.\n\tpubkeyResp2, err := s.ConsensusClients(0).ValidatorPubkeyProof(\n\t\ts.Ctx(), \"t\"+strconv.FormatUint(nextHeader.Time, 10), strconv.FormatUint(validatorIndex, 10),\n\t)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(pubkeyResp2)\n\ts.Require().NotNil(pubkeyResp2.BeaconBlockHeader)\n\ts.Require().Equal(*pubkeyResp.BeaconBlockHeader, *pubkeyResp2.BeaconBlockHeader)\n\ts.Require().Equal(pubkeyResp.BeaconBlockRoot, pubkeyResp2.BeaconBlockRoot)\n\ts.Require().Equal(pubkeyResp.ValidatorPubkey, pubkeyResp2.ValidatorPubkey)\n\ts.Require().ElementsMatch(pubkeyResp.ValidatorPubkeyProof, pubkeyResp2.ValidatorPubkeyProof)\n\n\t// Get the parent beacon block root of the current timestamp using EIP-4788 Beacon Roots\n\t// and verify equal to what is returned by the API proof/ endpoint.\n\tparentBlockRoot4788, err := sszTest.GetParentBlockRootAt(\n\t\t&bind.CallOpts{Context: s.Ctx()},\n\t\tnextHeader.Time,\n\t)\n\ts.Require().NoError(err)\n\ts.Require().Equal(common.Root(parentBlockRoot4788), pubkeyResp.BeaconBlockRoot)\n\n\t// Get the chain spec to determine the fork version.\n\tcs, err := spec.DevnetChainSpec()\n\ts.Require().NoError(err)\n\n\t// Get the fork version based on the block's timestamp.\n\theader, err := elClient.HeaderByNumber(\n\t\ts.Ctx(), new(big.Int).SetUint64(blockNumber-1),\n\t)\n\ts.Require().NoError(err)\n\tforkVersion := cs.ActiveForkVersionForTimestamp(math.U64(header.Time))\n\tzeroValidatorPubkeyGIndex, err := merkle.GetZeroValidatorPubkeyGIndexBlock(forkVersion)\n\ts.Require().NoError(err)\n\n\t// Calculate the pubkey GIndex based on fork version.\n\tgIndex := zeroValidatorPubkeyGIndex + (validatorIndex * merkle.ValidatorGIndexOffset)\n\n\t// Verify the validator pubkey proof.\n\tvalidatorPubkeyProof := make([][32]byte, len(pubkeyResp.ValidatorPubkeyProof))\n\tfor i, proofItem := range pubkeyResp.ValidatorPubkeyProof {\n\t\tvalidatorPubkeyProof[i] = proofItem\n\t}\n\terr = sszTest.MustVerifyProof(\n\t\t&bind.CallOpts{Context: s.Ctx()},\n\t\tvalidatorPubkeyProof,\n\t\tpubkeyResp.BeaconBlockRoot,\n\t\tpubkeyResp.ValidatorPubkey.HashTreeRoot(),\n\t\tnew(big.Int).SetUint64(gIndex),\n\t)\n\ts.Require().NoError(err)\n\n\t// Test with a different validator index\n\tvalidatorIndex2 := uint64(1)\n\tpubkeyResp3, err := s.ConsensusClients(0).ValidatorPubkeyProof(\n\t\ts.Ctx(), strconv.FormatUint(blockNumber-1, 10), strconv.FormatUint(validatorIndex2, 10),\n\t)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(pubkeyResp3)\n\n\t// Calculate the pubkey GIndex for validator 1\n\tgIndex2 := zeroValidatorPubkeyGIndex + (validatorIndex2 * merkle.ValidatorGIndexOffset)\n\n\t// Verify the validator pubkey proof for validator 1\n\tvalidatorPubkeyProof2 := make([][32]byte, len(pubkeyResp3.ValidatorPubkeyProof))\n\tfor i, proofItem := range pubkeyResp3.ValidatorPubkeyProof {\n\t\tvalidatorPubkeyProof2[i] = proofItem\n\t}\n\terr = sszTest.MustVerifyProof(\n\t\t&bind.CallOpts{Context: s.Ctx()},\n\t\tvalidatorPubkeyProof2,\n\t\tpubkeyResp3.BeaconBlockRoot,\n\t\tpubkeyResp3.ValidatorPubkey.HashTreeRoot(),\n\t\tnew(big.Int).SetUint64(gIndex2),\n\t)\n\ts.Require().NoError(err)\n}\n"
  },
  {
    "path": "testing/e2e/standard/setup_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//go:build e2e\n\npackage standard_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/testing/e2e/suite\"\n)\n\n// BeaconE2ESuite is a suite of tests simulating a fully function beacon-kit\n// network.\ntype BeaconKitE2ESuite struct {\n\tsuite.KurtosisE2ESuite\n}\n\n// TestBeaconKitE2ESuite runs the test suite.\nfunc TestBeaconKitE2ESuite(t *testing.T) {\n\tsuite.Run(t, new(BeaconKitE2ESuite))\n}\n\n// TestBasicStartup tests the basic startup of the beacon-kit network.\n// TODO: Should check all clients, opposed to just the RPC client.\nfunc (s *BeaconKitE2ESuite) TestBasicStartup() {\n\terr := s.WaitForFinalizedBlockNumber(10)\n\ts.Require().NoError(err)\n}\n"
  },
  {
    "path": "testing/e2e/standard/staking_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//go:build e2e\n\npackage standard_test\n\nimport (\n\t\"math/big\"\n\n\t\"github.com/attestantio/go-eth2-client/api\"\n\t\"github.com/attestantio/go-eth2-client/spec/phase0\"\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\t\"github.com/berachain/beacon-kit/gethlib/deposit\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/testing/e2e/config\"\n\t\"github.com/berachain/beacon-kit/testing/e2e/suite/types\"\n\t\"github.com/cometbft/cometbft/crypto/bls12381\"\n\t\"github.com/ethereum/go-ethereum/accounts/abi/bind\"\n\tgethcommon \"github.com/ethereum/go-ethereum/common\"\n\tcoretypes \"github.com/ethereum/go-ethereum/core/types\"\n)\n\nconst (\n\t// NumDepositsLoad is the number of deposits to load in the Deposit Robustness e2e test.\n\tNumDepositsLoad uint64 = 500\n)\n\n// Contains pre-test state for validator info to facilitate validation of the post-state.\ntype ValidatorTestStruct struct {\n\tIndex                 uint64\n\tPower                 *big.Int\n\tWithdrawalBalance     *big.Int\n\tWithdrawalCredentials [32]byte\n\tName                  string\n\tClient                *types.ConsensusClient\n}\n\n// TestDepositRobustness tests sending a large number of deposits txs to the Deposit Contract.\n// Then it checks whether all the validators' voting power have increased by the correct amount.\n//\n// TODO:\n// 1) Add staking tests for adding a new validator to the network.\n// 2) Add staking tests for hitting the validator set cap and eviction.\nfunc (s *BeaconKitE2ESuite) TestDepositRobustness() {\n\t// TODO: make test use configurable chain spec.\n\tchainSpec, err := spec.DevnetChainSpec()\n\ts.Require().NoError(err)\n\n\tweiPerGwei := big.NewInt(1e9)\n\n\t// This value is determined by the MIN_DEPOSIT_AMOUNT_IN_GWEI variable from the deposit contract.\n\tcontractMinDepositAmountWei := big.NewInt(0).Mul(big.NewInt(10_000), big.NewInt(1e9*1e9))\n\tdepositAmountWei := new(big.Int).Mul(contractMinDepositAmountWei, big.NewInt(100))\n\tdepositAmountGwei := new(big.Int).Div(depositAmountWei, weiPerGwei)\n\n\t// Our deposits should be greater than the min deposit amount.\n\ts.Require().Equal(1, depositAmountWei.Cmp(contractMinDepositAmountWei))\n\n\ts.Require().Equal(\n\t\t0, int(NumDepositsLoad%config.NumValidators),\n\t\t\"every validator must get an equal amount of deposits\",\n\t)\n\n\t// Get the execution client.\n\telClient := s.ExecutionClients(0)\n\ts.Require().NotNil(elClient)\n\n\t// Get the chain ID.\n\tchainID, err := elClient.ChainID(s.Ctx())\n\ts.Require().NoError(err)\n\n\t// Bind the deposit contract.\n\tdepositContractAddress := gethcommon.Address(chainSpec.DepositContractAddress())\n\n\tdc, err := deposit.NewDepositContract(depositContractAddress, elClient)\n\ts.Require().NoError(err)\n\n\t// Enforce the deposit count at genesis is equal to the number of validators.\n\tdepositCount, err := dc.DepositCount(&bind.CallOpts{\n\t\tBlockNumber: big.NewInt(0),\n\t})\n\ts.Require().NoError(err)\n\ts.Require().Equal(uint64(config.NumValidators), depositCount,\n\t\t\"initial deposit count should match number of validators\")\n\n\t// Check that the genesis deposits root is not empty. It is important that this value is\n\t// consistent across all EL nodes to ensure the EL has a consistent view of the CL deposits\n\t// at genesis. If the EL chain progresses past the genesis block, this is guaranteed.\n\tgenesisRoot, err := dc.GenesisDepositsRoot(&bind.CallOpts{\n\t\tBlockNumber: big.NewInt(0),\n\t})\n\ts.Require().NoError(err)\n\ts.Require().False(genesisRoot == [32]byte{})\n\n\tapiClient := s.ConsensusClients(0)\n\ts.Require().NotNil(apiClient)\n\n\t// Grab genesis validators to get withdrawal creds.\n\tresponse, err := apiClient.Validators(s.Ctx(), &api.ValidatorsOpts{\n\t\tState:   \"genesis\",\n\t\tIndices: []phase0.ValidatorIndex{0, 1, 2, 3, 4},\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotNil(response, \"Validators response should not be nil\")\n\ts.Require().NotNil(response.Data, \"Validators data should not be nil\")\n\n\tvals := response.Data\n\ts.Require().Len(vals, config.NumValidators)\n\n\t// Grab pre-state data for each validator.\n\tvalidators := make([]*ValidatorTestStruct, config.NumValidators)\n\tvar idx uint64\n\tfor i := range config.NumValidators {\n\t\tclient, name := s.ConsensusClients(i), config.ValidatorConsensusClientName(i)\n\t\ts.Require().NotNil(client)\n\t\tpower, cErr := client.GetConsensusPower(s.Ctx())\n\t\ts.Require().NoError(cErr)\n\n\t\ts.Require().Contains(vals, phase0.ValidatorIndex(idx))\n\t\tval := vals[phase0.ValidatorIndex(idx)]\n\t\ts.Require().NotNil(val)\n\t\ts.Require().NotNil(val.Validator)\n\t\tcreds := [32]byte(val.Validator.WithdrawalCredentials)\n\t\twithdrawalAddress := gethcommon.Address(creds[12:])\n\t\twithdrawalBalance, jErr := elClient.BalanceAt(s.Ctx(), withdrawalAddress, nil)\n\t\ts.Require().NoError(jErr)\n\n\t\t// Populate the validators testing struct so we can keep track of the pre-state.\n\t\tvalidators[idx] = &ValidatorTestStruct{\n\t\t\tIndex:                 idx,\n\t\t\tPower:                 new(big.Int).SetUint64(power),\n\t\t\tWithdrawalBalance:     withdrawalBalance,\n\t\t\tWithdrawalCredentials: creds,\n\t\t\tName:                  name,\n\t\t\tClient:                client,\n\t\t}\n\t\tidx++\n\t}\n\n\t// Sender account\n\tsender := s.TestAccounts()[0]\n\n\t// Get the block num\n\tblkNum, err := elClient.BlockNumber(s.Ctx())\n\ts.Require().NoError(err)\n\n\t// Get original evm balance\n\tbalance, err := elClient.BalanceAt(\n\t\ts.Ctx(), sender.Address(), new(big.Int).SetUint64(blkNum),\n\t)\n\ts.Require().NoError(err)\n\n\t// Get the nonce.\n\tnonce, err := elClient.NonceAt(\n\t\ts.Ctx(), sender.Address(), new(big.Int).SetUint64(blkNum),\n\t)\n\ts.Require().NoError(err)\n\n\tvar (\n\t\ttx           *coretypes.Transaction\n\t\tclientPubkey []byte\n\t\tpk           *bls12381.PubKey\n\t\tsignature    [96]byte\n\t\tvalue        = depositAmountWei\n\t\tsigner       = sender.SignerFunc(chainID)\n\t\tfrom         = sender.Address()\n\t)\n\tfor i := range NumDepositsLoad {\n\t\t// Create a deposit transaction using the default validators' pubkeys.\n\t\tcurVal := validators[i%config.NumValidators]\n\t\tclientPubkey, err = curVal.Client.GetPubKey(s.Ctx())\n\t\ts.Require().NoError(err)\n\t\tpk, err = bls12381.NewPublicKeyFromBytes(clientPubkey)\n\t\ts.Require().NoError(err)\n\t\tpubkey := pk.Compress()\n\t\ts.Require().Len(pubkey, 48)\n\n\t\t// Only the first deposit for a pubkey has a non-zero operator.\n\t\toperator := gethcommon.Address{}\n\t\tif i < config.NumValidators {\n\t\t\toperator = from\n\t\t}\n\t\ttx, err = dc.Deposit(&bind.TransactOpts{\n\t\t\tFrom:     from,\n\t\t\tValue:    value,\n\t\t\tSigner:   signer,\n\t\t\tNonce:    new(big.Int).SetUint64(nonce + i),\n\t\t\tGasLimit: 1000000,\n\t\t\tContext:  s.Ctx(),\n\t\t}, pubkey, curVal.WithdrawalCredentials[:], signature[:], operator)\n\t\ts.Require().NoError(err)\n\t\ts.Logger().Info(\"Deposit tx created\", \"num\", i+1, \"hash\", tx.Hash().Hex(), \"value\", value)\n\t}\n\n\t// Wait for the final deposit tx to be mined.\n\ts.Logger().Info(\n\t\t\"Waiting for the final deposit tx to be mined\",\n\t\t\"num\", NumDepositsLoad, \"hash\", tx.Hash().Hex(),\n\t)\n\treceipt, err := bind.WaitMined(s.Ctx(), elClient, tx)\n\ts.Require().NoError(err)\n\ts.Require().Equal(coretypes.ReceiptStatusSuccessful, receipt.Status)\n\ts.Logger().Info(\"Final deposit tx mined successfully\", \"hash\", receipt.TxHash.Hex())\n\n\t// Give time for the nodes to catch up.\n\terr = s.WaitForNBlockNumbers(NumDepositsLoad / chainSpec.MaxDepositsPerBlock())\n\ts.Require().NoError(err)\n\n\t// Compare height of nodes 0 and 1\n\theight, err := validators[0].Client.ABCIInfo(s.Ctx())\n\ts.Require().NoError(err)\n\theight2, err := validators[1].Client.ABCIInfo(s.Ctx())\n\ts.Require().NoError(err)\n\ts.Require().InDelta(height.LastBlockHeight, height2.LastBlockHeight, 1)\n\n\t// Check to see if evm balance decreased.\n\tpostDepositBalance, err := elClient.BalanceAt(s.Ctx(), sender.Address(), nil)\n\ts.Require().NoError(err)\n\n\t// Check that the eth spent is somewhere~ (gas) between\n\t// (depositAmountWei * NumDepositsLoad, depositAmountWei * NumDepositsLoad + 2ether)\n\tlowerBound := new(big.Int).Mul(value, new(big.Int).SetUint64(NumDepositsLoad))\n\tupperBound := new(big.Int).Add(lowerBound, big.NewInt(2e18))\n\tamtSpent := new(big.Int).Sub(balance, postDepositBalance)\n\n\ts.Require().Equal(1, amtSpent.Cmp(lowerBound), \"amount spent is less than lower bound\")\n\ts.Require().Equal(-1, amtSpent.Cmp(upperBound), \"amount spent is greater than upper bound\")\n\n\t// Check that all validators' voting power have increased by\n\t// (NumDepositsLoad / NumValidators) * depositAmountWei\n\t// after the end of the epoch (next multiple of SlotsPerEpoch after receipt.BlockNumber).\n\tblkNum, err = elClient.BlockNumber(s.Ctx())\n\ts.Require().NoError(err)\n\tnextEpoch := chainSpec.SlotToEpoch(math.Slot(blkNum)) + 1\n\tnextEpochBlockNum := nextEpoch.Unwrap() * chainSpec.SlotsPerEpoch()\n\terr = s.WaitForFinalizedBlockNumber(nextEpochBlockNum + 1)\n\ts.Require().NoError(err)\n\n\tincreaseAmt := new(big.Int).Mul(depositAmountGwei, big.NewInt(int64(NumDepositsLoad/config.NumValidators)))\n\n\tfor _, val := range validators {\n\t\t// Consensus Power is in Gwei.\n\t\tpowerAfterRaw, cErr := val.Client.GetConsensusPower(s.Ctx())\n\t\ts.Require().NoError(cErr)\n\t\tpowerAfter := new(big.Int).SetUint64(powerAfterRaw)\n\t\tpowerDiff := new(big.Int).Sub(powerAfter, val.Power)\n\n\t\t// withdrawal balance is in Wei, so we'll convert it to Gwei.\n\t\twithdrawalAddress := gethcommon.Address(val.WithdrawalCredentials[12:])\n\t\twithdrawalBalanceAfter, jErr := elClient.BalanceAt(s.Ctx(), withdrawalAddress, nil)\n\t\ts.Require().NoError(jErr)\n\t\twithdrawalDiff := new(big.Int).Sub(withdrawalBalanceAfter, val.WithdrawalBalance)\n\t\twithdrawalDiff.Div(withdrawalDiff, weiPerGwei)\n\n\t\t// TODO: currently the kurtosis devnet sets the withdrawal address the same for all validators.\n\t\t// We simply validate that the balance is NumValidators times larger than we expect it to be.\n\t\twithdrawalDiff.Div(withdrawalDiff, new(big.Int).SetUint64(config.NumValidators))\n\n\t\t// Verify input balance is equal to the power + withdrawal balances.\n\t\ts.Require().Equal(increaseAmt, new(big.Int).Add(powerDiff, withdrawalDiff))\n\t}\n}\n"
  },
  {
    "path": "testing/e2e/standard/withdrawal_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//go:build e2e\n\npackage standard_test\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math/big\"\n\t\"strconv\"\n\n\tbeaconapi \"github.com/attestantio/go-eth2-client/api\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/execution/requests/eip7002\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/utils\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\tbeaconmath \"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/berachain/beacon-kit/testing/e2e/suite\"\n\te2etypes \"github.com/berachain/beacon-kit/testing/e2e/suite/types\"\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-ethereum/common/hexutil\"\n\tgethcore \"github.com/ethereum/go-ethereum/core/types\"\n\tethcrypto \"github.com/ethereum/go-ethereum/crypto\"\n\t\"github.com/ethereum/go-ethereum/params\"\n\t\"github.com/ethereum/go-ethereum/rpc\"\n)\n\nconst (\n\t// DefaultWithdrawalAmount is the default withdrawal amount in Gwei for testing\n\tDefaultWithdrawalAmount = 1_000_000_000 // 1 BERA (10^9 Gwei)\n\n\t// WithdrawalTxGasLimit is the gas limit for withdrawal transactions\n\tWithdrawalTxGasLimit = 500_000\n\n\t// BlocksToWaitAfterWithdrawal is the number of blocks to wait after a withdrawal\n\tBlocksToWaitAfterWithdrawal = 3\n)\n\n// rpcWrapper wraps an rpc.Client and implements the rpcClient interface required by EIP7002.\n// Referenced from execution/requests/eip7002/interfaces.go\ntype rpcWrapper struct {\n\t*rpc.Client\n}\n\n// Call implements the rpcClient interface.\n// Referenced from execution/requests/eip7002/interfaces.go\nfunc (r *rpcWrapper) Call(ctx context.Context, target any, method string, params ...any) error {\n\treturn r.Client.CallContext(ctx, target, method, params...)\n}\n\n// getPendingPartialWithdrawals calls the beacon node's /eth/v1/beacon/states/{state_id}/pending_partial_withdrawals endpoint\n// and returns the list of pending withdrawals data if any\nfunc (s *BeaconKitE2ESuite) getPendingPartialWithdrawals(stateID string) ([]types.PendingPartialWithdrawalData, error) {\n\tclient := s.initHTTPBeaconTest()\n\n\turl := fmt.Sprintf(\"/eth/v1/beacon/states/%s/pending_partial_withdrawals\", stateID)\n\n\tresp, err := client.Get(url)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get pending partial withdrawals: %w\", err)\n\t}\n\tif resp == nil {\n\t\treturn nil, errors.New(\"received nil response\")\n\t}\n\n\tdefer resp.Body.Close()\n\n\tvar response types.PendingPartialWithdrawalsResponse\n\tdecoder := json.NewDecoder(resp.Body)\n\tif err = decoder.Decode(&response); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to decode response: %w\", err)\n\t}\n\n\t// Validate response fields\n\ts.Require().Equal(response.Version, version.Name(version.Fulu())) // TODO: assert this is after Electra\n\ts.Require().False(response.ExecutionOptimistic)\n\ts.Require().True(response.Finalized)\n\n\twithdrawals, ok := response.Data.([]types.PendingPartialWithdrawalData)\n\tif !ok {\n\t\t// Only if direct type assertion fails, fall back to JSON remarshal\n\t\tdataBytes, errInMarshal := json.Marshal(response.Data)\n\t\tif errInMarshal != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to marshal data: %w\", errInMarshal)\n\t\t}\n\n\t\tif errInUnmarshal := json.Unmarshal(dataBytes, &withdrawals); errInUnmarshal != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to unmarshal withdrawals: %w\", errInUnmarshal)\n\t\t}\n\t}\n\n\treturn withdrawals, nil\n}\n\n// findValidatorWithExecutionCredentials finds a validator with execution credentials\n// It returns the validator index and the BLS public key of the validator with execution credentials\nfunc (s *BeaconKitE2ESuite) findValidatorWithExecutionCredentials(client *e2etypes.ConsensusClient) (string, crypto.BLSPubkey, error) {\n\t// Get the validators to identify one with execution credentials (0x01)\n\tvalidatorsResp, err := client.Validators(\n\t\ts.Ctx(),\n\t\t&beaconapi.ValidatorsOpts{\n\t\t\tState: utils.StateIDHead,\n\t\t},\n\t)\n\tif err != nil {\n\t\treturn \"\", crypto.BLSPubkey{}, fmt.Errorf(\"failed to get validators: %w\", err)\n\t}\n\tif len(validatorsResp.Data) == 0 {\n\t\treturn \"\", crypto.BLSPubkey{}, errors.New(\"no validators found\")\n\t}\n\n\t// Find a validator with execution withdrawal credentials (starting with 0x01)\n\tvar validatorIndex string\n\tvar blsPubkey crypto.BLSPubkey\n\tfor _, validator := range validatorsResp.Data {\n\t\tcredentials := validator.Validator.WithdrawalCredentials\n\n\t\t// Create beacon-kit's WithdrawalCredentials type\n\t\tvar beaconKitCredentials ctypes.WithdrawalCredentials\n\t\tcopy(beaconKitCredentials[:], credentials)\n\n\t\t// Check if it has execution withdrawal credentials\n\t\tif beaconKitCredentials.IsValidEth1WithdrawalCredentials() {\n\t\t\tvalidatorIndex = fmt.Sprintf(\"%d\", validator.Index)\n\t\t\t// Convert the phase0.BLSPubKey to our crypto.BLSPubkey type\n\t\t\tcopy(blsPubkey[:], validator.Validator.PublicKey[:])\n\t\t\treturn validatorIndex, blsPubkey, nil\n\t\t}\n\t}\n\n\treturn \"\", crypto.BLSPubkey{}, errors.New(\"no validator with execution withdrawal credentials found\")\n}\n\n// TestSubmitPartialWithdrawalTransaction tests submitting a partial withdrawal transaction via the withdrawal contract\nfunc (s *BeaconKitE2ESuite) TestSubmitPartialWithdrawalTransaction() {\n\t// Use timeout context to better control the test\n\tctx, cancel := context.WithTimeout(s.Ctx(), suite.DefaultE2ETestTimeout)\n\tdefer cancel()\n\n\t// Initialize test client\n\tclient := s.initBeaconTest()\n\n\t// Find a validator with execution credentials\n\tvalidatorIndex, blsPubkey, err := s.findValidatorWithExecutionCredentials(client)\n\ts.Require().NoError(err)\n\ts.T().Logf(\"Found validator with index %s for withdrawal test\", validatorIndex)\n\n\t// Set withdrawal amount\n\twithdrawalAmount := beaconmath.Gwei(DefaultWithdrawalAmount)\n\n\t// Create an rpc client using the EL client URL\n\telClient := s.ExecutionClients(0)\n\ts.Require().NotNil(elClient)\n\trpcClient, err := rpc.Dial(elClient.URL())\n\ts.Require().NoError(err)\n\tdefer rpcClient.Close()\n\trpcWrapper := &rpcWrapper{Client: rpcClient}\n\n\t// Get current block number before withdrawal\n\tblkNum, err := elClient.BlockNumber(ctx)\n\ts.Require().NoError(err)\n\ts.T().Logf(\"Block number before withdrawal: %d\", blkNum)\n\n\t// Check for pending partial withdrawals before submitting the transaction\n\tpendingWithdrawalsBefore, err := s.getPendingPartialWithdrawals(utils.StateIDHead)\n\ts.Require().NoError(err)\n\ts.Require().Len(pendingWithdrawalsBefore, 0, \"Expected no pending withdrawals initially\")\n\n\t// Get the withdrawal fee\n\tfee, err := eip7002.GetWithdrawalFee(ctx, rpcWrapper)\n\ts.Require().NoError(err)\n\ts.T().Logf(\"Withdrawal fee: %s wei\", fee.String())\n\n\t// Create the withdrawal transaction data\n\twithdrawalTxData, err := eip7002.CreateWithdrawalRequestData(blsPubkey, withdrawalAmount)\n\ts.Require().NoError(err)\n\n\t// Use the private key of the withdrawal address of the validator used to submit the transaction\n\tprivateKey, err := ethcrypto.HexToECDSA(\"fffdbb37105441e14b0ee6330d855d8504ff39e705c3afa8f859ac9865f99306\")\n\ts.Require().NoError(err)\n\n\tchainID, err := elClient.ChainID(ctx)\n\ts.Require().NoError(err)\n\tsigner := gethcore.NewPragueSigner(chainID)\n\n\t// Get the sender's nonce\n\tvar nonce hexutil.Uint64\n\t// Use the address derived from the validator's withdrawal credentials.\n\t// In kurtosis we use the same withdrawal address for all validators.\n\terr = rpcClient.CallContext(ctx, &nonce, \"eth_getTransactionCount\",\n\t\tcommon.HexToAddress(\"0x20f33ce90a13a4b5e7697e3544c3083b8f8a51d4\"), \"latest\",\n\t)\n\ts.Require().NoError(err)\n\n\t// Create and sign the transaction\n\ttx := gethcore.MustSignNewTx(privateKey, signer, &gethcore.DynamicFeeTx{\n\t\tChainID:   chainID,\n\t\tNonce:     uint64(nonce),\n\t\tTo:        &params.WithdrawalQueueAddress,\n\t\tGas:       WithdrawalTxGasLimit,\n\t\tGasFeeCap: big.NewInt(10000000000),\n\t\tGasTipCap: big.NewInt(10000000000),\n\t\tValue:     fee,\n\t\tData:      withdrawalTxData,\n\t})\n\n\t// Serialize the transaction\n\ttxBytes, err := tx.MarshalBinary()\n\ts.Require().NoError(err)\n\n\t// Send the transaction\n\tvar txHash common.Hash\n\terr = rpcClient.CallContext(ctx, &txHash, \"eth_sendRawTransaction\", hexutil.Encode(txBytes))\n\ts.Require().NoError(err)\n\ts.T().Logf(\"Withdrawal transaction submitted: %s\", txHash.Hex())\n\n\t// Wait for blocks to be mined after submitting the transaction\n\terr = s.WaitForNBlockNumbers(BlocksToWaitAfterWithdrawal)\n\ts.Require().NoError(err)\n\n\t// Get the transaction receipt\n\treceipt, err := elClient.TransactionReceipt(ctx, txHash)\n\ts.Require().NoError(err)\n\ts.Require().NotNil(receipt, \"Transaction receipt should not be nil\")\n\ts.T().Logf(\"Withdrawal transaction included in block: %d\", receipt.BlockNumber)\n\n\t// Check for pending partial withdrawals after submitting the transaction\n\tpendingWithdrawalsAfter, err := s.getPendingPartialWithdrawals(utils.StateIDHead)\n\ts.Require().NoError(err)\n\ts.Require().Len(pendingWithdrawalsAfter, 1, \"Expected one pending withdrawal after transaction\")\n\n\t// Verify the withdrawal details\n\ts.Require().Equal(validatorIndex, strconv.FormatUint(pendingWithdrawalsAfter[0].ValidatorIndex, 10),\n\t\t\"Validator index mismatch in pending withdrawal\")\n\ts.Require().Equal(uint64(withdrawalAmount), pendingWithdrawalsAfter[0].Amount,\n\t\t\"Withdrawal amount mismatch in pending withdrawal\")\n}\n"
  },
  {
    "path": "testing/e2e/suite/constants.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage suite\n\nimport (\n\t\"time\"\n\n\t\"github.com/ethereum/go-ethereum/params\"\n)\n\n// Ether represents the number of wei in one ether, used for Ethereum\n// transactions.\nconst (\n\tEther   = params.Ether\n\tTenGwei = 10 * params.GWei // 10 Gwei = 1e10 wei\n)\n\n// EtherTransferGasLimit specifies the gas limit for a standard Ethereum\n// transfer.\n// This is the amount of gas required to perform a basic ether transfer.\nconst (\n\tEtherTransferGasLimit uint64 = 21000 // Standard gas limit for ether transfer\n)\n\n// DefaultE2ETestTimeout defines the default timeout duration for end-to-end\n// tests. This is used to specify how long to wait for a test before considering\n// it failed.\nconst (\n\tDefaultE2ETestTimeout = 60 * 10 * time.Second // timeout for E2E tests\n)\n"
  },
  {
    "path": "testing/e2e/suite/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage suite\n\nimport \"github.com/berachain/beacon-kit/errors\"\n\n// ErrUnexpectedBalance is returned when the balance is unexpected.\nvar ErrUnexpectedBalance = errors.New(\"unexpected balance\")\n"
  },
  {
    "path": "testing/e2e/suite/options.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage suite\n\n// Option is a functional option for the KurtosisE2ESuite.\ntype Option func(*KurtosisE2ESuite) error\n"
  },
  {
    "path": "testing/e2e/suite/setup.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage suite\n\nimport (\n\t\"context\"\n\t\"crypto/ecdsa\"\n\t\"fmt\"\n\t\"math/big\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"cosmossdk.io/log\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/berachain/beacon-kit/testing/e2e/config\"\n\t\"github.com/berachain/beacon-kit/testing/e2e/suite/types\"\n\t\"github.com/ethereum/go-ethereum/accounts/abi/bind\"\n\t\"github.com/ethereum/go-ethereum/common\"\n\tethtypes \"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/ethereum/go-ethereum/crypto\"\n\t\"github.com/ethereum/go-ethereum/rpc\"\n\t\"github.com/kurtosis-tech/kurtosis/api/golang/core/lib/starlark_run_config\"\n\t\"github.com/kurtosis-tech/kurtosis/api/golang/engine/lib/kurtosis_context\"\n\t\"github.com/sourcegraph/conc/iter\"\n)\n\n// SetupSuite executes before the test suite begins execution.\nfunc (s *KurtosisE2ESuite) SetupSuite() {\n\ts.SetupSuiteWithOptions()\n}\n\n// SetupSuiteWithOptions sets up the test suite with the provided options.\n//\n//nolint:funlen // setup suite has many responsibilities...\nfunc (s *KurtosisE2ESuite) SetupSuiteWithOptions(opts ...Option) {\n\tvar (\n\t\tkey0, key1, key2 *ecdsa.PrivateKey\n\t\terr              error\n\t)\n\n\t// Setup some sane defaults.\n\ts.cfg = config.DefaultE2ETestConfig()\n\ts.ctx = context.Background()\n\ts.logger = log.NewTestLogger(s.T())\n\ts.Require().NoError(err, \"Error loading starlark helper file\")\n\ts.testAccounts = make([]*types.EthAccount, 3) //nolint:mnd // number of accounts.\n\n\ts.genesisAccount = types.NewEthAccountFromHex(\n\t\t\"genesisAccount\", \"fffdbb37105441e14b0ee6330d855d8504ff39e705c3afa8f859ac9865f99306\",\n\t)\n\tkey0, err = crypto.GenerateKey()\n\ts.Require().NoError(err, \"Error generating key\")\n\tkey1, err = crypto.GenerateKey()\n\ts.Require().NoError(err, \"Error generating key\")\n\tkey2, err = crypto.GenerateKey()\n\ts.Require().NoError(err, \"Error generating key\")\n\n\ts.testAccounts[0] = types.NewEthAccount(\"testAccount0\", key0)\n\ts.testAccounts[1] = types.NewEthAccount(\"testAccount1\", key1)\n\ts.testAccounts[2] = types.NewEthAccount(\"testAccount2\", key2)\n\n\t// Apply all the provided options, this allows\n\t// the test suite to be configured in a flexible manner by\n\t// the caller (i.e. overriding defaults).\n\tfor _, opt := range opts {\n\t\tif err = opt(s); err != nil {\n\t\t\ts.Require().NoError(err, \"Error applying option\")\n\t\t}\n\t}\n\n\ts.kCtx, err = kurtosis_context.NewKurtosisContextFromLocalEngine()\n\ts.Require().NoError(err)\n\n\ts.logger.Info(\"Destroying any existing enclave...\")\n\t//#nosec:G703 // It's okay if this errors out. It will error out\n\t// if there is no enclave to destroy.\n\t_ = s.kCtx.DestroyEnclave(s.ctx, \"e2e-test-enclave\")\n\n\t// Restart the engine to clear any stale state (equivalent to `kurtosis engine restart`)\n\tcmd := exec.CommandContext(s.ctx, \"kurtosis\", \"engine\", \"restart\")\n\tout, restartErr := cmd.CombinedOutput()\n\ts.logger.Info(\"Kurtosis engine restart\", \"output\", string(out))\n\ts.Require().NoError(restartErr, \"Failed to restart kurtosis engine\")\n\n\t// Re-connect after restart since the engine process changed\n\ts.kCtx, err = kurtosis_context.NewKurtosisContextFromLocalEngine()\n\ts.Require().NoError(err)\n\n\ts.logger.Info(\"Creating enclave...\")\n\ts.enclave, err = s.kCtx.CreateEnclave(s.ctx, \"e2e-test-enclave\")\n\ts.Require().NoError(err)\n\n\ts.logger.Info(\n\t\t\"Spinning up enclave...\",\n\t\t\"num_validators\",\n\t\tlen(s.cfg.NetworkConfiguration.Validators.Nodes),\n\t\t\"num_full_nodes\",\n\t\tlen(s.cfg.NetworkConfiguration.FullNodes.Nodes),\n\t)\n\n\t_, thisFile, _, ok := runtime.Caller(0)\n\ts.Require().True(ok, \"could not determine source file path\")\n\tkurtosisDir := filepath.Join(filepath.Dir(thisFile), \"..\", \"..\", \"..\", \"kurtosis\")\n\n\tresult, err := s.enclave.RunStarlarkPackageBlocking(\n\t\ts.ctx, kurtosisDir,\n\t\tstarlark_run_config.NewRunStarlarkConfig(\n\t\t\tstarlark_run_config.WithSerializedParams(s.cfg.MustMarshalJSON()),\n\t\t),\n\t)\n\ts.Require().NoError(err, \"Error running Starlark package\")\n\ts.Require().Nil(result.ExecutionError, \"Error running Starlark package\")\n\ts.Require().Empty(result.ValidationErrors)\n\ts.logger.Info(\"Enclave spun up successfully\")\n\n\ts.logger.Info(\"Setting up consensus clients\")\n\terr = s.SetupConsensusClients(s.ctx)\n\ts.Require().NoError(err, \"Error setting up consensus clients\")\n\n\t// Setup the JSON-RPC Execution Clients.\n\ts.logger.Info(\"Setting up JSON-RPC Execution Clients\")\n\terr = s.SetupExecutionClients(s.ctx)\n\ts.Require().NoError(err, \"Error setting up JSON-RPC Execution Clients\")\n\n\ts.logger.Info(\"Waiting for nodes to get ready...\")\n\t//nolint:mnd // its okay.\n\ttime.Sleep(5 * time.Second)\n\t// Wait for the finalized block number to increase a bit to\n\t// ensure all clients are in sync.\n\t//nolint:mnd // 3 blocks\n\terr = s.WaitForFinalizedBlockNumber(3)\n\ts.Require().NoError(err, \"Error waiting for finalized block number\")\n\n\t// Fund any requested accounts.\n\ts.FundAccounts()\n}\n\n// SetupConsensusClients sets up the consensus clients for the validator nodes.\n//\n// TODO: set up consensus clients for full nodes as well.\nfunc (s *KurtosisE2ESuite) SetupConsensusClients(ctx context.Context) error {\n\ts.consensusClients = make(map[string]*types.ConsensusClient, config.NumValidators)\n\tfor i := range config.NumValidators {\n\t\tclientName := config.ValidatorConsensusClientName(i)\n\t\tsCtx, err := s.Enclave().GetServiceContext(clientName)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\ts.consensusClients[clientName] = types.NewConsensusClient(sCtx)\n\t\tif err = s.consensusClients[clientName].Start(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// SetupExecutionClients sets up the execution clients for the full nodes.\n//\n// TODO: set up execution clients for validators as well.\nfunc (s *KurtosisE2ESuite) SetupExecutionClients(ctx context.Context) error {\n\ts.executionClients = make(map[string]*types.ExecutionClient, config.NumFullNodes)\n\tfor i := range config.NumFullNodes {\n\t\tclientName := config.FullNodeExecutionClientName(i)\n\t\tsCtx, err := s.Enclave().GetServiceContext(clientName)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\ts.executionClients[clientName] = types.NewExecutionClient(sCtx)\n\t\tif err = s.executionClients[clientName].Start(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// FundAccounts funds the accounts for the test suite.\n//\n//nolint:funlen\nfunc (s *KurtosisE2ESuite) FundAccounts() {\n\tctx := context.Background()\n\tnonce := atomic.Uint64{}\n\telClient := s.ExecutionClients(0)\n\ts.Require().NotNil(elClient)\n\tpendingNonce, err := elClient.PendingNonceAt(\n\t\tctx, s.genesisAccount.Address())\n\ts.Require().NoError(err, \"Failed to get nonce for genesis account\")\n\tnonce.Store(pendingNonce)\n\n\tvar chainID *big.Int\n\tchainID, err = elClient.ChainID(ctx)\n\ts.Require().NoError(err, \"failed to get chain ID\")\n\ts.logger.Info(\"Chain-id is\", \"chain_id\", chainID)\n\t_, err = iter.MapErr(\n\t\ts.testAccounts,\n\t\tfunc(acc **types.EthAccount) (*ethtypes.Receipt, error) {\n\t\t\taccount := *acc\n\t\t\tvar gasTipCap *big.Int\n\n\t\t\tif gasTipCap, err = elClient.SuggestGasTipCap(ctx); err != nil {\n\t\t\t\tvar rpcErr rpc.Error\n\t\t\t\tif errors.As(err, &rpcErr) && rpcErr.ErrorCode() == -32601 {\n\t\t\t\t\t// Fallback to default value of 10 Gwei if method not supported\n\t\t\t\t\tgasTipCap = big.NewInt(0).SetUint64(TenGwei)\n\t\t\t\t} else {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tgasFeeCap := new(big.Int).Add(\n\t\t\t\tgasTipCap, big.NewInt(0).SetUint64(TenGwei))\n\t\t\tnonceToSubmit := nonce.Add(1) - 1\n\t\t\t//nolint:mnd // 2_000_000_000 Ether\n\t\t\tvalue := new(big.Int).Mul(big.NewInt(2_000_000_000), big.NewInt(Ether))\n\t\t\tdest := account.Address()\n\t\t\tvar signedTx *ethtypes.Transaction\n\t\t\tif signedTx, err = s.genesisAccount.SignTx(\n\t\t\t\tchainID, ethtypes.NewTx(&ethtypes.DynamicFeeTx{\n\t\t\t\t\tChainID: chainID, Nonce: nonceToSubmit,\n\t\t\t\t\tGasTipCap: gasTipCap, GasFeeCap: gasFeeCap,\n\t\t\t\t\tGas: EtherTransferGasLimit, To: &dest,\n\t\t\t\t\tValue: value, Data: nil,\n\t\t\t\t}),\n\t\t\t); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tcctx, cancel := context.WithTimeout(ctx, DefaultE2ETestTimeout)\n\t\t\tdefer cancel()\n\t\t\tif err = elClient.SendTransaction(cctx, signedTx); err != nil {\n\t\t\t\ts.logger.Error(\n\t\t\t\t\t\"error submitting funding transaction\",\n\t\t\t\t\t\"error\",\n\t\t\t\t\terr,\n\t\t\t\t)\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\ts.logger.Info(\n\t\t\t\t\"Funding transaction submitted, waiting for confirmation...\",\n\t\t\t\t\"tx_hash\", signedTx.Hash().Hex(), \"nonce\", nonceToSubmit,\n\t\t\t\t\"account\", account.Name(), \"value\", value,\n\t\t\t)\n\n\t\t\tvar receipt *ethtypes.Receipt\n\n\t\t\tif receipt, err = bind.WaitMined(\n\t\t\t\tcctx, elClient, signedTx,\n\t\t\t); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\ts.logger.Info(\n\t\t\t\t\"Funding transaction confirmed\",\n\t\t\t\t\"tx_hash\", signedTx.Hash().Hex(),\n\t\t\t\t\"account\", account.Name(),\n\t\t\t)\n\n\t\t\t// Verify the receipt status.\n\t\t\tif receipt.Status != ethtypes.ReceiptStatusSuccessful {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\t// Wait an extra block to ensure all clients are in sync.\n\t\t\t//nolint:mnd,contextcheck // its okay.\n\t\t\tif err = s.WaitForFinalizedBlockNumber(\n\t\t\t\treceipt.BlockNumber.Uint64() + 2,\n\t\t\t); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\t// Verify the balance of the account\n\t\t\tvar balance *big.Int\n\t\t\tif balance, err = elClient.BalanceAt(ctx, dest, nil); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t} else if balance.Cmp(value) != 0 {\n\t\t\t\treturn nil, errors.Wrap(\n\t\t\t\t\tErrUnexpectedBalance, fmt.Sprintf(\"expected: %v, got: %v\", value, balance),\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn receipt, nil\n\t\t},\n\t)\n\ts.Require().NoError(err, \"Error funding accounts\")\n}\n\n// WaitForFinalizedBlockNumber waits for the finalized block number\n// to reach the target block number across all execution clients.\nfunc (s *KurtosisE2ESuite) WaitForFinalizedBlockNumber(target uint64) error {\n\tcctx, cancel := context.WithTimeout(s.ctx, DefaultE2ETestTimeout)\n\tdefer cancel()\n\tticker := time.NewTicker(time.Second)\n\tdefer ticker.Stop()\n\n\telClient := s.ExecutionClients(0)\n\ts.Require().NotNil(elClient)\n\tfinalBlockNum, err := elClient.BlockNumber(cctx)\n\tif err != nil {\n\t\ts.logger.Error(\"error getting finalized block number\", \"error\", err)\n\t}\n\tfor finalBlockNum < target {\n\t\t// check if cctx deadline is exceeded to prevent endless loop\n\t\tselect {\n\t\tcase <-cctx.Done():\n\t\t\treturn cctx.Err()\n\t\tdefault:\n\t\t}\n\n\t\tfinalBlockNum, err = elClient.BlockNumber(cctx)\n\t\tif err != nil {\n\t\t\ts.logger.Error(\"error getting finalized block number\", \"error\", err)\n\t\t\tcontinue\n\t\t}\n\t\ts.logger.Info(\n\t\t\t\"Waiting for finalized block number to reach target\",\n\t\t\t\"target\",\n\t\t\ttarget,\n\t\t\t\"finalized\",\n\t\t\tfinalBlockNum,\n\t\t)\n\n\t\tselect {\n\t\tcase <-s.ctx.Done():\n\t\t\treturn s.ctx.Err()\n\t\tcase <-ticker.C:\n\t\t\tcontinue\n\t\t}\n\t}\n\n\ts.logger.Info(\n\t\t\"Finalized block number reached target 🎉\",\n\t\t\"target\",\n\t\ttarget,\n\t\t\"finalized\",\n\t\tfinalBlockNum,\n\t)\n\n\treturn nil\n}\n\n// WaitForNBlockNumbers waits for a specified amount of blocks into the future\n// from now.\nfunc (s *KurtosisE2ESuite) WaitForNBlockNumbers(n uint64) error {\n\telClient := s.ExecutionClients(0)\n\ts.Require().NotNil(elClient)\n\tcurrent, err := elClient.BlockNumber(s.ctx)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn s.WaitForFinalizedBlockNumber(current + n)\n}\n\n// TearDownSuite cleans up resources after all tests have been executed.\n// this function executes after all tests executed.\nfunc (s *KurtosisE2ESuite) TearDownSuite() {\n\ts.Logger().Info(\"Destroying enclave...\")\n\tfor _, client := range s.consensusClients {\n\t\tclient.Stop(s.ctx)\n\t}\n\ts.Require().NoError(s.kCtx.DestroyEnclave(s.ctx, \"e2e-test-enclave\"))\n}\n\n// CheckForSuccessfulTx returns true if the transaction was successful.\nfunc (s *KurtosisE2ESuite) CheckForSuccessfulTx(tx common.Hash) bool {\n\tctx, cancel := context.WithTimeout(s.Ctx(), DefaultE2ETestTimeout)\n\tdefer cancel()\n\n\telClient := s.ExecutionClients(0)\n\ts.Require().NotNil(elClient)\n\treceipt, err := elClient.TransactionReceipt(ctx, tx)\n\tif err != nil {\n\t\ts.Logger().Error(\"Error getting transaction receipt\", \"error\", err)\n\t\treturn false\n\t}\n\treturn receipt.Status == ethtypes.ReceiptStatusSuccessful\n}\n"
  },
  {
    "path": "testing/e2e/suite/suite.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage suite\n\nimport (\n\t\"context\"\n\n\t\"github.com/berachain/beacon-kit/log\"\n\t\"github.com/berachain/beacon-kit/testing/e2e/config\"\n\t\"github.com/berachain/beacon-kit/testing/e2e/suite/types\"\n\t\"github.com/kurtosis-tech/kurtosis/api/golang/core/lib/enclaves\"\n\t\"github.com/kurtosis-tech/kurtosis/api/golang/engine/lib/kurtosis_context\"\n\t\"github.com/stretchr/testify/suite\"\n)\n\n// Run is an alias for suite.Run to help with importing\n// in other packages.\n//\n//nolint:gochecknoglobals // intentionally.\nvar Run = suite.Run\n\n// KurtosisE2ESuite.\ntype KurtosisE2ESuite struct {\n\tsuite.Suite\n\tcfg     *config.E2ETestConfig\n\tlogger  log.Logger\n\tctx     context.Context\n\tkCtx    *kurtosis_context.KurtosisContext\n\tenclave *enclaves.EnclaveContext\n\n\tconsensusClients map[string]*types.ConsensusClient\n\texecutionClients map[string]*types.ExecutionClient\n\n\tgenesisAccount *types.EthAccount\n\ttestAccounts   []*types.EthAccount\n}\n\n// Config returns the E2ETestConfig associated with the KurtosisE2ESuite.\nfunc (s *KurtosisE2ESuite) Config() *config.E2ETestConfig {\n\treturn s.cfg\n}\n\n// ConsensusClients returns the consensus client for the given validator number.\nfunc (s *KurtosisE2ESuite) ConsensusClients(numValidator int) *types.ConsensusClient {\n\treturn s.consensusClients[config.ValidatorConsensusClientName(numValidator)]\n}\n\n// Ctx returns the context associated with the KurtosisE2ESuite.\n// This context is used throughout the suite to control the flow of operations,\n// including timeouts and cancellations.\nfunc (s *KurtosisE2ESuite) Ctx() context.Context {\n\treturn s.ctx\n}\n\n// Enclave returns the enclave running the beacon-kit network.\nfunc (s *KurtosisE2ESuite) Enclave() *enclaves.EnclaveContext {\n\treturn s.enclave\n}\n\n// ExecutionClients returns the execution client for the given full node number.\nfunc (s *KurtosisE2ESuite) ExecutionClients(numFullNode int) *types.ExecutionClient {\n\treturn s.executionClients[config.FullNodeExecutionClientName(numFullNode)]\n}\n\n// GenesisAccount returns the genesis account for the test suite.\nfunc (s *KurtosisE2ESuite) GenesisAccount() *types.EthAccount {\n\treturn s.genesisAccount\n}\n\n// KurtosisCtx returns the KurtosisContext associated with the KurtosisE2ESuite.\n// The KurtosisContext is a critical component that facilitates interaction with\n// the Kurtosis testnet, including creating and managing enclaves.\nfunc (s *KurtosisE2ESuite) KurtosisCtx() *kurtosis_context.KurtosisContext {\n\treturn s.kCtx\n}\n\n// Logger returns the logger for the test suite.\nfunc (s *KurtosisE2ESuite) Logger() log.Logger {\n\treturn s.logger\n}\n\n// TestAccounts returns the test accounts for the test suite.\nfunc (s *KurtosisE2ESuite) TestAccounts() []*types.EthAccount {\n\treturn s.testAccounts\n}\n"
  },
  {
    "path": "testing/e2e/suite/types/account.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"crypto/ecdsa\"\n\t\"math/big\"\n\n\t\"github.com/berachain/beacon-kit/errors\"\n\t\"github.com/ethereum/go-ethereum/accounts/abi/bind\"\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/ethereum/go-ethereum/crypto\"\n)\n\n// EthAccount represents an Ethereum account.\ntype EthAccount struct {\n\tname string\n\tpk   *ecdsa.PrivateKey\n}\n\n// NewEthAccountFromHex creates a new Ethereum account from hex private key.\nfunc NewEthAccountFromHex(\n\tname string,\n\thexPk string,\n) *EthAccount {\n\tpk, err := crypto.HexToECDSA(hexPk)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn &EthAccount{\n\t\tname: name,\n\t\tpk:   pk,\n\t}\n}\n\n// NewEthAccount creates a new Ethereum account.\nfunc NewEthAccount(\n\tname string,\n\tpk *ecdsa.PrivateKey,\n) *EthAccount {\n\treturn &EthAccount{\n\t\tname: name,\n\t\tpk:   pk,\n\t}\n}\n\n// Name returns the name of the account.\nfunc (a EthAccount) Name() string {\n\treturn a.name\n}\n\n// SignTx signs a transaction with the account's private key.\nfunc (a EthAccount) SignTx(\n\tchainID *big.Int, tx *types.Transaction,\n) (*types.Transaction, error) {\n\treturn types.SignTx(\n\t\ttx, types.LatestSignerForChainID(chainID), a.pk,\n\t)\n}\n\n// SignerFunc returns a signer function for the account.\nfunc (a EthAccount) SignerFunc(chainID *big.Int) bind.SignerFn {\n\treturn func(\n\t\taddr common.Address, tx *types.Transaction,\n\t) (*types.Transaction, error) {\n\t\tif addr != a.Address() {\n\t\t\treturn nil, errors.New(\"account not authorized to sign\")\n\t\t}\n\t\treturn a.SignTx(chainID, tx)\n\t}\n}\n\n// PublicKey returns the public key of the account.\nfunc (a EthAccount) PublicKey() *ecdsa.PublicKey {\n\treturn &a.pk.PublicKey\n}\n\n// PrivateKey returns the private key of the account.\nfunc (a EthAccount) PrivateKey() *ecdsa.PrivateKey {\n\treturn a.pk\n}\n\n// Address returns the address of the account.\nfunc (a EthAccount) Address() common.Address {\n\treturn crypto.PubkeyToAddress(a.pk.PublicKey)\n}\n"
  },
  {
    "path": "testing/e2e/suite/types/account_test.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/testing/e2e/suite/types\"\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-ethereum/crypto\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestNewEthAccount(t *testing.T) {\n\tt.Parallel()\n\tname := \"testAccount\"\n\thexPk := \"f561d45d1df30a6556d30e39f97011faa3632e43cd378224ad6cc83bb8aea3e6\"\n\n\taccount := types.NewEthAccountFromHex(name, hexPk)\n\trequire.NotNil(t, account.PrivateKey())\n\trequire.Equal(t, name, account.Name())\n}\n\nfunc TestEthAccount_PublicKey(t *testing.T) {\n\tt.Parallel()\n\thexPk := \"f561d45d1df30a6556d30e39f97011faa3632e43cd378224ad6cc83bb8aea3e6\"\n\texpectedPrivateKey, _ := crypto.HexToECDSA(hexPk)\n\trequire.NotNil(t, expectedPrivateKey)\n\n\taccount := types.NewEthAccountFromHex(\"testAccount\", hexPk)\n\tpublicKey := account.PublicKey()\n\n\trequire.Equal(t, expectedPrivateKey.PublicKey, *publicKey)\n}\n\nfunc TestEthAccount_Address(t *testing.T) {\n\tt.Parallel()\n\thexPk := \"f561d45d1df30a6556d30e39f97011faa3632e43cd378224ad6cc83bb8aea3e6\"\n\taccount := types.NewEthAccountFromHex(\"testAccount\", hexPk)\n\taddress := account.Address()\n\n\texpectedAddress := common.HexToAddress(\n\t\t\"0x9e0437E86fE55b4D6Bb1191CbACdA384775fF63D\",\n\t)\n\trequire.Equal(t, expectedAddress, address)\n}\n"
  },
  {
    "path": "testing/e2e/suite/types/beacon_client.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\n\tclient \"github.com/attestantio/go-eth2-client\"\n\tbeaconapi \"github.com/attestantio/go-eth2-client/api\"\n\tapiv1 \"github.com/attestantio/go-eth2-client/api/v1\"\n\tbeaconhttp \"github.com/attestantio/go-eth2-client/http\"\n\t\"github.com/attestantio/go-eth2-client/spec/phase0\"\n\tptypes \"github.com/berachain/beacon-kit/node-api/handlers/proof/types\"\n\t\"github.com/pkg/errors\"\n)\n\n// BeaconKitNodeClient is a wrapper around the client.Service interface to add\n// additional methods specific to a beacon-kit node's API.\ntype BeaconKitNodeClient interface {\n\tclient.Service\n\n\tclient.FarFutureEpochProvider\n\tclient.SignedBeaconBlockProvider\n\tclient.BlobSidecarsProvider\n\tclient.BeaconCommitteesProvider\n\tclient.SyncCommitteesProvider\n\tclient.AggregateAttestationProvider\n\tclient.AggregateAttestationsSubmitter\n\tclient.AttestationDataProvider\n\tclient.AttestationPoolProvider\n\tclient.AttestationsSubmitter\n\tclient.AttesterSlashingSubmitter\n\tclient.AttesterDutiesProvider\n\tclient.SyncCommitteeDutiesProvider\n\tclient.SyncCommitteeMessagesSubmitter\n\tclient.SyncCommitteeSubscriptionsSubmitter\n\tclient.SyncCommitteeContributionProvider\n\tclient.SyncCommitteeContributionsSubmitter\n\tclient.BLSToExecutionChangesSubmitter\n\tclient.BeaconBlockHeadersProvider\n\tclient.ProposalProvider\n\tclient.ProposalSlashingSubmitter\n\tclient.BeaconBlockRootProvider\n\tclient.ProposalSubmitter\n\tclient.BeaconCommitteeSubscriptionsSubmitter\n\tclient.BeaconStateProvider\n\tclient.BeaconStateRandaoProvider\n\tclient.BeaconStateRootProvider\n\tclient.BlindedProposalSubmitter\n\tclient.ValidatorRegistrationsSubmitter\n\tclient.EventsProvider\n\tclient.FinalityProvider\n\tclient.ForkChoiceProvider\n\tclient.ForkProvider\n\tclient.ForkScheduleProvider\n\tclient.GenesisProvider\n\tclient.NodePeersProvider\n\tclient.NodeSyncingProvider\n\tclient.NodeVersionProvider\n\tclient.ProposalPreparationsSubmitter\n\tclient.ProposerDutiesProvider\n\tclient.SpecProvider\n\tclient.ValidatorBalancesProvider\n\tclient.ValidatorsProvider\n\tclient.VoluntaryExitSubmitter\n\tclient.VoluntaryExitPoolProvider\n\tclient.DomainProvider\n\tclient.NodeClientProvider\n\n\t// BlockProposerProof calls `bkit/v1/proof/block_proposer/:timestamp_id` endpoint to get\n\t// the merkle proofs that can be used to verify the block proposer for a given timestamp id.\n\tBlockProposerProof(\n\t\tctx context.Context, timestampID string,\n\t) (*ptypes.BlockProposerResponse, error)\n\n\t// ValidatorBalanceProof calls `bkit/v1/proof/validator_balance/:timestamp_id/:validator_index` endpoint to get\n\t// the merkle proofs that can be used to verify the validator balance for a given timestamp id and validator index.\n\tValidatorBalanceProof(\n\t\tctx context.Context, timestampID string, validatorIndex string,\n\t) (*ptypes.ValidatorBalanceResponse, error)\n\n\t// ValidatorCredentialsProof calls `bkit/v1/proof/validator_credentials/:timestamp_id/:validator_index` endpoint to get\n\t// the merkle proofs that can be used to verify the validator withdrawal credentials for a given timestamp id and validator index.\n\tValidatorCredentialsProof(\n\t\tctx context.Context, timestampID string, validatorIndex string,\n\t) (*ptypes.ValidatorWithdrawalCredentialsResponse, error)\n\n\t// ValidatorPubkeyProof calls `bkit/v1/proof/validator_pubkey/:timestamp_id/:validator_index` endpoint to get\n\t// the merkle proof that can be used to verify the validator pubkey for a given timestamp id and validator index.\n\tValidatorPubkeyProof(\n\t\tctx context.Context, timestampID string, validatorIndex string,\n\t) (*ptypes.ValidatorPubkeyResponse, error)\n}\n\n// customBeaconClient is a custom implementation of the BeaconKitNodeClient interface\n// that overrides the Validators method to handle deneb1.\ntype customBeaconClient struct {\n\t*beaconhttp.Service\n\taddress string\n\tclient  *http.Client\n}\n\n// NewBeaconKitNodeClient creates a new beacon-kit node-api client instance\n// with the given cancel context.\nfunc NewBeaconKitNodeClient(\n\tcancelCtx context.Context,\n\tparams ...beaconhttp.Parameter,\n) (BeaconKitNodeClient, error) {\n\tservice, err := beaconhttp.New(\n\t\tcancelCtx,\n\t\tparams...,\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif service == nil {\n\t\treturn nil, errors.New(\"service is nil\")\n\t}\n\n\taddress := service.Address()\n\tif address == \"\" {\n\t\treturn nil, errors.New(\"no address specified\")\n\t}\n\n\t// Type assert service to beaconhttp.Service\n\thttpService, ok := service.(*beaconhttp.Service)\n\tif !ok {\n\t\treturn nil, errors.New(\"failed to cast service to beaconhttp.Service\")\n\t}\n\n\treturn &customBeaconClient{\n\t\tService: httpService,\n\t\taddress: address,\n\t\tclient:  &http.Client{},\n\t}, nil\n}\n\n// Validators implements a custom validator query that handles deneb1.\nfunc (c *customBeaconClient) Validators(\n\tctx context.Context,\n\topts *beaconapi.ValidatorsOpts,\n) (*beaconapi.Response[map[phase0.ValidatorIndex]*apiv1.Validator], error) {\n\tif opts == nil {\n\t\treturn nil, errors.New(\"no options specified\")\n\t}\n\tif opts.State == \"\" {\n\t\treturn nil, errors.New(\"no state specified\")\n\t}\n\n\t// Construct the URL\n\turl := fmt.Sprintf(\"%s/eth/v1/beacon/states/%s/validators\", c.address, opts.State)\n\n\tparams := make([]string, 0)\n\t// Add indices\n\tfor _, idx := range opts.Indices {\n\t\tparams = append(params, fmt.Sprintf(\"id=%d\", idx))\n\t}\n\n\t// Add pubkeys\n\tfor _, key := range opts.PubKeys {\n\t\tparams = append(params, fmt.Sprintf(\"id=%s\", key))\n\t}\n\n\t// Add validator states\n\tfor _, state := range opts.ValidatorStates {\n\t\tparams = append(params, fmt.Sprintf(\"status=%s\", state))\n\t}\n\n\tif len(params) > 0 {\n\t\turl = fmt.Sprintf(\"%s?%s\", url, strings.Join(params, \"&\"))\n\t}\n\n\t// Make GET request for empty indices\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create request: %w\", err)\n\t}\n\n\tresp, err := c.client.Do(req) //#nosec:G704 // URL is from trusted test infrastructure.\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to send request: %w\", err)\n\t}\n\tif resp == nil {\n\t\treturn nil, errors.New(\"received nil response\")\n\t}\n\tdefer resp.Body.Close()\n\n\t// Parse response\n\tvar result struct {\n\t\tData                []*apiv1.Validator `json:\"data\"`\n\t\tExecutionOptimistic bool               `json:\"execution_optimistic\"`\n\t\tFinalized           bool               `json:\"finalized\"`\n\t}\n\n\tif err = json.NewDecoder(resp.Body).Decode(&result); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to decode response: %w\", err)\n\t}\n\n\t// Convert array to map\n\tvalidators := make(map[phase0.ValidatorIndex]*apiv1.Validator)\n\tfor _, v := range result.Data {\n\t\tvalidators[v.Index] = v\n\t}\n\n\treturn &beaconapi.Response[map[phase0.ValidatorIndex]*apiv1.Validator]{\n\t\tData: validators,\n\t\tMetadata: map[string]any{\n\t\t\t\"execution_optimistic\": result.ExecutionOptimistic,\n\t\t\t\"finalized\":            result.Finalized,\n\t\t},\n\t}, nil\n}\n\n// BlockProposerProof calls `bkit/v1/proof/block_proposer/:timestamp_id` endpoint to get\n// the merkle proofs that can be used to verify the block proposer for a given timestamp id.\nfunc (c *customBeaconClient) BlockProposerProof(\n\tctx context.Context, timestampID string,\n) (*ptypes.BlockProposerResponse, error) {\n\turl := fmt.Sprintf(\"%s/bkit/v1/proof/block_proposer/%s\", c.address, timestampID)\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create request: %w\", err)\n\t}\n\n\tresp, err := c.client.Do(req) //#nosec:G704 // URL is from trusted test infrastructure.\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to send request: %w\", err)\n\t}\n\tif resp == nil {\n\t\treturn nil, errors.New(\"received nil response\")\n\t}\n\tdefer resp.Body.Close()\n\n\tvar result ptypes.BlockProposerResponse\n\tif err = json.NewDecoder(resp.Body).Decode(&result); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to decode response: %w\", err)\n\t}\n\n\treturn &result, nil\n}\n\n// ValidatorBalanceProof calls `bkit/v1/proof/validator_balance/:timestamp_id/:validator_index` endpoint to get\n// the merkle proofs that can be used to verify the validator balance for a given timestamp id and validator index.\nfunc (c *customBeaconClient) ValidatorBalanceProof(\n\tctx context.Context, timestampID string, validatorIndex string,\n) (*ptypes.ValidatorBalanceResponse, error) {\n\turl := fmt.Sprintf(\"%s/bkit/v1/proof/validator_balance/%s/%s\", c.address, timestampID, validatorIndex)\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create request: %w\", err)\n\t}\n\n\tresp, err := c.client.Do(req) //#nosec:G704 // URL is from trusted test infrastructure.\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to send request: %w\", err)\n\t}\n\tif resp == nil {\n\t\treturn nil, errors.New(\"received nil response\")\n\t}\n\tdefer resp.Body.Close()\n\n\tvar result ptypes.ValidatorBalanceResponse\n\tif err = json.NewDecoder(resp.Body).Decode(&result); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to decode response: %w\", err)\n\t}\n\n\treturn &result, nil\n}\n\n// ValidatorCredentialsProof calls `bkit/v1/proof/validator_credentials/:timestamp_id/:validator_index` endpoint to get\n// the merkle proofs that can be used to verify the validator withdrawal credentials for a given timestamp id and validator index.\nfunc (c *customBeaconClient) ValidatorCredentialsProof(\n\tctx context.Context, timestampID string, validatorIndex string,\n) (*ptypes.ValidatorWithdrawalCredentialsResponse, error) {\n\turl := fmt.Sprintf(\"%s/bkit/v1/proof/validator_credentials/%s/%s\", c.address, timestampID, validatorIndex)\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create request: %w\", err)\n\t}\n\n\tresp, err := c.client.Do(req) //#nosec:G704 // URL is from trusted test infrastructure.\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to send request: %w\", err)\n\t}\n\tif resp == nil {\n\t\treturn nil, errors.New(\"received nil response\")\n\t}\n\tdefer resp.Body.Close()\n\n\tvar result ptypes.ValidatorWithdrawalCredentialsResponse\n\tif err = json.NewDecoder(resp.Body).Decode(&result); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to decode response: %w\", err)\n\t}\n\n\treturn &result, nil\n}\n\n// ValidatorPubkeyProof calls `bkit/v1/proof/validator_pubkey/:timestamp_id/:validator_index` endpoint to get\n// the merkle proof that can be used to verify the validator pubkey for a given timestamp id and validator index.\nfunc (c *customBeaconClient) ValidatorPubkeyProof(\n\tctx context.Context, timestampID string, validatorIndex string,\n) (*ptypes.ValidatorPubkeyResponse, error) {\n\turl := fmt.Sprintf(\"%s/bkit/v1/proof/validator_pubkey/%s/%s\", c.address, timestampID, validatorIndex)\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create request: %w\", err)\n\t}\n\n\tresp, err := c.client.Do(req) //#nosec:G704 // URL is from trusted test infrastructure.\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to send request: %w\", err)\n\t}\n\tif resp == nil {\n\t\treturn nil, errors.New(\"received nil response\")\n\t}\n\tdefer resp.Body.Close()\n\n\tvar result ptypes.ValidatorPubkeyResponse\n\tif err = json.NewDecoder(resp.Body).Decode(&result); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to decode response: %w\", err)\n\t}\n\n\treturn &result, nil\n}\n"
  },
  {
    "path": "testing/e2e/suite/types/consensus_client.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\tbeaconapi \"github.com/attestantio/go-eth2-client/api\"\n\tapiv1 \"github.com/attestantio/go-eth2-client/api/v1\"\n\tbeaconhttp \"github.com/attestantio/go-eth2-client/http\"\n\t\"github.com/attestantio/go-eth2-client/spec/deneb\"\n\t\"github.com/attestantio/go-eth2-client/spec/phase0\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\tptypes \"github.com/berachain/beacon-kit/node-api/handlers/proof/types\"\n\tabcitypes \"github.com/cometbft/cometbft/abci/types\"\n\trpcclient \"github.com/cometbft/cometbft/rpc/client\"\n\thttpclient \"github.com/cometbft/cometbft/rpc/client/http\"\n\tcoretypes \"github.com/cometbft/cometbft/rpc/core/types\"\n\t\"github.com/kurtosis-tech/kurtosis/api/golang/core/lib/services\"\n\t\"github.com/rs/zerolog\"\n)\n\n// ConsensusClient represents a consensus client.\ntype ConsensusClient struct {\n\t*services.ServiceContext\n\n\t// Comet JSON-RPC client\n\tcometClient rpcclient.Client\n\n\t// Beacon node-api client\n\tbeaconClient BeaconKitNodeClient\n\n\t// Cancel function for the context\n\tcancelFunc context.CancelFunc\n}\n\n// NewConsensusClient creates a new consensus client.\nfunc NewConsensusClient(serviceCtx *services.ServiceContext) *ConsensusClient {\n\treturn &ConsensusClient{\n\t\tServiceContext: serviceCtx,\n\t}\n}\n\n// Start starts the consensus client.\nfunc (cc *ConsensusClient) Start(ctx context.Context) error {\n\t// Start by trying to get the public port for the comet JSON-RPC.\n\tcometPort, ok := cc.GetPublicPorts()[\"cometbft-rpc\"]\n\tif !ok {\n\t\treturn ErrPublicPortNotFound\n\t}\n\tclientURL := fmt.Sprintf(\"http://0.0.0.0:%d\", cometPort.GetNumber())\n\tclient, err := httpclient.New(clientURL)\n\tif err != nil {\n\t\treturn err\n\t}\n\tcc.cometClient = client\n\n\t// Then try to get the public port for the node API.\n\tnodePort, ok := cc.GetPublicPorts()[\"node-api\"]\n\tif !ok {\n\t\treturn ErrPublicPortNotFound\n\t}\n\tcancelCtx, cancel := context.WithCancel(ctx)\n\n\tcc.beaconClient, err = NewBeaconKitNodeClient(\n\t\tcancelCtx,\n\t\tbeaconhttp.WithAddress(\n\t\t\tfmt.Sprintf(\"http://0.0.0.0:%d\", nodePort.GetNumber()),\n\t\t),\n\t\tbeaconhttp.WithLogLevel(zerolog.DebugLevel),\n\t)\n\tif err != nil {\n\t\tcancel()\n\t\treturn err\n\t}\n\tcc.cancelFunc = cancel\n\n\treturn nil\n}\n\n// Stop stops the consensus client.\nfunc (cc *ConsensusClient) Stop(context.Context) {\n\tif cc.cancelFunc != nil {\n\t\tcc.cancelFunc()\n\t}\n}\n\n// GetPubKey returns the public key of the validator running on this node.\nfunc (cc *ConsensusClient) GetPubKey(ctx context.Context) ([]byte, error) {\n\tres, err := cc.cometClient.Status(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t} else if res.ValidatorInfo.PubKey == nil {\n\t\treturn nil, errors.New(\"node public key is nil\")\n\t}\n\n\treturn res.ValidatorInfo.PubKey.Bytes(), nil\n}\n\n// GetConsensusPower returns the consensus power of the node.\nfunc (cc *ConsensusClient) GetConsensusPower(ctx context.Context) (uint64, error) {\n\tres, err := cc.cometClient.Status(ctx)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\t// #nosec G115 -- VotingPower won't ever be negative.\n\treturn uint64(res.ValidatorInfo.VotingPower), nil\n}\n\n// IsActive returns true if the node is an active validator.\nfunc (cc *ConsensusClient) IsActive(ctx context.Context) (bool, error) {\n\tres, err := cc.cometClient.Status(ctx)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\treturn res.ValidatorInfo.VotingPower > 0, nil\n}\n\n// ABCIInfo returns the ABCI info of the node.\nfunc (cc ConsensusClient) ABCIInfo(\n\tctx context.Context,\n) (*abcitypes.InfoResponse, error) {\n\tif cc.cometClient == nil {\n\t\treturn nil, errors.New(\"comet client is not initialized\")\n\t}\n\tresp, err := cc.cometClient.ABCIInfo(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &resp.Response, nil\n}\n\n// ABCIQuery returns the ABCI query from the comet node.\nfunc (cc ConsensusClient) ABCIQuery(\n\tctx context.Context,\n\tpath string,\n\tdata []byte,\n\topts rpcclient.ABCIQueryOptions,\n) (*abcitypes.QueryResponse, error) {\n\tif cc.cometClient == nil {\n\t\treturn nil, errors.New(\"comet client is not initialized\")\n\t}\n\tresp, err := cc.cometClient.ABCIQueryWithOptions(ctx, path, data, opts)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &resp.Response, nil\n}\n\n// BeaconStateRoot returns the beacon state root of the node.\nfunc (cc ConsensusClient) BeaconStateRoot(\n\tctx context.Context,\n\topts *beaconapi.BeaconStateRootOpts,\n) (*beaconapi.Response[*phase0.Root], error) {\n\tif cc.beaconClient == nil {\n\t\treturn nil, errors.New(\"beacon client is not initialized\")\n\t}\n\treturn cc.beaconClient.BeaconStateRoot(ctx, opts)\n}\n\n// Validators returns the validator.\nfunc (cc ConsensusClient) Validators(\n\tctx context.Context,\n\topts *beaconapi.ValidatorsOpts,\n) (*beaconapi.Response[map[phase0.ValidatorIndex]*apiv1.Validator], error) {\n\tif cc.beaconClient == nil {\n\t\treturn nil, errors.New(\"beacon client is not initialized\")\n\t}\n\treturn cc.beaconClient.Validators(ctx, opts)\n}\n\n// BlobSidecars returns the blob sidecars for a given block.\nfunc (cc ConsensusClient) BlobSidecars(\n\tctx context.Context,\n\topts *beaconapi.BlobSidecarsOpts,\n) (*beaconapi.Response[[]*deneb.BlobSidecar], error) {\n\tif cc.beaconClient == nil {\n\t\treturn nil, errors.New(\"beacon client is not initialized\")\n\t}\n\treturn cc.beaconClient.BlobSidecars(ctx, opts)\n}\n\n// ValidatorBalances returns the validator balances for a given state.\nfunc (cc ConsensusClient) ValidatorBalances(\n\tctx context.Context,\n\topts *beaconapi.ValidatorBalancesOpts,\n) (*beaconapi.Response[map[phase0.ValidatorIndex]phase0.Gwei], error) {\n\tif cc.beaconClient == nil {\n\t\treturn nil, errors.New(\"beacon client is not initialized\")\n\t}\n\treturn cc.beaconClient.ValidatorBalances(ctx, opts)\n}\n\n// Genesis returns the genesis of the beacon node.\nfunc (cc ConsensusClient) Genesis(\n\tctx context.Context,\n\topts *beaconapi.GenesisOpts,\n) (*beaconapi.Response[*apiv1.Genesis], error) {\n\tif cc.beaconClient == nil {\n\t\treturn nil, errors.New(\"beacon client is not initialized\")\n\t}\n\treturn cc.beaconClient.Genesis(ctx, opts)\n}\n\n// Spec returns the spec of the beacon node.\nfunc (cc ConsensusClient) Spec(\n\tctx context.Context,\n\topts *beaconapi.SpecOpts,\n) (*beaconapi.Response[map[string]any], error) {\n\tif cc.beaconClient == nil {\n\t\treturn nil, errors.New(\"beacon client is not initialized\")\n\t}\n\treturn cc.beaconClient.Spec(ctx, opts)\n}\n\n// BlockProposerProof returns the block proposer proof for a given timestamp id.\nfunc (cc ConsensusClient) BlockProposerProof(\n\tctx context.Context,\n\ttimestampID string,\n) (*ptypes.BlockProposerResponse, error) {\n\tif cc.beaconClient == nil {\n\t\treturn nil, errors.New(\"beacon client is not initialized\")\n\t}\n\treturn cc.beaconClient.BlockProposerProof(ctx, timestampID)\n}\n\n// ValidatorBalanceProof returns the validator balance proof for a given timestamp id and validator index.\nfunc (cc ConsensusClient) ValidatorBalanceProof(\n\tctx context.Context,\n\ttimestampID string,\n\tvalidatorIndex string,\n) (*ptypes.ValidatorBalanceResponse, error) {\n\tif cc.beaconClient == nil {\n\t\treturn nil, errors.New(\"beacon client is not initialized\")\n\t}\n\treturn cc.beaconClient.ValidatorBalanceProof(ctx, timestampID, validatorIndex)\n}\n\n// ValidatorCredentialsProof returns the validator withdrawal credentials proof for a given timestamp id and validator index.\nfunc (cc ConsensusClient) ValidatorCredentialsProof(\n\tctx context.Context,\n\ttimestampID string,\n\tvalidatorIndex string,\n) (*ptypes.ValidatorWithdrawalCredentialsResponse, error) {\n\tif cc.beaconClient == nil {\n\t\treturn nil, errors.New(\"beacon client is not initialized\")\n\t}\n\treturn cc.beaconClient.ValidatorCredentialsProof(ctx, timestampID, validatorIndex)\n}\n\n// ValidatorPubkeyProof returns the validator pubkey proof for a given timestamp id and validator index.\nfunc (cc ConsensusClient) ValidatorPubkeyProof(\n\tctx context.Context,\n\ttimestampID string,\n\tvalidatorIndex string,\n) (*ptypes.ValidatorPubkeyResponse, error) {\n\tif cc.beaconClient == nil {\n\t\treturn nil, errors.New(\"beacon client is not initialized\")\n\t}\n\treturn cc.beaconClient.ValidatorPubkeyProof(ctx, timestampID, validatorIndex)\n}\n\n// Commit returns the commit for a block.\nfunc (cc ConsensusClient) Commit(\n\tctx context.Context,\n\theight *int64,\n) (*coretypes.ResultCommit, error) {\n\tif cc.cometClient == nil {\n\t\treturn nil, errors.New(\"comet client is not initialized\")\n\t}\n\treturn cc.cometClient.Commit(ctx, height)\n}\n\n// TODO: Add helpers for the beacon node-api client (converting from\n// go-eth2-client types to beacon-kit consensus types).\n"
  },
  {
    "path": "testing/e2e/suite/types/errors.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport \"github.com/berachain/beacon-kit/errors\"\n\nvar (\n\t// ErrPublicPortNotFound is returned when the public port is not found.\n\tErrPublicPortNotFound = errors.New(\"failed to get public ports\")\n)\n"
  },
  {
    "path": "testing/e2e/suite/types/execution_client.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage types\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"time\"\n\n\tberaclient \"github.com/berachain/beacon-kit/gethlib/ethclient\"\n\t\"github.com/ethereum/go-ethereum/ethclient\"\n\t\"github.com/ethereum/go-ethereum/rpc\"\n\t\"github.com/kurtosis-tech/kurtosis/api/golang/core/lib/services\"\n)\n\n// ExecutionClient represents an execution client.\ntype ExecutionClient struct {\n\t*beraclient.Client\n\n\tserviceCtx *services.ServiceContext\n\turl        string\n}\n\n// NewExecutionClientFromServiceCtx creates a new execution client from a\n// service context.\nfunc NewExecutionClient(serviceCtx *services.ServiceContext) *ExecutionClient {\n\treturn &ExecutionClient{\n\t\tserviceCtx: serviceCtx,\n\t}\n}\n\nfunc (ec *ExecutionClient) Start(ctx context.Context) error {\n\tport, ok := ec.serviceCtx.GetPublicPorts()[\"eth-json-rpc\"]\n\tif !ok {\n\t\treturn ErrPublicPortNotFound\n\t}\n\n\tec.url = fmt.Sprintf(\"http://0.0.0.0:%d\", port.GetNumber())\n\tethClient, err := DialWithPooling(ctx, ec.url)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tec.Client = beraclient.Wrap(ethClient)\n\treturn nil\n}\n\n// URL returns the URL of the execution client.\nfunc (ec *ExecutionClient) URL() string {\n\treturn ec.url\n}\n\n// DialWithPooling creates an ethclient with an HTTP transport configured\n// for high connection reuse, avoiding ephemeral port exhaustion under\n// heavy concurrent load.\nfunc DialWithPooling(ctx context.Context, url string) (*ethclient.Client, error) {\n\tconst (\n\t\tpoolMaxIdleConns    = 256\n\t\tpoolIdleTimeoutSecs = 90\n\t)\n\thttpClient := &http.Client{\n\t\tTransport: &http.Transport{\n\t\t\tMaxIdleConns:        poolMaxIdleConns,\n\t\t\tMaxIdleConnsPerHost: poolMaxIdleConns,\n\t\t\tIdleConnTimeout:     poolIdleTimeoutSecs * time.Second,\n\t\t},\n\t}\n\trpcClient, err := rpc.DialOptions(ctx, url, rpc.WithHTTPClient(httpClient))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn ethclient.NewClient(rpcClient), nil\n}\n"
  },
  {
    "path": "testing/e2e/suite/types/tx/eip4844.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage tx\n\nimport (\n\t\"math/big\"\n\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/ethereum/go-ethereum/crypto/kzg4844\"\n\t\"github.com/ethereum/go-ethereum/params\"\n\t\"github.com/holiman/uint256\"\n)\n\n// New4844Tx creates a new 4844 tx.\nfunc New4844Tx(\n\tnonce uint64, to *common.Address, gasLimit uint64,\n\tchainID, tip, feeCap, value *big.Int, code []byte,\n\tblobFeeCap *big.Int, blobData []byte, al types.AccessList,\n) *types.Transaction {\n\tblobs, commits, aggProof, versionedHashes, err := EncodeBlobs(blobData)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tif to == nil {\n\t\tto = &common.Address{}\n\t}\n\treturn types.NewTx(&types.BlobTx{\n\t\tChainID:    uint256.MustFromBig(chainID),\n\t\tNonce:      nonce,\n\t\tGasTipCap:  uint256.MustFromBig(tip),\n\t\tGasFeeCap:  uint256.MustFromBig(feeCap),\n\t\tGas:        gasLimit,\n\t\tTo:         *to,\n\t\tValue:      uint256.MustFromBig(value),\n\t\tData:       code,\n\t\tAccessList: al,\n\t\tBlobFeeCap: uint256.MustFromBig(blobFeeCap),\n\t\tBlobHashes: versionedHashes,\n\t\tSidecar: &types.BlobTxSidecar{\n\t\t\tBlobs:       blobs,\n\t\t\tCommitments: commits,\n\t\t\tProofs:      aggProof,\n\t\t},\n\t})\n}\n\n// EncodeBlobs encodes blobs.\nfunc EncodeBlobs(\n\tdata []byte,\n) (\n\t[]kzg4844.Blob, []kzg4844.Commitment,\n\t[]kzg4844.Proof, []common.Hash, error,\n) {\n\tblobs := encodeBlobs(data)\n\tcommits := make([]kzg4844.Commitment, 0, len(blobs))\n\tproofs := make([]kzg4844.Proof, 0, len(blobs))\n\tversionedHashes := make([]common.Hash, 0, len(blobs))\n\tfor i := range blobs {\n\t\tcommit, err := kzg4844.BlobToCommitment(&blobs[i])\n\t\tif err != nil {\n\t\t\treturn nil, nil, nil, nil, err\n\t\t}\n\t\tcommits = append(commits, commit)\n\n\t\tproof, err := kzg4844.ComputeBlobProof(&blobs[i], commit)\n\t\tif err != nil {\n\t\t\treturn nil, nil, nil, nil, err\n\t\t}\n\t\tproofs = append(proofs, proof)\n\n\t\tversionedHashes = append(\n\t\t\tversionedHashes,\n\t\t\teip4844.KZGCommitment(commit).ToVersionedHash(),\n\t\t)\n\t}\n\treturn blobs, commits, proofs, versionedHashes, nil\n}\n\n// encodeBlobs encodes data into blobs.\n//\n//nolint:mnd // its chill.\nfunc encodeBlobs(data []byte) []kzg4844.Blob {\n\tblobs := []kzg4844.Blob{{}}\n\tblobIndex := 0\n\tfieldIndex := -1\n\tfor i := 0; i < len(data); i += 31 {\n\t\tfieldIndex++\n\t\tif fieldIndex == params.BlobTxFieldElementsPerBlob {\n\t\t\tblobs = append(blobs, kzg4844.Blob{})\n\t\t\tblobIndex++\n\t\t\tfieldIndex = 0\n\t\t}\n\t\tmaxSize := i + 31\n\t\tif maxSize > len(data) {\n\t\t\tmaxSize = len(data)\n\t\t}\n\t\tcopy(blobs[blobIndex][fieldIndex*32+1:], data[i:maxSize])\n\t}\n\treturn blobs\n}\n"
  },
  {
    "path": "testing/files/entrypoint.sh",
    "content": "#!/usr/bin/env bash\n# SPDX-License-Identifier: MIT\n#\n# Copyright (c) 2025 Berachain Foundation\n#\n# Permission is hereby granted, free of charge, to any person\n# obtaining a copy of this software and associated documentation\n# files (the \"Software\"), to deal in the Software without\n# restriction, including without limitation the rights to use,\n# copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the\n# Software is furnished to do so, subject to the following\n# conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n# OTHER DEALINGS IN THE SOFTWARE.\n\n# function to resolve absolute path from relative\nresolve_path() {\n\tif [[ \"$1\" =~ : ]]; then\n        # treat as an address or url, return as is\n        echo \"$1\"\n\tfi\n    cd \"$(dirname \"$1\")\"\n    local abs_path\n    abs_path=\"$(pwd -P)/$(basename \"$1\")\"\n    echo \"$abs_path\"\n}\n\n# Check if the chain spec is provided as an argument.\nCHAIN_SPEC=\"\"\nCHAIN_SPEC_ARG=\"\"\nif [ -z \"$1\" ]; then\n    echo \"No chain spec provided\"\n\texit 1\nelse\n\tCHAIN_SPEC=\"$1\"\n    CHAIN_SPEC_ARG=\"--beacon-kit.chain-spec $CHAIN_SPEC\"\n\tif [ \"$CHAIN_SPEC\" == \"file\" ]; then\n\t\tCHAIN_SPEC_FILE=$(resolve_path \"$2\")\n\t\tCHAIN_SPEC_ARG=\"$CHAIN_SPEC_ARG --beacon-kit.chain-spec-file $CHAIN_SPEC_FILE\"\n\tfi\nfi\n\nCHAINID=\"beacond-2061\"\nMONIKER=\"localtestnet\"\nLOGLEVEL=\"info\"\nHOMEDIR=\"./.tmp/beacond\"\n\n# Path variables\nGENESIS=$HOMEDIR/config/genesis.json\nTMP_GENESIS=$HOMEDIR/config/tmp_genesis.json\nETH_GENESIS=$(resolve_path \"./testing/files/eth-genesis.json\")\nKZG_PATH=$(resolve_path \"./testing/files/kzg-trusted-setup.json\")\n\n# used to exit on first error (any non-zero exit code)\nset -e\n\n# Reinstall daemon\nmake build\n\noverwrite=\"N\"\nif [ -d $HOMEDIR ]; then\n\tprintf \"\\nAn existing folder at '%s' was found. You can choose to delete this folder and start a new local node with new keys from genesis. When declined, the existing local node is started. \\n\" $HOMEDIR\n\techo \"Overwrite the existing configuration and start a new local node? [y/n]\"\n\tread -r overwrite\nelse\noverwrite=\"Y\"\nfi\n\n# Setup local node if overwrite is set to Yes, otherwise skip setup\nif [[ $overwrite == \"y\" || $overwrite == \"Y\" ]]; then\n\trm -rf $HOMEDIR\n\t./build/bin/beacond init $MONIKER --chain-id $CHAINID --home $HOMEDIR $CHAIN_SPEC_ARG\n\n\tif [ \"$CHAIN_SPEC\" == \"testnet\" ]; then\n\t    network_dir=\"testing/networks/80069\"\n\t\tcp -f $network_dir/*.toml $network_dir/genesis.json ${HOMEDIR}/config\n    \tKZG_PATH=$network_dir/kzg-trusted-setup.json\n\telif [ \"$CHAIN_SPEC\" == \"mainnet\" ]; then\n\t\tnetwork_dir=\"testing/networks/80094\"\n\t\tcp -f $network_dir/*.toml $network_dir/genesis.json ${HOMEDIR}/config\n    \tKZG_PATH=$network_dir/kzg-trusted-setup.json\n\telse\n\t\t./build/bin/beacond genesis add-premined-deposit --home $HOMEDIR \\\n\t\t\t32000000000 0x20f33ce90a13a4b5e7697e3544c3083b8f8a51d4 $CHAIN_SPEC_ARG\n\t\t./build/bin/beacond genesis collect-premined-deposits --home $HOMEDIR $CHAIN_SPEC_ARG\n\t\t./build/bin/beacond genesis set-deposit-storage \"$ETH_GENESIS\" --home $HOMEDIR $CHAIN_SPEC_ARG\n\t\t./build/bin/beacond genesis execution-payload \"$HOMEDIR/eth-genesis.json\" --home $HOMEDIR $CHAIN_SPEC_ARG\n\tfi\nfi\n\n# Start the node (remove the --pruning=nothing flag if historical queries are not needed)\nBEACON_START_CMD=\"./build/bin/beacond start $CHAIN_SPEC_ARG --pruning=nothing \"$TRACE\" \\\n--beacon-kit.logger.log-level $LOGLEVEL --home $HOMEDIR \\\n--beacon-kit.engine.jwt-secret-path ${JWT_SECRET_PATH} \\\n--beacon-kit.kzg.trusted-setup-path ${KZG_PATH}  \\\n--beacon-kit.node-api.enabled --beacon-kit.node-api.logging\"\n\n# Conditionally add the rpc-dial-url flag if RPC_DIAL_URL is not empty\nif [ -n \"$RPC_DIAL_URL\" ]; then\n\t# this will overwrite the default dial url\n\tRPC_DIAL_URL=$(resolve_path \"$RPC_DIAL_URL\")\n\techo \"Overwriting the default dial url with $RPC_DIAL_URL\"\n\tBEACON_START_CMD=\"$BEACON_START_CMD --beacon-kit.engine.rpc-dial-url ${RPC_PREFIX}${RPC_DIAL_URL}\"\nfi\n\neval $BEACON_START_CMD\n"
  },
  {
    "path": "testing/files/eth-genesis.json",
    "content": "{\n  \"config\": {\n    \"chainId\": 80087,\n    \"homesteadBlock\": 0,\n    \"daoForkBlock\": 0,\n    \"daoForkSupport\": true,\n    \"eip150Block\": 0,\n    \"eip155Block\": 0,\n    \"eip158Block\": 0,\n    \"byzantiumBlock\": 0,\n    \"constantinopleBlock\": 0,\n    \"petersburgBlock\": 0,\n    \"istanbulBlock\": 0,\n    \"muirGlacierBlock\": 0,\n    \"berlinBlock\": 0,\n    \"londonBlock\": 0,\n    \"arrowGlacierBlock\": 0,\n    \"grayGlacierBlock\": 0,\n    \"mergeNetsplitBlock\": 0,\n    \"shanghaiTime\": 0,\n    \"cancunTime\": 0,\n    \"pragueTime\": 0,\n    \"osakaTime\": 0,\n    \"terminalTotalDifficulty\": 0,\n    \"terminalTotalDifficultyPassed\": true,\n    \"ethash\": {},\n    \"blobSchedule\": {\n      \"cancun\": {\n        \"target\": 3,\n        \"max\": 6,\n        \"baseFeeUpdateFraction\": 3338477\n      },\n      \"prague\": {\n        \"target\": 3,\n        \"max\": 6,\n        \"baseFeeUpdateFraction\": 3338477\n      }\n    },\n    \"berachain\": {\n      \"prague1\": {\n        \"time\": 0,\n        \"baseFeeChangeDenominator\": 48,\n        \"minimumBaseFeeWei\": 1000000000,\n        \"polDistributorAddress\": \"0x4200000000000000000000000000000000000042\"\n      },\n      \"prague2\": {\n        \"time\": 0,\n        \"minimumBaseFeeWei\": 0\n      }\n    }\n  },\n  \"coinbase\": \"0x0000000000000000000000000000000000000000\",\n  \"difficulty\": \"0x0\",\n  \"extraData\": \"0x0000000000000000000000000000000000000000000000000000000000000000658bdf435d810c91414ec09147daa6db624063790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n  \"gasLimit\": \"0x1c9c380\",\n  \"nonce\": \"0x0000000000000000\",\n  \"timestamp\": \"0x0\",\n  \"alloc\": {\n    \"0x00000961Ef480Eb55e80D19ad83579A64c007002\": {\n      \"code\": \"0x3373fffffffffffffffffffffffffffffffffffffffe1460cb5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f457600182026001905f5b5f82111560685781019083028483029004916001019190604d565b909390049250505036603814608857366101f457346101f4575f5260205ff35b34106101f457600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160df575060105b5f5b8181146101835782810160030260040181604c02815460601b8152601401816001015481526020019060020154807fffffffffffffffffffffffffffffffff00000000000000000000000000000000168252906010019060401c908160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160e1565b910180921461019557906002556101a0565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101cd57505f5b6001546002828201116101e25750505f6101e8565b01600290035b5f555f600155604c025ff35b5f5ffd\",\n      \"nonce\": \"0x1\",\n      \"balance\": \"0x0\",\n      \"storage\": {\n        \"0x0000000000000000000000000000000000000000000000000000000000000000\": \"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"\n      }\n    },\n    \"0x0000BBdDc7CE488642fb579F8B00f3a590007251\": {\n      \"code\": \"0x3373fffffffffffffffffffffffffffffffffffffffe1460d35760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f82111560685781019083028483029004916001019190604d565b9093900492505050366060146088573661019a573461019a575f5260205ff35b341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060021160e7575060025b5f5b8181146101295782810160040260040181607402815460601b815260140181600101548152602001816002015481526020019060030154905260010160e9565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd\",\n      \"nonce\": \"0x1\",\n      \"balance\": \"0x0\",\n      \"storage\": {\n        \"0x0000000000000000000000000000000000000000000000000000000000000000\": \"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"\n      }\n    },\n    \"0x20f33ce90a13a4b5e7697e3544c3083b8f8a51d4\": {\n      \"balance\": \"0x123450000000000000000\"\n    },\n    \"0x56898d1aFb10cad584961eb96AcD476C6826e41E\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1e2e53c2451d0f9ED4B7952991BE0c95165D5c01\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3bd0E8f1B1E8Ec99a4E1762F4058F9884C93af31\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xD073a84e2ccDF91a9025179330438485E886D206\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x8a88215ae882dfA519730c40109556c1C235729f\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1a0A57e5e6a66aD732295ddAF0aed286a4e64310\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x185F4Eebd01614aE3d12a5E49b184B054C46d37B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xdb96E9cDD1e457b602f97d33e51736D7a5216496\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x44a5FBfa7d6f3Fd92cca01f6764509f8Fc33dfa5\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3649839562C8dA64E6215EB0f5371629Ead9729D\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x51e15e71c865FE702C9347610667f83658A20e00\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xBC9BC89b295a14F3976234Cc37C73e3D286f3a49\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x12De044207a90709Ef2602D3D9D945d64dAe6147\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x4Afe0DFDAcc91F0fA2AEe39F9eAd66b64d03EbD6\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xBC3c03b4185A6F10618CC4E7B9f4AdD59AB5FbbA\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xDc6De65f6070b409125217a12Cf576A208Cc1998\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xF60fD8632Fc77E19b3A0637d115d0fdd06F36968\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xbcC90AD39D377cA0b7b4F36eC463103E2728C33F\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x6F69542fC88fF84C480FFf510aB7108120447247\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2f6eB3D9a41157322dE01A6E707F6F118Cb00A7b\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x187bE38A1f448b0F42423151A683dCAea949008B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xA1d283f1a11A36D20FF38F29e12CA8F7Cf8709c1\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x868a33C94F91398B6245e1f0E4CF128B2F28714B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x67c942Ef50Fc690eA779067a6A0d444a8234baB5\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xDE8E0E641E2Fb52c22460e6a1533c6BD13A00B37\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x9beFa0FB7a1A9E6cC7596204DbB8962E87091D64\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x62cB9bF32EA104f6D5eBf6879e876439f9492E4B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xdb9cB94B166DfdC9F337EA63b32B448d993d7008\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7c4d7dB81c544B768E1f4782011077202B74B5C0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xaEf63D7F7e2637c99FeA1B63366b244B4da12D70\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3DFb4173ec41EB976260fd689E5AB9772C66beaf\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x5145b1B855bca67A119CB02A42aF4Bdbc66B725C\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf4b2eb959A4C4b0E148340676999FC0446D446D4\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xb86d37333072eFb48cEaa46C67271A27CA5Bda82\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x6CBcF4198fDA91D00fD469340E6DF6df086159e3\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xE7F444b5f772281384117674002d540131e533Ca\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x719Be866A77CeEc1BaC4FD37910c0975eFd52f55\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x0e10cDAd84D788843aF48673C5b260A02ef78742\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xcB6632daA65e6c921c2963C37320f63f54fC8fE3\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xDe5C7198e2416baB7e7a1EA758858Cd7301740bF\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x25fc16D8E2314B305dF05C032E617638284801D6\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xD2a3b89AE8D2c3bD39E2F24612ecFCD8600360C9\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2F4fD8a82A1400E654eeEC59b0e588445ffE0F96\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x10FdFa4EFc83d6CC42F5ef14c13da8b98E458214\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x49cE37B2019bb2d0B8b6a094ef87a6Dd625454A0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x800830F031ab1dd5895a5ec5B561427AD18f9ea8\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3124d9885b11B52c56A2aee610AfCf5740d484F0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xA6177defF3b768b1D678EdF7583b8cf210C777c0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xF99139D2FCc5E25F57B0B91fd382a21B3AFF9cbA\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xC4DD08191B4d5173e3698491A11e05b63F9Ee097\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xB8865B4B8C56861534CC07ebBD2EA569a9a16323\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2B9935698dc5c19Ab7414AE22f27Da5F4478008a\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xAC3c80F41C3049A89Aba8072FFbFc38a90fb6D8c\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xD6D4Fb22B91FAa54700852a05698B37d45514166\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xAf325Ccc92ae883DEF1634D499d8B093192D7a0c\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7469CeEf99FB67e4990c5F1c085a1B39b2902331\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x14DA5251a1EB236238969575ccE943e2Fb0f4AA1\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xF9f58a87C3f0B3A4a0592938c80C41a7c659f855\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1CF7e940A657eE706718CF180eb21864DE9672C3\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x440C37b22e8D7469128Ea7De6ac2f31419B4A8b1\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x4bD04ABA9fc709835b1EE4789195d10E9e8E53F5\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x4dC3aC871b22F8a98197B0aae976a8dE08e5Bebe\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1f1D0FCa7e19b799c315d4fDf31bA50e6A2AB153\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x28879749Dda99387bdB43295B28bdF251d999F3b\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xC4eD09A472B82516daa3A4d8D1E38AE94CF4855C\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf22FbA9cBeB75ED353931418E9eca71EF1Ab9921\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xC59D8935c0570E75BA0E55E3C661f535C86e368B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf97a36c417D33D1fC60a9163A8715e1aecb29102\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x4245537d9e3fb36fBBf054247FfFB28b0d931503\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xFeb1eafa0154D291e28e393FAF10Bc89e5cCbB22\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf11D16e2EE6BefED82Fbca0b005906E09303aB95\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x9C75eD1A37ae420b4FC0a1F4c26B673227Fd3AFa\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x6a354C708fd248FD778F6adF75E41AA554700F68\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xea94749deFcc40dC5992687974b1C84B1bB9D6df\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7689BE67b205EB5d32811d95D60587Eae4F3036F\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xdBfb742BD2e0e6E353cb61E75B9e11257aC8fB1A\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2E5f031578e8FF82199aaF16f42c44D43Fe61819\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x611a42A2EF62c2461D123e3F0B64b93938bc4781\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1a0c826048DF0E4661E3c53bBd447d497E3f701F\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7f0E54bc3C1a72405646F5dFbBE0D4565c649fe2\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x54e1F990Dc0B7367F1E8eD96dA63BC4bca0E8061\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xbE651bc261b9Da5499a24Bf4214fD494c6e1F5Ac\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xD3c5dAC705289cD005C402C79C8445a47502d8be\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xE5981AA0807eb05611cDb666e32e53b2001bd61d\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x0fb648Cb08e21602AF61AF53fE104E29d46433F7\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x0474f52d25529c4db5f4E72F43303dA71B3541C6\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xe3024d098953661638d59E06f7FcD0B61c424854\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x8b1e58f651CacaAa40291d2a6E0a6404d7Ed99e6\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x8724C57fb8f38A1FccA7177543dd1D8FcD49E5aa\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xd0F043dED28773953562f824334C4cbb84210AE7\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xE3d2b9191EaBD3636A5dd057D522335cfae8c7CF\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3f51B3BB6A18141282Ba002F7709c7E2f337F961\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf6B6A52aA9BD788837c6682f47ACE009BD84b6fc\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x795B761Db5969B7ba53472d5D37c230C859a472F\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7d7f187C2A05cDDCF700dCF2E02c96E7eF03f9B0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2d88ECD4d8F4b0A954886eE8C0802aE14684cd07\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x92B3feac5b7816Dcef96a303c1D5112271A70D2c\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x5DD7bc3BEE395831ce499315ecAFE81DE0556F99\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x5227aaebCA3E5e893547A667666E2e4e12Ca20e0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x47575DAE85403cD408d4639068D1187C427B9897\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xE69ac59e1DF47291AaB8DEc540C796f81De7c892\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xb87fb371Bd3C2093b608cd0E7a8dDD60Bb05C995\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02\": {\n      \"balance\": \"0x0\",\n      \"nonce\": \"0x1\",\n      \"code\": \"0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500\"\n    },\n    \"0x4e59b44847b379578588920cA78FbF26c0B4956C\": {\n      \"balance\": \"0x0\",\n      \"nonce\": \"0x1\",\n      \"code\": \"0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3\"\n    },\n    \"0x4242424242424242424242424242424242424242\": {\n      \"balance\": \"0x0\",\n      \"nonce\": \"0x1\",\n      \"code\": \"0x608060405260043610610093575f3560e01c8063577212fe11610066578063c53925d91161004c578063c53925d914610231578063e12cf4cb14610250578063fea7ab7714610263575f80fd5b8063577212fe146101cc5780639eaffa96146101ed575f80fd5b806301ffc9a7146100975780632dfdf0b5146100cb5780633523f9bd14610103578063560036ec14610126575b5f80fd5b3480156100a2575f80fd5b506100b66100b1366004610bb7565b610282565b60405190151581526020015b60405180910390f35b3480156100d6575f80fd5b505f546100ea9067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016100c2565b34801561010e575f80fd5b5061011860015481565b6040519081526020016100c2565b348015610131575f80fd5b50610193610140366004610c2a565b80516020818301810180516003825292820191909301209152546bffffffffffffffffffffffff8116906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1682565b604080516bffffffffffffffffffffffff909316835273ffffffffffffffffffffffffffffffffffffffff9091166020830152016100c2565b3480156101d7575f80fd5b506101eb6101e6366004610d5f565b61031a565b005b3480156101f8575f80fd5b5061020c610207366004610d5f565b6103e7565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c2565b34801561023c575f80fd5b506101eb61024b366004610d5f565b610428565b6101eb61025e366004610dc1565b61063d565b34801561026e575f80fd5b506101eb61027d366004610e70565b61095c565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f136f920d00000000000000000000000000000000000000000000000000000000145b92915050565b6002828260405161032c929190610ec0565b908152604051908190036020019020543373ffffffffffffffffffffffffffffffffffffffff90911614610383576103837f7c214f0400000000000000000000000000000000000000000000000000000000610afc565b60038282604051610395929190610ec0565b9081526040519081900360200181205f90556103b49083908390610ec0565b604051908190038120907f1c0a7e1bd09da292425c039309671a03de56b89a0858598aab6df6ce84b006db905f90a25050565b5f600283836040516103fa929190610ec0565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff16905092915050565b5f6003838360405161043b929190610ec0565b908152604051908190036020019020805490915073ffffffffffffffffffffffffffffffffffffffff6c01000000000000000000000000820416906bffffffffffffffffffffffff163382146104b4576104b47f819a0d0b00000000000000000000000000000000000000000000000000000000610afc565b6bffffffffffffffffffffffff42166104d06201518083610efc565b6bffffffffffffffffffffffff16111561050d5761050d7fe8966d7a00000000000000000000000000000000000000000000000000000000610afc565b5f60028686604051610520929190610ec0565b9081526040519081900360200181205473ffffffffffffffffffffffffffffffffffffffff169150839060029061055a9089908990610ec0565b908152604051908190036020018120805473ffffffffffffffffffffffffffffffffffffffff939093167fffffffffffffffffffffffff0000000000000000000000000000000000000000909316929092179091556003906105bf9088908890610ec0565b9081526040519081900360200181205f90556105de9087908790610ec0565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff808716845284166020840152917f0adffd98d3072c48341843974dffd7a910bb849ba6ca04163d43bb26feb17403910160405180910390a2505050505050565b6030861461066e5761066e7f9f10647200000000000000000000000000000000000000000000000000000000610afc565b6020841461069f5761069f7fb39bca1600000000000000000000000000000000000000000000000000000000610afc565b606082146106d0576106d07f4be6321b00000000000000000000000000000000000000000000000000000000610afc565b5f73ffffffffffffffffffffffffffffffffffffffff16600288886040516106f9929190610ec0565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff16036108375773ffffffffffffffffffffffffffffffffffffffff8116610768576107687f51969a7a00000000000000000000000000000000000000000000000000000000610afc565b806002888860405161077b929190610ec0565b908152604051908190036020018120805473ffffffffffffffffffffffffffffffffffffffff939093167fffffffffffffffffffffffff0000000000000000000000000000000000000000909316929092179091556107dd9088908890610ec0565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff841683525f6020840152917f0adffd98d3072c48341843974dffd7a910bb849ba6ca04163d43bb26feb17403910160405180910390a261087c565b73ffffffffffffffffffffffffffffffffffffffff81161561087c5761087c7fc4142b4100000000000000000000000000000000000000000000000000000000610afc565b5f610885610b04565b90506509184e72a00067ffffffffffffffff821610156108c8576108c87f0e1eddda00000000000000000000000000000000000000000000000000000000610afc565b5f80547f68af751683498a9f9be59fe8b0d52a64dd155255d85cdb29fea30b1e3f891d46918a918a918a918a9187918b918b9167ffffffffffffffff16908061091083610f20565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060405161094a989796959493929190610f93565b60405180910390a15050505050505050565b5f6002848460405161096f929190610ec0565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff1690503381146109c7576109c77f7c214f0400000000000000000000000000000000000000000000000000000000610afc565b73ffffffffffffffffffffffffffffffffffffffff8216610a0b57610a0b7fd92e233d00000000000000000000000000000000000000000000000000000000610afc565b5f60038585604051610a1e929190610ec0565b908152604051908190036020018120426bffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff86166c01000000000000000000000000027fffffffffffffffffffffffffffffffffffffffff000000000000000000000000161781559150610a969086908690610ec0565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff8681168452851660208401524283830152905190917f7640ec3c8c4695deadda414dd20400acf275297a7c38715f9237657e97ddba5f919081900360600190a25050505050565b805f5260045ffd5b5f610b13633b9aca003461102b565b15610b4157610b417f40567b3800000000000000000000000000000000000000000000000000000000610afc565b5f610b50633b9aca003461103e565b905067ffffffffffffffff811115610b8b57610b8b7f2aa6673400000000000000000000000000000000000000000000000000000000610afc565b610b955f34610b9a565b919050565b5f385f3884865af1610bb35763b12d13eb5f526004601cfd5b5050565b5f60208284031215610bc7575f80fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610bf6575f80fd5b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f60208284031215610c3a575f80fd5b813567ffffffffffffffff811115610c50575f80fd5b8201601f81018413610c60575f80fd5b803567ffffffffffffffff811115610c7a57610c7a610bfd565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160116810181811067ffffffffffffffff82111715610ce657610ce6610bfd565b604052818152828201602001861015610cfd575f80fd5b816020840160208301375f91810160200191909152949350505050565b5f8083601f840112610d2a575f80fd5b50813567ffffffffffffffff811115610d41575f80fd5b602083019150836020828501011115610d58575f80fd5b9250929050565b5f8060208385031215610d70575f80fd5b823567ffffffffffffffff811115610d86575f80fd5b610d9285828601610d1a565b90969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610b95575f80fd5b5f805f805f805f6080888a031215610dd7575f80fd5b873567ffffffffffffffff811115610ded575f80fd5b610df98a828b01610d1a565b909850965050602088013567ffffffffffffffff811115610e18575f80fd5b610e248a828b01610d1a565b909650945050604088013567ffffffffffffffff811115610e43575f80fd5b610e4f8a828b01610d1a565b9094509250610e62905060608901610d9e565b905092959891949750929550565b5f805f60408486031215610e82575f80fd5b833567ffffffffffffffff811115610e98575f80fd5b610ea486828701610d1a565b9094509250610eb7905060208501610d9e565b90509250925092565b818382375f9101908152919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b6bffffffffffffffffffffffff818116838216019081111561031457610314610ecf565b5f67ffffffffffffffff821667ffffffffffffffff8103610f4357610f43610ecf565b60010192915050565b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60a081525f610fa660a083018a8c610f4c565b8281036020840152610fb981898b610f4c565b905067ffffffffffffffff871660408401528281036060840152610fde818688610f4c565b91505067ffffffffffffffff831660808301529998505050505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f8261103957611039610ffe565b500690565b5f8261104c5761104c610ffe565b50049056fea164736f6c634300081a000a\"\n    },\n    \"0x4200000000000000000000000000000000000042\": {\n      \"code\": \"0x608060405234801561000f575f80fd5b5060043610610034575f3560e01c8063163db71b1461003857806360644a6b14610052575b5f80fd5b6100405f5481565b60405190815260200160405180910390f35b610065610060366004610183565b610067565b005b3373fffffffffffffffffffffffffffffffffffffffe146100b4576040517f5e742c5a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805490806100c2836101f1565b90915550506040517f999da65b0000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000439063999da65b90610119908590859060040161024d565b5f604051808303815f87803b158015610130575f80fd5b505af1158015610142573d5f803e3d5ffd5b505050507f60b106db8802e863a4a9dc4af78cb0dd63feb55ad4ee60f0453c13309bfdbdd4828260405161017792919061024d565b60405180910390a15050565b5f8060208385031215610194575f80fd5b823567ffffffffffffffff8111156101aa575f80fd5b8301601f810185136101ba575f80fd5b803567ffffffffffffffff8111156101d0575f80fd5b8560208284010111156101e1575f80fd5b6020919091019590945092505050565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610246577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5060010190565b60208152816020820152818360408301375f818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010191905056fea2646970667358221220e6dfa8c5d72bb391aff9e891c09a1f86d26cfd1d112aaab4b577bcbc5b94bafe64736f6c634300081a0033\",\n      \"nonce\": \"0x1\",\n      \"balance\": \"0x0\"\n    },\n    \"0x4200000000000000000000000000000000000043\": {\n      \"code\": \"0x608060405234801561000f575f80fd5b5060043610610034575f3560e01c80634b28f9a214610038578063999da65b14610052575b5f80fd5b6100405f5481565b60405190815260200160405180910390f35b6100656100603660046100b8565b610067565b005b5f8054908061007583610126565b91905055507fb3a8fa51f8d3759f320e88b7f8d3fb73a2a51b31b3324b37833c4816cf41e7c45f546040516100ac91815260200190565b60405180910390a15050565b5f80602083850312156100c9575f80fd5b823567ffffffffffffffff8111156100df575f80fd5b8301601f810185136100ef575f80fd5b803567ffffffffffffffff811115610105575f80fd5b856020828401011115610116575f80fd5b6020919091019590945092505050565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361017b577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b506001019056fea2646970667358221220e5db2a9698e23f84b7c83d023ea72ca3f01627daffa1ff16ae15918143d892a564736f6c634300081a0033\",\n      \"nonce\": \"0x1\",\n      \"balance\": \"0x0\"\n    }\n  }\n}\n"
  },
  {
    "path": "testing/files/jwt.hex",
    "content": "0xc4d70beb372fc886335d5bef3aabd63b4324b621132f5d8de67a06ddd0405fcd"
  },
  {
    "path": "testing/files/kzg-trusted-setup.json",
    "content": "{\n  \"g1_lagrange\": [\n    \"0xa0413c0dcafec6dbc9f47d66785cf1e8c981044f7d13cfe3e4fcbb71b5408dfde6312493cb3c1d30516cb3ca88c03654\",\n    \"0x8b997fb25730d661918371bb41f2a6e899cac23f04fc5365800b75433c0a953250e15e7a98fb5ca5cc56a8cd34c20c57\",\n    \"0x83302852db89424d5699f3f157e79e91dc1380f8d5895c5a772bb4ea3a5928e7c26c07db6775203ce33e62a114adaa99\",\n    \"0xa759c48b7e4a685e735c01e5aa6ef9c248705001f470f9ad856cd87806983e917a8742a3bd5ee27db8d76080269b7c83\",\n    \"0x967f8dc45ebc3be14c8705f43249a30ff48e96205fb02ae28daeab47b72eb3f45df0625928582aa1eb4368381c33e127\",\n    \"0xa418eb1e9fb84cb32b370610f56f3cb470706a40ac5a47c411c464299c45c91f25b63ae3fcd623172aa0f273c0526c13\",\n    \"0x8f44e3f0387293bc7931e978165abbaed08f53acd72a0a23ac85f6da0091196b886233bcee5b4a194db02f3d5a9b3f78\",\n    \"0x97173434b336be73c89412a6d70d416e170ea355bf1956c32d464090b107c090ef2d4e1a467a5632fbc332eeb679bf2d\",\n    \"0xa24052ad8d55ad04bc5d951f78e14213435681594110fd18173482609d5019105b8045182d53ffce4fc29fc8810516c1\",\n    \"0xb950768136b260277590b5bec3f56bbc2f7a8bc383d44ce8600e85bf8cf19f479898bcc999d96dfbd2001ede01d94949\",\n    \"0x92ab8077871037bd3b57b95cbb9fb10eb11efde9191690dcac655356986fd02841d8fdb25396faa0feadfe3f50baf56d\",\n    \"0xa79b096dff98038ac30f91112dd14b78f8ad428268af36d20c292e2b3b6d9ed4fb28480bb04e465071cc67d05786b6d1\",\n    \"0xb9ff71461328f370ce68bf591aa7fb13027044f42a575517f3319e2be4aa4843fa281e756d0aa5645428d6dfa857cef2\",\n    \"0x8d765808c00b3543ff182e2d159c38ae174b12d1314da88ea08e13bd9d1c37184cb515e6bf6420531b5d41767987d7ce\",\n    \"0xb8c9a837d20c3b53e6f578e4a257bb7ef8fc43178614ec2a154915b267ad2be135981d01ed2ee1b5fbd9d9bb27f0800a\",\n    \"0xa9773d92cf23f65f98ef68f6cf95c72b53d0683af2f9bf886bb9036e4a38184b1131b26fd24397910b494fbef856f3aa\",\n    \"0xb41ebe38962d112da4a01bf101cb248d808fbd50aaf749fc7c151cf332032eb3e3bdbd716db899724b734d392f26c412\",\n    \"0x90fbb030167fb47dcc13d604a726c0339418567c1d287d1d87423fa0cb92eec3455fbb46bcbe2e697144a2d3972142e4\",\n    \"0xb11d298bd167464b35fb923520d14832bd9ed50ed841bf6d7618424fd6f3699190af21759e351b89142d355952149da1\",\n    \"0x8bc36066f69dc89f7c4d1e58d67497675050c6aa002244cebd9fc957ec5e364c46bab4735ea3db02b73b3ca43c96e019\",\n    \"0xab7ab92c5d4d773068e485aa5831941ebd63db7118674ca38089635f3b4186833af2455a6fb9ed2b745df53b3ce96727\",\n    \"0xaf191ca3089892cb943cd97cf11a51f38e38bd9be50844a4e8da99f27e305e876f9ed4ab0628e8ae3939066b7d34a15f\",\n    \"0xa3204c1747feabc2c11339a542195e7cb6628fd3964f846e71e2e3f2d6bb379a5e51700682ea1844eba12756adb13216\",\n    \"0x903a29883846b7c50c15968b20e30c471aeac07b872c40a4d19eb1a42da18b649d5bbfde4b4cf6225d215a461b0deb6d\",\n    \"0x8e6e9c15ffbf1e16e5865a5fef7ed751dc81957a9757b535cb38b649e1098cda25d42381dc4f776778573cdf90c3e6e0\",\n    \"0xa8f6dd26100b512a8c96c52e00715c4b2cb9ac457f17aed8ffe1cf1ea524068fe5a1ddf218149845fc1417b789ecfc98\",\n    \"0xa5b0ffc819451ea639cfd1c18cbc9365cc79368d3b2e736c0ae54eba2f0801e6eb0ee14a5f373f4a70ca463bdb696c09\",\n    \"0x879f91ccd56a1b9736fbfd20d8747354da743fb121f0e308a0d298ff0d9344431890e41da66b5009af3f442c636b4f43\",\n    \"0x81bf3a2d9755e206b515a508ac4d1109bf933c282a46a4ae4a1b4cb4a94e1d23642fad6bd452428845afa155742ade7e\",\n    \"0x8de778d4742f945df40004964e165592f9c6b1946263adcdd5a88b00244bda46c7bb49098c8eb6b3d97a0dd46148a8ca\",\n    \"0xb7a57b21d13121907ee28c5c1f80ee2e3e83a3135a8101e933cf57171209a96173ff5037f5af606e9fd6d066de6ed693\",\n    \"0xb0877d1963fd9200414a38753dffd9f23a10eb3198912790d7eddbc9f6b477019d52ddd4ebdcb9f60818db076938a5a9\",\n    \"0x88da2d7a6611bc16adc55fc1c377480c828aba4496c645e3efe0e1a67f333c05a0307f7f1d2df8ac013602c655c6e209\",\n    \"0x95719eb02e8a9dede1a888c656a778b1c69b7716fbe3d1538fe8afd4a1bc972183c7d32aa7d6073376f7701df80116d8\",\n    \"0x8e8a1ca971f2444b35af3376e85dccda3abb8e8e11d095d0a4c37628dfe5d3e043a377c3de68289ef142e4308e9941a0\",\n    \"0xb720caaff02f6d798ac84c4f527203e823ff685869e3943c979e388e1c34c3f77f5c242c6daa7e3b30e511aab917b866\",\n    \"0x86040d55809afeec10e315d1ad950d269d37cfee8c144cd8dd4126459e3b15a53b3e68df5981df3c2346d23c7b4baaf4\",\n    \"0x82d8cabf13ab853db0377504f0aec00dba3a5cd3119787e8ad378ddf2c40b022ecfc67c642b7acc8c1e3dd03ab50993e\",\n    \"0xb8d873927936719d2484cd03a6687d65697e17dcf4f0d5aed6f5e4750f52ef2133d4645894e7ebfc4ef6ce6788d404c8\",\n    \"0xb1235594dbb15b674a419ff2b2deb644ad2a93791ca05af402823f87114483d6aa1689b7a9bea0f547ad12fe270e4344\",\n    \"0xa53fda86571b0651f5affb74312551a082fffc0385cfd24c1d779985b72a5b1cf7c78b42b4f7e51e77055f8e5e915b00\",\n    \"0xb579adcfd9c6ef916a5a999e77a0cb21d378c4ea67e13b7c58709d5da23a56c2e54218691fc4ac39a4a3d74f88cc31f7\",\n    \"0xab79e584011713e8a2f583e483a91a0c2a40771b77d91475825b5acbea82db4262132901cb3e4a108c46d7c9ee217a4e\",\n    \"0xa0fe58ea9eb982d7654c8aaf9366230578fc1362f6faae0594f8b9e659bcb405dff4aac0c7888bbe07f614ecf0d800a6\",\n    \"0x867e50e74281f28ecd4925560e2e7a6f8911b135557b688254623acce0dbc41e23ac3e706a184a45d54c586edc416eb0\",\n    \"0x89f81b61adda20ea9d0b387a36d0ab073dc7c7cbff518501962038be19867042f11fcc7ff78096e5d3b68c6d8dc04d9b\",\n    \"0xa58ee91bb556d43cf01f1398c5811f76dc0f11efdd569eed9ef178b3b0715e122060ec8f945b4dbf6eebfa2b90af6fa6\",\n    \"0xac460be540f4c840def2eef19fc754a9af34608d107cbadb53334cf194cc91138d53b9538fcd0ec970b5d4aa455b224a\",\n    \"0xb09b91f929de52c09d48ca0893be6eb44e2f5210a6c394689dc1f7729d4be4e11d0474b178e80cea8c2ac0d081f0e811\",\n    \"0x8d37a442a76b06a02a4e64c2504aea72c8b9b020ab7bcc94580fe2b9603c7c50d7b1e9d70d2a7daea19c68667e8f8c31\",\n    \"0xa9838d4c4e3f3a0075a952cf7dd623307ec633fcc81a7cf9e52e66c31780de33dbb3d74c320dc7f0a4b72f7a49949515\",\n    \"0xa44766b6251af458fe4f5f9ed1e02950f35703520b8656f09fc42d9a2d38a700c11a7c8a0436ac2e5e9f053d0bb8ff91\",\n    \"0xad78d9481c840f5202546bea0d13c776826feb8b1b7c72e83d99a947622f0bf38a4208551c4c41beb1270d7792075457\",\n    \"0xb619ffa8733b470039451e224b777845021e8dc1125f247a4ff2476cc774657d0ff9c5279da841fc1236047de9d81c60\",\n    \"0xaf760b0a30a1d6af3bc5cd6686f396bd41779aeeb6e0d70a09349bd5da17ca2e7965afc5c8ec22744198fbe3f02fb331\",\n    \"0xa0cc209abdb768b589fcb7b376b6e1cac07743288c95a1cf1a0354b47f0cf91fca78a75c1fcafa6f5926d6c379116608\",\n    \"0x864add673c89c41c754eeb3cd8dcff5cdde1d739fce65c30e474a082bb5d813cba6412e61154ce88fdb6c12c5d9be35b\",\n    \"0xb091443b0ce279327dc37cb484e9a5b69b257a714ce21895d67539172f95ffa326903747b64a3649e99aea7bb10d03f7\",\n    \"0xa8c452b8c4ca8e0a61942a8e08e28f17fb0ef4c5b018b4e6d1a64038280afa2bf1169202f05f14af24a06ca72f448ccd\",\n    \"0xa23c24721d18bc48d5dcf70effcbef89a7ae24e67158d70ae1d8169ee75d9a051d34b14e9cf06488bac324fe58549f26\",\n    \"0x92a730e30eb5f3231feb85f6720489dbb1afd42c43f05a1610c6b3c67bb949ec8fde507e924498f4ffc646f7b07d9123\",\n    \"0x8dbe5abf4031ec9ba6bb06d1a47dd1121fb9e03b652804069250967fd5e9577d0039e233441b7f837a7c9d67ba18c28e\",\n    \"0xaa456bcfef6a21bb88181482b279df260297b3778e84594ebddbdf337e85d9e3d46ca1d0b516622fb0b103df8ec519b7\",\n    \"0xa3b31ae621bd210a2b767e0e6f22eb28fe3c4943498a7e91753225426168b9a26da0e02f1dc5264da53a5ad240d9f51b\",\n    \"0xaa8d66857127e6e71874ce2202923385a7d2818b84cb73a6c42d71afe70972a70c6bdd2aad1a6e8c5e4ca728382a8ea8\",\n    \"0xac7e8e7a82f439127a5e40558d90d17990f8229852d21c13d753c2e97facf077cf59582b603984c3dd3faebd80aff4f5\",\n    \"0x93a8bcf4159f455d1baa73d2ef2450dcd4100420de84169bbe28b8b7a5d1746273f870091a87a057e834f754f34204b1\",\n    \"0x89d0ebb287c3613cdcae7f5acc43f17f09c0213fc40c074660120b755d664109ffb9902ed981ede79e018ddb0c845698\",\n    \"0xa87ccbfad431406aadbee878d9cf7d91b13649d5f7e19938b7dfd32645a43b114eef64ff3a13201398bd9b0337832e5a\",\n    \"0x833c51d0d0048f70c3eefb4e70e4ff66d0809c41838e8d2c21c288dd3ae9d9dfaf26d1742bf4976dab83a2b381677011\",\n    \"0x8bcd6b1c3b02fffead432e8b1680bad0a1ac5a712d4225e220690ee18df3e7406e2769e1f309e2e803b850bc96f0e768\",\n    \"0xb61e3dbd88aaf4ff1401521781e2eea9ef8b66d1fac5387c83b1da9e65c2aa2a56c262dea9eceeb4ad86c90211672db0\",\n    \"0x866d3090db944ecf190dd0651abf67659caafd31ae861bab9992c1e3915cb0952da7c561cc7e203560a610f48fae633b\",\n    \"0xa5e8971543c14274a8dc892b0be188c1b4fbc75c692ed29f166e0ea80874bc5520c2791342b7c1d2fb5dd454b03b8a5b\",\n    \"0x8f2f9fc50471bae9ea87487ebd1bc8576ef844cc42d606af5c4c0969670fdf2189afd643e4de3145864e7773d215f37f\",\n    \"0xb1bb0f2527db6d51f42b9224383c0f96048bbc03d469bf01fe1383173ef8b1cc9455d9dd8ba04d46057f46949bfc92b5\",\n    \"0xaa7c99d906b4d7922296cfe2520473fc50137c03d68b7865c5bfb8adbc316b1034310ec4b5670c47295f4a80fb8d61e9\",\n    \"0xa5d1da4d6aba555919df44cbaa8ff79378a1c9e2cfdfbf9d39c63a4a00f284c5a5724e28ecbc2d9dba27fe4ee5018bd5\",\n    \"0xa8db53224f70af4d991b9aae4ffe92d2aa5b618ad9137784b55843e9f16cefbfd25ada355d308e9bbf55f6d2f7976fb3\",\n    \"0xb6536c4232bb20e22af1a8bb12de76d5fec2ad9a3b48af1f38fa67e0f8504ef60f305a73d19385095bb6a9603fe29889\",\n    \"0x87f7e371a1817a63d6838a8cf4ab3a8473d19ce0d4f40fd013c03d5ddd5f4985df2956531cc9f187928ef54c68f4f9a9\",\n    \"0xae13530b1dbc5e4dced9d909ea61286ec09e25c12f37a1ed2f309b0eb99863d236c3b25ed3484acc8c076ad2fa8cd430\",\n    \"0x98928d850247c6f7606190e687d5c94a627550198dbdbea0161ef9515eacdb1a0f195cae3bb293112179082daccf8b35\",\n    \"0x918528bb8e6a055ad4db6230d3a405e9e55866da15c4721f5ddd1f1f37962d4904aad7a419218fe6d906fe191a991806\",\n    \"0xb71e31a06afe065773dd3f4a6e9ef81c3292e27a3b7fdfdd452d03e05af3b6dd654c355f7516b2a93553360c6681a73a\",\n    \"0x8870b83ab78a98820866f91ac643af9f3ff792a2b7fda34185a9456a63abdce42bfe8ad4dc67f08a6392f250d4062df4\",\n    \"0x91eea1b668e52f7a7a5087fabf1cab803b0316f78d9fff469fbfde2162f660c250e4336a9eea4cb0450bd30ac067bc8b\",\n    \"0x8b74990946de7b72a92147ceac1bd9d55999a8b576e8df68639e40ed5dc2062cfcd727903133de482b6dca19d0aaed82\",\n    \"0x8ebad537fece090ebbab662bdf2618e21ca30cf6329c50935e8346d1217dcbe3c1fe1ea28efca369c6003ce0a94703c1\",\n    \"0xa8640479556fb59ebd1c40c5f368fbd960932fdbb782665e4a0e24e2bdb598fc0164ce8c0726d7759cfc59e60a62e182\",\n    \"0xa9a52a6bf98ee4d749f6d38be2c60a6d54b64d5cbe4e67266633dc096cf28c97fe998596707d31968cbe2064b72256bf\",\n    \"0x847953c48a4ce6032780e9b39d0ed4384e0be202c2bbe2dfda3910f5d87aa5cd3c2ffbfcfae4dddce16d6ab657599b95\",\n    \"0xb6f6e1485d3ec2a06abaecd23028b200b2e4a0096c16144d07403e1720ff8f9ba9d919016b5eb8dc5103880a7a77a1d3\",\n    \"0x98dfc2065b1622f596dbe27131ea60bef7a193b12922cecb27f8c571404f483014f8014572e86ae2e341ab738e4887ef\",\n    \"0xacb0d205566bacc87bbe2e25d10793f63f7a1f27fd9e58f4f653ceae3ffeba511eaf658e068fad289eeb28f9edbeb35b\",\n    \"0xae4411ed5b263673cee894c11fe4abc72a4bf642d94022a5c0f3369380fcdfc1c21e277f2902972252503f91ada3029a\",\n    \"0xac4a7a27ba390a75d0a247d93d4a8ef1f0485f8d373a4af4e1139369ec274b91b3464d9738eeaceb19cd6f509e2f8262\",\n    \"0x87379c3bf231fdafcf6472a79e9e55a938d851d4dd662ab6e0d95fd47a478ed99e2ad1e6e39be3c0fc4f6d996a7dd833\",\n    \"0x81316904b035a8bcc2041199a789a2e6879486ba9fddcba0a82c745cc8dd8374a39e523b91792170cd30be7aa3005b85\",\n    \"0xb8206809c6cd027ed019f472581b45f7e12288f89047928ba32b4856b6560ad30395830d71e5e30c556f6f182b1fe690\",\n    \"0x88d76c028f534a62e019b4a52967bb8642ede6becfa3807be68fdd36d366fc84a4ac8dc176e80a68bc59eb62caf5dff9\",\n    \"0x8c3b8be685b0f8aad131ee7544d0e12f223f08a6f8edaf464b385ac644e0ddc9eff7cc7cb5c1b50ab5d71ea0f41d2213\",\n    \"0x8d91410e004f76c50fdc05784157b4d839cb5090022c629c7c97a5e0c3536eeafee17a527b54b1165c3cd81774bb54ce\",\n    \"0xb25c2863bc28ec5281ce800ddf91a7e1a53f4c6d5da1e6c86ef4616e93bcf55ed49e297216d01379f5c6e7b3c1e46728\",\n    \"0x865f7b09ac3ca03f20be90c48f6975dd2588838c2536c7a3532a6aa5187ed0b709cd03d91ff4048061c10d0aa72b69ce\",\n    \"0xb3f7477c90c11596eb4f8bbf34adbcb832638c4ff3cdd090d4d477ee50472ac9ddaf5be9ad7eca3f148960d362bbd098\",\n    \"0x8db35fd53fca04faecd1c76a8227160b3ab46ac1af070f2492445a19d8ff7c25bbaef6c9fa0c8c088444561e9f7e4eb2\",\n    \"0xa478b6e9d058a2e01d2fc053b739092e113c23a6a2770a16afbef044a3709a9e32f425ace9ba7981325f02667c3f9609\",\n    \"0x98caa6bd38916c08cf221722a675a4f7577f33452623de801d2b3429595f988090907a7e99960fff7c076d6d8e877b31\",\n    \"0xb79aaaacefc49c3038a14d2ac468cfec8c2161e88bdae91798d63552cdbe39e0e02f9225717436b9b8a40a022c633c6e\",\n    \"0x845a31006c680ee6a0cc41d3dc6c0c95d833fcf426f2e7c573fa15b2c4c641fbd6fe5ebb0e23720cc3467d6ee1d80dc4\",\n    \"0xa1bc287e272cf8b74dbf6405b3a5190883195806aa351f1dc8e525aa342283f0a35ff687e3b434324dedee74946dd185\",\n    \"0xa4fd2dc8db75d3783a020856e2b3aa266dc6926e84f5c491ef739a3bddd46dc8e9e0fc1177937839ef1b18d062ffbb9e\",\n    \"0xacbf0d3c697f57c202bb8c5dc4f3fc341b8fc509a455d44bd86acc67cad2a04495d5537bcd3e98680185e8aa286f2587\",\n    \"0xa5caf423a917352e1b8e844f5968a6da4fdeae467d10c6f4bbd82b5eea46a660b82d2f5440d3641c717b2c3c9ed0be52\",\n    \"0x8a39d763c08b926599ab1233219c49c825368fad14d9afc7c0c039224d37c00d8743293fd21645bf0b91eaf579a99867\",\n    \"0xb2b53a496def0ba06e80b28f36530fbe0fb5d70a601a2f10722e59abee529369c1ae8fd0f2db9184dd4a2519bb832d94\",\n    \"0xa73980fcef053f1b60ebbb5d78ba6332a475e0b96a0c724741a3abf3b59dd344772527f07203cf4c9cb5155ebed81fa0\",\n    \"0xa070d20acce42518ece322c9db096f16aed620303a39d8d5735a0df6e70fbeceb940e8d9f5cc38f3314b2240394ec47b\",\n    \"0xa50cf591f522f19ca337b73089557f75929d9f645f3e57d4f241e14cdd1ea3fb48d84bcf05e4f0377afbb789fbdb5d20\",\n    \"0x82a5ffce451096aca8eeb0cd2ae9d83db3ed76da3f531a80d9a70a346359bf05d74863ce6a7c848522b526156a5e20cd\",\n    \"0x88e0e84d358cbb93755a906f329db1537c3894845f32b9b0b691c29cbb455373d9452fadd1e77e20a623f6eaf624de6f\",\n    \"0xaa07ac7b84a6d6838826e0b9e350d8ec75e398a52e9824e6b0da6ae4010e5943fec4f00239e96433f291fef9d1d1e609\",\n    \"0xac8887bf39366034bc63f6cc5db0c26fd27307cbc3d6cce47894a8a019c22dd51322fb5096edc018227edfafc053a8f6\",\n    \"0xb7d26c26c5b33f77422191dca94977588ab1d4b9ce7d0e19c4a3b4cd1c25211b78c328dbf81e755e78cd7d1d622ad23e\",\n    \"0x99a676d5af49f0ba44047009298d8474cabf2d5bca1a76ba21eff7ee3c4691a102fdefea27bc948ccad8894a658abd02\",\n    \"0xb0d09a91909ab3620c183bdf1d53d43d39eb750dc7a722c661c3de3a1a5d383ad221f71bae374f8a71867505958a3f76\",\n    \"0x84681a883de8e4b93d68ac10e91899c2bbb815ce2de74bb48a11a6113b2a3f4df8aceabda1f5f67bc5aacac8c9da7221\",\n    \"0x9470259957780fa9b43521fab3644f555f5343281c72582b56d2efd11991d897b3b481cafa48681c5aeb80c9663b68f7\",\n    \"0xab1b29f7ece686e6fa968a4815da1d64f3579fed3bc92e1f3e51cd13a3c076b6cf695ed269d373300a62463dc98a4234\",\n    \"0x8ab415bfcd5f1061f7687597024c96dd9c7cb4942b5989379a7a3b5742f7d394337886317659cbeacaf030234a24f972\",\n    \"0xb9b524aad924f9acc63d002d617488f31b0016e0f0548f050cada285ce7491b74a125621638f19e9c96eabb091d945be\",\n    \"0x8c4c373e79415061837dd0def4f28a2d5d74d21cb13a76c9049ad678ca40228405ab0c3941df49249847ecdefc1a5b78\",\n    \"0xa8edf4710b5ab2929d3db6c1c0e3e242261bbaa8bcec56908ddadd7d2dad2dca9d6eb9de630b960b122ebeea41040421\",\n    \"0x8d66bb3b50b9df8f373163629f9221b3d4b6980a05ea81dc3741bfe9519cf3ebba7ab98e98390bae475e8ede5821bd5c\",\n    \"0x8d3c21bae7f0cfb97c56952bb22084b58e7bb718890935b73103f33adf5e4d99cd262f929c6eeab96209814f0dbae50a\",\n    \"0xa5c66cfab3d9ebf733c4af24bebc97070e7989fe3c73e79ac85fb0e4d40ae44fb571e0fad4ad72560e13ed453900d14f\",\n    \"0x9362e6b50b43dbefbc3254471372297b5dcce809cd3b60bf74a1268ab68bdb50e46e462cbd78f0d6c056330e982846af\",\n    \"0x854630d08e3f0243d570cc2e856234cb4c1a158d9c1883bf028a76525aaa34be897fe918d5f6da9764a3735fa9ebd24a\",\n    \"0x8c7d246985469ff252c3f4df6c7c9196fc79f05c1c66a609d84725c78001d0837c7a7049394ba5cf7e863e2d58af8417\",\n    \"0xae050271e01b528925302e71903f785b782f7bf4e4e7a7f537140219bc352dc7540c657ed03d3a297ad36798ecdb98cd\",\n    \"0x8d2ae9179fcf2b0c69850554580b52c1f4a5bd865af5f3028f222f4acad9c1ad69a8ef6c7dc7b03715ee5c506b74325e\",\n    \"0xb8ef8de6ce6369a8851cd36db0ccf00a85077e816c14c4e601f533330af9e3acf0743a95d28962ed8bfcfc2520ef3cfe\",\n    \"0xa6ecad6fdfb851b40356a8b1060f38235407a0f2706e7b8bb4a13465ca3f81d4f5b99466ac2565c60af15f022d26732e\",\n    \"0x819ff14cdea3ab89d98e133cd2d0379361e2e2c67ad94eeddcdb9232efd509f51d12f4f03ebd4dd953bd262a886281f7\",\n    \"0x8561cd0f7a6dbcddd83fcd7f472d7dbcba95b2d4fb98276f48fccf69f76d284e626d7e41314b633352df8e6333fd52a1\",\n    \"0xb42557ccce32d9a894d538c48712cb3e212d06ac05cd5e0527ccd2db1078ee6ae399bf6a601ffdab1f5913d35fc0b20c\",\n    \"0x89b4008d767aad3c6f93c349d3b956e28307311a5b1cec237e8d74bb0dee7e972c24f347fd56afd915a2342bd7bc32f0\",\n    \"0x877487384b207e53f5492f4e36c832c2227f92d1bb60542cfeb35e025a4a7afc2b885fae2528b33b40ab09510398f83e\",\n    \"0x8c411050b63c9053dd0cd81dacb48753c3d7f162028098e024d17cd6348482703a69df31ad6256e3d25a8bbf7783de39\",\n    \"0xa8506b54a88d17ac10fb1b0d1fe4aa40eae7553a064863d7f6b52ccc4236dd4b82d01dca6ba87da9a239e3069ba879fb\",\n    \"0xb1a24caef9df64750c1350789bb8d8a0db0f39474a1c74ea9ba064b1516db6923f00af8d57c632d58844fb8786c3d47a\",\n    \"0x959d6e255f212b0708c58a2f75cb1fe932248c9d93424612c1b8d1e640149656059737e4db2139afd5556bcdacf3eda2\",\n    \"0x84525af21a8d78748680b6535bbc9dc2f0cf9a1d1740d12f382f6ecb2e73811d6c1da2ad9956070b1a617c61fcff9fe5\",\n    \"0xb74417d84597a485d0a8e1be07bf78f17ebb2e7b3521b748f73935b9afbbd82f34b710fb7749e7d4ab55b0c7f9de127d\",\n    \"0xa4a9aecb19a6bab167af96d8b9d9aa5308eab19e6bfb78f5a580f9bf89bdf250a7b52a09b75f715d651cb73febd08e84\",\n    \"0x9777b30be2c5ffe7d29cc2803a562a32fb43b59d8c3f05a707ab60ec05b28293716230a7d264d7cd9dd358fc031cc13e\",\n    \"0x95dce7a3d4f23ac0050c510999f5fbf8042f771e8f8f94192e17bcbfa213470802ebdbe33a876cb621cf42e275cbfc8b\",\n    \"0xb0b963ebcbbee847ab8ae740478544350b3ac7e86887e4dfb2299ee5096247cd2b03c1de74c774d9bde94ae2ee2dcd59\",\n    \"0xa4ab20bafa316030264e13f7ef5891a2c3b29ab62e1668fcb5881f50a9acac6adbe3d706c07e62f2539715db768f6c43\",\n    \"0x901478a297669d608e406fe4989be75264b6c8be12169aa9e0ad5234f459ca377f78484ffd2099a2fe2db5e457826427\",\n    \"0x88c76e5c250810c057004a03408b85cd918e0c8903dc55a0dd8bb9b4fc2b25c87f9b8cf5943eb19fbbe99d36490050c5\",\n    \"0x91607322bbad4a4f03fc0012d0821eff5f8c516fda45d1ec1133bface6f858bf04b25547be24159cab931a7aa08344d4\",\n    \"0x843203e07fce3c6c81f84bc6dc5fb5e9d1c50c8811ace522dc66e8658433a0ef9784c947e6a62c11bf705307ef05212e\",\n    \"0x91dd8813a5d6dddcda7b0f87f672b83198cd0959d8311b2b26fb1fae745185c01f796fbd03aad9db9b58482483fdadd8\",\n    \"0x8d15911aacf76c8bcd7136e958febd6963104addcd751ce5c06b6c37213f9c4fb0ffd4e0d12c8e40c36d658999724bfd\",\n    \"0x8a36c5732d3f1b497ebe9250610605ee62a78eaa9e1a45f329d09aaa1061131cf1d9df00f3a7d0fe8ad614a1ff9caaae\",\n    \"0xa407d06affae03660881ce20dab5e2d2d6cddc23cd09b95502a9181c465e57597841144cb34d22889902aff23a76d049\",\n    \"0xb5fd856d0578620a7e25674d9503be7d97a2222900e1b4738c1d81ff6483b144e19e46802e91161e246271f90270e6cf\",\n    \"0x91b7708869cdb5a7317f88c0312d103f8ce90be14fb4f219c2e074045a2a83636fdc3e69e862049fc7c1ef000e832541\",\n    \"0xb64719cc5480709d1dae958f1d3082b32a43376da446c8f9f64cb02a301effc9c34d9102051733315a8179aed94d53cc\",\n    \"0x94347a9542ff9d18f7d9eaa2f4d9b832d0e535fe49d52aa2de08aa8192400eddabdb6444a2a78883e27c779eed7fdf5a\",\n    \"0x840ef44a733ff1376466698cd26f82cf56bb44811e196340467f932efa3ae1ef9958a0701b3b032f50fd9c1d2aed9ab5\",\n    \"0x90ab3f6f67688888a31ffc2a882bb37adab32d1a4b278951a21646f90d03385fc976715fc639a785d015751171016f10\",\n    \"0xb56f35d164c24b557dbcbc8a4bfa681ec916f8741ffcb27fb389c164f4e3ed2be325210ef5bdaeae7a172ca9599ab442\",\n    \"0xa7921a5a80d7cf6ae81ba9ee05e0579b18c20cd2852762c89d6496aa4c8ca9d1ca2434a67b2c16d333ea8e382cdab1e3\",\n    \"0xa506bcfbd7e7e5a92f68a1bd87d07ad5fe3b97aeee40af2bf2cae4efcd77fff03f872732c5b7883aa6584bee65d6f8cb\",\n    \"0xa8c46cff58931a1ce9cbe1501e1da90b174cddd6d50f3dfdfb759d1d4ad4673c0a8feed6c1f24c7af32865a7d6c984e5\",\n    \"0xb45686265a83bff69e312c5149db7bb70ac3ec790dc92e392b54d9c85a656e2bf58596ce269f014a906eafc97461aa5f\",\n    \"0x8d4009a75ccb2f29f54a5f16684b93202c570d7a56ec1a8b20173269c5f7115894f210c26b41e8d54d4072de2d1c75d0\",\n    \"0xaef8810af4fc676bf84a0d57b189760ddc3375c64e982539107422e3de2580b89bd27aa6da44e827b56db1b5555e4ee8\",\n    \"0x888f0e1e4a34f48eb9a18ef4de334c27564d72f2cf8073e3d46d881853ac1424d79e88d8ddb251914890588937c8f711\",\n    \"0xb64b0aa7b3a8f6e0d4b3499fe54e751b8c3e946377c0d5a6dbb677be23736b86a7e8a6be022411601dd75012012c3555\",\n    \"0x8d57776f519f0dd912ea14f79fbab53a30624e102f9575c0bad08d2dc754e6be54f39b11278c290977d9b9c7c0e1e0ad\",\n    \"0xa018fc00d532ceb2e4de908a15606db9b6e0665dd77190e2338da7c87a1713e6b9b61554e7c1462f0f6d4934b960b15c\",\n    \"0x8c932be83ace46f65c78e145b384f58e41546dc0395270c1397874d88626fdeda395c8a289d602b4c312fe98c1311856\",\n    \"0x89174838e21639d6bdd91a0621f04dc056907b88e305dd66e46a08f6d65f731dea72ae87ca5e3042d609e8de8de9aa26\",\n    \"0xb7b7f508bb74f7a827ac8189daa855598ff1d96fa3a02394891fd105d8f0816224cd50ac4bf2ed1cf469ace516c48184\",\n    \"0xb31877ad682583283baadd68dc1bebd83f5748b165aadd7fe9ef61a343773b88bcd3a022f36d6c92f339b7bfd72820a9\",\n    \"0xb79d77260b25daf9126dab7a193df2d7d30542786fa1733ffaf6261734770275d3ca8bae1d9915d1181a78510b3439db\",\n    \"0x91894fb94cd4c1dd2ceaf9c53a7020c5799ba1217cf2d251ea5bc91ed26e1159dd758e98282ebe35a0395ef9f1ed15a0\",\n    \"0xab59895cdafd33934ceedfc3f0d5d89880482cba6c99a6db93245f9e41987efd76e0640e80aef31782c9a8c7a83fccec\",\n    \"0xaa22ea63654315e033e09d4d4432331904a6fc5fb1732557987846e3c564668ca67c60a324b4af01663a23af11a9ce4b\",\n    \"0xb53ba3ef342601467e1f71aa280e100fbabbd38518fa0193e0099505036ee517c1ac78e96e9baeb549bb6879bb698fb0\",\n    \"0x943fd69fd656f37487cca3605dc7e5a215fddd811caf228595ec428751fc1de484a0cb84c667fe4d7c35599bfa0e5e34\",\n    \"0x9353128b5ebe0dddc555093cf3e5942754f938173541033e8788d7331fafc56f68d9f97b4131e37963ab7f1c8946f5f1\",\n    \"0xa76cd3c566691f65cfb86453b5b31dbaf3cab8f84fe1f795dd1e570784b9b01bdd5f0b3c1e233942b1b5838290e00598\",\n    \"0x983d84b2e53ffa4ae7f3ba29ef2345247ea2377686b74a10479a0ef105ecf90427bf53b74c96dfa346d0f842b6ffb25b\",\n    \"0x92e0fe9063306894a2c6970c001781cff416c87e87cb5fbac927a3192655c3da4063e6fa93539f6ff58efac6adcc5514\",\n    \"0xb00a81f03c2b8703acd4e2e4c21e06973aba696415d0ea1a648ace2b0ea19b242fede10e4f9d7dcd61c546ab878bc8f9\",\n    \"0xb0d08d880f3b456a10bf65cff983f754f545c840c413aea90ce7101a66eb0a0b9b1549d6c4d57725315828607963f15a\",\n    \"0x90cb64d03534f913b411375cce88a9e8b1329ce67a9f89ca5df8a22b8c1c97707fec727dbcbb9737f20c4cf751359277\",\n    \"0x8327c2d42590dfcdb78477fc18dcf71608686ad66c49bce64d7ee874668be7e1c17cc1042a754bbc77c9daf50b2dae07\",\n    \"0x8532171ea13aa7e37178e51a6c775da469d2e26ec854eb16e60f3307db4acec110d2155832c202e9ba525fc99174e3b0\",\n    \"0x83ca44b15393d021de2a511fa5511c5bd4e0ac7d67259dce5a5328f38a3cce9c3a269405959a2486016bc27bb140f9ff\",\n    \"0xb1d36e8ca812be545505c8214943b36cabee48112cf0de369957afa796d37f86bf7249d9f36e8e990f26f1076f292b13\",\n    \"0x9803abf45be5271e2f3164c328d449efc4b8fc92dfc1225d38e09630909fe92e90a5c77618daa5f592d23fc3ad667094\",\n    \"0xb268ad68c7bf432a01039cd889afae815c3e120f57930d463aece10af4fd330b5bd7d8869ef1bcf6b2e78e4229922edc\",\n    \"0xa4c91a0d6f16b1553264592b4cbbbf3ca5da32ab053ffbdd3dbb1aed1afb650fb6e0dc5274f71a51d7160856477228db\",\n    \"0xad89d043c2f0f17806277ffdf3ecf007448e93968663f8a0b674254f36170447b7527d5906035e5e56f4146b89b5af56\",\n    \"0x8b6964f757a72a22a642e4d69102951897e20c21449184e44717bd0681d75f7c5bfa5ee5397f6e53febf85a1810d6ed1\",\n    \"0xb08f5cdaabec910856920cd6e836c830b863eb578423edf0b32529488f71fe8257d90aed4a127448204df498b6815d79\",\n    \"0xaf26bb3358be9d280d39b21d831bb53145c4527a642446073fee5a86215c4c89ff49a3877a7a549486262f6f57a0f476\",\n    \"0xb4010b37ec4d7c2af20800e272539200a6b623ae4636ecbd0e619484f4ab9240d02bc5541ace3a3fb955dc0a3d774212\",\n    \"0x82752ab52bdcc3cc2fc405cb05a2e694d3df4a3a68f2179ec0652536d067b43660b96f85f573f26fbd664a9ef899f650\",\n    \"0x96d392dde067473a81faf2d1fea55b6429126b88b160e39b4210d31d0a82833ffd3a80e07d24d495aea2d96be7251547\",\n    \"0xa76d8236d6671204d440c33ac5b8deb71fa389f6563d80e73be8b043ec77d4c9b06f9a586117c7f957f4af0331cbc871\",\n    \"0xb6c90961f68b5e385d85c9830ec765d22a425f506904c4d506b87d8944c2b2c09615e740ed351df0f9321a7b93979cae\",\n    \"0xa6ec5ea80c7558403485b3b1869cdc63bde239bafdf936d9b62a37031628402a36a2cfa5cfbb8e26ac922cb0a209b3ba\",\n    \"0x8c3195bbdbf9bc0fc95fa7e3d7f739353c947f7767d1e3cb24d8c8602d8ea0a1790ac30b815be2a2ba26caa5227891e2\",\n    \"0xa7f8a63d809f1155722c57f375ea00412b00147776ae4444f342550279ef4415450d6f400000a326bf11fea6c77bf941\",\n    \"0x97fa404df48433a00c85793440e89bb1af44c7267588ae937a1f5d53e01e1c4d4fc8e4a6d517f3978bfdd6c2dfde012f\",\n    \"0xa984a0a3836de3d8d909c4629a2636aacb85393f6f214a2ef68860081e9db05ad608024762db0dc35e895dc00e2d4cdd\",\n    \"0x9526cf088ab90335add1db4d3a4ac631b58cbfbe88fa0845a877d33247d1cfeb85994522e1eb8f8874651bfb1df03e2a\",\n    \"0xac83443fd0afe99ad49de9bf8230158c118e2814c9c89db5ac951c240d6c2ce45e7677221279d9e97848ec466b99aafe\",\n    \"0xaeeefdbaba612e971697798ceaf63b247949dc823a0ad771ae5b988a5e882b338a98d3d0796230f49d533ec5ba411b39\",\n    \"0xae3f248b5a7b0f92b7820a6c5ae21e5bd8f4265d4f6e21a22512079b8ee9be06393fd3133ce8ebac0faf23f4f8517e36\",\n    \"0xa64a831b908eee784b8388b45447d2885ec0551b26b0c2b15e5f417d0a12c79e867fb7bd3d008d0af98b44336f8ec1ad\",\n    \"0xb242238cd8362b6e440ba21806905714dd55172db25ec7195f3fc4937b2aba146d5cbf3cf691a1384b4752dc3b54d627\",\n    \"0x819f97f337eea1ffb2a678cc25f556f1aab751c6b048993a1d430fe1a3ddd8bb411c152e12ca60ec6e057c190cd1db9a\",\n    \"0xb9d7d187407380df54ee9fef224c54eec1bfabf17dc8abf60765b7951f538f59aa26fffd5846cfe05546c35f59b573f4\",\n    \"0xaa6e3c14efa6a5962812e3f94f8ce673a433f4a82d07a67577285ea0eaa07f8be7115853122d12d6d4e1fdf64c504be1\",\n    \"0x82268bee9c1662d3ddb5fb785abfae6fb8b774190f30267f1d47091d2cd4b3874db4372625aa36c32f27b0eee986269b\",\n    \"0xb236459565b7b966166c4a35b2fa71030b40321821b8e96879d95f0e83a0baf33fa25721f30af4a631df209e25b96061\",\n    \"0x8708d752632d2435d2d5b1db4ad1fa2558d776a013655f88e9a3556d86b71976e7dfe5b8834fdec97682cd94560d0d0d\",\n    \"0xae1424a68ae2dbfb0f01211f11773732a50510b5585c1fb005cb892b2c6a58f4a55490b5c5b4483c6fce40e9d3236a52\",\n    \"0xb3f5f722af9dddb07293c871ce97abbccba0093ca98c8d74b1318fa21396fc1b45b69c15084f63d728f9908442024506\",\n    \"0x9606f3ce5e63886853ca476dc0949e7f1051889d529365c0cb0296fdc02abd088f0f0318ecd2cf36740a3634132d36f6\",\n    \"0xb11a833a49fa138db46b25ff8cdda665295226595bc212c0931b4931d0a55c99da972c12b4ef753f7e37c6332356e350\",\n    \"0xafede34e7dab0a9e074bc19a7daddb27df65735581ca24ad70c891c98b1349fcebbcf3ba6b32c2617fe06a5818dabc2d\",\n    \"0x97993d456e459e66322d01f8eb13918979761c3e8590910453944bdff90b24091bb018ac6499792515c9923be289f99f\",\n    \"0x977e3e967eff19290a192cd11df3667d511b398fb3ac9a5114a0f3707e25a0edcb56105648b1b85a8b7519fc529fc6f6\",\n    \"0xb873a7c88bf58731fe1bf61ff6828bf114cf5228f254083304a4570e854e83748fc98683ddba62d978fff7909f2c5c47\",\n    \"0xad4b2691f6f19da1d123aaa23cca3e876247ed9a4ab23c599afdbc0d3aa49776442a7ceaa996ac550d0313d9b9a36cee\",\n    \"0xb9210713c78e19685608c6475bfa974b57ac276808a443f8b280945c5d5f9c39da43effa294bfb1a6c6f7b6b9f85bf6c\",\n    \"0xa65152f376113e61a0e468759de38d742caa260291b4753391ee408dea55927af08a4d4a9918600a3bdf1df462dffe76\",\n    \"0x8bf8c27ad5140dde7f3d2280fd4cc6b29ab76537e8d7aa7011a9d2796ee3e56e9a60c27b5c2da6c5e14fc866301dc195\",\n    \"0x92fde8effc9f61393a2771155812b863cff2a0c5423d7d40aa04d621d396b44af94ddd376c28e7d2f53c930aea947484\",\n    \"0x97a01d1dd9ee30553ce676011aea97fa93d55038ada95f0057d2362ae9437f3ed13de8290e2ff21e3167dd7ba10b9c3f\",\n    \"0x89affffaa63cb2df3490f76f0d1e1d6ca35c221dd34057176ba739fa18d492355e6d2a5a5ad93a136d3b1fed0bb8aa19\",\n    \"0x928b8e255a77e1f0495c86d3c63b83677b4561a5fcbbe5d3210f1e0fc947496e426d6bf3b49394a5df796c9f25673fc4\",\n    \"0x842a0af91799c9b533e79ee081efe2a634cac6c584c2f054fb7d1db67dde90ae36de36cbf712ec9cd1a0c7ee79e151ea\",\n    \"0xa65b946cf637e090baf2107c9a42f354b390e7316beb8913638130dbc67c918926eb87bec3b1fe92ef72bc77a170fa3b\",\n    \"0xaafc0f19bfd71ab5ae4a8510c7861458b70ad062a44107b1b1dbacbfa44ba3217028c2824bd7058e2fa32455f624040b\",\n    \"0x95269dc787653814e0be899c95dba8cfa384f575a25e671c0806fd80816ad6797dc819d30ae06e1d0ed9cb01c3950d47\",\n    \"0xa1e760f7fa5775a1b2964b719ff961a92083c5c617f637fc46e0c9c20ab233f8686f7f38c3cb27d825c54dd95e93a59b\",\n    \"0xac3b8a7c2317ea967f229eddc3e23e279427f665c4705c7532ed33443f1243d33453c1088f57088d2ab1e3df690a9cc9\",\n    \"0xb787beeddfbfe36dd51ec4efd9cf83e59e84d354c3353cc9c447be53ae53d366ed1c59b686e52a92f002142c8652bfe0\",\n    \"0xb7a64198300cb6716aa7ac6b25621f8bdec46ad5c07a27e165b3f774cdf65bcfdbf31e9bae0c16b44de4b00ada7a4244\",\n    \"0xb8ae9f1452909e0c412c7a7fe075027691ea8df1347f65a5507bc8848f1d2c833d69748076db1129e5b4fb912f65c86c\",\n    \"0x9682e41872456b9fa67def89e71f06d362d6c8ca85c9c48536615bc401442711e1c9803f10ab7f8ab5feaec0f9df20a6\",\n    \"0x88889ff4e271dc1c7e21989cc39f73cde2f0475acd98078281591ff6c944fadeb9954e72334319050205d745d4df73df\",\n    \"0x8f79b5b8159e7fd0d93b0645f3c416464f39aec353b57d99ecf24f96272df8a068ad67a6c90c78d82c63b40bb73989bb\",\n    \"0x838c01a009a3d8558a3f0bdd5e22de21af71ca1aefc8423c91dc577d50920e9516880e87dce3e6d086e11cd45c9052d9\",\n    \"0xb97f1c6eee8a78f137c840667cc288256e39294268a3009419298a04a1d0087c9c9077b33c917c65caf76637702dda8a\",\n    \"0x972284ce72f96a61c899260203dfa06fc3268981732bef74060641c1a5068ead723e3399431c247ca034b0dae861e8df\",\n    \"0x945a8d52d6d3db6663dbd3110c6587f9e9c44132045eeffba15621576d178315cb52870fa5861669f84f0bee646183fe\",\n    \"0xa0a547b5f0967b1c3e5ec6c6a9a99f0578521489180dfdfbb5561f4d166baac43a2f06f950f645ce991664e167537eed\",\n    \"0xa0592cda5cdddf1340033a745fd13a6eff2021f2e26587116c61c60edead067e0f217bc2bef4172a3c9839b0b978ab35\",\n    \"0xb9c223b65a3281587fa44ec829e609154b32f801fd1de6950e01eafb07a8324243b960d5735288d0f89f0078b2c42b5b\",\n    \"0x99ebfc3b8f9f98249f4d37a0023149ed85edd7a5abe062c8fb30c8c84555258b998bdcdd1d400bc0fa2a4aaa8b224466\",\n    \"0x955b68526e6cb3937b26843270f4e60f9c6c8ece2fa9308fe3e23afa433309c068c66a4bc16ee2cf04220f095e9afce4\",\n    \"0xb766caeafcc00378135ae53397f8a67ed586f5e30795462c4a35853de6681b1f17401a1c40958de32b197c083b7279c1\",\n    \"0x921bf87cad947c2c33fa596d819423c10337a76fe5a63813c0a9dc78a728207ae7b339407a402fc4d0f7cba3af6da6fc\",\n    \"0xa74ba1f3bc3e6c025db411308f49b347ec91da1c916bda9da61e510ec8d71d25e0ac0f124811b7860e5204f93099af27\",\n    \"0xa29b4d144e0bf17a7e8353f2824cef0ce85621396babe8a0b873ca1e8a5f8d508b87866cf86da348470649fceefd735c\",\n    \"0xa8040e12ffc3480dd83a349d06741d1572ef91932c46f5cf03aee8454254156ee95786fd013d5654725e674c920cec32\",\n    \"0x8c4cf34ca60afd33923f219ffed054f90cd3f253ffeb2204a3b61b0183417e366c16c07fae860e362b0f2bfe3e1a1d35\",\n    \"0x8195eede4ddb1c950459df6c396b2e99d83059f282b420acc34220cadeed16ab65c856f2c52568d86d3c682818ed7b37\",\n    \"0x91fff19e54c15932260aa990c7fcb3c3c3da94845cc5aa8740ef56cf9f58d19b4c3c55596f8d6c877f9f4d22921d93aa\",\n    \"0xa3e0bf7e5d02a80b75cf75f2db7e66cb625250c45436e3c136d86297d652590ec97c2311bafe407ad357c79ab29d107b\",\n    \"0x81917ff87e5ed2ae4656b481a63ced9e6e5ff653b8aa6b7986911b8bc1ee5b8ef4f4d7882c3f250f2238e141b227e510\",\n    \"0x915fdbe5e7de09c66c0416ae14a8750db9412e11dc576cf6158755fdcaf67abdbf0fa79b554cac4fe91c4ec245be073f\",\n    \"0x8df27eafb5c3996ba4dc5773c1a45ca77e626b52e454dc1c4058aa94c2067c18332280630cc3d364821ee53bf2b8c130\",\n    \"0x934f8a17c5cbb827d7868f5c8ca00cb027728a841000a16a3428ab16aa28733f16b52f58c9c4fbf75ccc45df72d9c4df\",\n    \"0xb83f4da811f9183c25de8958bc73b504cf790e0f357cbe74ef696efa7aca97ad3b7ead1faf76e9f982c65b6a4d888fc2\",\n    \"0x87188213c8b5c268dc2b6da413f0501c95749e953791b727450af3e43714149c115b596b33b63a2f006a1a271b87efd0\",\n    \"0x83e9e888ab9c3e30761de635d9aabd31248cdd92f7675fc43e4b21fd96a03ec1dc4ad2ec94fec857ffb52683ac98e360\",\n    \"0xb4b9a1823fe2d983dc4ec4e3aaea297e581c3fc5ab4b4af5fa1370caa37af2d1cc7fc6bfc5e7da60ad8fdce27dfe4b24\",\n    \"0x856388bc78aef465dbcdd1f559252e028c9e9a2225c37d645c138e78f008f764124522705822a61326a6d1c79781e189\",\n    \"0xa6431b36db93c3b47353ba22e7c9592c9cdfb9cbdd052ecf2cc3793f5b60c1e89bc96e6bae117bfd047f2308da00dd2f\",\n    \"0xb619972d48e7e4291542dcde08f7a9cdc883c892986ded2f23ccb216e245cd8d9ad1d285347b0f9d7611d63bf4cee2bc\",\n    \"0x8845cca6ff8595955f37440232f8e61d5351500bd016dfadd182b9d39544db77a62f4e0102ff74dd4173ae2c181d24ef\",\n    \"0xb2f5f7fa26dcd3b6550879520172db2d64ee6aaa213cbef1a12befbce03f0973a22eb4e5d7b977f466ac2bf8323dcedd\",\n    \"0x858b7f7e2d44bdf5235841164aa8b4f3d33934e8cb122794d90e0c1cac726417b220529e4f896d7b77902ab0ccd35b3a\",\n    \"0x80b0408a092dae2b287a5e32ea1ad52b78b10e9c12f49282976cd738f5d834e03d1ad59b09c5ccaccc39818b87d06092\",\n    \"0xb996b0a9c6a2d14d984edcd6ab56bc941674102980d65b3ad9733455f49473d3f587c8cbf661228a7e125ddbe07e3198\",\n    \"0x90224fcebb36865293bd63af786e0c5ade6b67c4938d77eb0cbae730d514fdd0fe2d6632788e858afd29d46310cf86df\",\n    \"0xb71351fdfff7168b0a5ec48397ecc27ac36657a8033d9981e97002dcca0303e3715ce6dd3f39423bc8ef286fa2e9e669\",\n    \"0xae2a3f078b89fb753ce4ed87e0c1a58bb19b4f0cfb6586dedb9fcab99d097d659a489fb40e14651741e1375cfc4b6c5f\",\n    \"0x8ef476b118e0b868caed297c161f4231bbeb863cdfa5e2eaa0fc6b6669425ce7af50dc374abceac154c287de50c22307\",\n    \"0x92e46ab472c56cfc6458955270d3c72b7bde563bb32f7d4ab4d959db6f885764a3d864e1aa19802fefaa5e16b0cb0b54\",\n    \"0x96a3f68323d1c94e73d5938a18a377af31b782f56212de3f489d22bc289cf24793a95b37f1d6776edf88114b5c1fa695\",\n    \"0x962cc068cfce6faaa27213c4e43e44eeff0dfbb6d25b814e82c7da981fb81d7d91868fa2344f05fb552362f98cfd4a72\",\n    \"0x895d4e4c4ad670abf66d43d59675b1add7afad7438ada8f42a0360c704cee2060f9ac15b4d27e9b9d0996bb801276fe3\",\n    \"0xb3ad18d7ece71f89f2ef749b853c45dc56bf1c796250024b39a1e91ed11ca32713864049c9aaaea60cde309b47486bbf\",\n    \"0x8f05404e0c0258fdbae50e97ccb9b72ee17e0bd2400d9102c0dad981dac8c4c71585f03e9b5d50086d0a2d3334cb55d1\",\n    \"0x8bd877e9d4591d02c63c6f9fc9976c109de2d0d2df2bfa5f6a3232bab5b0b8b46e255679520480c2d7a318545efa1245\",\n    \"0x8d4c16b5d98957c9da13d3f36c46f176e64e5be879f22be3179a2c0e624fe4758a82bf8c8027410002f973a3b84cd55a\",\n    \"0x86e2a8dea86427b424fa8eada881bdff896907084a495546e66556cbdf070b78ba312bf441eb1be6a80006d25d5097a3\",\n    \"0x8608b0c117fd8652fdab0495b08fadbeba95d9c37068e570de6fddfef1ba4a1773b42ac2be212836141d1bdcdef11a17\",\n    \"0xa13d6febf5fb993ae76cae08423ca28da8b818d6ef0fde32976a4db57839cd45b085026b28ee5795f10a9a8e3098c683\",\n    \"0x8e261967fa6de96f00bc94a199d7f72896a6ad8a7bbb1d6187cca8fad824e522880e20f766620f4f7e191c53321d70f9\",\n    \"0x8b8e8972ac0218d7e3d922c734302803878ad508ca19f5f012bc047babd8a5c5a53deb5fe7c15a4c00fd6d1cb9b1dbd0\",\n    \"0xb5616b233fb3574a2717d125a434a2682ff68546dccf116dd8a3b750a096982f185614b9fb6c7678107ff40a451f56fa\",\n    \"0xaa6adf9b0c3334b0d0663f583a4914523b2ac2e7adffdb026ab9109295ff6af003ef8357026dbcf789896d2afded8d73\",\n    \"0xacb72df56a0b65496cd534448ed4f62950bb1e11e50873b6ed349c088ee364441821294ce0f7c61bd7d38105bea3b442\",\n    \"0xabae12df83e01ec947249fedd0115dc501d2b03ff7232092979eda531dbbca29ace1d46923427c7dde4c17bdf3fd7708\",\n    \"0x820b4fc2b63a9fda7964acf5caf19a2fc4965007cb6d6b511fcafcb1f71c3f673a1c0791d3f86e3a9a1eb6955b191cc0\",\n    \"0xaf277259d78c6b0f4f030a10c53577555df5e83319ddbad91afbd7c30bc58e7671c56d00d66ec3ab5ef56470cd910cee\",\n    \"0xad4a861c59f1f5ca1beedd488fb3d131dea924fffd8e038741a1a7371fad7370ca5cf80dc01f177fbb9576713bb9a5b3\",\n    \"0xb67a5162982ce6a55ccfb2f177b1ec26b110043cf18abd6a6c451cf140b5af2d634591eb4f28ad92177d8c7e5cd0a5e8\",\n    \"0x96176d0a83816330187798072d449cbfccff682561e668faf6b1220c9a6535b32a6e4f852e8abb00f79abb87493df16b\",\n    \"0xb0afe6e7cb672e18f0206e4423f51f8bd0017bf464c4b186d46332c5a5847647f89ff7fa4801a41c1b0b42f6135bcc92\",\n    \"0x8fc5e7a95ef20c1278c645892811f6fe3f15c431ebc998a32ec0da44e7213ea934ed2be65239f3f49b8ec471e9914160\",\n    \"0xb7793e41adda6c82ba1f2a31f656f6205f65bf8a3d50d836ee631bc7ce77c153345a2d0fc5c60edf8b37457c3729c4ec\",\n    \"0xa504dd7e4d6b2f4379f22cc867c65535079c75ccc575955f961677fa63ecb9f74026fa2f60c9fb6323c1699259e5e9c8\",\n    \"0xab899d00ae693649cc1afdf30fb80d728973d2177c006e428bf61c7be01e183866614e05410041bc82cb14a33330e69c\",\n    \"0x8a3bd8b0b1be570b65c4432a0f6dc42f48a2000e30ab089cf781d38f4090467b54f79c0d472fcbf18ef6a00df69cc6f3\",\n    \"0xb4d7028f7f76a96a3d7803fca7f507ae11a77c5346e9cdfccb120a833a59bda1f4264e425aa588e7a16f8e7638061d84\",\n    \"0xb9c7511a76ea5fb105de905d44b02edb17008335766ee357ed386b7b3cf19640a98b38785cb14603c1192bee5886c9b6\",\n    \"0x8563afb12e53aed71ac7103ab8602bfa8371ae095207cb0d59e8fd389b6ad1aff0641147e53cb6a7ca16c7f37c9c5e6b\",\n    \"0x8e108be614604e09974a9ed90960c28c4ea330a3d9a0cb4af6dd6f193f84ab282b243ecdf549b3131036bebc8905690c\",\n    \"0xb794d127fbedb9c5b58e31822361706ffac55ce023fbfe55716c3c48c2fd2f2c7660a67346864dfe588812d369cb50b6\",\n    \"0xb797a3442fc3b44f41baefd30346f9ac7f96e770d010d53c146ce74ce424c10fb62758b7e108b8abfdc5fafd89d745cb\",\n    \"0x993bb71e031e8096442e6205625e1bfddfe6dd6a83a81f3e2f84fafa9e5082ab4cad80a099f21eff2e81c83457c725c3\",\n    \"0x8711ab833fc03e37acf2e1e74cfd9133b101ff4144fe30260654398ae48912ab46549d552eb9d15d2ea57760d35ac62e\",\n    \"0xb21321fd2a12083863a1576c5930e1aecb330391ef83326d9d92e1f6f0d066d1394519284ddab55b2cb77417d4b0292f\",\n    \"0x877d98f731ffe3ee94b0b5b72d127630fa8a96f6ca4f913d2aa581f67732df6709493693053b3e22b0181632ac6c1e3b\",\n    \"0xae391c12e0eb8c145103c62ea64f41345973311c3bf7281fa6bf9b7faafac87bcf0998e5649b9ef81e288c369c827e07\",\n    \"0xb83a2842f36998890492ab1cd5a088d9423d192681b9a3a90ec518d4c541bce63e6c5f4df0f734f31fbfdd87785a2463\",\n    \"0xa21b6a790011396e1569ec5b2a423857b9bec16f543e63af28024e116c1ea24a3b96e8e4c75c6537c3e4611fd265e896\",\n    \"0xb4251a9c4aab3a495da7a42e684ba4860dbcf940ad1da4b6d5ec46050cbe8dab0ab9ae6b63b5879de97b905723a41576\",\n    \"0x8222f70aebfe6ac037f8543a08498f4cadb3edaac00336fc00437eb09f2cba758f6c38e887cc634b4d5b7112b6334836\",\n    \"0x86f05038e060594c46b5d94621a1d9620aa8ba59a6995baf448734e21f58e23c1ea2993d3002ad5250d6edd5ba59b34f\",\n    \"0xa7c0c749baef811ab31b973c39ceb1d94750e2bc559c90dc5eeb20d8bb6b78586a2b363c599ba2107d6be65cd435f24e\",\n    \"0x861d46a5d70b38d6c1cd72817a2813803d9f34c00320c8b62f8b9deb67f5b5687bc0b37c16d28fd017367b92e05da9ca\",\n    \"0xb3365d3dab639bffbe38e35383686a435c8c88b397b717cd4aeced2772ea1053ceb670f811f883f4e02975e5f1c4ac58\",\n    \"0xa5750285f61ab8f64cd771f6466e2c0395e01b692fd878f2ef2d5c78bdd8212a73a3b1dfa5e4c8d9e1afda7c84857d3b\",\n    \"0x835a10809ccf939bc46cf950a33b36d71be418774f51861f1cd98a016ade30f289114a88225a2c11e771b8b346cbe6ef\",\n    \"0xa4f59473a037077181a0a62f1856ec271028546ca9452b45cedfcb229d0f4d1aabfc13062b07e536cc8a0d4b113156a2\",\n    \"0x95cd14802180b224d44a73cc1ed599d6c4ca62ddcaa503513ccdc80aaa8be050cc98bd4b4f3b639549beb4587ac6caf9\",\n    \"0x973b731992a3e69996253d7f36dd7a0af1982b5ed21624b77a7965d69e9a377b010d6dabf88a8a97eec2a476259859cc\",\n    \"0xaf8a1655d6f9c78c8eb9a95051aa3baaf9c811adf0ae8c944a8d3fcba87b15f61021f3baf6996fa0aa51c81b3cb69de1\",\n    \"0x835aad5c56872d2a2d6c252507b85dd742bf9b8c211ccb6b25b52d15c07245b6d89b2a40f722aeb5083a47cca159c947\",\n    \"0xabf4e970b02bef8a102df983e22e97e2541dd3650b46e26be9ee394a3ea8b577019331857241d3d12b41d4eacd29a3ac\",\n    \"0xa13c32449dbedf158721c13db9539ae076a6ce5aeaf68491e90e6ad4e20e20d1cdcc4a89ed9fd49cb8c0dd50c17633c1\",\n    \"0x8c8f78f88b7e22dd7e9150ab1c000f10c28e696e21d85d6469a6fe315254740f32e73d81ab1f3c1cf8f544c86df506e8\",\n    \"0xb4b77f2acfe945abf81f2605f906c10b88fb4d28628487fb4feb3a09f17f28e9780445dfcee4878349d4c6387a9d17d4\",\n    \"0x8d255c235f3812c6ecc646f855fa3832be5cb4dbb9c9e544989fafdf3f69f05bfd370732eaf954012f0044aa013fc9c6\",\n    \"0xb982efd3f34b47df37c910148ac56a84e8116647bea24145a49e34e0a6c0176e3284d838dae6230cb40d0be91c078b85\",\n    \"0x983f365aa09bd85df2a6a2ad8e4318996b1e27d02090755391d4486144e40d80b1fbfe1c798d626db92f52e33aa634da\",\n    \"0x95fd1981271f3ea3a41d654cf497e6696730d9ff7369f26bc4d7d15c7adb4823dd0c42e4a005a810af12d234065e5390\",\n    \"0xa9f5219bd4b913c186ef30c02f995a08f0f6f1462614ea5f236964e02bdaa33db9d9b816c4aee5829947840a9a07ba60\",\n    \"0x9210e6ceb05c09b46fd09d036287ca33c45124ab86315e5d6911ff89054f1101faaa3e83d123b7805056d388bcec6664\",\n    \"0x8ed9cbf69c6ff3a5c62dd9fe0d7264578c0f826a29e614bc2fb4d621d90c8c9992438accdd7a614b1dca5d1bb73dc315\",\n    \"0x85cf2a8cca93e00da459e3cecd22c342d697eee13c74d5851634844fc215f60053cf84b0e03c327cb395f48d1c71a8a4\",\n    \"0x8818a18e9a2ec90a271b784400c1903089ffb0e0b40bc5abbbe12fbebe0f731f91959d98c5519ef1694543e31e2016d4\",\n    \"0x8dabc130f296fa7a82870bf9a8405aaf542b222ed9276bba9bd3c3555a0f473acb97d655ee7280baff766a827a8993f0\",\n    \"0xac7952b84b0dc60c4d858f034093b4d322c35959605a3dad2b806af9813a4680cb038c6d7f4485b4d6b2ff502aaeca25\",\n    \"0xad65cb6d57b48a2602568d2ec8010baed0eb440eec7638c5ec8f02687d764e9de5b5d42ad5582934e592b48471c22d26\",\n    \"0xa02ab8bd4c3d114ea23aebdd880952f9495912817da8c0c08eabc4e6755439899d635034413d51134c72a6320f807f1c\",\n    \"0x8319567764b8295402ec1ebef4c2930a138480b37e6d7d01c8b4c9cd1f2fc3f6e9a44ae6e380a0c469b25b06db23305f\",\n    \"0xafec53b2301dc0caa8034cd9daef78c48905e6068d692ca23d589b84a6fa9ddc2ed24a39480597e19cb3e83eec213b3f\",\n    \"0xac0b4ffdb5ae08e586a9cdb98f9fe56f4712af3a97065e89e274feacfb52b53c839565aee93c4cfaaccfe51432c4fab0\",\n    \"0x8972cbf07a738549205b1094c5987818124144bf187bc0a85287c94fdb22ce038c0f11df1aa16ec5992e91b44d1af793\",\n    \"0xb7267aa6f9e3de864179b7da30319f1d4cb2a3560f2ea980254775963f1523b44c680f917095879bebfa3dc2b603efcf\",\n    \"0x80f68f4bfc337952e29504ee5149f15093824ea7ab02507efd1317a670f6cbc3611201848560312e3e52e9d9af72eccf\",\n    \"0x8897fee93ce8fc1e1122e46b6d640bba309384dbd92e46e185e6364aa8210ebf5f9ee7e5e604b6ffba99aa80a10dd7d0\",\n    \"0xb58ea6c02f2360be60595223d692e82ee64874fda41a9f75930f7d28586f89be34b1083e03bbc1575bbfdda2d30db1ea\",\n    \"0x85a523a33d903280d70ac5938770453a58293480170c84926457ac2df45c10d5ff34322ab130ef4a38c916e70d81af53\",\n    \"0xa2cbf045e1bed38937492c1f2f93a5ba41875f1f262291914bc1fc40c60bd0740fb3fea428faf6da38b7c180fe8ac109\",\n    \"0x8c09328770ed8eb17afc6ac7ddd87bb476de18ed63cab80027234a605806895959990c47bd10d259d7f3e2ecb50074c9\",\n    \"0xb4b9e19edb4a33bde8b7289956568a5b6b6557404e0a34584b5721fe6f564821091013fbb158e2858c6d398293bb4b59\",\n    \"0x8a47377df61733a2aa5a0e945fce00267f8e950f37e109d4487d92d878fb8b573317bb382d902de515b544e9e233458d\",\n    \"0xb5804c9d97efeff5ca94f3689b8088c62422d92a1506fd1d8d3b1b30e8a866ad0d6dad4abfa051dfc4471250cac4c5d9\",\n    \"0x9084a6ee8ec22d4881e9dcc8a9eb3c2513523d8bc141942370fd191ad2601bf9537a0b1e84316f3209b3d8a54368051e\",\n    \"0x85447eea2fa26656a649f8519fa67279183044791d61cf8563d0783d46d747d96af31d0a93507bbb2242666aa87d3720\",\n    \"0x97566a84481027b60116c751aec552adfff2d9038e68d48c4db9811fb0cbfdb3f1d91fc176a0b0d988a765f8a020bce1\",\n    \"0xae87e5c1b9e86c49a23dceda4ecfd1dcf08567f1db8e5b6ec752ebd45433c11e7da4988573cdaebbb6f4135814fc059e\",\n    \"0xabee05cf9abdbc52897ac1ce9ed157f5466ed6c383d6497de28616238d60409e5e92619e528af8b62cc552bf09970dc2\",\n    \"0xae6d31cd7bf9599e5ee0828bab00ceb4856d829bba967278a73706b5f388465367aa8a6c7da24b5e5f1fdd3256ef8e63\",\n    \"0xac33e7b1ee47e1ee4af472e37ab9e9175260e506a4e5ce449788075da1b53c44cb035f3792d1eea2aa24b1f688cc6ed3\",\n    \"0x80f65b205666b0e089bb62152251c48c380a831e5f277f11f3ef4f0d52533f0851c1b612267042802f019ec900dc0e8f\",\n    \"0x858520ad7aa1c9fed738e3b583c84168f2927837ad0e1d326afe9935c26e9b473d7f8c382e82ef1fe37d2b39bb40a1ee\",\n    \"0xb842dd4af8befe00a97c2d0f0c33c93974761e2cb9e5ab8331b25170318ddd5e4bdbc02d8f90cbfdd5f348f4f371c1f7\",\n    \"0x8bf2cb79bc783cb57088aae7363320cbeaabd078ffdec9d41bc74ff49e0043d0dad0086a30e5112b689fd2f5a606365d\",\n    \"0x982eb03bbe563e8850847cd37e6a3306d298ab08c4d63ab6334e6b8c1fa13fce80cf2693b09714c7621d74261a0ff306\",\n    \"0xb143edb113dec9f1e5105d4a93fbe502b859e587640d3db2f628c09a17060e6aec9e900e2c8c411cda99bc301ff96625\",\n    \"0xaf472d9befa750dcebc5428fe1a024f18ec1c07bca0f95643ce6b5f4189892a910285afb03fd7ed7068fbe614e80d33c\",\n    \"0xa97e3bc57ede73ecd1bbf02de8f51b4e7c1a067da68a3cd719f4ba26a0156cbf1cef2169fd35a18c5a4cced50d475998\",\n    \"0xa862253c937cf3d75d7183e5f5be6a4385d526aeda5171c1c60a8381fea79f88f5f52a4fab244ecc70765d5765e6dfd5\",\n    \"0x90cb776f8e5a108f1719df4a355bebb04bf023349356382cae55991b31720f0fd03206b895fa10c56c98f52453be8778\",\n    \"0xa7614e8d0769dccd520ea4b46f7646e12489951efaef5176bc889e9eb65f6e31758df136b5bf1e9107e68472fa9b46ec\",\n    \"0xac3a9b80a3254c42e5ed3a090a0dd7aee2352f480de96ad187027a3bb6c791eddfc3074b6ffd74eea825188f107cda4d\",\n    \"0x82a01d0168238ef04180d4b6e0a0e39024c02c2d75b065017c2928039e154d093e1af4503f4d1f3d8a948917abb5d09f\",\n    \"0x8fab000a2b0eef851a483aec8d2dd85fe60504794411a2f73ed82e116960547ac58766cb73df71aea71079302630258d\",\n    \"0x872451a35c6db61c63e9b8bb9f16b217f985c20be4451c14282c814adb29d7fb13f201367c664435c7f1d4d9375d7a58\",\n    \"0x887d9ff54cc96b35d562df4a537ff972d7c4b3fd91ab06354969a4cfede0b9fc68bbffb61d0dbf1a58948dc701e54f5a\",\n    \"0x8cb5c2a6bd956875d88f41ae24574434f1308514d44057b55c9c70f13a3366ed054150eed0955a38fda3f757be73d55f\",\n    \"0x89ad0163cad93e24129d63f8e38422b7674632a8d0a9016ee8636184cab177659a676c4ee7efba3abe1a68807c656d60\",\n    \"0xb9ec01c7cab6d00359b5a0b4a1573467d09476e05ca51a9227cd16b589a9943d161eef62dcc73f0de2ec504d81f4d252\",\n    \"0x8031d17635d39dfe9705c485d2c94830b6fc9bc67b91300d9d2591b51e36a782e77ab5904662effa9382d9cca201f525\",\n    \"0x8be5a5f6bc8d680e5092d6f9a6585acbaaaa2ddc671da560dcf5cfa4472f4f184b9597b5b539438accd40dda885687cc\",\n    \"0xb1fc0f052fae038a2e3de3b3a96b0a1024b009de8457b8b3adb2d315ae68a89af905720108a30038e5ab8d0d97087785\",\n    \"0x8b8bdc77bd3a6bc7ca5492b6f8c614852c39a70d6c8a74916eaca0aeb4533b11898b8820a4c2620a97bf35e275480029\",\n    \"0xaf35f4dc538d4ad5cdf710caa38fd1eb496c3fa890a047b6a659619c5ad3054158371d1e88e0894428282eed9f47f76b\",\n    \"0x8166454a7089cc07758ad78724654f4e7a1a13e305bbf88ddb86f1a4b2904c4fc8ab872d7da364cdd6a6c0365239e2ad\",\n    \"0xab287c7d3addce74ce40491871c768abe01daaa0833481276ff2e56926b38a7c6d2681ffe837d2cc323045ad1a4414f9\",\n    \"0xb90317f4505793094d89365beb35537f55a6b5618904236258dd04ca61f21476837624a2f45fef8168acf732cab65579\",\n    \"0x98ae5ea27448e236b6657ab5ef7b1cccb5372f92ab25f5fa651fbac97d08353a1dae1b280b1cd42b17d2c6a70a63ab9d\",\n    \"0xadcf54e752d32cbaa6cb98fbca48d8cd087b1db1d131d465705a0d8042c8393c8f4d26b59006eb50129b21e6240f0c06\",\n    \"0xb591a3e4db18a7345fa935a8dd7994bbac5cc270b8ebd84c8304c44484c7a74afb45471fdbe4ab22156a30fae1149b40\",\n    \"0x806b53ac049a42f1dcc1d6335505371da0bf27c614f441b03bbf2e356be7b2fb4eed7117eabcce9e427a542eaa2bf7d8\",\n    \"0x800482e7a772d49210b81c4a907f5ce97f270b959e745621ee293cf8c71e8989363d61f66a98f2d16914439544ca84c7\",\n    \"0x99de9eafdad3617445312341644f2bb888680ff01ce95ca9276b1d2e5ef83fa02dab5e948ebf66c17df0752f1bd37b70\",\n    \"0x961ee30810aa4c93ae157fbe9009b8e443c082192bd36a73a6764ff9b2ad8b0948fe9a73344556e01399dd77badb4257\",\n    \"0xae0a361067c52efbe56c8adf982c00432cd478929459fc7f74052c8ee9531cd031fe1335418fde53f7c2ef34254eb7ac\",\n    \"0xa3503d16b6b27eb20c1b177bcf90d13706169220523a6271b85b2ce35a9a2b9c5bed088540031c0a4ebfdae3a4c6ab04\",\n    \"0x909420122c3e723289ca4e7b81c2df5aff312972a2203f4c45821b176e7c862bf9cac7f7df3adf1d59278f02694d06e7\",\n    \"0x989f42380ae904b982f85d0c6186c1aef5d6bcba29bcfbb658e811b587eb2749c65c6e4a8cc6409c229a107499a4f5d7\",\n    \"0x8037a6337195c8e26a27ea4ef218c6e7d79a9720aaab43932d343192abc2320fe72955f5e431c109093bda074103330a\",\n    \"0xb312e168663842099b88445e940249cc508f080ab0c94331f672e7760258dbd86be5267e4cf25ea25facb80bff82a7e9\",\n    \"0xaaa3ff8639496864fcdbfdda1ac97edc4f08e3c9288b768f6c8073038c9fbbf7e1c4bea169b4d45c31935cdf0680d45e\",\n    \"0x97dbd3df37f0b481a311dfc5f40e59227720f367912200d71908ef6650f32cc985cb05b981e3eea38958f7e48d10a15d\",\n    \"0xa89d49d1e267bb452d6cb621b9a90826fe55e9b489c0427b94442d02a16f390eed758e209991687f73f6b5a032321f42\",\n    \"0x9530dea4e0e19d6496f536f2e75cf7d814d65fde567055eb20db48fd8d20d501cd2a22fb506db566b94c9ee10f413d43\",\n    \"0x81a7009b9e67f1965fa7da6a57591c307de91bf0cd35ab4348dc4a98a4961e096d004d7e7ad318000011dc4342c1b809\",\n    \"0x83440a9402b766045d7aca61a58bba2aa29cac1cf718199e472ba086f5d48093d9dda4d135292ba51d049a23964eceae\",\n    \"0xa06c9ce5e802df14f6b064a3d1a0735d429b452f0e2e276042800b0a4f16df988fd94cf3945921d5dd3802ab2636f867\",\n    \"0xb1359e358b89936dee9e678a187aad3e9ab14ac40e96a0a68f70ee2583cdcf467ae03bef4215e92893f4e12f902adec8\",\n    \"0x835304f8619188b4d14674d803103d5a3fa594d48e96d9699e653115dd05fdc2dda6ba3641cf7ad53994d448da155f02\",\n    \"0x8327cba5a9ff0d3f5cd0ae55e77167448926d5fcf76550c0ad978092a14122723090c51c415e88e42a2b62eb07cc3981\",\n    \"0xb373dcdaea85f85ce9978b1426a7ef4945f65f2d3467a9f1cc551a99766aac95df4a09e2251d3f89ca8c9d1a7cfd7b0e\",\n    \"0xab1422dc41af2a227b973a6fd124dfcb2367e2a11a21faa1d381d404f51b7257e5bc82e9cf20cd7fe37d7ae761a2ab37\",\n    \"0xa93774a03519d2f20fdf2ef46547b0a5b77c137d6a3434b48d56a2cbef9e77120d1b85d0092cf8842909213826699477\",\n    \"0x8eb967a495a38130ea28711580b7e61bcd1d051cd9e4f2dbf62f1380bd86e0d60e978d72f6f31e909eb97b3b9a2b867c\",\n    \"0xae8213378da1287ba1fe4242e1acaec19b877b6fe872400013c6eac1084b8d03156792fa3020201725b08228a1e80f49\",\n    \"0xb143daf6893d674d607772b3b02d8ac48f294237e2f2c87963c0d4e26d9227d94a2a13512457c3d5883544bbc259f0ef\",\n    \"0xb343bd2aca8973888e42542218924e2dda2e938fd1150d06878af76f777546213912b7c7a34a0f94186817d80ffa185c\",\n    \"0xb188ebc6a8c3007001aa347ae72cc0b15d09bc6c19a80e386ee4b334734ec0cc2fe8b493c2422f38d1e6d133cc3db6fe\",\n    \"0xb795f6a8b9b826aaeee18ccd6baf6c5adeeec85f95eb5b6d19450085ec7217e95a2d9e221d77f583b297d0872073ba0e\",\n    \"0xb1c7dbd998ad32ae57bfa95deafa147024afd57389e98992c36b6e52df915d3d5a39db585141ec2423173e85d212fed8\",\n    \"0x812bcdeb9fe5f12d0e1df9964798056e1f1c3de3b17b6bd2919b6356c4b86d8e763c01933efbe0224c86a96d5198a4be\",\n    \"0xb19ebeda61c23d255cbf472ef0b8a441f4c55b70f0d8ed47078c248b1d3c7c62e076b43b95c00a958ec8b16d5a7cb0d7\",\n    \"0xb02adc9aaa20e0368a989c2af14ff48b67233d28ebee44ff3418bb0473592e6b681af1cc45450bd4b175df9051df63d9\",\n    \"0x8d87f0714acee522eb58cec00360e762adc411901dba46adc9227124fa70ee679f9a47e91a6306d6030dd4eb8de2f3c1\",\n    \"0x8be54cec21e74bcc71de29dc621444263737db15f16d0bb13670f64e42f818154e04b484593d19ef95f2ee17e4b3fe21\",\n    \"0xab8e20546c1db38d31493b5d5f535758afb17e459645c1b70813b1cf7d242fd5d1f4354a7c929e8f7259f6a25302e351\",\n    \"0x89f035a1ed8a1e302ac893349ba8ddf967580fcb6e73d44af09e3929cde445e97ff60c87dafe489e2c0ab9c9986cfa00\",\n    \"0x8b2b0851a795c19191a692af55f7e72ad2474efdc5401bc3733cfdd910e34c918aaebe69d5ea951bdddf3c01cabbfc67\",\n    \"0xa4edb52c2b51495ccd1ee6450fc14b7b3ede8b3d106808929d02fb31475bacb403e112ba9c818d2857651e508b3a7dd1\",\n    \"0x9569341fded45d19f00bcf3cbf3f20eb2b4d82ef92aba3c8abd95866398438a2387437e580d8b646f17cf6fde8c5af23\",\n    \"0xaa4b671c6d20f72f2f18a939a6ff21cc37e0084b44b4a717f1be859a80b39fb1be026b3205adec2a66a608ec2bcd578f\",\n    \"0x94902e980de23c4de394ad8aec91b46f888d18f045753541492bfbb92c59d3daa8de37ae755a6853744af8472ba7b72b\",\n    \"0xaf651ef1b2a0d30a7884557edfad95b6b5d445a7561caebdc46a485aedd25932c62c0798465c340a76f6feaa196dd712\",\n    \"0xb7b669b8e5a763452128846dd46b530dca4893ace5cc5881c7ddcd3d45969d7e73fbebdb0e78aa81686e5f7b22ec5759\",\n    \"0x82507fd4ebe9fa656a7f2e084d64a1fa6777a2b0bc106d686e2d9d2edafc58997e58cb6bfd0453b2bf415704aa82ae62\",\n    \"0xb40bce2b42b88678400ecd52955bbdadd15f8b9e1b3751a1a3375dc0efb5ca3ee258cf201e1140b3c09ad41217d1d49e\",\n    \"0xb0210d0cbb3fbf3b8cdb39e862f036b0ff941cd838e7aaf3a8354e24246e64778d22f3de34572e6b2a580614fb6425be\",\n    \"0x876693cba4301b251523c7d034108831df3ce133d8be5a514e7a2ca494c268ca0556fa2ad8310a1d92a16b55bcd99ea9\",\n    \"0x8660281406d22a4950f5ef050bf71dd3090edb16eff27fa29ef600cdea628315e2054211ed2cc6eaf8f2a1771ef689fd\",\n    \"0xa610e7e41e41ab66955b809ba4ade0330b8e9057d8efc9144753caed81995edeb1a42a53f93ce93540feca1fae708dac\",\n    \"0xa49e2c176a350251daef1218efaccc07a1e06203386ede59c136699d25ca5cb2ac1b800c25b28dd05678f14e78e51891\",\n    \"0x83e0915aa2b09359604566080d411874af8c993beba97d4547782fdbe1a68e59324b800ff1f07b8db30c71adcbd102a8\",\n    \"0xa19e84e3541fb6498e9bb8a099c495cbfcad113330e0262a7e4c6544495bb8a754b2208d0c2d895c93463558013a5a32\",\n    \"0x87f2bd49859a364912023aca7b19a592c60214b8d6239e2be887ae80b69ebdeb59742bdebcfa73a586ab23b2c945586c\",\n    \"0xb8e8fdddae934a14b57bc274b8dcd0d45ebb95ddbaabef4454e0f6ce7d3a5a61c86181929546b3d60c447a15134d08e1\",\n    \"0x87e0c31dcb736ea4604727e92dc1d9a3cf00adcff79df3546e02108355260f3dd171531c3c0f57be78d8b28058fcc8c0\",\n    \"0x9617d74e8f808a4165a8ac2e30878c349e1c3d40972006f0787b31ea62d248c2d9f3fc3da83181c6e57e95feedfd0e8c\",\n    \"0x8949e2cee582a2f8db86e89785a6e46bc1565c2d8627d5b6bf43ba71ffadfab7e3c5710f88dcb5fb2fc6edf6f4fae216\",\n    \"0xad3fa7b0edceb83118972a2935a09f409d09a8db3869f30be3a76f67aa9fb379cabb3a3aff805ba023a331cad7d7eb64\",\n    \"0x8c95718a4112512c4efbd496be38bf3ca6cdcaad8a0d128f32a3f9aae57f3a57bdf295a3b372a8c549fda8f4707cffed\",\n    \"0x88f3261d1e28a58b2dee3fcc799777ad1c0eb68b3560f9b4410d134672d9533532a91ea7be28a041784872632d3c9d80\",\n    \"0xb47472a41d72dd2e8b72f5c4f8ad626737dde3717f63d6bc776639ab299e564cbad0a2ad5452a07f02ff49a359c437e5\",\n    \"0x9896d21dc2e8aad87b76d6df1654f10cd7bceed4884159d50a818bea391f8e473e01e14684814c7780235f28e69dca6e\",\n    \"0x82d47c332bbd31bbe83b5eb44a23da76d4a7a06c45d7f80f395035822bc27f62f59281d5174e6f8e77cc9b5c3193d6f0\",\n    \"0x95c74cd46206e7f70c9766117c34c0ec45c2b0f927a15ea167901a160e1530d8522943c29b61e03568aa0f9c55926c53\",\n    \"0xa89d7757825ae73a6e81829ff788ea7b3d7409857b378ebccd7df73fdbe62c8d9073741cf038314971b39af6c29c9030\",\n    \"0x8c1cd212d0b010905d560688cfc036ae6535bc334fa8b812519d810b7e7dcf1bb7c5f43deaa40f097158358987324a7f\",\n    \"0xb86993c383c015ed8d847c6b795164114dd3e9efd25143f509da318bfba89389ea72a420699e339423afd68b6512fafb\",\n    \"0x8d06bd379c6d87c6ed841d8c6e9d2d0de21653a073725ff74be1934301cc3a79b81ef6dd0aad4e7a9dc6eac9b73019bc\",\n    \"0x81af4d2d87219985b9b1202d724fe39ef988f14fef07dfe3c3b11714e90ffba2a97250838e8535eb63f107abfe645e96\",\n    \"0x8c5e0af6330a8becb787e4b502f34f528ef5756e298a77dc0c7467433454347f3a2e0bd2641fbc2a45b95e231c6e1c02\",\n    \"0x8e2a8f0f04562820dc8e7da681d5cad9fe2e85dd11c785fb6fba6786c57a857e0b3bd838fb849b0376c34ce1665e4837\",\n    \"0xa39be8269449bfdfc61b1f62077033649f18dae9bef7c6163b9314ca8923691fb832f42776f0160b9e8abd4d143aa4e1\",\n    \"0x8c154e665706355e1cc98e0a4cabf294ab019545ba9c4c399d666e6ec5c869ca9e1faf8fb06cd9c0a5c2f51a7d51b70a\",\n    \"0xa046a7d4de879d3ebd4284f08f24398e9e3bf006cd4e25b5c67273ade248689c69affff92ae810c07941e4904296a563\",\n    \"0xafd94c1cb48758e5917804df03fb38a6da0e48cd9b6262413ea13b26973f9e266690a1b7d9d24bbaf7e82718e0e594b0\",\n    \"0x859e21080310c8d6a38e12e2ac9f90a156578cdeb4bb2e324700e97d9a5511cd6045dc39d1d0de3f94aeed043a24119d\",\n    \"0xa219fb0303c379d0ab50893264919f598e753aac9065e1f23ef2949abc992577ab43c636a1d2c089203ec9ddb941e27d\",\n    \"0xb0fdb639d449588a2ca730afcba59334e7c387342d56defdfb7ef79c493f7fd0e5277eff18e7203e756c7bdda5803047\",\n    \"0x87f9c3b7ed01f54368aca6dbcf2f6e06bff96e183c4b2c65f8baa23b377988863a0a125d5cdd41a072da8462ced4c070\",\n    \"0x99ef7a5d5ac2f1c567160e1f8c95f2f38d41881850f30c461a205f7b1b9fb181277311333839b13fb3ae203447e17727\",\n    \"0xaeaca9b1c2afd24e443326cc68de67b4d9cedb22ad7b501a799d30d39c85bb2ea910d4672673e39e154d699e12d9b3dc\",\n    \"0xa11675a1721a4ba24dd3d0e4c3c33a6edf4cd1b9f6b471070b4386c61f77452266eae6e3f566a40cfc885eada9a29f23\",\n    \"0xb228334445e37b9b49cb4f2cc56b454575e92173ddb01370a553bba665adadd52df353ad74470d512561c2c3473c7bb9\",\n    \"0xa18177087c996572d76f81178d18ed1ceebc8362a396348ce289f1d8bd708b9e99539be6fccd4acb1112381cfc5749b4\",\n    \"0x8e7b8bf460f0d3c99abb19803b9e43422e91507a1c0c22b29ee8b2c52d1a384da4b87c292e28eff040db5be7b1f8641f\",\n    \"0xb03d038d813e29688b6e6f444eb56fec3abba64c3d6f890a6bcf2e916507091cdb2b9d2c7484617be6b26552ed1c56cb\",\n    \"0xa1c88ccd30e934adfc5494b72655f8afe1865a84196abfb376968f22ddc07761210b6a9fb7638f1413d1b4073d430290\",\n    \"0x961b714faebf172ad2dbc11902461e286e4f24a99a939152a53406117767682a571057044decbeb3d3feef81f4488497\",\n    \"0xa03dc4059b46effdd786a0a03cc17cfee8585683faa35bb07936ded3fa3f3a097f518c0b8e2db92fd700149db1937789\",\n    \"0xadf60180c99ca574191cbcc23e8d025b2f931f98ca7dfcebfc380226239b6329347100fcb8b0fcb12db108c6ad101c07\",\n    \"0x805d4f5ef24d46911cbf942f62cb84b0346e5e712284f82b0db223db26d51aabf43204755eb19519b00e665c7719fcaa\",\n    \"0x8dea7243e9c139662a7fe3526c6c601eee72fd8847c54c8e1f2ad93ef7f9e1826b170afe58817dac212427164a88e87f\",\n    \"0xa2ba42356606d651b077983de1ad643650997bb2babb188c9a3b27245bb65d2036e46667c37d4ce02cb1be5ae8547abe\",\n    \"0xaf2ae50b392bdc013db2d12ce2544883472d72424fc767d3f5cb0ca2d973fc7d1f425880101e61970e1a988d0670c81b\",\n    \"0x98e6bec0568d3939b31d00eb1040e9b8b2a35db46ddf4369bdaee41bbb63cc84423d29ee510a170fb5b0e2df434ba589\",\n    \"0x822ff3cd12fbef4f508f3ca813c04a2e0b9b799c99848e5ad3563265979e753ee61a48f6adc2984a850f1b46c1a43d35\",\n    \"0x891e8b8b92a394f36653d55725ef514bd2e2a46840a0a2975c76c2a935577f85289026aaa74384da0afe26775cbddfb9\",\n    \"0xb2a3131a5d2fe7c8967047aa66e4524babae941d90552171cc109527f345f42aa0df06dcbb2fa01b33d0043917bbed69\",\n    \"0x80c869469900431f3eeefafdbe07b8afd8cee7739e659e6d0109b397cacff85a88247698f87dc4e2fe39a592f250ac64\",\n    \"0x9091594f488b38f9d2bb5df49fd8b4f8829d9c2f11a197dd1431ed5abbc5c954bbde3387088f9ee3a5a834beb7619bce\",\n    \"0xb472e241e6956146cca57b97a8a204668d050423b4e76f857bad5b47f43b203a04c8391ba9d9c3e95093c071f9d376a1\",\n    \"0xb7dd2de0284844392f7dfb56fe7ca3ede41e27519753ffc579a0a8d2d65ceb8108d06b6b0d4c3c1a2588951297bd1a1e\",\n    \"0x902116ce70d0a079ac190321c1f48701318c05f8e69ee09694754885d33a835a849cafe56f499a2f49f6cda413ddf9a7\",\n    \"0xb18105cc736787fafaf7c3c11c448bce9466e683159dff52723b7951dff429565e466e4841d982e3aaa9ee2066838666\",\n    \"0x97ab9911f3f659691762d568ae0b7faa1047b0aed1009c319fa79d15d0db8db9f808fc385dc9a68fa388c10224985379\",\n    \"0xb2a2cba65f5b927e64d2904ba412e2bac1cf18c9c3eda9c72fb70262497ecf505b640827e2afebecf10eebbcf48ccd3e\",\n    \"0xb36a3fd677baa0d3ef0dac4f1548ff50a1730286b8c99d276a0a45d576e17b39b3cbadd2fe55e003796d370d4be43ce3\",\n    \"0xa5dfec96ca3c272566e89dc453a458909247e3895d3e44831528130bc47cc9d0a0dac78dd3cad680a4351d399d241967\",\n    \"0x8029382113909af6340959c3e61db27392531d62d90f92370a432aec3eb1e4c36ae1d4ef2ba8ec6edb4d7320c7a453f6\",\n    \"0x971d85121ea108e6769d54f9c51299b0381ece8b51d46d49c89f65bedc123bab4d5a8bc14d6f67f4f680077529cbae4c\",\n    \"0x98ff6afc01d0bec80a278f25912e1b1ebff80117adae72e31d5b9fa4d9624db4ba2065b444df49b489b0607c45e26c4c\",\n    \"0x8fa29be10fb3ab30ce25920fec0187e6e91e458947009dabb869aade7136c8ba23602682b71e390c251f3743164cbdaa\",\n    \"0xb3345c89eb1653418fe3940cf3e56a9a9c66526389b98f45ca02dd62bfb37baa69a4baaa7132d7320695f8ea6ad1fd94\",\n    \"0xb72c7f5541c9ac6b60a7ec9f5415e7fb14da03f7164ea529952a29399f3a071576608dbbcc0d45994f21f92ddbeb1e19\",\n    \"0xaa3450bb155a5f9043d0ef95f546a2e6ade167280bfb75c9f09c6f9cdb1fffb7ce8181436161a538433afa3681c7a141\",\n    \"0x92a18fecaded7854b349f441e7102b638ababa75b1b0281dd0bded6541abe7aa37d96693595be0b01fe0a2e2133d50f9\",\n    \"0x980756ddf9d2253cfe6c94960b516c94889d09e612810935150892627d2ecee9a2517e04968eea295d0106850c04ca44\",\n    \"0xae68c6ccc454318cdd92f32b11d89116a3b8350207a36d22a0f626718cad671d960090e054c0c77ac3162ae180ecfd4b\",\n    \"0x99f31f66eaaa551749ad91d48a0d4e3ff4d82ef0e8b28f3184c54e852422ba1bdafd53b1e753f3a070f3b55f3c23b6a2\",\n    \"0xa44eaeaa6589206069e9c0a45ff9fc51c68da38d4edff1d15529b7932e6f403d12b9387019c44a1488a5d5f27782a51f\",\n    \"0xb80b5d54d4b344840e45b79e621bd77a3f83fb4ce6d8796b7d6915107b3f3c34d2e7d95bdafd120f285669e5acf2437a\",\n    \"0xb36c069ec085a612b5908314d6b84c00a83031780261d1c77a0384c406867c9847d5b0845deddfa512cc04a8df2046fb\",\n    \"0xb09dbe501583220f640d201acea7ee3e39bf9eda8b91aa07b5c50b7641d86d71acb619b38d27835ce97c3759787f08e9\",\n    \"0x87403d46a2bf63170fff0b857acacf42ee801afe9ccba8e5b4aea967b68eac73a499a65ca46906c2eb4c8f27bc739faa\",\n    \"0x82b93669f42a0a2aa5e250ffe6097269da06a9c02fcd1801abbad415a7729a64f830754bafc702e64600ba47671c2208\",\n    \"0x8e3a3029be7edb8dd3ab1f8216664c8dc50d395f603736061d802cef77627db7b859ef287ed850382c13b4d22d6a2d80\",\n    \"0x968e9ec7194ff424409d182ce0259acd950c384c163c04463bc8700a40b79beba6146d22b7fa7016875a249b7b31c602\",\n    \"0x8b42c984bbe4996e0c20862059167c6bdc5164b1ffcd928f29512664459212d263e89f0f0e30eed4e672ffa5ed0b01b5\",\n    \"0x96bac54062110dada905363211133f1f15dc7e4fd80a4c6e4a83bc9a0bcbbaba11cd2c7a13debcf0985e1a954c1da66b\",\n    \"0xa16dc8a653d67a7cd7ae90b2fffac0bf1ca587005430fe5ba9403edd70ca33e38ba5661d2ed6e9d2864400d997626a62\",\n    \"0xa68ab11a570a27853c8d67e491591dcba746bfbee08a2e75ae0790399130d027ed387f41ef1d7de8df38b472df309161\",\n    \"0x92532b74886874447c0300d07eda9bbe4b41ed25349a3da2e072a93fe32c89d280f740d8ff70d5816793d7f2b97373cc\",\n    \"0x88e35711b471e89218fd5f4d0eadea8a29405af1cd81974427bc4a5fb26ed60798daaf94f726c96e779b403a2cd82820\",\n    \"0xb5c72aa4147c19f8c4f3a0a62d32315b0f4606e0a7025edc5445571eaf4daff64f4b7a585464821574dd50dbe1b49d08\",\n    \"0x9305d9b4095258e79744338683fd93f9e657367b3ab32d78080e51d54eec331edbc224fad5093ebf8ee4bd4286757eb8\",\n    \"0xb2a17abb3f6a05bcb14dc7b98321fa8b46d299626c73d7c6eb12140bf4c3f8e1795250870947af817834f033c88a59d6\",\n    \"0xb3477004837dbd8ba594e4296f960fc91ab3f13551458445e6c232eb04b326da803c4d93e2e8dcd268b4413305ff84da\",\n    \"0x924b4b2ebaafdcfdfedb2829a8bf46cd32e1407d8d725a5bd28bdc821f1bafb3614f030ea4352c671076a63494275a3f\",\n    \"0x8b81b9ef6125c82a9bece6fdcb9888a767ac16e70527753428cc87c56a1236e437da8be4f7ecfe57b9296dc3ae7ba807\",\n    \"0x906e19ec8b8edd58bdf9ae05610a86e4ea2282b1bbc1e8b00b7021d093194e0837d74cf27ac9916bdb8ec308b00da3da\",\n    \"0xb41c5185869071760ac786078a57a2ab4e2af60a890037ac0c0c28d6826f15c2cf028fddd42a9b6de632c3d550bfbc14\",\n    \"0xa646e5dec1b713ae9dfdf7bdc6cd474d5731a320403c7dfcfd666ffc9ae0cff4b5a79530e8df3f4aa9cb80568cb138e9\",\n    \"0xb0efad22827e562bd3c3e925acbd0d9425d19057868608d78c2209a531cccd0f2c43dc5673acf9822247428ffa2bb821\",\n    \"0xa94c19468d14b6f99002fc52ac06bbe59e5c472e4a0cdb225144a62f8870b3f10593749df7a2de0bd3c9476ce682e148\",\n    \"0x803864a91162f0273d49271dafaab632d93d494d1af935aefa522768af058fce52165018512e8d6774976d52bd797e22\",\n    \"0xa08711c2f7d45c68fb340ac23597332e1bcaec9198f72967b9921204b9d48a7843561ff318f87908c05a44fc35e3cc9d\",\n    \"0x91c3cad94a11a3197ae4f9461faab91a669e0dddb0371d3cab3ed9aeb1267badc797d8375181130e461eadd05099b2a2\",\n    \"0x81bdaaf48aae4f7b480fc13f1e7f4dd3023a41439ba231760409ce9292c11128ab2b0bdbbf28b98af4f97b3551f363af\",\n    \"0x8d60f9df9fd303f625af90e8272c4ecb95bb94e6efc5da17b8ab663ee3b3f673e9f6420d890ccc94acf4d2cae7a860d8\",\n    \"0xa7b75901520c06e9495ab983f70b61483504c7ff2a0980c51115d11e0744683ce022d76e3e09f4e99e698cbd21432a0d\",\n    \"0x82956072df0586562fda7e7738226f694e1c73518dd86e0799d2e820d7f79233667192c9236dcb27637e4c65ef19d493\",\n    \"0xa586beb9b6ffd06ad200957490803a7cd8c9bf76e782734e0f55e04a3dc38949de75dc607822ec405736c576cf83bca3\",\n    \"0xa179a30d00def9b34a7e85607a447eea0401e32ab5abeee1a281f2acd1cf6ec81a178020666f641d9492b1bdf66f05a3\",\n    \"0x83e129705c538787ed8e0fdc1275e6466a3f4ee21a1e6abedd239393b1df72244723b92f9d9d9339a0cab6ebf28f5a16\",\n    \"0x811bd8d1e3722b64cd2f5b431167e7f91456e8bba2cc669d3fbbce7d553e29c3c19f629fcedd2498bc26d33a24891d17\",\n    \"0xa243c030c858f1f60cccd26b45b024698cc6d9d9e6198c1ed4964a235d9f8d0baf9cde10c8e63dfaa47f8e74e51a6e85\",\n    \"0xab839eb82e23ca52663281f863b55b0a3d6d4425c33ffb4eeb1d7979488ab068bf99e2a60e82cea4dc42c56c26cbfebe\",\n    \"0x8b896f9bb21d49343e67aec6ad175b58c0c81a3ca73d44d113ae4354a0065d98eb1a5cafedaf232a2bb9cdc62152f309\",\n    \"0xaf6230340cc0b66f5bf845540ed4fc3e7d6077f361d60762e488d57834c3e7eb7eacc1b0ed73a7d134f174a01410e50c\",\n    \"0x88975e1b1af678d1b5179f72300a30900736af580dd748fd9461ef7afccc91ccd9bed33f9da55c8711a7635b800e831f\",\n    \"0xa97486bb9047391661718a54b8dd5a5e363964e495eae6c692730264478c927cf3e66dd3602413189a3699fbeae26e15\",\n    \"0xa5973c161ab38732885d1d2785fd74bf156ba34881980cba27fe239caef06b24a533ffe6dbbbeca5e6566682cc00300a\",\n    \"0xa24776e9a840afda0003fa73b415d5bd6ecd9b5c2cc842b643ee51b8c6087f4eead4d0bfbd987eb174c489a7b952ff2a\",\n    \"0xa8a6ee06e3af053b705a12b59777267c546f33ba8a0f49493af8e6df4e15cf8dd2d4fb4daf7e84c6b5d3a7363118ff03\",\n    \"0xa28e59ce6ad02c2ce725067c0123117e12ac5a52c8f5af13eec75f4a9efc4f696777db18a374fa33bcae82e0734ebd16\",\n    \"0x86dfc3b78e841c708aff677baa8ee654c808e5d257158715097c1025d46ece94993efe12c9d188252ad98a1e0e331fec\",\n    \"0xa88d0275510f242eab11fdb0410ff6e1b9d7a3cbd3658333539815f1b450a84816e6613d15aa8a8eb15d87cdad4b27a2\",\n    \"0x8440acea2931118a5b481268ff9f180ee4ede85d14a52c026adc882410825b8275caa44aff0b50c2b88d39f21b1a0696\",\n    \"0xa7c3182eab25bd6785bacf12079d0afb0a9b165d6ed327814e2177148539f249eb9b5b2554538f54f3c882d37c0a8abe\",\n    \"0x85291fbe10538d7da38efdd55a7acebf03b1848428a2f664c3ce55367aece60039f4f320b1771c9c89a35941797f717c\",\n    \"0xa2c6414eeb1234728ab0de94aa98fc06433a58efa646ca3fcbd97dbfb8d98ae59f7ce6d528f669c8149e1e13266f69c9\",\n    \"0x840c8462785591ee93aee2538d9f1ec44ba2ca61a569ab51d335ac873f5d48099ae8d7a7efa0725d9ff8f9475bfa4f56\",\n    \"0xa7065a9d02fb3673acf7702a488fbc01aa69580964932f6f40b6c2d1c386b19e50b0e104fcac24ea26c4e723611d0238\",\n    \"0xb72db6d141267438279e032c95e6106c2ccb3164b842ba857a2018f3a35f4b040da92680881eb17cd61d0920d5b8f006\",\n    \"0xa8005d6c5960e090374747307ef0be2871a7a43fa4e76a16c35d2baab808e9777b496e9f57a4218b23390887c33a0b55\",\n    \"0x8e152cea1e00a451ca47c20a1e8875873419700af15a5f38ee2268d3fbc974d4bd5f4be38008fa6f404dbdedd6e6e710\",\n    \"0xa3391aed1fcd68761f06a7d1008ec62a09b1cb3d0203cd04e300a0c91adfed1812d8bc1e4a3fd7976dc0aae0e99f52f1\",\n    \"0x967eb57bf2aa503ee0c6e67438098149eac305089c155f1762cf5e84e31f0fbf27c34a9af05621e34645c1ec96afaec8\",\n    \"0x88af97ddc4937a95ec0dcd25e4173127260f91c8db2f6eac84afb789b363705fb3196235af631c70cafd09411d233589\",\n    \"0xa32df75b3f2c921b8767638fd289bcfc61e08597170186637a7128ffedd52c798c434485ac2c7de07014f9e895c2c3d8\",\n    \"0xb0a783832153650aa0d766a3a73ec208b6ce5caeb40b87177ffc035ab03c7705ecdd1090b6456a29f5fb7e90e2fa8930\",\n    \"0xb59c8e803b4c3486777d15fc2311b97f9ded1602fa570c7b0200bada36a49ee9ef4d4c1474265af8e1c38a93eb66b18b\",\n    \"0x982f2c85f83e852022998ff91bafbb6ff093ef22cf9d5063e083a48b29175ccbd51b9c6557151409e439096300981a6c\",\n    \"0x939e3b5989fefebb9d272a954659a4eb125b98c9da6953f5e628d26266bd0525ec38304b8d56f08d65abc4d6da4a8dbb\",\n    \"0x8898212fe05bc8de7d18503cb84a1c1337cc2c09d1eeef2b475aa79185b7322bf1f8e065f1bf871c0c927dd19faf1f6d\",\n    \"0x94b0393a41cd00f724aee2d4bc72103d626a5aecb4b5486dd1ef8ac27528398edf56df9db5c3d238d8579af368afeb09\",\n    \"0x96ac564450d998e7445dd2ea8e3fc7974d575508fa19e1c60c308d83b645864c029f2f6b7396d4ff4c1b24e92e3bac37\",\n    \"0x8adf6638e18aff3eb3b47617da696eb6c4bdfbecbbc3c45d3d0ab0b12cbad00e462fdfbe0c35780d21aa973fc150285e\",\n    \"0xb53f94612f818571b5565bbb295e74bada9b5f9794b3b91125915e44d6ddcc4da25510eab718e251a09c99534d6042d9\",\n    \"0x8b96462508d77ee083c376cd90807aebad8de96bca43983c84a4a6f196d5faf6619a2351f43bfeec101864c3bf255519\",\n    \"0xaeadf34657083fc71df33bd44af73bf5281c9ca6d906b9c745536e1819ea90b56107c55e2178ebad08f3ba75b3f81c86\",\n    \"0x9784ba29b2f0057b5af1d3ab2796d439b8753f1f749c73e791037461bdfc3f7097394283105b8ab01788ea5255a96710\",\n    \"0x8756241bda159d4a33bf74faba0d4594d963c370fb6a18431f279b4a865b070b0547a6d1613cf45b8cfb5f9236bbf831\",\n    \"0xb03ebfd6b71421dfd49a30460f9f57063eebfe31b9ceaa2a05c37c61522b35bdc09d7db3ad75c76c253c00ba282d3cd2\",\n    \"0xb34e7e6341fa9d854b2d3153bdda0c4ae2b2f442ab7af6f99a0975d45725aa48e36ae5f7011edd249862e91f499687d4\",\n    \"0xb462ee09dc3963a14354244313e3444de5cc37ea5ccfbf14cd9aca8027b59c4cb2a949bc30474497cab8123e768460e6\",\n    \"0xaea753290e51e2f6a21a9a0ee67d3a2713f95c2a5c17fe41116c87d3aa77b1683761264d704df1ac34f8b873bc88ef7b\",\n    \"0x98430592afd414394f98ddfff9f280fcb1c322dbe3510f45e1e9c4bb8ee306b3e0cf0282c0ee73ebb8ba087d4d9e0858\",\n    \"0xb95d3b5aaf54ffca11f4be8d57f76e14afdb20afc859dc7c7471e0b42031e8f3d461b726ecb979bdb2f353498dfe95ea\",\n    \"0x984d17f9b11a683132e0b5a9ee5945e3ff7054c2d5c716be73b29078db1d36f54c6e652fd2f52a19da313112e97ade07\",\n    \"0xab232f756b3fff3262be418a1af61a7e0c95ceebbc775389622a8e10610508cd6784ab7960441917a83cc191c58829ea\",\n    \"0xa28f41678d6e60de76b0e36ab10e4516e53e02e9c77d2b5af3cfeee3ce94cfa30c5797bd1daab20c98e1cad83ad0f633\",\n    \"0xb55395fca84dd3ccc05dd480cb9b430bf8631ff06e24cb51d54519703d667268c2f8afcde4ba4ed16bece8cc7bc8c6e0\",\n    \"0x8a8a5392a0e2ea3c7a8c51328fab11156004e84a9c63483b64e8f8ebf18a58b6ffa8fe8b9d95af0a2f655f601d096396\",\n    \"0xab480000fe194d23f08a7a9ec1c392334e9c687e06851f083845121ce502c06b54dda8c43092bcc1035df45cc752fe9b\",\n    \"0xb265644c29f628d1c7e8e25a5e845cabb21799371814730a41a363e1bda8a7be50fee7c3996a365b7fcba4642add10db\",\n    \"0xb8a915a3c685c2d4728f6931c4d29487cad764c5ce23c25e64b1a3259ac27235e41b23bfe7ae982921b4cb84463097df\",\n    \"0x8efa7338442a4b6318145a5440fc213b97869647eeae41b9aa3c0a27ee51285b73e3ae3b4a9423df255e6add58864aa9\",\n    \"0x9106d65444f74d217f4187dfc8fcf3810b916d1e4275f94f6a86d1c4f3565b131fd6cde1fa708bc05fe183c49f14941a\",\n    \"0x948252dac8026bbbdb0a06b3c9d66ec4cf9532163bab68076fda1bd2357b69e4b514729c15aaa83b5618b1977bbc60c4\",\n    \"0xae6596ccfdf5cbbc5782efe3bb0b101bb132dbe1d568854ca24cacc0b2e0e9fabcb2ca7ab42aecec412efd15cf8cb7a2\",\n    \"0x84a0b6c198ff64fd7958dfd1b40eac9638e8e0b2c4cd8cf5d8cdf80419baee76a05184bce6c5b635f6bf2d30055476a7\",\n    \"0x8893118be4a055c2b3da593dbca51b1ae2ea2469911acfb27ee42faf3e6c3ad0693d3914c508c0b05b36a88c8b312b76\",\n    \"0xb097479e967504deb6734785db7e60d1d8034d6ca5ba9552887e937f5e17bb413fccac2c1d1082154ed76609127860ad\",\n    \"0xa0294e6b9958f244d29943debf24b00b538b3da1116269b6e452bb12dc742226712fd1a15b9c88195afeb5d2415f505c\",\n    \"0xb3cc15f635080bc038f61b615f62b5b5c6f2870586191f59476e8368a73641d6ac2f7d0c1f54621982defdb318020230\",\n    \"0x99856f49b9fe1604d917c94d09cc0ed753d13d015d30587a94e6631ffd964b214e607deb8a69a8b5e349a7edf4309206\",\n    \"0xa8571e113ea22b4b4fce41a094da8c70de37830ae32e62c65c2fa5ad06a9bc29e884b945e73d448c72b176d6ecebfb58\",\n    \"0xa9e9c6e52beb0013273c29844956b3ce291023678107cdc785f7b44eff5003462841ad8780761b86aefc6b734adde7cf\",\n    \"0x80a784b0b27edb51ef2bad3aee80e51778dcaa0f3f5d3dcb5dc5d4f4b2cf7ae35b08de6680ea9dac53f8438b92eb09ef\",\n    \"0x827b543e609ea328e97e373f70ad72d4915a2d1daae0c60d44ac637231070e164c43a2a58db80a64df1c624a042b38f9\",\n    \"0xb449c65e8195202efdcb9bdb4e869a437313b118fef8b510cbbf8b79a4e99376adb749b37e9c20b51b31ed3310169e27\",\n    \"0x8ea3028f4548a79a94c717e1ed28ad4d8725b8d6ab18b021063ce46f665c79da3c49440c6577319dab2d036b7e08f387\",\n    \"0x897798431cfb17fe39f08f5f854005dc37b1c1ec1edba6c24bc8acb3b88838d0534a75475325a5ea98b326ad47dbad75\",\n    \"0x89cf232e6303b0751561960fd4dea5754a28c594daf930326b4541274ffb03c7dd75938e411eb9a375006a70ce38097f\",\n    \"0x9727c6ae7f0840f0b6c8bfb3a1a5582ceee705e0b5c59b97def7a7a2283edd4d3f47b7971e902a3a2079e40b53ff69b8\",\n    \"0xb76ed72b122c48679d221072efc0eeea063cb205cbf5f9ef0101fd10cb1075b8628166c83577cced654e1c001c7882f7\",\n    \"0xae908c42d208759da5ee9b405df85a6532ea35c6f0f6a1288d22870f59d98edc896841b8ac890a538e6c8d1e8b02d359\",\n    \"0x809d12fe4039a0ec80dc9be6a89acaab7797e5f7f9b163378f52f9a75a1d73b2e9ae6e3dd49e32ced439783c1cabbef5\",\n    \"0xa4149530b7f85d1098ba534d69548c6c612c416e8d35992fc1f64f4deeb41e09e49c6cf7aadbed7e846b91299358fe2d\",\n    \"0xa49342eacd1ec1148b8df1e253b1c015f603c39de11fa0a364ccb86ea32d69c34fd7aa6980a1fadcd8e785a57fa46f60\",\n    \"0x87d43eff5a006dc4dddcf76cc96c656a1f3a68f19f124181feab86c6cc9a52cb9189cdbb423414defdd9bb0ca8ff1ddc\",\n    \"0x861367e87a9aa2f0f68296ba50aa5dbc5713008d260cc2c7e62d407c2063064749324c4e8156dc21b749656cfebce26b\",\n    \"0xb5303c2f72e84e170e66ae1b0fbd51b8c7a6f27476eaf5694b64e8737d5c84b51fe90100b256465a4c4156dd873cddb0\",\n    \"0xb62849a4f891415d74f434cdc1d23c4a69074487659ca96e1762466b2b7a5d8525b056b891d0feea6fe6845cba8bc7fb\",\n    \"0x923dd9e0d6590a9307e8c4c23f13bae3306b580e297a937711a8b13e8de85e41a61462f25b7d352b682e8437bf2b4ab3\",\n    \"0x9147379860cd713cd46c94b8cdf75125d36c37517fbecf81ace9680b98ce6291cd1c3e472f84249cc3b2b445e314b1b6\",\n    \"0xa808a4f17ac21e3fb5cfef404e61fae3693ca3e688d375f99b6116779696059a146c27b06de3ac36da349b0649befd56\",\n    \"0x87787e9322e1b75e66c1f0d9ea0915722a232770930c2d2a95e9478c4b950d15ab767e30cea128f9ed65893bfc2d0743\",\n    \"0x9036a6ee2577223be105defe1081c48ea7319e112fff9110eb9f61110c319da25a6cea0464ce65e858635b079691ef1f\",\n    \"0xaf5548c7c24e1088c23b57ee14d26c12a83484c9fd9296edf1012d8dcf88243f20039b43c8c548c265ef9a1ffe9c1c88\",\n    \"0xa0fff520045e14065965fb8accd17e878d3fcaf9e0af2962c8954e50be6683d31fa0bf4816ab68f08630dbac6bfce52a\",\n    \"0xb4c1b249e079f6ae1781af1d97a60b15855f49864c50496c09c91fe1946266915b799f0406084d7783f5b1039116dd8b\",\n    \"0x8b0ffa5e7c498cb3879dddca34743b41eee8e2dea3d4317a6e961b58adb699ef0c92400c068d5228881a2b08121226bf\",\n    \"0x852ae8b19a1d80aa8ae5382e7ee5c8e7670ceb16640871c56b20b96b66b3b60e00015a3dde039446972e57b49a999ddd\",\n    \"0xa49942f04234a7d8492169da232cfff8051df86e8e1ba3db46aede02422c689c87dc1d99699c25f96cb763f5ca0983e5\",\n    \"0xb04b597b7760cf5dcf411ef896d1661e6d5b0db3257ac2cf64b20b60c6cc18fa10523bb958a48d010b55bac7b02ab3b1\",\n    \"0xa494591b51ea8285daecc194b5e5bd45ae35767d0246ac94fae204d674ee180c8e97ff15f71f28b7aeb175b8aea59710\",\n    \"0x97d2624919e78406e7460730680dea8e71c8571cf988e11441aeea54512b95bd820e78562c99372d535d96f7e200d20d\",\n    \"0xac693ddb00e48f76e667243b9b6a7008424043fb779e4f2252330285232c3fccac4da25cbd6d95fe9ad959ff305a91f6\",\n    \"0x8d20ca0a71a64a3f702a0825bb46bd810d03bebfb227683680d474a52f965716ff99e19a165ebaf6567987f4f9ee3c94\",\n    \"0xa5c516a438f916d1d68ca76996404792e0a66e97b7f18fc54c917bf10cf3211b62387932756e39e67e47b0bd6e88385a\",\n    \"0xb089614d830abc0afa435034cec7f851f2f095d479cacf1a3fb57272da826c499a52e7dcbc0eb85f4166fb94778e18e9\",\n    \"0xa8dacc943765d930848288192f4c69e2461c4b9bc6e79e30eeef9a543318cf9ae9569d6986c65c5668a89d49993f8e07\",\n    \"0xab5a9361fa339eec8c621bdad0a58078983abd8942d4282b22835d7a3a47e132d42414b7c359694986f7db39386c2e19\",\n    \"0x94230517fb57bd8eb26c6f64129b8b2abd0282323bf7b94b8bac7fab27b4ecc2c4290c294275e1a759de19f2216134f3\",\n    \"0xb8f158ea5006bc3b90b285246625faaa6ac9b5f5030dc69701b12f3b79a53ec7e92eeb5a63bbd1f9509a0a3469ff3ffc\",\n    \"0x8b6944fd8cb8540957a91a142fdcda827762aa777a31e8810ca6d026e50370ee1636fc351724767e817ca38804ebe005\",\n    \"0x82d1ee40fe1569c29644f79fa6c4033b7ed45cd2c3b343881f6eb0de2e79548fded4787fae19bed6ee76ed76ff9f2f11\",\n    \"0xa8924c7035e99eaed244ca165607e7e568b6c8085510dcdbaf6ebdbed405af2e6c14ee27d94ffef10d30aa52a60bf66d\",\n    \"0x956f82a6c2ae044635e85812581e4866c5fa2f427b01942047d81f6d79a14192f66fbbe77c9ffeaef4e6147097fdd2b5\",\n    \"0xb1100255a1bcf5e05b6aff1dfeb6e1d55b5d68d43a7457ba10cc76b61885f67f4d0d5179abda786e037ae95deb8eea45\",\n    \"0x99510799025e3e5e8fbf06dedb14c060c6548ba2bda824f687d3999dc395e794b1fb6514b9013f3892b6cf65cb0d65aa\",\n    \"0x8f9091cebf5e9c809aab415942172258f894e66e625d7388a05289183f01b8d994d52e05a8e69f784fba41db9ea357f0\",\n    \"0xa13d2eeb0776bdee9820ecb6693536720232848c51936bb4ef4fe65588d3f920d08a21907e1fdb881c1ad70b3725e726\",\n    \"0xa68b8f18922d550284c5e5dc2dda771f24c21965a6a4d5e7a71678178f46df4d8a421497aad8fcb4c7e241aba26378a0\",\n    \"0x8b7601f0a3c6ad27f03f2d23e785c81c1460d60100f91ea9d1cab978aa03b523150206c6d52ce7c7769c71d2c8228e9e\",\n    \"0xa8e02926430813caa851bb2b46de7f0420f0a64eb5f6b805401c11c9091d3b6d67d841b5674fa2b1dce0867714124cd8\",\n    \"0xb7968ecba568b8193b3058400af02c183f0a6df995a744450b3f7e0af7a772454677c3857f99c140bbdb2a09e832e8e0\",\n    \"0x8f20b1e9ba87d0a3f35309b985f3c18d2e8800f1ca7f0c52cadef773f1496b6070c936eea48c4a1cae83fd2524e9d233\",\n    \"0x88aef260042db0d641a51f40639dbeeefa9e9811df30bee695f3791f88a2f84d318f04e8926b7f47bf25956cb9e3754f\",\n    \"0x9725345893b647e9ba4e6a29e12f96751f1ae25fcaec2173e9a259921a1a7edb7a47159b3c8767e44d9e2689f5aa0f72\",\n    \"0x8c281e6f72752cb11e239e4df9341c45106eb7993c160e54423c2bffe10bc39d42624b45a1f673936ef2e1a02fc92f1a\",\n    \"0x90aba2f68bddb2fcce6c51430dacdfeec43ea8dc379660c99095df11017691ccf5faa27665cf4b9f0eea7728ae53c327\",\n    \"0xb7022695c16521c5704f49b7ddbdbec9b5f57ce0ceebe537bc0ebb0906d8196cc855a9afeb8950a1710f6a654464d93f\",\n    \"0x8fe1b9dd3c6a258116415d36e08374e094b22f0afb104385a5da48be17123e86fb8327baacc4f0d9ebae923d55d99bb5\",\n    \"0x817e85d8e3d19a4cbc1dec31597142c2daa4871bda89c2177fa719c00eda3344eb08b82eb92d4aa91a9eaacb3fc09783\",\n    \"0xb59053e1081d2603f1ca0ba553804d6fa696e1fd996631db8f62087b26a40dfef02098b0326bb75f99ec83b9267ca738\",\n    \"0x990a173d857d3ba81ff3789b931bfc9f5609cde0169b7f055fa3cb56451748d593d62d46ba33f80f9cafffe02b68dd14\",\n    \"0xb0c538dbba4954b809ab26f9f94a3cf1dcb77ce289eaec1d19f556c0ae4be1fa03af4a9b7057837541c3cc0a80538736\",\n    \"0xac3ba42f5f44f9e1fc453ce49c4ab79d0e1d5c42d3b30b1e098f3ab3f414c4c262fa12fb2be249f52d4aaf3c5224beb9\",\n    \"0xaf47467eb152e59870e21f0d4da2f43e093daf40180ab01438030684b114d025326928eaab12c41b81a066d94fce8436\",\n    \"0x98d1b58ba22e7289b1c45c79a24624f19b1d89e00f778eef327ec4856a9a897278e6f1a9a7e673844b31dde949153000\",\n    \"0x97ccb15dfadc7c59dca08cfe0d22df2e52c684cf97de1d94bc00d7ba24e020025130b0a39c0f4d46e4fc872771ee7875\",\n    \"0xb699e4ed9a000ff96ca296b2f09dce278832bc8ac96851ff3cff99ed3f6f752cfc0fea8571be28cd9b5a7ec36f1a08ee\",\n    \"0xb9f49f0edb7941cc296435ff0a912e3ad16848ee8765ab5f60a050b280d6ea585e5b34051b15f6b8934ef01ceb85f648\",\n    \"0xac3893df7b4ceab23c6b9054e48e8ba40d6e5beda8fbe90b814f992f52494186969b35d8c4cdc3c99890a222c9c09008\",\n    \"0xa41293ad22fae81dea94467bc1488c3707f3d4765059173980be93995fa4fcc3c9340796e3eed0beeb0ba0d9bb4fa3aa\",\n    \"0xa0543e77acd2aeecde13d18d258aeb2c7397b77f17c35a1992e8666ea7abcd8a38ec6c2741bd929abba2f766138618cc\",\n    \"0x92e79b22bc40e69f6527c969500ca543899105837b6b1075fa1796755c723462059b3d1b028e0b3df2559fa440e09175\",\n    \"0xa1fa1eac8f41a5197a6fb4aa1eae1a031c89f9c13ff9448338b222780cf9022e0b0925d930c37501a0ef7b2b00fdaf83\",\n    \"0xb3cb29ff73229f0637335f28a08ad8c5f166066f27c6c175164d0f26766a927f843b987ee9b309ed71cbf0a65d483831\",\n    \"0x84d4ab787f0ac00f104f4a734dc693d62d48c2aeb03913153da62c2ae2c27d11b1110dcef8980368dd84682ea2c1a308\",\n    \"0xab6a8e4bbc78d4a7b291ad3e9a8fe2d65f640524ba3181123b09d2d18a9e300e2509ccf7000fe47e75b65f3e992a2e7e\",\n    \"0xb7805ebe4f1a4df414003dc10bca805f2ab86ca75820012653e8f9b79c405196b0e2cab099f2ab953d67f0d60d31a0f9\",\n    \"0xb12c582454148338ea605d22bd00a754109063e22617f1f8ac8ddf5502c22a181c50c216c3617b9852aa5f26af56b323\",\n    \"0x86333ad9f898947e31ce747728dc8c887479e18d36ff3013f69ebef807d82c6981543b5c3788af93c4d912ba084d3cba\",\n    \"0xb514efa310dc4ad1258add138891e540d8c87142a881b5f46563cc58ecd1488e6d3a2fca54c0b72a929f3364ca8c333e\",\n    \"0xaa0a30f92843cf2f484066a783a1d75a7aa6f41f00b421d4baf20a6ac7886c468d0eea7ca8b17dd22f4f74631b62b640\",\n    \"0xb3b7dc63baec9a752e8433c0cdee4d0f9bc41f66f2b8d132faf925eef9cf89aae756fc132c45910f057122462605dc10\",\n    \"0xb9b8190dac5bfdeb59fd44f4da41a57e7f1e7d2c21faba9da91fa45cbeca06dcf299c9ae22f0c89ece11ac46352d619f\",\n    \"0x89f8cf36501ad8bdfeab863752a9090e3bfda57cf8fdeca2944864dc05925f501e252c048221bcc57136ab09a64b64b2\",\n    \"0xb0cbfaf317f05f97be47fc9d69eda2dd82500e00d42612f271a1fe24626408c28881f171e855bd5bd67409f9847502b4\",\n    \"0xa7c21a8fcede581bfd9847b6835eda62ba250bea81f1bb17372c800a19c732abe03064e64a2f865d974fb636cab4b859\",\n    \"0x95f9df524ba7a4667351696c4176b505d8ea3659f5ff2701173064acc624af69a0fad4970963736383b979830cb32260\",\n    \"0x856a74fe8b37a2e3afeac858c8632200485d438422a16ae3b29f359e470e8244995c63ad79c7e007ed063f178d0306fd\",\n    \"0xb37faa4d78fdc0bb9d403674dbea0176c2014a171c7be8527b54f7d1a32a76883d3422a3e7a5f5fcc5e9b31b57822eeb\",\n    \"0x8d37234d8594ec3fe75670b5c9cc1ec3537564d4739b2682a75b18b08401869a4264c0f264354219d8d896cded715db4\",\n    \"0xb5289ee5737f0e0bde485d32096d23387d68dab8f01f47821ab4f06cc79a967afe7355e72dc0c751d96b2747b26f6255\",\n    \"0x9085e1fdf9f813e9c3b8232d3c8863cd84ab30d45e8e0d3d6a0abd9ebc6fd70cdf749ff4d04390000e14c7d8c6655fc7\",\n    \"0x93a388c83630331eca4da37ea4a97b3b453238af474817cc0a0727fd3138dcb4a22de38c04783ec829c22cb459cb4e8e\",\n    \"0xa5377116027c5d061dbe24c240b891c08cdd8cd3f0899e848d682c873aff5b8132c1e7cfe76d2e5ed97ee0eb1d42cb68\",\n    \"0xa274c84b04338ed28d74683e2a7519c2591a3ce37c294d6f6e678f7d628be2db8eff253ede21823e2df7183e6552f622\",\n    \"0x8bc201147a842453a50bec3ac97671397bc086d6dfc9377fa38c2124cdc286abda69b7324f47d64da094ae011d98d9d9\",\n    \"0x9842d0c066c524592b76fbec5132bc628e5e1d21c424bec4555efca8619cc1fd8ea3161febcb8b9e8ab54702f4e815e2\",\n    \"0xa19191b713a07efe85c266f839d14e25660ee74452e6c691cd9997d85ae4f732052d802d3deb018bdd847caa298a894b\",\n    \"0xa24f71fc0db504da4e287dd118a4a74301cbcd16033937ba2abc8417956fcb4ae19b8e63b931795544a978137eff51cb\",\n    \"0xa90eec4a6a3a4b8f9a5b93d978b5026fcf812fe65585b008d7e08c4aaf21195a1d0699f12fc16f79b6a18a369af45771\",\n    \"0x8b551cf89737d7d06d9b3b9c4c1c73b41f2ea0af4540999c70b82dabff8580797cf0a3caf34c86c59a7069eb2e38f087\",\n    \"0xb8d312e6c635e7a216a1cda075ae77ba3e1d2fd501dc31e83496e6e81ed5d9c7799f8e578869c2e0e256fb29f5de10a7\",\n    \"0x8d144bdb8cae0b2cdb5b33d44bbc96984a5925202506a8cc65eb67ac904b466f5a7fe3e1cbf04aa785bbb7348c4bb73c\",\n    \"0xa101b3d58b7a98659244b88de0b478b3fb87dc5fc6031f6e689b99edf498abd43e151fd32bd4bbd240e0b3e59c440359\",\n    \"0x907453abca7d8e7151a05cc3d506c988007692fe7401395dc93177d0d07d114ab6cca0cc658eb94c0223fe8658295cad\",\n    \"0x825329ffbe2147ddb68f63a0a67f32d7f309657b8e5d9ab5bb34b3730bfa2c77a23eaaadb05def7d9f94a9e08fdc1e96\",\n    \"0x88ee923c95c1dac99ae7ed6067906d734d793c5dc5d26339c1bb3314abe201c5dccb33b9007351885eb2754e9a8ea06c\",\n    \"0x98bc9798543f5f1adc9f2cfcfa72331989420e9c3f6598c45269f0dc9b7c8607bbeaf03faa0aea2ddde2b8f17fdceff5\",\n    \"0x8ee87877702a79aef923ab970db6fa81561b3c07d5bf1a072af0a7bad765b4cbaec910afe1a91703feacc7822fa38a94\",\n    \"0x8060b9584aa294fe8adc2b22f67e988bc6da768eae91e429dcc43ddc53cfcc5d6753fdc1b420b268c7eb2fb50736a970\",\n    \"0xb344a5524d80a2f051870c7001f74fcf348a70fcf78dbd20c6ff9ca85d81567d2318c8b8089f2c4f195d6aec9fc15fa6\",\n    \"0x8f5a5d893e1936ed062149d20eb73d98b62b7f50ab5d93a6429c03656b36688d1c80cb5010e4977491e51fa0d7dd35d5\",\n    \"0x86fa32ebbf97328c5f5f15564e1238297e289ec3219b9a741724e9f3ae8d5c15277008f555863a478b247ba5dc601d44\",\n    \"0x9557e55377e279f4b6b5e0ffe01eca037cc13aac242d67dfcd0374a1e775c5ed5cb30c25fe21143fee54e3302d34a3ea\",\n    \"0x8cb6bcbc39372d23464a416ea7039f57ba8413cf3f00d9a7a5b356ab20dcb8ed11b3561f7bce372b8534d2870c7ee270\",\n    \"0xb5d59075cb5abde5391f64b6c3b8b50adc6e1f654e2a580b6d6d6eff3f4fbdd8fffc92e06809c393f5c8eab37f774c4b\",\n    \"0xafcfb6903ef13e493a1f7308675582f15af0403b6553e8c37afb8b2808ad21b88b347dc139464367dc260df075fea1ad\",\n    \"0x810fbbe808375735dd22d5bc7fc3828dc49fdd22cc2d7661604e7ac9c4535c1df578780affb3b895a0831640a945bcad\",\n    \"0x8056b0c678803b416f924e09a6299a33cf9ad7da6fe1ad7accefe95c179e0077da36815fde3716711c394e2c5ea7127f\",\n    \"0x8b67403702d06979be19f1d6dc3ec73cc2e81254d6b7d0cc49cd4fdda8cd51ab0835c1d2d26fc0ecab5df90585c2f351\",\n    \"0x87f97f9e6d4be07e8db250e5dd2bffdf1390665bc5709f2b631a6fa69a7fca958f19bd7cc617183da1f50ee63e9352b5\",\n    \"0xae151310985940471e6803fcf37600d7fa98830613e381e00dab943aec32c14162d51c4598e8847148148000d6e5af5c\",\n    \"0x81eb537b35b7602c45441cfc61b27fa9a30d3998fad35a064e05bc9479e9f10b62eba2b234b348219eea3cadcaac64bb\",\n    \"0x8a441434934180ab6f5bc541f86ebd06eadbee01f438836d797e930fa803a51510e005c9248cecc231a775b74d12b5e9\",\n    \"0x81f3c250a27ba14d8496a5092b145629eb2c2e6a5298438670375363f57e2798207832c8027c3e9238ad94ecdadfc4df\",\n    \"0xa6217c311f2f3db02ceaa5b6096849fe92b6f4b6f1491535ef8525f6ccee6130bed2809e625073ecbaddd4a3eb3df186\",\n    \"0x82d1c396f0388b942cf22b119d7ef1ad03d3dad49a74d9d01649ee284f377c8daddd095d596871669e16160299a210db\",\n    \"0xa40ddf7043c5d72a7246bd727b07f7fff1549f0e443d611de6f9976c37448b21664c5089c57f20105102d935ab82f27b\",\n    \"0xb6c03c1c97adf0c4bf4447ec71366c6c1bff401ba46236cd4a33d39291e7a1f0bb34bd078ba3a18d15c98993b153a279\",\n    \"0x8a94f5f632068399c359c4b3a3653cb6df2b207379b3d0cdace51afdf70d6d5cce6b89a2b0fee66744eba86c98fb21c2\",\n    \"0xb2f19e78ee85073f680c3bba1f07fd31b057c00b97040357d97855b54a0b5accb0d3b05b2a294568fcd6a4be6f266950\",\n    \"0xa74632d13bbe2d64b51d7a9c3ae0a5a971c19f51cf7596a807cea053e6a0f3719700976d4e394b356c0329a2dced9aa2\",\n    \"0xafef616d341a9bc94393b8dfba68ff0581436aa3a3adb7c26a1bbf2cf19fa877066191681f71f17f3cd6f9cf6bf70b5a\",\n    \"0x8ce96d93ae217408acf7eb0f9cbb9563363e5c7002e19bbe1e80760bc9d449daee2118f3878b955163ed664516b97294\",\n    \"0x8414f79b496176bc8b8e25f8e4cfee28f4f1c2ddab099d63d2aca1b6403d26a571152fc3edb97794767a7c4686ad557c\",\n    \"0xb6c61d01fd8ce087ef9f079bf25bf10090db483dd4f88c4a786d31c1bdf52065651c1f5523f20c21e75cea17df69ab73\",\n    \"0xa5790fd629be70545093631efadddc136661f63b65ec682609c38ef7d3d7fa4e56bdf94f06e263bc055b90cb1c6bcefe\",\n    \"0xb515a767e95704fb7597bca9e46f1753abacdc0e56e867ee3c6f4cd382643c2a28e65312c05ad040eaa3a8cbe7217a65\",\n    \"0x8135806a02ead6aa92e9adb6fefb91349837ab73105aaa7be488ef966aa8dfaafdfa64bbae30fcbfa55dd135a036a863\",\n    \"0x8f22435702716d76b1369750694540742d909d5e72b54d0878245fab7c269953b1c6f2b29c66f08d5e0263ca3a731771\",\n    \"0x8e0f8a8e8753e077dac95848212aeffd51c23d9b6d611df8b102f654089401954413ecbedc6367561ca599512ae5dda7\",\n    \"0x815a9084e3e2345f24c5fa559deec21ee1352fb60f4025c0779be65057f2d528a3d91593bd30d3a185f5ec53a9950676\",\n    \"0x967e6555ccba395b2cc1605f8484c5112c7b263f41ce8439a99fd1c71c5ed14ad02684d6f636364199ca48afbbde13be\",\n    \"0x8cd0ccf17682950b34c796a41e2ea7dd5367aba5e80a907e01f4cdc611e4a411918215e5aebf4292f8b24765d73314a6\",\n    \"0xa58bf1bbb377e4b3915df6f058a0f53b8fb8130fdec8c391f6bc82065694d0be59bb67ffb540e6c42cc8b380c6e36359\",\n    \"0x92af3151d9e6bfb3383d85433e953c0160859f759b0988431ec5893542ba40288f65db43c78a904325ef8d324988f09d\",\n    \"0x8011bbb05705167afb47d4425065630f54cb86cd462095e83b81dfebf348f846e4d8fbcf1c13208f5de1931f81da40b9\",\n    \"0x81c743c104fc3cb047885c9fa0fb9705c3a83ee24f690f539f4985509c3dafd507af3f6a2128276f45d5939ef70c167f\",\n    \"0xa2c9679b151c041aaf5efeac5a737a8f70d1631d931609fca16be1905682f35e291292874cb3b03f14994f98573c6f44\",\n    \"0xa4949b86c4e5b1d5c82a337e5ce6b2718b1f7c215148c8bfb7e7c44ec86c5c9476048fc5c01f57cb0920876478c41ad6\",\n    \"0x86c2495088bd1772152e527a1da0ef473f924ea9ab0e5b8077df859c28078f73c4e22e3a906b507fdf217c3c80808b5c\",\n    \"0x892e0a910dcf162bcea379763c3e2349349e4cda9402949255ac4a78dd5a47e0bf42f5bd0913951576b1d206dc1e536a\",\n    \"0xa7009b2c6b396138afe4754b7cc10dee557c51c7f1a357a11486b3253818531f781ea8107360c8d4c3b1cd96282353c0\",\n    \"0x911763ef439c086065cc7b4e57484ed6d693ea44acee4b18c9fd998116da55fbe7dcb8d2a0f0f9b32132fca82d73dff6\",\n    \"0xa722000b95a4a2d40bed81870793f15ba2af633f9892df507f2842e52452e02b5ea8dea6a043c2b2611d82376e33742a\",\n    \"0x9387ac49477bd719c2f92240d0bdfcf9767aad247ca93dc51e56106463206bc343a8ec855eb803471629a66fffb565d6\",\n    \"0x92819a1fa48ab4902939bb72a0a4e6143c058ea42b42f9bc6cea5df45f49724e2530daf3fc4f097cceefa2a8b9db0076\",\n    \"0x98eac7b04537653bc0f4941aae732e4b1f84bd276c992c64a219b8715eb1fb829b5cbd997d57feb15c7694c468f95f70\",\n    \"0xb275e7ba848ce21bf7996e12dbeb8dadb5d0e4f1cb5a0248a4f8f9c9fe6c74e3c93f4b61edbcb0a51af5a141e1c14bc7\",\n    \"0x97243189285aba4d49c53770c242f2faf5fd3914451da4931472e3290164f7663c726cf86020f8f181e568c72fd172d1\",\n    \"0x839b0b3c25dd412bee3dc24653b873cc65454f8f16186bb707bcd58259c0b6765fa4c195403209179192a4455c95f3b8\",\n    \"0x8689d1a870514568a074a38232e2ceb4d7df30fabeb76cff0aed5b42bf7f02baea12c5fadf69f4713464dbd52aafa55f\",\n    \"0x8958ae7b290f0b00d17c3e9fdb4dbf168432b457c7676829299dd428984aba892de1966fc106cfc58a772862ecce3976\",\n    \"0xa422bc6bd68b8870cfa5bc4ce71781fd7f4368b564d7f1e0917f6013c8bbb5b240a257f89ecfdbecb40fe0f3aa31d310\",\n    \"0xaa61f78130cebe09bc9a2c0a37f0dd57ed2d702962e37d38b1df7f17dc554b1d4b7a39a44182a452ce4c5eb31fa4cfcc\",\n    \"0xb7918bd114f37869bf1a459023386825821bfadce545201929d13ac3256d92a431e34f690a55d944f77d0b652cefeffc\",\n    \"0x819bba35fb6ace1510920d4dcff30aa682a3c9af9022e287751a6a6649b00c5402f14b6309f0aeef8fce312a0402915e\",\n    \"0x8b7c9ad446c6f63c11e1c24e24014bd570862b65d53684e107ba9ad381e81a2eaa96731b4b33536efd55e0f055071274\",\n    \"0x8fe79b53f06d33386c0ec7d6d521183c13199498594a46d44a8a716932c3ec480c60be398650bbfa044fa791c4e99b65\",\n    \"0x9558e10fb81250b9844c99648cf38fa05ec1e65d0ccbb18aa17f2d1f503144baf59d802c25be8cc0879fff82ed5034ad\",\n    \"0xb538a7b97fbd702ba84645ca0a63725be1e2891c784b1d599e54e3480e4670d0025526674ef5cf2f87dddf2290ba09f0\",\n    \"0x92eafe2e869a3dd8519bbbceb630585c6eb21712b2f31e1b63067c0acb5f9bdbbcbdb612db4ea7f9cc4e7be83d31973f\",\n    \"0xb40d21390bb813ab7b70a010dff64c57178418c62685761784e37d327ba3cb9ef62df87ecb84277c325a637fe3709732\",\n    \"0xb349e6fbf778c4af35fbed33130bd8a7216ed3ba0a79163ebb556e8eb8e1a7dad3456ddd700dad9d08d202491c51b939\",\n    \"0xa8fdaedecb251f892b66c669e34137f2650509ade5d38fbe8a05d9b9184bb3b2d416186a3640429bd1f3e4b903c159dd\",\n    \"0xac6167ebfee1dbab338eff7642f5e785fc21ef0b4ddd6660333fe398068cbd6c42585f62e81e4edbb72161ce852a1a4f\",\n    \"0x874b1fbf2ebe140c683bd7e4e0ab017afa5d4ad38055aaa83ee6bbef77dbc88a6ce8eb0dcc48f0155244af6f86f34c2d\",\n    \"0x903c58e57ddd9c446afab8256a6bb6c911121e6ccfb4f9b4ed3e2ed922a0e500a5cb7fa379d5285bc16e11dac90d1fda\",\n    \"0x8dae7a0cffa2fd166859cd1bf10ff82dd1932e488af377366b7efc0d5dec85f85fe5e8150ff86a79a39cefc29631733a\",\n    \"0xaa047857a47cc4dfc08585f28640420fcf105b881fd59a6cf7890a36516af0644d143b73f3515ab48faaa621168f8c31\",\n    \"0x864508f7077c266cc0cb3f7f001cb6e27125ebfe79ab57a123a8195f2e27d3799ff98413e8483c533b46a816a3557f1f\",\n    \"0x8bcd45ab1f9cbab36937a27e724af819838f66dfeb15923f8113654ff877bd8667c54f6307aaf0c35027ca11b6229bfd\",\n    \"0xb21aa34da9ab0a48fcfdd291df224697ce0c1ebc0e9b022fdee8750a1a4b5ba421c419541ed5c98b461eecf363047471\",\n    \"0xa9a18a2ab2fae14542dc336269fe612e9c1af6cf0c9ac933679a2f2cb77d3c304114f4d219ca66fe288adde30716775b\",\n    \"0xb5205989b92c58bdda71817f9a897e84100b5c4e708de1fced5c286f7a6f01ae96b1c8d845f3a320d77c8e2703c0e8b1\",\n    \"0xa364059412bbcc17b8907d43ac8e5df90bc87fd1724b5f99832d0d24559fae6fa76a74cff1d1eac8cbac6ec80b44af20\",\n    \"0xae709f2c339886b31450834cf29a38b26eb3b0779bd77c9ac269a8a925d1d78ea3837876c654b61a8fe834b3b6940808\",\n    \"0x8802581bba66e1952ac4dab36af371f66778958f4612901d95e5cac17f59165e6064371d02de8fb6fccf89c6dc8bd118\",\n    \"0xa313252df653e29c672cbcfd2d4f775089cb77be1077381cf4dc9533790e88af6cedc8a119158e7da5bf6806ad9b91a1\",\n    \"0x992a065b4152c7ef11515cd54ba9d191fda44032a01aed954acff3443377ee16680c7248d530b746b8c6dee2d634e68c\",\n    \"0xb627b683ee2b32c1ab4ccd27b9f6cce2fe097d96386fa0e5c182ad997c4c422ab8dfc03870cd830b8c774feb66537282\",\n    \"0xb823cf8a9aee03dadd013eb9efe40a201b4b57ef67efaae9f99683005f5d1bf55e950bf4af0774f50859d743642d3fea\",\n    \"0xb8a7449ffac0a3f206677097baf7ce00ca07a4d2bd9b5356fbcb83f3649b0fda07cfebad220c1066afba89e5a52abf4b\",\n    \"0xb2dd1a2f986395bb4e3e960fbbe823dbb154f823284ebc9068502c19a7609790ec0073d08bfa63f71e30c7161b6ef966\",\n    \"0x98e5236de4281245234f5d40a25b503505af140b503a035fc25a26159a9074ec81512b28f324c56ea2c9a5aa7ce90805\",\n    \"0x89070847dc8bbf5bc4ed073aa2e2a1f699cf0c2ca226f185a0671cecc54e7d3e14cd475c7752314a7a8e7476829da4bc\",\n    \"0xa9402dc9117fdb39c4734c0688254f23aed3dce94f5f53f5b7ef2b4bf1b71a67f85ab1a38ec224a59691f3bee050aeb3\",\n    \"0x957288f9866a4bf56a4204218ccc583f717d7ce45c01ea27142a7e245ad04a07f289cc044f8cf1f21d35e67e39299e9c\",\n    \"0xb2fb31ccb4e69113763d7247d0fc8edaae69b550c5c56aecacfd780c7217dc672f9fb7496edf4aba65dacf3361268e5b\",\n    \"0xb44a4526b2f1d6eb2aa8dba23bfa385ff7634572ab2afddd0546c3beb630fbfe85a32f42dd287a7fec069041411537f7\",\n    \"0x8db5a6660c3ac7fd7a093573940f068ee79a82bc17312af900b51c8c439336bc86ca646c6b7ab13aaaa008a24ca508ab\",\n    \"0x8f9899a6d7e8eb4367beb5c060a1f8e94d8a21099033ae582118477265155ba9e72176a67f7f25d7bad75a152b56e21a\",\n    \"0xa67de0e91ade8d69a0e00c9ff33ee2909b8a609357095fa12319e6158570c232e5b6f4647522efb7345ce0052aa9d489\",\n    \"0x82eb2414898e9c3023d57907a2b17de8e7eea5269029d05a94bfd7bf5685ac4a799110fbb375eb5e0e2bd16acf6458ae\",\n    \"0x94451fc7fea3c5a89ba701004a9693bab555cb622caf0896b678faba040409fdfd14a978979038b2a81e8f0abc4994d2\",\n    \"0xac879a5bb433998e289809a4a966bd02b4bf6a9c1cc276454e39c886efcf4fc68baebed575826bde577ab5aa71d735a9\",\n    \"0x880c0f8f49c875dfd62b4ddedde0f5c8b19f5687e693717f7e5c031bc580e58e13ab497d48b4874130a18743c59fdce3\",\n    \"0xb582af8d8ff0bf76f0a3934775e0b54c0e8fed893245d7d89cae65b03c8125b7237edc29dc45b4fe1a3fe6db45d280ee\",\n    \"0x89f337882ed3ae060aaee98efa20d79b6822bde9708c1c5fcee365d0ec9297f694cae37d38fd8e3d49717c1e86f078e7\",\n    \"0x826d2c1faea54061848b484e288a5f4de0d221258178cf87f72e14baaa4acc21322f8c9eab5dde612ef497f2d2e1d60b\",\n    \"0xa5333d4f227543e9cd741ccf3b81db79f2f03ca9e649e40d6a6e8ff9073e06da83683566d3b3c8d7b258c62970fb24d1\",\n    \"0xa28f08c473db06aaf4c043a2fae82b3c8cfaa160bce793a4c208e4e168fb1c65115ff8139dea06453c5963d95e922b94\",\n    \"0x8162546135cc5e124e9683bdfaa45833c18553ff06a0861c887dc84a5b12ae8cd4697f6794c7ef6230492c32faba7014\",\n    \"0xb23f0d05b74c08d6a7df1760792be83a761b36e3f8ae360f3c363fb196e2a9dd2de2e492e49d36561366e14daa77155c\",\n    \"0xb6f70d6c546722d3907c708d630dbe289771d2c8bf059c2e32b77f224696d750b4dda9b3a014debda38e7d02c9a77585\",\n    \"0x83bf4c4a9f3ca022c631017e7a30ea205ba97f7f5927cba8fc8489a4646eac6712cb821c5668c9ffe94d69d524374a27\",\n    \"0xb0371475425a8076d0dd5f733f55aabbe42d20a7c8ea7da352e736d4d35a327b2beb370dfcb05284e22cfd69c5f6c4cc\",\n    \"0xa0031ba7522c79211416c2cca3aa5450f96f8fee711552a30889910970ba13608646538781a2c08b834b140aadd7166f\",\n    \"0x99d273c80c7f2dc6045d4ed355d9fc6f74e93549d961f4a3b73cd38683f905934d359058cd1fc4da8083c7d75070487f\",\n    \"0xb0e4b0efa3237793e9dcce86d75aafe9879c5fa23f0d628649aef2130454dcf72578f9bf227b9d2b9e05617468e82588\",\n    \"0xa5ab076fa2e1c5c51f3ae101afdd596ad9d106bba7882b359c43d8548b64f528af19afa76cd6f40da1e6c5fca4def3fa\",\n    \"0x8ce2299e570331d60f6a6eff1b271097cd5f1c0e1113fc69b89c6a0f685dabea3e5bc2ac6bd789aa492ab189f89be494\",\n    \"0x91b829068874d911a310a5f9dee001021f97471307b5a3de9ec336870ec597413e1d92010ce320b619f38bed7c4f7910\",\n    \"0xb14fe91f4b07bf33b046e9285b66cb07927f3a8da0af548ac2569b4c4fb1309d3ced76d733051a20814e90dd5b75ffd1\",\n    \"0xabaab92ea6152d40f82940277c725aa768a631ee0b37f5961667f82fb990fc11e6d3a6a2752b0c6f94563ed9bb28265c\",\n    \"0xb7fe28543eca2a716859a76ab9092f135337e28109544f6bd2727728d0a7650428af5713171ea60bfc273d1c821d992c\",\n    \"0x8a4917b2ab749fc7343fc64bdf51b6c0698ff15d740cc7baf248c030475c097097d5a473bcc00d8c25817563fe0447b4\",\n    \"0xaa96156d1379553256350a0a3250166add75948fb9cde62aa555a0a9dc0a9cb7f2f7b8428aff66097bf6bfedaf14bbe2\",\n    \"0xae4ffeb9bdc76830d3eca2b705f30c1bdede6412fa064260a21562c8850c7fb611ec62bc68479fe48f692833e6f66d8d\",\n    \"0xb96543caaba9d051600a14997765d49e4ab10b07c7a92cccf0c90b309e6da334fdd6d18c96806cbb67a7801024fbd3c7\",\n    \"0x97b2b9ad76f19f500fcc94ca8e434176249f542ac66e5881a3dccd07354bdab6a2157018b19f8459437a68d8b86ba8e0\",\n    \"0xa8d206f6c5a14c80005849474fde44b1e7bcf0b2d52068f5f97504c3c035b09e65e56d1cf4b5322791ae2c2fdbd61859\",\n    \"0x936bad397ad577a70cf99bf9056584a61bd7f02d2d5a6cf219c05d770ae30a5cd902ba38366ce636067fc1dd10108d31\",\n    \"0xa77e30195ee402b84f3882e2286bf5380c0ed374a112dbd11e16cef6b6b61ab209d4635e6f35cdaaa72c1a1981d5dabe\",\n    \"0xa46ba4d3947188590a43c180757886a453a0503f79cc435322d92490446f37419c7b999fdf868a023601078070e03346\",\n    \"0x80d8d4c5542f223d48240b445d4d8cf6a75d120b060bc08c45e99a13028b809d910b534d2ac47fb7068930c54efd8da9\",\n    \"0x803be9c68c91b42b68e1f55e58917a477a9a6265e679ca44ee30d3eb92453f8c89c64eafc04c970d6831edd33d066902\",\n    \"0xb14b2b3d0dfe2bb57cee4cd72765b60ac33c1056580950be005790176543826c1d4fbd737f6cfeada6c735543244ab57\",\n    \"0xa9e480188bba1b8fb7105ff12215706665fd35bf1117bacfb6ab6985f4dbc181229873b82e5e18323c2b8f5de03258e0\",\n    \"0xa66a0f0779436a9a3999996d1e6d3000f22c2cac8e0b29cddef9636393c7f1457fb188a293b6c875b05d68d138a7cc4a\",\n    \"0x848397366300ab40c52d0dbbdafbafef6cd3dadf1503bb14b430f52bb9724188928ac26f6292a2412bc7d7aa620763c8\",\n    \"0x95466cc1a78c9f33a9aaa3829a4c8a690af074916b56f43ae46a67a12bb537a5ac6dbe61590344a25b44e8512355a4a7\",\n    \"0x8b5f7a959f818e3baf0887f140f4575cac093d0aece27e23b823cf421f34d6e4ff4bb8384426e33e8ec7b5eed51f6b5c\",\n    \"0x8d5e1368ec7e3c65640d216bcc5d076f3d9845924c734a34f3558ac0f16e40597c1a775a25bf38b187213fbdba17c93b\",\n    \"0xb4647c1b823516880f60d20c5cc38c7f80b363c19d191e8992226799718ee26b522a12ecb66556ed3d483aa4824f3326\",\n    \"0xac3abaea9cd283eb347efda4ed9086ea3acf495043e08d0d19945876329e8675224b685612a6badf8fd72fb6274902b1\",\n    \"0x8eae1ce292d317aaa71bcf6e77e654914edd5090e2e1ebab78b18bb41b9b1bc2e697439f54a44c0c8aa0d436ebe6e1a9\",\n    \"0x94dc7d1aec2c28eb43d93b111fa59aaa0d77d5a09501220bd411768c3e52208806abf973c6a452fd8292ff6490e0c9e2\",\n    \"0x8fd8967f8e506fef27d17b435d6b86b232ec71c1036351f12e6fb8a2e12daf01d0ee04451fb944d0f1bf7fd20e714d02\",\n    \"0x824e6865be55d43032f0fec65b3480ea89b0a2bf860872237a19a54bc186a85d2f8f9989cc837fbb325b7c72d9babe2c\",\n    \"0x8bd361f5adb27fd6f4e3f5de866e2befda6a8454efeb704aacc606f528c03f0faae888f60310e49440496abd84083ce2\",\n    \"0xb098a3c49f2aaa28b6b3e85bc40ce6a9cdd02134ee522ae73771e667ad7629c8d82c393fba9f27f5416986af4c261438\",\n    \"0xb385f5ca285ff2cfe64dcaa32dcde869c28996ed091542600a0b46f65f3f5a38428cca46029ede72b6cf43e12279e3d3\",\n    \"0x8196b03d011e5be5288196ef7d47137d6f9237a635ab913acdf9c595fa521d9e2df722090ec7eb0203544ee88178fc5f\",\n    \"0x8ed1270211ef928db18e502271b7edf24d0bbd11d97f2786aee772d70c2029e28095cf8f650b0328cc8a4c38d045316d\",\n    \"0xa52ab60e28d69b333d597a445884d44fd2a7e1923dd60f763951e1e45f83e27a4dac745f3b9eff75977b3280e132c15d\",\n    \"0x91e9fe78cdac578f4a4687f71b800b35da54b824b1886dafec073a3c977ce7a25038a2f3a5b1e35c2c8c9d1a7312417c\",\n    \"0xa42832173f9d9491c7bd93b21497fbfa4121687cd4d2ab572e80753d7edcbb42cfa49f460026fbde52f420786751a138\",\n    \"0x97b947126d84dcc70c97be3c04b3de3f239b1c4914342fa643b1a4bb8c4fe45c0fcb585700d13a7ed50784790c54bef9\",\n    \"0x860e407d353eac070e2418ef6cb80b96fc5f6661d6333e634f6f306779651588037be4c2419562c89c61f9aa2c4947f5\",\n    \"0xb2c9d93c3ba4e511b0560b55d3501bf28a510745fd666b3cb532db051e6a8617841ea2f071dda6c9f15619c7bfd2737f\",\n    \"0x8596f4d239aeeac78311207904d1bd863ef68e769629cc379db60e019aaf05a9d5cd31dc8e630b31e106a3a93e47cbc5\",\n    \"0x8b26e14e2e136b65c5e9e5c2022cee8c255834ea427552f780a6ca130a6446102f2a6f334c3f9a0308c53df09e3dba7e\",\n    \"0xb54724354eb515a3c8bed0d0677ff1db94ac0a07043459b4358cb90e3e1aa38ac23f2caa3072cf9647275d7cd61d0e80\",\n    \"0xb7ce9fe0e515e7a6b2d7ddcb92bc0196416ff04199326aea57996eef8c5b1548bd8569012210da317f7c0074691d01b7\",\n    \"0xa1a13549c82c877253ddefa36a29ea6a23695ee401fdd48e65f6f61e5ebd956d5e0edeff99484e9075cb35071fec41e2\",\n    \"0x838ba0c1e5bd1a6da05611ff1822b8622457ebd019cb065ece36a2d176bd2d889511328120b8a357e44569e7f640c1e6\",\n    \"0xb916eccff2a95519400bbf76b5f576cbe53cf200410370a19d77734dc04c05b585cfe382e8864e67142d548cd3c4c2f4\",\n    \"0xa610447cb7ca6eea53a6ff1f5fe562377dcb7f4aaa7300f755a4f5e8eba61e863c51dc2aa9a29b35525b550fbc32a0fe\",\n    \"0x9620e8f0f0ee9a4719aa9685eeb1049c5c77659ba6149ec4c158f999cfd09514794b23388879931fe26fea03fa471fd3\",\n    \"0xa9dcf8b679e276583cf5b9360702a185470d09aea463dc474ee9c8aee91ef089dacb073e334e47fbc78ec5417c90465c\",\n    \"0x8c9adee8410bdd99e5b285744cee61e2593b6300ff31a8a83b0ec28da59475a5c6fb9346fe43aadea2e6c3dad2a8e30a\",\n    \"0x97d5afe9b3897d7b8bb628b7220cf02d8ee4e9d0b78f5000d500aaf4c1df9251aaaabfd1601626519f9d66f00a821d4e\",\n    \"0x8a382418157b601ce4c3501d3b8409ca98136a4ef6abcbf62885e16e215b76b035c94d149cc41ff92e42ccd7c43b9b3d\",\n    \"0xb64b8d11fb3b01abb2646ac99fdb9c02b804ce15d98f9fe0fbf1c9df8440c71417487feb6cdf51e3e81d37104b19e012\",\n    \"0x849d7d044f9d8f0aab346a9374f0b3a5d14a9d1faa83dbacccbdc629ad1ef903a990940255564770537f8567521d17f0\",\n    \"0x829dbb0c76b996c2a91b4cbbe93ba455ca0d5729755e5f0c92aaee37dff7f36fcdc06f33aca41f1b609c784127b67d88\",\n    \"0x85a7c0069047b978422d264d831ab816435f63938015d2e977222b6b5746066c0071b7f89267027f8a975206ed25c1b0\",\n    \"0x84b9fbc1cfb302df1acdcf3dc5d66fd1edfe7839f7a3b2fb3a0d5548656249dd556104d7c32b73967bccf0f5bdcf9e3b\",\n    \"0x972220ac5b807f53eac37dccfc2ad355d8b21ea6a9c9b011c09fe440ddcdf7513e0b43d7692c09ded80d7040e26aa28f\",\n    \"0x855885ed0b21350baeca890811f344c553cf9c21024649c722453138ba29193c6b02c4b4994cd414035486f923472e28\",\n    \"0x841874783ae6d9d0e59daea03e96a01cbbe4ecaced91ae4f2c8386e0d87b3128e6d893c98d17c59e4de1098e1ad519dd\",\n    \"0x827e50fc9ce56f97a4c3f2f4cbaf0b22f1c3ce6f844ff0ef93a9c57a09b8bf91ebfbd2ba9c7f83c442920bffdaf288cc\",\n    \"0xa441f9136c7aa4c08d5b3534921b730e41ee91ab506313e1ba5f7c6f19fd2d2e1594e88c219834e92e6fb95356385aa7\",\n    \"0x97d75b144471bf580099dd6842b823ec0e6c1fb86dd0da0db195e65524129ea8b6fd4a7a9bbf37146269e938a6956596\",\n    \"0xa4b6fa87f09d5a29252efb2b3aaab6b3b6ea9fab343132a651630206254a25378e3e9d6c96c3d14c150d01817d375a8e\",\n    \"0xa31a671876d5d1e95fe2b8858dc69967231190880529d57d3cab7f9f4a2b9b458ac9ee5bdaa3289158141bf18f559efb\",\n    \"0x90bee6fff4338ba825974021b3b2a84e36d617e53857321f13d2b3d4a28954e6de3b3c0e629d61823d18a9763313b3bf\",\n    \"0x96b622a63153f393bb419bfcf88272ea8b3560dbd46b0aa07ada3a6223990d0abdd6c2adb356ef4be5641688c8d83941\",\n    \"0x84c202adeaff9293698022bc0381adba2cd959f9a35a4e8472288fd68f96f6de8be9da314c526d88e291c96b1f3d6db9\",\n    \"0x8ca01a143b8d13809e5a8024d03e6bc9492e22226073ef6e327edf1328ef4aff82d0bcccee92cb8e212831fa35fe1204\",\n    \"0xb2f970dbad15bfbefb38903c9bcc043d1367055c55dc1100a850f5eb816a4252c8c194b3132c929105511e14ea10a67d\",\n    \"0xa5e36556472a95ad57eb90c3b6623671b03eafd842238f01a081997ffc6e2401f76e781d049bb4aa94d899313577a9cf\",\n    \"0x8d1057071051772f7c8bedce53a862af6fd530dd56ae6321eaf2b9fc6a68beff5ed745e1c429ad09d5a118650bfd420a\",\n    \"0x8aadc4f70ace4fcb8d93a78610779748dcffc36182d45b932c226dc90e48238ea5daa91f137c65ed532352c4c4d57416\",\n    \"0xa2ea05ae37e673b4343232ae685ee14e6b88b867aef6dfac35db3589cbcd76f99540fed5c2641d5bb5a4a9f808e9bf0d\",\n    \"0x947f1abad982d65648ae4978e094332b4ecb90f482c9be5741d5d1cf5a28acf4680f1977bf6e49dd2174c37f11e01296\",\n    \"0xa27b144f1565e4047ba0e3f4840ef19b5095d1e281eaa463c5358f932114cbd018aa6dcf97546465cf2946d014d8e6d6\",\n    \"0x8574e1fc3acade47cd4539df578ce9205e745e161b91e59e4d088711a7ab5aa3b410d517d7304b92109924d9e2af8895\",\n    \"0xa48ee6b86b88015d6f0d282c1ae01d2a5b9e8c7aa3d0c18b35943dceb1af580d08a65f54dc6903cde82fd0d73ce94722\",\n    \"0x8875650cec543a7bf02ea4f2848a61d167a66c91ffaefe31a9e38dc8511c6a25bde431007eefe27a62af3655aca208dc\",\n    \"0x999b0a6e040372e61937bf0d68374e230346b654b5a0f591a59d33a4f95bdb2f3581db7c7ccb420cd7699ed709c50713\",\n    \"0x878c9e56c7100c5e47bbe77dc8da5c5fe706cec94d37fa729633bca63cace7c40102eee780fcdabb655f5fa47a99600e\",\n    \"0x865006fb5b475ada5e935f27b96f9425fc2d5449a3c106aa366e55ebed3b4ee42adc3c3f0ac19fd129b40bc7d6bc4f63\",\n    \"0xb7a7da847f1202e7bc1672553e68904715e84fd897d529243e3ecda59faa4e17ba99c649a802d53f6b8dfdd51f01fb74\",\n    \"0x8b2fb4432c05653303d8c8436473682933a5cb604da10c118ecfcd2c8a0e3132e125afef562bdbcc3df936164e5ce4f2\",\n    \"0x808d95762d33ddfa5d0ee3d7d9f327de21a994d681a5f372e2e3632963ea974da7f1f9e5bac8ccce24293509d1f54d27\",\n    \"0x932946532e3c397990a1df0e94c90e1e45133e347a39b6714c695be21aeb2d309504cb6b1dde7228ff6f6353f73e1ca2\",\n    \"0x9705e7c93f0cdfaa3fa96821f830fe53402ad0806036cd1b48adc2f022d8e781c1fbdab60215ce85c653203d98426da3\",\n    \"0xaa180819531c3ec1feb829d789cb2092964c069974ae4faad60e04a6afcce5c3a59aec9f11291e6d110a788d22532bc6\",\n    \"0x88f755097f7e25cb7dd3c449520c89b83ae9e119778efabb54fbd5c5714b6f37c5f9e0346c58c6ab09c1aef2483f895d\",\n    \"0x99fc03ab7810e94104c494f7e40b900f475fde65bdec853e60807ffd3f531d74de43335c3b2646b5b8c26804a7448898\",\n    \"0xaf2dea9683086bed1a179110efb227c9c00e76cd00a2015b089ccbcee46d1134aa18bda5d6cab6f82ae4c5cd2461ac21\",\n    \"0xa500f87ba9744787fdbb8e750702a3fd229de6b8817594348dec9a723b3c4240ddfa066262d002844b9e38240ce55658\",\n    \"0x924d0e45c780f5bc1c1f35d15dfc3da28036bdb59e4c5440606750ecc991b85be18bc9a240b6c983bc5430baa4c68287\",\n    \"0x865b11e0157b8bf4c5f336024b016a0162fc093069d44ac494723f56648bc4ded13dfb3896e924959ea11c96321afefc\",\n    \"0x93672d8607d4143a8f7894f1dcca83fb84906dc8d6dd7dd063bb0049cfc20c1efd933e06ca7bd03ea4cb5a5037990bfe\",\n    \"0x826891efbdff0360446825a61cd1fa04326dd90dae8c33dfb1ed97b045e165766dd070bd7105560994d0b2044bdea418\",\n    \"0x93c4a4a8bcbc8b190485cc3bc04175b7c0ed002c28c98a540919effd6ed908e540e6594f6db95cd65823017258fb3b1c\",\n    \"0xaeb2a0af2d2239fda9aa6b8234b019708e8f792834ff0dd9c487fa09d29800ddceddd6d7929faa9a3edcb9e1b3aa0d6b\",\n    \"0x87f11de7236d387863ec660d2b04db9ac08143a9a2c4dfff87727c95b4b1477e3bc473a91e5797313c58754905079643\",\n    \"0x80dc1db20067a844fe8baceca77f80db171a5ca967acb24e2d480eae9ceb91a3343c31ad1c95b721f390829084f0eae6\",\n    \"0x9825c31f1c18da0de3fa84399c8b40f8002c3cae211fb6a0623c76b097b4d39f5c50058f57a16362f7a575909d0a44a2\",\n    \"0xa99fc8de0c38dbf7b9e946de83943a6b46a762167bafe2a603fb9b86f094da30d6de7ed55d639aafc91936923ee414b3\",\n    \"0xad594678b407db5d6ea2e90528121f84f2b96a4113a252a30d359a721429857c204c1c1c4ff71d8bb5768c833f82e80e\",\n    \"0xb33d985e847b54510b9b007e31053732c8a495e43be158bd2ffcea25c6765bcbc7ca815f7c60b36ad088b955dd6e9350\",\n    \"0x815f8dfc6f90b3342ca3fbd968c67f324dae8f74245cbf8bc3bef10e9440c65d3a2151f951e8d18959ba01c1b50b0ec1\",\n    \"0x94c608a362dd732a1abc56e338637c900d59013db8668e49398b3c7a0cae3f7e2f1d1bf94c0299eeafe6af7f76c88618\",\n    \"0x8ebd8446b23e5adfcc393adc5c52fe172f030a73e63cd2d515245ca0dd02782ceed5bcdd9ccd9c1b4c5953dfac9c340c\",\n    \"0x820437f3f6f9ad0f5d7502815b221b83755eb8dc56cd92c29e9535eb0b48fb8d08c9e4fcc26945f9c8cca60d89c44710\",\n    \"0x8910e4e8a56bf4be9cc3bbf0bf6b1182a2f48837a2ed3c2aaec7099bfd7f0c83e14e608876b17893a98021ff4ab2f20d\",\n    \"0x9633918fde348573eec15ce0ad53ac7e1823aac86429710a376ad661002ae6d049ded879383faaa139435122f64047c6\",\n    \"0xa1f5e3fa558a9e89318ca87978492f0fb4f6e54a9735c1b8d2ecfb1d1c57194ded6e0dd82d077b2d54251f3bee1279e1\",\n    \"0xb208e22d04896abfd515a95c429ff318e87ff81a5d534c8ac2c33c052d6ffb73ef1dccd39c0bbe0734b596c384014766\",\n    \"0x986d5d7d2b5bde6d16336f378bd13d0e671ad23a8ec8a10b3fc09036faeeb069f60662138d7a6df3dfb8e0d36180f770\",\n    \"0xa2d4e6c5f5569e9cef1cddb569515d4b6ace38c8aed594f06da7434ba6b24477392cc67ba867c2b079545ca0c625c457\",\n    \"0xb5ac32b1d231957d91c8b7fc43115ce3c5c0d8c13ca633374402fa8000b6d9fb19499f9181844f0c10b47357f3f757ce\",\n    \"0x96b8bf2504b4d28fa34a4ec378e0e0b684890c5f44b7a6bb6e19d7b3db2ab27b1e2686389d1de9fbd981962833a313ea\",\n    \"0x953bfd7f6c3a0469ad432072b9679a25486f5f4828092401eff494cfb46656c958641a4e6d0d97d400bc59d92dba0030\",\n    \"0x876ab3cea7484bbfd0db621ec085b9ac885d94ab55c4bb671168d82b92e609754b86aaf472c55df3d81421d768fd108a\",\n    \"0x885ff4e67d9ece646d02dd425aa5a087e485c3f280c3471b77532b0db6145b69b0fbefb18aa2e3fa5b64928b43a94e57\",\n    \"0xb91931d93f806d0b0e6cc62a53c718c099526140f50f45d94b8bbb57d71e78647e06ee7b42aa5714aed9a5c05ac8533f\",\n    \"0xa0313eeadd39c720c9c27b3d671215331ab8d0a794e71e7e690f06bcd87722b531d6525060c358f35f5705dbb7109ccb\",\n    \"0x874c0944b7fedc6701e53344100612ddcb495351e29305c00ec40a7276ea5455465ffb7bded898886c1853139dfb1fc7\",\n    \"0x8dc31701a01ee8137059ca1874a015130d3024823c0576aa9243e6942ec99d377e7715ed1444cd9b750a64b85dcaa3e5\",\n    \"0x836d2a757405e922ec9a2dfdcf489a58bd48b5f9683dd46bf6047688f778c8dee9bc456de806f70464df0b25f3f3d238\",\n    \"0xb30b0a1e454a503ea3e2efdec7483eaf20b0a5c3cefc42069e891952b35d4b2c955cf615f3066285ed8fafd9fcfbb8f6\",\n    \"0x8e6d4044b55ab747e83ec8762ea86845f1785cc7be0279c075dadf08aca3ccc5a096c015bb3c3f738f647a4eadea3ba5\",\n    \"0xad7735d16ab03cbe09c029610aa625133a6daecfc990b297205b6da98eda8c136a7c50db90f426d35069708510d5ae9c\",\n    \"0x8d62d858bbb59ec3c8cc9acda002e08addab4d3ad143b3812098f3d9087a1b4a1bb255dcb1635da2402487d8d0249161\",\n    \"0x805beec33238b832e8530645a3254aeef957e8f7ea24bcfc1054f8b9c69421145ebb8f9d893237e8a001c857fedfc77e\",\n    \"0xb1005644be4b085e3f5775aa9bd3e09a283e87ddada3082c04e7a62d303dcef3b8cf8f92944c200c7ae6bb6bdf63f832\",\n    \"0xb4ba0e0790dc29063e577474ffe3b61f5ea2508169f5adc1e394934ebb473e356239413a17962bc3e5d3762d72cce8c2\",\n    \"0xa157ba9169c9e3e6748d9f1dd67fbe08b9114ade4c5d8fc475f87a764fb7e6f1d21f66d7905cd730f28a1c2d8378682a\",\n    \"0x913e52b5c93989b5d15e0d91aa0f19f78d592bc28bcfdfddc885a9980c732b1f4debb8166a7c4083c42aeda93a702898\",\n    \"0x90fbfc1567e7cd4e096a38433704d3f96a2de2f6ed3371515ccc30bc4dd0721a704487d25a97f3c3d7e4344472702d8d\",\n    \"0x89646043028ffee4b69d346907586fd12c2c0730f024acb1481abea478e61031966e72072ff1d5e65cb8c64a69ad4eb1\",\n    \"0xb125a45e86117ee11d2fb42f680ab4a7894edd67ff927ae2c808920c66c3e55f6a9d4588eee906f33a05d592e5ec3c04\",\n    \"0xaad47f5b41eae9be55fb4f67674ff1e4ae2482897676f964a4d2dcb6982252ee4ff56aac49578b23f72d1fced707525e\",\n    \"0xb9ddff8986145e33851b4de54d3e81faa3352e8385895f357734085a1616ef61c692d925fe62a5ed3be8ca49f5d66306\",\n    \"0xb3cb0963387ed28c0c0adf7fe645f02606e6e1780a24d6cecef5b7c642499109974c81a7c2a198b19862eedcea2c2d8c\",\n    \"0xac9c53c885457aaf5cb36c717a6f4077af701e0098eebd7aa600f5e4b14e6c1067255b3a0bc40e4a552025231be7de60\",\n    \"0x8e1a8d823c4603f6648ec21d064101094f2a762a4ed37dd2f0a2d9aa97b2d850ce1e76f4a4b8cae58819b058180f7031\",\n    \"0xb268b73bf7a179b6d22bd37e5e8cb514e9f5f8968c78e14e4f6d5700ca0d0ca5081d0344bb73b028970eebde3cb4124e\",\n    \"0xa7f57d71940f0edbd29ed8473d0149cae71d921dd15d1ff589774003e816b54b24de2620871108cec1ab9fa956ad6ce6\",\n    \"0x8053e6416c8b120e2b999cc2fc420a6a55094c61ac7f2a6c6f0a2c108a320890e389af96cbe378936132363c0d551277\",\n    \"0xb3823f4511125e5aa0f4269e991b435a0d6ceb523ebd91c04d7add5534e3df5fc951c504b4fd412a309fd3726b7f940b\",\n    \"0xae6eb04674d04e982ca9a6add30370ab90e303c71486f43ed3efbe431af1b0e43e9d06c11c3412651f304c473e7dbf39\",\n    \"0x96ab55e641ed2e677591f7379a3cd126449614181fce403e93e89b1645d82c4af524381ff986cae7f9cebe676878646d\",\n    \"0xb52423b4a8c37d3c3e2eca8f0ddbf7abe0938855f33a0af50f117fab26415fb0a3da5405908ec5fdc22a2c1f2ca64892\",\n    \"0x82a69ce1ee92a09cc709d0e3cd22116c9f69d28ea507fe5901f5676000b5179b9abe4c1875d052b0dd42d39925e186bb\",\n    \"0xa84c8cb84b9d5cfb69a5414f0a5283a5f2e90739e9362a1e8c784b96381b59ac6c18723a4aa45988ee8ef5c1f45cc97d\",\n    \"0xafd7efce6b36813082eb98257aae22a4c1ae97d51cac7ea9c852d4a66d05ef2732116137d8432e3f117119725a817d24\",\n    \"0xa0f5fe25af3ce021b706fcff05f3d825384a272284d04735574ce5fb256bf27100fad0b1f1ba0e54ae9dcbb9570ecad3\",\n    \"0x8751786cb80e2e1ff819fc7fa31c2833d25086534eb12b373d31f826382430acfd87023d2a688c65b5e983927e146336\",\n    \"0x8cf5c4b17fa4f3d35c78ce41e1dc86988fd1135cd5e6b2bb0c108ee13538d0d09ae7102609c6070f39f937b439b31e33\",\n    \"0xa9108967a2fedd7c322711eca8159c533dd561bedcb181b646de98bf5c3079449478eab579731bee8d215ae8852c7e21\",\n    \"0xb54c5171704f42a6f0f4e70767cdb3d96ffc4888c842eece343a01557da405961d53ffdc34d2f902ea25d3e1ed867cad\",\n    \"0xae8d4b764a7a25330ba205bf77e9f46182cd60f94a336bbd96773cf8064e3d39caf04c310680943dc89ed1fbad2c6e0d\",\n    \"0xaa5150e911a8e1346868e1b71c5a01e2a4bb8632c195861fb6c3038a0e9b85f0e09b3822e9283654a4d7bb17db2fc5f4\",\n    \"0x9685d3756ce9069bf8bb716cf7d5063ebfafe37e15b137fc8c3159633c4e006ff4887ddd0ae90360767a25c3f90cba7f\",\n    \"0x82155fd70f107ab3c8e414eadf226c797e07b65911508c76c554445422325e71af8c9a8e77fd52d94412a6fc29417cd3\",\n    \"0xabfae52f53a4b6e00760468d973a267f29321997c3dbb5aee36dc1f20619551229c0c45b9d9749f410e7f531b73378e8\",\n    \"0x81a76d921f8ef88e774fd985e786a4a330d779b93fad7def718c014685ca0247379e2e2a007ad63ee7f729cd9ed6ce1b\",\n    \"0x81947c84bc5e28e26e2e533af5ae8fe10407a7b77436dbf8f1d5b0bbe86fc659eae10f974659dc7c826c6dabd03e3a4b\",\n    \"0x92b8c07050d635b8dd4fd09df9054efe4edae6b86a63c292e73cc819a12a21dd7d104ce51fa56af6539dedf6dbe6f7b6\",\n    \"0xb44c579e3881f32b32d20c82c207307eca08e44995dd2aac3b2692d2c8eb2a325626c80ac81c26eeb38c4137ff95add5\",\n    \"0x97efab8941c90c30860926dea69a841f2dcd02980bf5413b9fd78d85904588bf0c1021798dbc16c8bbb32cce66c82621\",\n    \"0x913363012528b50698e904de0588bf55c8ec5cf6f0367cfd42095c4468fcc64954fbf784508073e542fee242d0743867\",\n    \"0x8ed203cf215148296454012bd10fddaf119203db1919a7b3d2cdc9f80e66729464fdfae42f1f2fc5af1ed53a42b40024\",\n    \"0xab84312db7b87d711e9a60824f4fe50e7a6190bf92e1628688dfcb38930fe87b2d53f9e14dd4de509b2216856d8d9188\",\n    \"0x880726def069c160278b12d2258eac8fa63f729cd351a710d28b7e601c6712903c3ac1e7bbd0d21e4a15f13ca49db5aa\",\n    \"0x980699cd51bac6283959765f5174e543ed1e5f5584b5127980cbc2ef18d984ecabba45042c6773b447b8e694db066028\",\n    \"0xaeb019cb80dc4cb4207430d0f2cd24c9888998b6f21d9bf286cc638449668d2eec0018a4cf3fe6448673cd6729335e2b\",\n    \"0xb29852f6aa6c60effdffe96ae88590c88abae732561d35cc19e82d3a51e26cb35ea00986193e07f90060756240f5346e\",\n    \"0xa0fa855adc5ba469f35800c48414b8921455950a5c0a49945d1ef6e8f2a1881f2e2dfae47de6417270a6bf49deeb091d\",\n    \"0xb6c7332e3b14813641e7272d4f69ecc7e09081df0037d6dab97ce13a9e58510f5c930d300633f208181d9205c5534001\",\n    \"0x85a6c050f42fce560b5a8d54a11c3bbb8407abbadd859647a7b0c21c4b579ec65671098b74f10a16245dc779dff7838e\",\n    \"0x8f3eb34bb68759d53c6677de4de78a6c24dd32c8962a7fb355ed362572ef8253733e6b52bc21c9f92ecd875020a9b8de\",\n    \"0xa17dd44181e5dab4dbc128e1af93ec22624b57a448ca65d2d9e246797e4af7d079e09c6e0dfb62db3a9957ce92f098d5\",\n    \"0xa56a1b854c3183082543a8685bb34cae1289f86cfa8123a579049dbd059e77982886bfeb61bf6e05b4b1fe4e620932e7\",\n    \"0xaedae3033cb2fb7628cb4803435bdd7757370a86f808ae4cecb9a268ad0e875f308c048c80cbcac523de16b609683887\",\n    \"0x9344905376aa3982b1179497fac5a1d74b14b7038fd15e3b002db4c11c8bfc7c39430db492cdaf58b9c47996c9901f28\",\n    \"0xa3bfafdae011a19f030c749c3b071f83580dee97dd6f949e790366f95618ca9f828f1daaeabad6dcd664fcef81b6556d\",\n    \"0x81c03d8429129e7e04434dee2c529194ddb01b414feda3adee2271eb680f6c85ec872a55c9fa9d2096f517e13ed5abcc\",\n    \"0x98205ef3a72dff54c5a9c82d293c3e45d908946fa74bb749c3aabe1ab994ea93c269bcce1a266d2fe67a8f02133c5985\",\n    \"0x85a70aeed09fda24412fadbafbbbf5ba1e00ac92885df329e147bfafa97b57629a3582115b780d8549d07d19b7867715\",\n    \"0xb0fbe81c719f89a57d9ea3397705f898175808c5f75f8eb81c2193a0b555869ba7bd2e6bc54ee8a60cea11735e21c68c\",\n    \"0xb03a0bd160495ee626ff3a5c7d95bc79d7da7e5a96f6d10116600c8fa20bedd1132f5170f25a22371a34a2d763f2d6d0\",\n    \"0xa90ab04091fbca9f433b885e6c1d60ab45f6f1daf4b35ec22b09909d493a6aab65ce41a6f30c98239cbca27022f61a8b\",\n    \"0xb66f92aa3bf2549f9b60b86f99a0bd19cbdd97036d4ae71ca4b83d669607f275260a497208f6476cde1931d9712c2402\",\n    \"0xb08e1fdf20e6a9b0b4942f14fa339551c3175c1ffc5d0ab5b226b6e6a322e9eb0ba96adc5c8d59ca4259e2bdd04a7eb0\",\n    \"0xa2812231e92c1ce74d4f5ac3ab6698520288db6a38398bb38a914ac9326519580af17ae3e27cde26607e698294022c81\",\n    \"0xabfcbbcf1d3b9e84c02499003e490a1d5d9a2841a9e50c7babbef0b2dd20d7483371d4dc629ba07faf46db659459d296\",\n    \"0xb0fe9f98c3da70927c23f2975a9dc4789194d81932d2ad0f3b00843dd9cbd7fb60747a1da8fe5a79f136a601becf279d\",\n    \"0xb130a6dba7645165348cb90f023713bed0eefbd90a976b313521c60a36d34f02032e69a2bdcf5361e343ed46911297ec\",\n    \"0x862f0cffe3020cea7a5fd4703353aa1eb1be335e3b712b29d079ff9f7090d1d8b12013011e1bdcbaa80c44641fd37c9f\",\n    \"0x8c6f11123b26633e1abb9ed857e0bce845b2b3df91cc7b013b2fc77b477eee445da0285fc6fc793e29d5912977f40916\",\n    \"0x91381846126ea819d40f84d3005e9fb233dc80071d1f9bb07f102bf015f813f61e5884ffffb4f5cd333c1b1e38a05a58\",\n    \"0x8add7d908de6e1775adbd39c29a391f06692b936518db1f8fde74eb4f533fc510673a59afb86e3a9b52ade96e3004c57\",\n    \"0x8780e086a244a092206edcde625cafb87c9ab1f89cc3e0d378bc9ee776313836160960a82ec397bc3800c0a0ec3da283\",\n    \"0xa6cb4cd9481e22870fdd757fae0785edf4635e7aacb18072fe8dc5876d0bab53fb99ce40964a7d3e8bcfff6f0ab1332f\",\n    \"0xaf30ff47ecc5b543efba1ba4706921066ca8bb625f40e530fb668aea0551c7647a9d126e8aba282fbcce168c3e7e0130\",\n    \"0x91b0bcf408ce3c11555dcb80c4410b5bc2386d3c05caec0b653352377efdcb6bab4827f2018671fc8e4a0e90d772acc1\",\n    \"0xa9430b975ef138b6b2944c7baded8fe102d31da4cfe3bd3d8778bda79189c99d38176a19c848a19e2d1ee0bddd9a13c1\",\n    \"0xaa5a4eef849d7c9d2f4b018bd01271c1dd83f771de860c4261f385d3bdcc130218495860a1de298f14b703ec32fa235f\",\n    \"0xb0ce79e7f9ae57abe4ff366146c3b9bfb38b0dee09c28c28f5981a5d234c6810ad4d582751948affb480d6ae1c8c31c4\",\n    \"0xb75122748560f73d15c01a8907d36d06dc068e82ce22b84b322ac1f727034493572f7907dec34ebc3ddcc976f2f89ed7\",\n    \"0xb0fc7836369a3e4411d34792d6bd5617c14f61d9bba023dda64e89dc5fb0f423244e9b48ee64869258931daa9753a56f\",\n    \"0x8956d7455ae9009d70c6e4a0bcd7610e55f37494cf9897a8f9e1b904cc8febc3fd2d642ebd09025cfff4609ad7e3bc52\",\n    \"0xad741efe9e472026aa49ae3d9914cb9c1a6f37a54f1a6fe6419bebd8c7d68dca105a751c7859f4389505ede40a0de786\",\n    \"0xb52f418797d719f0d0d0ffb0846788b5cba5d0454a69a2925de4b0b80fa4dd7e8c445e5eac40afd92897ed28ca650566\",\n    \"0xa0ab65fb9d42dd966cd93b1de01d7c822694669dd2b7a0c04d99cd0f3c3de795f387b9c92da11353412f33af5c950e9a\",\n    \"0xa0052f44a31e5741a331f7cac515a08b3325666d388880162d9a7b97598fde8b61f9ff35ff220df224eb5c4e40ef0567\",\n    \"0xa0101cfdc94e42b2b976c0d89612a720e55d145a5ef6ef6f1f78cf6de084a49973d9b5d45915349c34ce712512191e3c\",\n    \"0xa0dd99fcf3f5cead5aaf08e82212df3a8bb543c407a4d6fab88dc5130c1769df3f147e934a46f291d6c1a55d92b86917\",\n    \"0xa5939153f0d1931bbda5cf6bdf20562519ea55fbfa978d6dbc6828d298260c0da7a50c37c34f386e59431301a96c2232\",\n    \"0x9568269f3f5257200f9ca44afe1174a5d3cf92950a7f553e50e279c239e156a9faaa2a67f288e3d5100b4142efe64856\",\n    \"0xb746b0832866c23288e07f24991bbf687cad794e7b794d3d3b79367566ca617d38af586cdc8d6f4a85a34835be41d54f\",\n    \"0xa871ce28e39ab467706e32fec1669fda5a4abba2f8c209c6745df9f7a0fa36bbf1919cf14cb89ea26fa214c4c907ae03\",\n    \"0xa08dacdd758e523cb8484f6bd070642c0c20e184abdf8e2a601f61507e93952d5b8b0c723c34fcbdd70a8485eec29db2\",\n    \"0x85bdb78d501382bb95f1166b8d032941005661aefd17a5ac32df9a3a18e9df2fc5dc2c1f07075f9641af10353cecc0c9\",\n    \"0x98d730c28f6fa692a389e97e368b58f4d95382fad8f0baa58e71a3d7baaea1988ead47b13742ce587456f083636fa98e\",\n    \"0xa557198c6f3d5382be9fb363feb02e2e243b0c3c61337b3f1801c4a0943f18e38ce1a1c36b5c289c8fa2aa9d58742bab\",\n    \"0x89174f79201742220ac689c403fc7b243eed4f8e3f2f8aba0bf183e6f5d4907cb55ade3e238e3623d9885f03155c4d2b\",\n    \"0xb891d600132a86709e06f3381158db300975f73ea4c1f7c100358e14e98c5fbe792a9af666b85c4e402707c3f2db321e\",\n    \"0xb9e5b2529ef1043278c939373fc0dbafe446def52ddd0a8edecd3e4b736de87e63e187df853c54c28d865de18a358bb6\",\n    \"0x8589b2e9770340c64679062c5badb7bbef68f55476289b19511a158a9a721f197da03ece3309e059fc4468b15ac33aa3\",\n    \"0xaad8c6cd01d785a881b446f06f1e9cd71bca74ba98674c2dcddc8af01c40aa7a6d469037498b5602e76e9c91a58d3dbd\",\n    \"0xabaccb1bd918a8465f1bf8dbe2c9ad4775c620b055550b949a399f30cf0d9eb909f3851f5b55e38f9e461e762f88f499\",\n    \"0xae62339d26db46e85f157c0151bd29916d5cc619bd4b832814b3fd2f00af8f38e7f0f09932ffe5bba692005dab2d9a74\",\n    \"0x93a6ff30a5c0edf8058c89aba8c3259e0f1b1be1b80e67682de651e5346f7e1b4b4ac3d87cbaebf198cf779524aff6bf\",\n    \"0x8980a2b1d8f574af45b459193c952400b10a86122b71fca2acb75ee0dbd492e7e1ef5b959baf609a5172115e371f3177\",\n    \"0x8c2f49f3666faee6940c75e8c7f6f8edc3f704cca7a858bbb7ee5e96bba3b0cf0993996f781ba6be3b0821ef4cb75039\",\n    \"0xb14b9e348215b278696018330f63c38db100b0542cfc5be11dc33046e3bca6a13034c4ae40d9cef9ea8b34fef0910c4e\",\n    \"0xb59bc3d0a30d66c16e6a411cb641f348cb1135186d5f69fda8b0a0934a5a2e7f6199095ba319ec87d3fe8f1ec4a06368\",\n    \"0x8874aca2a3767aa198e4c3fec2d9c62d496bc41ff71ce242e9e082b7f38cdf356089295f80a301a3cf1182bde5308c97\",\n    \"0xb1820ebd61376d91232423fc20bf008b2ba37e761199f4ef0648ea2bd70282766799b4de814846d2f4d516d525c8daa7\",\n    \"0xa6b202e5dedc16a4073e04a11af3a8509b23dfe5a1952f899adeb240e75c3f5bde0c424f811a81ea48d343591faffe46\",\n    \"0xa69becee9c93734805523b92150a59a62eed4934f66056b645728740d42223f2925a1ad38359ba644da24d9414f4cdda\",\n    \"0xad72f0f1305e37c7e6b48c272323ee883320994cb2e0d850905d6655fafc9f361389bcb9c66b3ff8d2051dbb58c8aa96\",\n    \"0xb563600bd56fad7c8853af21c6a02a16ed9d8a8bbeea2c31731d63b976d83cb05b9779372d898233e8fd597a75424797\",\n    \"0xb0abb78ce465bf7051f563c62e8be9c57a2cc997f47c82819300f36e301fefd908894bb2053a9d27ce2d0f8c46d88b5b\",\n    \"0xa071a85fb8274bac2202e0cb8e0e2028a5e138a82d6e0374d39ca1884a549c7c401312f00071b91f455c3a2afcfe0cda\",\n    \"0xb931c271513a0f267b9f41444a5650b1918100b8f1a64959c552aff4e2193cc1b9927906c6fa7b8a8c68ef13d79aaa52\",\n    \"0xa6a1bb9c7d32cb0ca44d8b75af7e40479fbce67d216b48a2bb680d3f3a772003a49d3cd675fc64e9e0f8fabeb86d6d61\",\n    \"0xb98d609858671543e1c3b8564162ad828808bb50ded261a9f8690ded5b665ed8368c58f947365ed6e84e5a12e27b423d\",\n    \"0xb3dca58cd69ec855e2701a1d66cad86717ff103ef862c490399c771ad28f675680f9500cb97be48de34bcdc1e4503ffd\",\n    \"0xb34867c6735d3c49865e246ddf6c3b33baf8e6f164db3406a64ebce4768cb46b0309635e11be985fee09ab7a31d81402\",\n    \"0xacb966c554188c5b266624208f31fab250b3aa197adbdd14aee5ab27d7fb886eb4350985c553b20fdf66d5d332bfd3fe\",\n    \"0x943c36a18223d6c870d54c3b051ef08d802b85e9dd6de37a51c932f90191890656c06adfa883c87b906557ae32d09da0\",\n    \"0x81bca7954d0b9b6c3d4528aadf83e4bc2ef9ea143d6209bc45ae9e7ae9787dbcd8333c41f12c0b6deee8dcb6805e826a\",\n    \"0xaba176b92256efb68f574e543479e5cf0376889fb48e3db4ebfb7cba91e4d9bcf19dcfec444c6622d9398f06de29e2b9\",\n    \"0xb9f743691448053216f6ece7cd699871fff4217a1409ceb8ab7bdf3312d11696d62c74b0664ba0a631b1e0237a8a0361\",\n    \"0xa383c2b6276fa9af346b21609326b53fb14fdf6f61676683076e80f375b603645f2051985706d0401e6fbed7eb0666b6\",\n    \"0xa9ef2f63ec6d9beb8f3d04e36807d84bda87bdd6b351a3e4a9bf7edcb5618c46c1f58cfbf89e64b40f550915c6988447\",\n    \"0xa141b2d7a82f5005eaea7ae7d112c6788b9b95121e5b70b7168d971812f3381de8b0082ac1f0a82c7d365922ebd2d26a\",\n    \"0xb1b76ef8120e66e1535c17038b75255a07849935d3128e3e99e56567b842fb1e8d56ef932d508d2fb18b82f7868fe1a9\",\n    \"0x8e2e234684c81f21099f5c54f6bbe2dd01e3b172623836c77668a0c49ce1fe218786c3827e4d9ae2ea25c50a8924fb3c\",\n    \"0xa5caf5ff948bfd3c4ca3ffbdfcd91eec83214a6c6017235f309a0bbf7061d3b0b466307c00b44a1009cf575163898b43\",\n    \"0x986415a82ca16ebb107b4c50b0c023c28714281db0bcdab589f6cb13d80e473a3034b7081b3c358e725833f6d845cb14\",\n    \"0xb94836bf406ac2cbacb10e6df5bcdfcc9d9124ae1062767ca4e322d287fd5e353fdcebd0e52407cb3cd68571258a8900\",\n    \"0x83c6d70a640b33087454a4788dfd9ef3ed00272da084a8d36be817296f71c086b23b576f98178ab8ca6a74f04524b46b\",\n    \"0xad4115182ad784cfe11bcfc5ce21fd56229cc2ce77ac82746e91a2f0aa53ca6593a22efd2dc4ed8d00f84542643d9c58\",\n    \"0xab1434c5e5065da826d10c2a2dba0facccab0e52b506ce0ce42fbe47ced5a741797151d9ecc99dc7d6373cfa1779bbf6\",\n    \"0x8a8b591d82358d55e6938f67ea87a89097ab5f5496f7260adb9f649abb289da12b498c5b2539c2f9614fb4e21b1f66b0\",\n    \"0x964f355d603264bc1f44c64d6d64debca66f37dff39c971d9fc924f2bc68e6c187b48564a6dc82660a98b035f8addb5d\",\n    \"0xb66235eaaf47456bc1dc4bde454a028e2ce494ece6b713a94cd6bf27cf18c717fd0c57a5681caaa2ad73a473593cdd7a\",\n    \"0x9103e3bb74304186fa4e3e355a02da77da4aca9b7e702982fc2082af67127ebb23a455098313c88465bc9b7d26820dd5\",\n    \"0xb6a42ff407c9dd132670cdb83cbad4b20871716e44133b59a932cd1c3f97c7ac8ff7f61acfaf8628372508d8dc8cad7c\",\n    \"0x883a9c21c16a167a4171b0f084565c13b6f28ba7c4977a0de69f0a25911f64099e7bbb4da8858f2e93068f4155d04e18\",\n    \"0x8dbb3220abc6a43220adf0331e3903d3bfd1d5213aadfbd8dfcdf4b2864ce2e96a71f35ecfb7a07c3bbabf0372b50271\",\n    \"0xb4ad08aee48e176bda390b7d9acf2f8d5eb008f30d20994707b757dc6a3974b2902d29cd9b4d85e032810ad25ac49e97\",\n    \"0x865bb0f33f7636ec501bb634e5b65751c8a230ae1fa807a961a8289bbf9c7fe8c59e01fbc4c04f8d59b7f539cf79ddd5\",\n    \"0x86a54d4c12ad1e3605b9f93d4a37082fd26e888d2329847d89afa7802e815f33f38185c5b7292293d788ad7d7da1df97\",\n    \"0xb26c8615c5e47691c9ff3deca3021714662d236c4d8401c5d27b50152ce7e566266b9d512d14eb63e65bc1d38a16f914\",\n    \"0x827639d5ce7db43ba40152c8a0eaad443af21dc92636cc8cc2b35f10647da7d475a1e408901cd220552fddad79db74df\",\n    \"0xa2b79a582191a85dbe22dc384c9ca3de345e69f6aa370aa6d3ff1e1c3de513e30b72df9555b15a46586bd27ea2854d9d\",\n    \"0xae0d74644aba9a49521d3e9553813bcb9e18f0b43515e4c74366e503c52f47236be92dfbd99c7285b3248c267b1de5a0\",\n    \"0x80fb0c116e0fd6822a04b9c25f456bdca704e2be7bdc5d141dbf5d1c5eeb0a2c4f5d80db583b03ef3e47517e4f9a1b10\",\n    \"0xac3a1fa3b4a2f30ea7e0a114cdc479eb51773573804c2a158d603ad9902ae8e39ffe95df09c0d871725a5d7f9ba71a57\",\n    \"0xb56b2b0d601cba7f817fa76102c68c2e518c6f20ff693aad3ff2e07d6c4c76203753f7f91686b1801e8c4659e4d45c48\",\n    \"0x89d50c1fc56e656fb9d3915964ebce703cb723fe411ab3c9eaa88ccc5d2b155a9b2e515363d9c600d3c0cee782c43f41\",\n    \"0xb24207e61462f6230f3cd8ccf6828357d03e725769f7d1de35099ef9ee4dca57dbce699bb49ed994462bee17059d25ce\",\n    \"0xb886f17fcbcbfcd08ac07f04bb9543ef58510189decaccea4b4158c9174a067cb67d14b6be3c934e6e2a18c77efa9c9c\",\n    \"0xb9c050ad9cafd41c6e2e192b70d080076eed59ed38ea19a12bd92fa17b5d8947d58d5546aaf5e8e27e1d3b5481a6ce51\",\n    \"0xaaf7a34d3267e3b1ddbc54c641e3922e89303f7c86ebebc7347ebca4cffad5b76117dac0cbae1a133053492799cd936f\",\n    \"0xa9ee604ada50adef82e29e893070649d2d4b7136cc24fa20e281ce1a07bd736bf0de7c420369676bcbcecff26fb6e900\",\n    \"0x9855315a12a4b4cf80ab90b8bd13003223ba25206e52fd4fe6a409232fbed938f30120a3db23eab9c53f308bd8b9db81\",\n    \"0x8cd488dd7a24f548a3cf03c54dec7ff61d0685cb0f6e5c46c2d728e3500d8c7bd6bba0156f4bf600466fda53e5b20444\",\n    \"0x890ad4942ebac8f5b16c777701ab80c68f56fa542002b0786f8fea0fb073154369920ac3dbfc07ea598b82f4985b8ced\",\n    \"0x8de0cf9ddc84c9b92c59b9b044387597799246b30b9f4d7626fc12c51f6e423e08ee4cbfe9289984983c1f9521c3e19d\",\n    \"0xb474dfb5b5f4231d7775b3c3a8744956b3f0c7a871d835d7e4fd9cc895222c7b868d6c6ce250de568a65851151fac860\",\n    \"0x86433b6135d9ed9b5ee8cb7a6c40e5c9d30a68774cec04988117302b8a02a11a71a1e03fd8e0264ef6611d219f103007\",\n    \"0x80b9ed4adbe9538fb1ef69dd44ec0ec5b57cbfea820054d8d445b4261962624b4c70ac330480594bc5168184378379c3\",\n    \"0x8b2e83562ccd23b7ad2d17f55b1ab7ef5fbef64b3a284e6725b800f3222b8bdf49937f4a873917ada9c4ddfb090938c2\",\n    \"0xabe78cebc0f5a45d754140d1f685e387489acbfa46d297a8592aaa0d676a470654f417a4f7d666fc0b2508fab37d908e\",\n    \"0xa9c5f8ff1f8568e252b06d10e1558326db9901840e6b3c26bbd0cd5e850cb5fb3af3f117dbb0f282740276f6fd84126f\",\n    \"0x975f8dc4fb55032a5df3b42b96c8c0ffecb75456f01d4aef66f973cb7270d4eff32c71520ceefc1adcf38d77b6b80c67\",\n    \"0xb043306ed2c3d8a5b9a056565afd8b5e354c8c4569fda66b0d797a50a3ce2c08cffbae9bbe292da69f39e89d5dc7911e\",\n    \"0x8d2afc36b1e44386ba350c14a6c1bb31ff6ea77128a0c5287584ac3584282d18516901ce402b4644a53db1ed8e7fa581\",\n    \"0x8c294058bed53d7290325c363fe243f6ec4f4ea2343692f4bac8f0cb86f115c069ccb8334b53d2e42c067691ad110dba\",\n    \"0xb92157b926751aaf7ef82c1aa8c654907dccab6376187ee8b3e8c0c82811eae01242832de953faa13ebaff7da8698b3e\",\n    \"0xa780c4bdd9e4ba57254b09d745075cecab87feda78c88ffee489625c5a3cf96aa6b3c9503a374a37927d9b78de9bd22b\",\n    \"0x811f548ef3a2e6a654f7dcb28ac9378de9515ed61e5a428515d9594a83e80b35c60f96a5cf743e6fab0d3cb526149f49\",\n    \"0x85a4dccf6d90ee8e094731eec53bd00b3887aec6bd81a0740efddf812fd35e3e4fe4f983afb49a8588691c202dabf942\",\n    \"0xb152c2da6f2e01c8913079ae2b40a09b1f361a80f5408a0237a8131b429677c3157295e11b365b1b1841924b9efb922e\",\n    \"0x849b9efee8742502ffd981c4517c88ed33e4dd518a330802caff168abae3cd09956a5ee5eda15900243bc2e829016b74\",\n    \"0x955a933f3c18ec0f1c0e38fa931e4427a5372c46a3906ebe95082bcf878c35246523c23f0266644ace1fa590ffa6d119\",\n    \"0x911989e9f43e580c886656377c6f856cdd4ff1bd001b6db3bbd86e590a821d34a5c6688a29b8d90f28680e9fdf03ba69\",\n    \"0xb73b8b4f1fd6049fb68d47cd96a18fcba3f716e0a1061aa5a2596302795354e0c39dea04d91d232aec86b0bf2ba10522\",\n    \"0x90f87456d9156e6a1f029a833bf3c7dbed98ca2f2f147a8564922c25ae197a55f7ea9b2ee1f81bf7383197c4bad2e20c\",\n    \"0x903cba8b1e088574cb04a05ca1899ab00d8960580c884bd3c8a4c98d680c2ad11410f2b75739d6050f91d7208cac33a5\",\n    \"0x9329987d42529c261bd15ecedd360be0ea8966e7838f32896522c965adfc4febf187db392bd441fb43bbd10c38fdf68b\",\n    \"0x8178ee93acf5353baa349285067b20e9bb41aa32d77b5aeb7384fe5220c1fe64a2461bd7a83142694fe673e8bbf61b7c\",\n    \"0xa06a8e53abcff271b1394bcc647440f81fb1c1a5f29c27a226e08f961c3353f4891620f2d59b9d1902bf2f5cc07a4553\",\n    \"0xaaf5fe493b337810889e777980e6bbea6cac39ac66bc0875c680c4208807ac866e9fda9b5952aa1d04539b9f4a4bec57\",\n    \"0xaa058abb1953eceac14ccfa7c0cc482a146e1232905dcecc86dd27f75575285f06bbae16a8c9fe8e35d8713717f5f19f\",\n    \"0x8f15dd732799c879ca46d2763453b359ff483ca33adb1d0e0a57262352e0476c235987dc3a8a243c74bc768f93d3014c\",\n    \"0xa61cc8263e9bc03cce985f1663b8a72928a607121005a301b28a278e9654727fd1b22bc8a949af73929c56d9d3d4a273\",\n    \"0x98d6dc78502d19eb9f921225475a6ebcc7b44f01a2df6f55ccf6908d65b27af1891be2a37735f0315b6e0f1576c1f8d8\",\n    \"0x8bd258b883f3b3793ec5be9472ad1ff3dc4b51bc5a58e9f944acfb927349ead8231a523cc2175c1f98e7e1e2b9f363b8\",\n    \"0xaeacc2ecb6e807ad09bedd99654b097a6f39840e932873ace02eabd64ccfbb475abdcb62939a698abf17572d2034c51e\",\n    \"0xb8ccf78c08ccd8df59fd6eda2e01de328bc6d8a65824d6f1fc0537654e9bc6bf6f89c422dd3a295cce628749da85c864\",\n    \"0x8f91fd8cb253ba2e71cc6f13da5e05f62c2c3b485c24f5d68397d04665673167fce1fc1aec6085c69e87e66ec555d3fd\",\n    \"0xa254baa10cb26d04136886073bb4c159af8a8532e3fd36b1e9c3a2e41b5b2b6a86c4ebc14dbe624ee07b7ccdaf59f9ab\",\n    \"0x94e3286fe5cd68c4c7b9a7d33ae3d714a7f265cf77cd0e9bc19fc51015b1d1c34ad7e3a5221c459e89f5a043ee84e3a9\",\n    \"0xa279da8878af8d449a9539bec4b17cea94f0242911f66fab275b5143ab040825f78c89cb32a793930609415cfa3a1078\",\n    \"0xac846ceb89c9e5d43a2991c8443079dc32298cd63e370e64149cec98cf48a6351c09c856f2632fd2f2b3d685a18bbf8b\",\n    \"0xa847b27995c8a2e2454aaeb983879fb5d3a23105c33175839f7300b7e1e8ec3efd6450e9fa3f10323609dee7b98c6fd5\",\n    \"0xa2f432d147d904d185ff4b2de8c6b82fbea278a2956bc406855b44c18041854c4f0ecccd472d1d0dff1d8aa8e281cb1d\",\n    \"0x94a48ad40326f95bd63dff4755f863a1b79e1df771a1173b17937f9baba57b39e651e7695be9f66a472f098b339364fc\",\n    \"0xa12a0ccd8f96e96e1bc6494341f7ebce959899341b3a084aa1aa87d1c0d489ac908552b7770b887bb47e7b8cbc3d8e66\",\n    \"0x81a1f1681bda923bd274bfe0fbb9181d6d164fe738e54e25e8d4849193d311e2c4253614ed673c98af2c798f19a93468\",\n    \"0xabf71106a05d501e84cc54610d349d7d5eae21a70bd0250f1bebbf412a130414d1c8dbe673ffdb80208fd72f1defa4d4\",\n    \"0x96266dc2e0df18d8136d79f5b59e489978eee0e6b04926687fe389d4293c14f36f055c550657a8e27be4118b64254901\",\n    \"0x8df5dcbefbfb4810ae3a413ca6b4bf08619ca53cd50eb1dde2a1c035efffc7b7ac7dff18d403253fd80104bd83dc029e\",\n    \"0x9610b87ff02e391a43324a7122736876d5b3af2a137d749c52f75d07b17f19900b151b7f439d564f4529e77aa057ad12\",\n    \"0xa90a5572198b40fe2fcf47c422274ff36c9624df7db7a89c0eb47eb48a73a03c985f4ac5016161c76ca317f64339bce1\",\n    \"0x98e5e61a6ab6462ba692124dba7794b6c6bde4249ab4fcc98c9edd631592d5bc2fb5e38466691a0970a38e48d87c2e43\",\n    \"0x918cefb8f292f78d4db81462c633daf73b395e772f47b3a7d2cea598025b1d8c3ec0cbff46cdb23597e74929981cde40\",\n    \"0xa98918a5dc7cf610fe55f725e4fd24ce581d594cb957bb9b4e888672e9c0137003e1041f83e3f1d7b9caab06462c87d4\",\n    \"0xb92b74ac015262ca66c33f2d950221e19d940ba3bf4cf17845f961dc1729ae227aa9e1f2017829f2135b489064565c29\",\n    \"0xa053ee339f359665feb178b4e7ee30a85df37debd17cacc5a27d6b3369d170b0114e67ad1712ed26d828f1df641bcd99\",\n    \"0x8c3c8bad510b35da5ce5bd84b35c958797fbea024ad1c97091d2ff71d9b962e9222f65a9b776e5b3cc29c36e1063d2ee\",\n    \"0xaf99dc7330fe7c37e850283eb47cc3257888e7c197cb0d102edf94439e1e02267b6a56306d246c326c4c79f9dc8c6986\",\n    \"0xafecb2dc34d57a725efbd7eb93d61eb29dbe8409b668ab9ea040791f5b796d9be6d4fc10d7f627bf693452f330cf0435\",\n    \"0x93334fedf19a3727a81a6b6f2459db859186227b96fe7a391263f69f1a0884e4235de64d29edebc7b99c44d19e7c7d7a\",\n    \"0x89579c51ac405ad7e9df13c904061670ce4b38372492764170e4d3d667ed52e5d15c7cd5c5991bbfa3a5e4e3fa16363e\",\n    \"0x9778f3e8639030f7ef1c344014f124e375acb8045bd13d8e97a92c5265c52de9d1ffebaa5bc3e1ad2719da0083222991\",\n    \"0x88f77f34ee92b3d36791bdf3326532524a67d544297dcf1a47ff00b47c1b8219ff11e34034eab7d23b507caa2fd3c6b9\",\n    \"0xa699c1e654e7c484431d81d90657892efeb4adcf72c43618e71ca7bd7c7a7ebbb1db7e06e75b75dc4c74efd306b5df3f\",\n    \"0x81d13153baebb2ef672b5bdb069d3cd669ce0be96b742c94e04038f689ff92a61376341366b286eee6bf3ae85156f694\",\n    \"0x81efb17de94400fdacc1deec2550cbe3eecb27c7af99d8207e2f9be397e26be24a40446d2a09536bb5172c28959318d9\",\n    \"0x989b21ebe9ceab02488992673dc071d4d5edec24bff0e17a4306c8cb4b3c83df53a2063d1827edd8ed16d6e837f0d222\",\n    \"0x8d6005d6536825661b13c5fdce177cb37c04e8b109b7eb2b6d82ea1cb70efecf6a0022b64f84d753d165edc2bba784a3\",\n    \"0xa32607360a71d5e34af2271211652d73d7756d393161f4cf0da000c2d66a84c6826e09e759bd787d4fd0305e2439d342\",\n    \"0xaaad8d6f6e260db45d51b2da723be6fa832e76f5fbcb77a9a31e7f090dd38446d3b631b96230d78208cae408c288ac4e\",\n    \"0xabcfe425255fd3c5cffd3a818af7650190c957b6b07b632443f9e33e970a8a4c3bf79ac9b71f4d45f238a04d1c049857\",\n    \"0xaeabf026d4c783adc4414b5923dbd0be4b039cc7201219f7260d321f55e9a5b166d7b5875af6129c034d0108fdc5d666\",\n    \"0xaf49e740c752d7b6f17048014851f437ffd17413c59797e5078eaaa36f73f0017c3e7da020310cfe7d3c85f94a99f203\",\n    \"0x8854ca600d842566e3090040cd66bb0b3c46dae6962a13946f0024c4a8aca447e2ccf6f240045f1ceee799a88cb9210c\",\n    \"0xb6c03b93b1ab1b88ded8edfa1b487a1ed8bdce8535244dddb558ffb78f89b1c74058f80f4db2320ad060d0c2a9c351cc\",\n    \"0xb5bd7d17372faff4898a7517009b61a7c8f6f0e7ed4192c555db264618e3f6e57fb30a472d169fea01bf2bf0362a19a8\",\n    \"0x96eb1d38319dc74afe7e7eb076fcd230d19983f645abd14a71e6103545c01301b31c47ae931e025f3ecc01fb3d2f31fa\",\n    \"0xb55a8d30d4403067def9b65e16f867299f8f64c9b391d0846d4780bc196569622e7e5b64ce799b5aefac8f965b2a7a7b\",\n    \"0x8356d199a991e5cbbff608752b6291731b6b6771aed292f8948b1f41c6543e4ab1bedc82dd26d10206c907c03508df06\",\n    \"0x97f4137445c2d98b0d1d478049de952610ad698c91c9d0f0e7227d2aae690e9935e914ec4a2ea1fbf3fc1dddfeeacebb\",\n    \"0xaf5621707e0938320b15ddfc87584ab325fbdfd85c30efea36f8f9bd0707d7ec12c344eff3ec21761189518d192df035\",\n    \"0x8ac7817e71ea0825b292687928e349da7140285d035e1e1abff0c3704fa8453faaae343a441b7143a74ec56539687cc4\",\n    \"0x8a5e0a9e4758449489df10f3386029ada828d1762e4fb0a8ffe6b79e5b6d5d713cb64ed95960e126398b0cdb89002bc9\",\n    \"0x81324be4a71208bbb9bca74b77177f8f1abb9d3d5d9db195d1854651f2cf333cd618d35400da0f060f3e1b025124e4b2\",\n    \"0x849971d9d095ae067525b3cbc4a7dfae81f739537ade6d6cec1b42fb692d923176197a8770907c58069754b8882822d6\",\n    \"0x89f830825416802477cc81fdf11084885865ee6607aa15aa4eb28e351c569c49b8a1b9b5e95ddc04fa0ebafe20071313\",\n    \"0x9240aeeaff37a91af55f860b9badd466e8243af9e8c96a7aa8cf348cd270685ab6301bc135b246dca9eda696f8b0e350\",\n    \"0xacf74db78cc33138273127599eba35b0fb4e7b9a69fe02dae18fc6692d748ca332bd00b22afa8e654ed587aab11833f3\",\n    \"0xb091e6d37b157b50d76bd297ad752220cd5c9390fac16dc838f8557aed6d9833fc920b61519df21265406216315e883f\",\n    \"0xa6446c429ebf1c7793c622250e23594c836b2fbcaf6c5b3d0995e1595a37f50ea643f3e549b0be8bbdadd69044d72ab9\",\n    \"0x93e675353bd60e996bf1c914d5267eeaa8a52fc3077987ccc796710ef9becc6b7a00e3d82671a6bdfb8145ee3c80245a\",\n    \"0xa2f731e43251d04ed3364aa2f072d05355f299626f2d71a8a38b6f76cf08c544133f7d72dd0ab4162814b674b9fc7fa6\",\n    \"0x97a8b791a5a8f6e1d0de192d78615d73d0c38f1e557e4e15d15adc663d649e655bc8da3bcc499ef70112eafe7fb45c7a\",\n    \"0x98cd624cbbd6c53a94469be4643c13130916b91143425bcb7d7028adbbfede38eff7a21092af43b12d4fab703c116359\",\n    \"0x995783ce38fd5f6f9433027f122d4cf1e1ff3caf2d196ce591877f4a544ce9113ead60de2de1827eaff4dd31a20d79a8\",\n    \"0x8cf251d6f5229183b7f3fe2f607a90b4e4b6f020fb4ba2459d28eb8872426e7be8761a93d5413640a661d73e34a5b81f\",\n    \"0xb9232d99620652a3aa7880cad0876f153ff881c4ed4c0c2e7b4ea81d5d42b70daf1a56b869d752c3743c6d4c947e6641\",\n    \"0x849716f938f9d37250cccb1bf77f5f9fde53096cdfc6f2a25536a6187029a8f1331cdbed08909184b201f8d9f04b792f\",\n    \"0x80c7c4de098cbf9c6d17b14eba1805e433b5bc905f6096f8f63d34b94734f2e4ebf4bce8a177efd1186842a61204a062\",\n    \"0xb790f410cf06b9b8daadceeb4fd5ff40a2deda820c8df2537e0a7554613ae3948e149504e3e79aa84889df50c8678eeb\",\n    \"0x813aab8bd000299cd37485b73cd7cba06e205f8efb87f1efc0bae8b70f6db2bc7702eb39510ad734854fb65515fe9d0f\",\n    \"0x94f0ab7388ac71cdb67f6b85dfd5945748afb2e5abb622f0b5ad104be1d4d0062b651f134ba22385c9e32c2dfdcccce1\",\n    \"0xab6223dca8bd6a4f969e21ccd9f8106fc5251d321f9e90cc42cea2424b3a9c4e5060a47eeef6b23c7976109b548498e8\",\n    \"0x859c56b71343fce4d5c5b87814c47bf55d581c50fd1871a17e77b5e1742f5af639d0e94d19d909ec7dfe27919e954e0c\",\n    \"0xaae0d632b6191b8ad71b027791735f1578e1b89890b6c22e37de0e4a6074886126988fe8319ae228ac9ef3b3bcccb730\",\n    \"0x8ca9f32a27a024c3d595ecfaf96b0461de57befa3b331ab71dc110ec3be5824fed783d9516597537683e77a11d334338\",\n    \"0xa061df379fb3f4b24816c9f6cd8a94ecb89b4c6dc6cd81e4b8096fa9784b7f97ab3540259d1de9c02eb91d9945af4823\",\n    \"0x998603102ac63001d63eb7347a4bb2bf4cf33b28079bb48a169076a65c20d511ccd3ef696d159e54cc8e772fb5d65d50\",\n    \"0x94444d96d39450872ac69e44088c252c71f46be8333a608a475147752dbb99db0e36acfc5198f158509401959c12b709\",\n    \"0xac1b51b6c09fe055c1d7c9176eea9adc33f710818c83a1fbfa073c8dc3a7eb3513cbdd3f5960b7845e31e3e83181e6ba\",\n    \"0x803d530523fc9e1e0f11040d2412d02baef3f07eeb9b177fa9bfa396af42eea898a4276d56e1db998dc96ae47b644cb2\",\n    \"0x85a3c9fc7638f5bf2c3e15ba8c2fa1ae87eb1ceb44c6598c67a2948667a9dfa41e61f66d535b4e7fda62f013a5a8b885\",\n    \"0xa961cf5654c46a1a22c29baf7a4e77837a26b7f138f410e9d1883480ed5fa42411d522aba32040b577046c11f007388e\",\n    \"0xad1154142344f494e3061ef45a34fab1aaacf5fdf7d1b26adbb5fbc3d795655fa743444e39d9a4119b4a4f82a6f30441\",\n    \"0xb1d6c30771130c77806e7ab893b73d4deb590b2ff8f2f8b5e54c2040c1f3e060e2bd99afc668cf706a2df666a508bbf6\",\n    \"0xa00361fd440f9decabd98d96c575cd251dc94c60611025095d1201ef2dedde51cb4de7c2ece47732e5ed9b3526c2012c\",\n    \"0xa85c5ab4d17d328bda5e6d839a9a6adcc92ff844ec25f84981e4f44a0e8419247c081530f8d9aa629c7eb4ca21affba6\",\n    \"0xa4ddd3eab4527a2672cf9463db38bc29f61460e2a162f426b7852b7a7645fbd62084fd39a8e4d60e1958cce436dd8f57\",\n    \"0x811648140080fe55b8618f4cf17f3c5a250adb0cd53d885f2ddba835d2b4433188e41fc0661faac88e4ff910b16278c0\",\n    \"0xb85c7f1cfb0ed29addccf7546023a79249e8f15ac2d14a20accbfef4dd9dc11355d599815fa09d2b6b4e966e6ea8cff1\",\n    \"0xa10b5d8c260b159043b020d5dd62b3467df2671afea6d480ca9087b7e60ed170c82b121819d088315902842d66c8fb45\",\n    \"0x917e191df1bcf3f5715419c1e2191da6b8680543b1ba41fe84ed07ef570376e072c081beb67b375fca3565a2565bcabb\",\n    \"0x881fd967407390bfd7badc9ab494e8a287559a01eb07861f527207c127eadea626e9bcc5aa9cca2c5112fbac3b3f0e9c\",\n    \"0x959fd71149af82cc733619e0e5bf71760ca2650448c82984b3db74030d0e10f8ab1ce1609a6de6f470fe8b5bd90df5b3\",\n    \"0xa3370898a1c5f33d15adb4238df9a6c945f18b9ada4ce2624fc32a844f9ece4c916a64e9442225b6592afa06d2e015f2\",\n    \"0x817efb8a791435e4236f7d7b278181a5fa34587578c629dbc14fbf9a5c26772290611395eecd20222a4c58649fc256d8\",\n    \"0xa04c9876acf2cfdc8ef96de4879742709270fa1d03fe4c8511fbef2d59eb0aaf0336fa2c7dfe41a651157377fa217813\",\n    \"0x81e15875d7ea7f123e418edf14099f2e109d4f3a6ce0eb65f67fe9fb10d2f809a864a29f60ad3fc949f89e2596b21783\",\n    \"0xb49f529975c09e436e6bc202fdc16e3fdcbe056db45178016ad6fdece9faad4446343e83aed096209690b21a6910724f\",\n    \"0x879e8eda589e1a279f7f49f6dd0580788c040d973748ec4942dbe51ea8fbd05983cc919b78f0c6b92ef3292ae29db875\",\n    \"0x81a2b74b2118923f34139a102f3d95e7eee11c4c2929c2576dee200a5abfd364606158535a6c9e4178a6a83dbb65f3c4\",\n    \"0x8913f281d8927f2b45fc815d0f7104631cb7f5f7278a316f1327d670d15868daadd2a64e3eb98e1f53fe7e300338cc80\",\n    \"0xa6f815fba7ef9af7fbf45f93bc952e8b351f5de6568a27c7c47a00cb39a254c6b31753794f67940fc7d2e9cc581529f4\",\n    \"0xb3722a15c66a0014ce4d082de118def8d39190c15678a472b846225585f3a83756ae1b255b2e3f86a26168878e4773b2\",\n    \"0x817ae61ab3d0dd5b6e24846b5a5364b1a7dc2e77432d9fed587727520ae2f307264ea0948c91ad29f0aea3a11ff38624\",\n    \"0xb3db467464415fcad36dc1de2d6ba7686772a577cc2619242ac040d6734881a45d3b40ed4588db124e4289cfeec4bbf6\",\n    \"0xad66a14f5a54ac69603b16e5f1529851183da77d3cc60867f10aea41339dd5e06a5257982e9e90a352cdd32750f42ee4\",\n    \"0xadafa3681ef45d685555601a25a55cf23358319a17f61e2179e704f63df83a73bdd298d12cf6cef86db89bd17119e11d\",\n    \"0xa379dc44cb6dd3b9d378c07b2ec654fec7ca2f272de6ba895e3d00d20c9e4c5550498a843c8ac67e4221db2115bedc1c\",\n    \"0xb7bf81c267a78efc6b9e5a904574445a6487678d7ef70054e3e93ea6a23f966c2b68787f9164918e3b16d2175459ed92\",\n    \"0xb41d66a13a4afafd5760062b77f79de7e6ab8ccacde9c6c5116a6d886912fb491dc027af435b1b44aacc6af7b3c887f2\",\n    \"0x9904d23a7c1c1d2e4bab85d69f283eb0a8e26d46e8b7b30224438015c936729b2f0af7c7c54c03509bb0500acb42d8a4\",\n    \"0xae30d65e9e20c3bfd603994ae2b175ff691d51f3e24b2d058b3b8556d12ca4c75087809062dddd4aaac81c94d15d8a17\",\n    \"0x9245162fab42ac01527424f6013310c3eb462982518debef6c127f46ba8a06c705d7dc9f0a41e796ba8d35d60ae6cc64\",\n    \"0x87fab853638d7a29a20f3ba2b1a7919d023e9415bfa78ebb27973d8cbc7626f584dc5665d2e7ad71f1d760eba9700d88\",\n    \"0x85aac46ecd330608e5272430970e6081ff02a571e8ea444f1e11785ea798769634a22a142d0237f67b75369d3c484a8a\",\n    \"0x938c85ab14894cc5dfce3d80456f189a2e98eddbc8828f4ff6b1df1dcb7b42b17ca2ff40226a8a1390a95d63dca698dd\",\n    \"0xa18ce1f846e3e3c4d846822f60271eecf0f5d7d9f986385ac53c5ace9589dc7c0188910448c19b91341a1ef556652fa9\",\n    \"0x8611608a9d844f0e9d7584ad6ccf62a5087a64f764caf108db648a776b5390feb51e5120f0ef0e9e11301af3987dd7dc\",\n    \"0x8106333ba4b4de8d1ae43bc9735d3fea047392e88efd6a2fa6f7b924a18a7a265ca6123c3edc0f36307dd7fb7fe89257\",\n    \"0xa91426fa500951ff1b051a248c050b7139ca30dde8768690432d597d2b3c4357b11a577be6b455a1c5d145264dcf81fc\",\n    \"0xb7f9f90e0e450f37b081297f7f651bad0496a8b9afd2a4cf4120a2671aaaa8536dce1af301258bfbfdb122afa44c5048\",\n    \"0x84126da6435699b0c09fa4032dec73d1fca21d2d19f5214e8b0bea43267e9a8dd1fc44f8132d8315e734c8e2e04d7291\",\n    \"0xaff064708103884cb4f1a3c1718b3fc40a238d35cf0a7dc24bdf9823693b407c70da50df585bf5bc4e9c07d1c2d203e8\",\n    \"0xa8b40fc6533752983a5329c31d376c7a5c13ce6879cc7faee648200075d9cd273537001fb4c86e8576350eaac6ba60c2\",\n    \"0xa02db682bdc117a84dcb9312eb28fcbde12d49f4ce915cc92c610bb6965ec3cc38290f8c5b5ec70afe153956692cda95\",\n    \"0x86decd22b25d300508472c9ce75d3e465b737e7ce13bc0fcce32835e54646fe12322ba5bc457be18bfd926a1a6ca4a38\",\n    \"0xa18666ef65b8c2904fd598791f5627207165315a85ee01d5fb0e6b2e10bdd9b00babc447da5bd63445e3337de33b9b89\",\n    \"0x89bb0c06effadefdaf34ffe4b123e1678a90d4451ee856c863df1e752eef41fd984689ded8f0f878bf8916d5dd8e8024\",\n    \"0x97cfcba08ebec05d0073992a66b1d7d6fb9d95871f2cdc36db301f78bf8069294d1c259efef5c93d20dc937eedae3a1a\",\n    \"0xac2643b14ece79dcb2e289c96776a47e2bebd40dd6dc74fd035df5bb727b5596f40e3dd2d2202141e69b0993717ede09\",\n    \"0xa5e6fd88a2f9174d9bd4c6a55d9c30974be414992f22aa852f552c7648f722ed8077acf5aba030abd47939bb451b2c60\",\n    \"0x8ad40a612824a7994487731a40b311b7349038c841145865539c6ada75c56de6ac547a1c23df190e0caaafecddd80ccc\",\n    \"0x953a7cea1d857e09202c438c6108060961f195f88c32f0e012236d7a4b39d840c61b162ec86436e8c38567328bea0246\",\n    \"0x80d8b47a46dae1868a7b8ccfe7029445bbe1009dad4a6c31f9ef081be32e8e1ac1178c3c8fb68d3e536c84990cc035b1\",\n    \"0x81ecd99f22b3766ce0aca08a0a9191793f68c754fdec78b82a4c3bdc2db122bbb9ebfd02fc2dcc6e1567a7d42d0cc16a\",\n    \"0xb1dd0446bccc25846fb95d08c1c9cc52fb51c72c4c5d169ffde56ecfe800f108dc1106d65d5c5bd1087c656de3940b63\",\n    \"0xb87547f0931e164e96de5c550ca5aa81273648fe34f6e193cd9d69cf729cb432e17aa02e25b1c27a8a0d20a3b795e94e\",\n    \"0x820a94e69a927e077082aae66f6b292cfbe4589d932edf9e68e268c9bd3d71ef76cf7d169dd445b93967c25db11f58f1\",\n    \"0xb0d07ddf2595270c39adfa0c8cf2ab1322979b0546aa4d918f641be53cd97f36c879bb75d205e457c011aca3bbd9f731\",\n    \"0x8700b876b35b4b10a8a9372c5230acecd39539c1bb87515640293ad4464a9e02929d7d6a6a11112e8a29564815ac0de4\",\n    \"0xa61a601c5bb27dcb97e37c8e2b9ce479c6b192a5e04d9ed5e065833c5a1017ee5f237b77d1a17be5d48f8e7cc0bcacf6\",\n    \"0x92fb88fe774c1ba1d4a08cae3c0e05467ad610e7a3f1d2423fd47751759235fe0a3036db4095bd6404716aa03820f484\",\n    \"0xb274f140d77a3ce0796f5e09094b516537ccaf27ae1907099bff172e6368ba85e7c3ef8ea2a07457cac48ae334da95b3\",\n    \"0xb2292d9181f16581a9a9142490b2bdcdfb218ca6315d1effc8592100d792eb89d5356996c890441f04f2b4a95763503e\",\n    \"0x8897e73f576d86bc354baa3bd96e553107c48cf5889dcc23c5ba68ab8bcd4e81f27767be2233fdfa13d39f885087e668\",\n    \"0xa29eac6f0829791c728d71abc49569df95a4446ecbfc534b39f24f56c88fe70301838dfc1c19751e7f3c5c1b8c6af6a0\",\n    \"0x9346dc3720adc5df500a8df27fd9c75ef38dc5c8f4e8ed66983304750e66d502c3c59b8e955be781b670a0afc70a2167\",\n    \"0x9566d534e0e30a5c5f1428665590617e95fd05d45f573715f58157854ad596ece3a3cfec61356aee342308d623e029d5\",\n    \"0xa464fb8bffe6bd65f71938c1715c6e296cc6d0311a83858e4e7eb5873b7f2cf0c584d2101e3407b85b64ca78b2ac93ce\",\n    \"0xb54088f7217987c87e9498a747569ac5b2f8afd5348f9c45bf3fd9fbf713a20f495f49c8572d087efe778ac7313ad6d3\",\n    \"0x91fa9f5f8000fe050f5b224d90b59fcce13c77e903cbf98ded752e5b3db16adb2bc1f8c94be48b69f65f1f1ad81d6264\",\n    \"0x92d04a5b0ac5d8c8e313709b432c9434ecd3e73231f01e9b4e7952b87df60cbfa97b5dedd2200bd033b4b9ea8ba45cc1\",\n    \"0xa94b90ad3c3d6c4bbe169f8661a790c40645b40f0a9d1c7220f01cf7fc176e04d80bab0ced9323fcafb93643f12b2760\",\n    \"0x94d86149b9c8443b46196f7e5a3738206dd6f3be7762df488bcbb9f9ee285a64c997ed875b7b16b26604fa59020a8199\",\n    \"0x82efe4ae2c50a2d7645240c173a047f238536598c04a2c0b69c96e96bd18e075a99110f1206bc213f39edca42ba00cc1\",\n    \"0xab8667685f831bc14d4610f84a5da27b4ea5b133b4d991741a9e64dceb22cb64a3ce8f1b6e101d52af6296df7127c9ad\",\n    \"0x83ba433661c05dcc5d562f4a9a261c8110dac44b8d833ae1514b1fc60d8b4ee395b18804baea04cb10adb428faf713c3\",\n    \"0xb5748f6f660cc5277f1211d2b8649493ed8a11085b871cd33a5aea630abd960a740f08c08be5f9c21574600ac9bf5737\",\n    \"0xa5c8dd12af48fb710642ad65ebb97ca489e8206741807f7acfc334f8035d3c80593b1ff2090c9bb7bd138f0c48714ca8\",\n    \"0xa2b382fd5744e3babf454b1d806cc8783efeb4761bc42b6914ea48a46a2eae835efbe0a18262b6bc034379e03cf1262b\",\n    \"0xb3145ffaf603f69f15a64936d32e3219eea5ed49fdfd2f5bf40ea0dfd974b36fb6ff12164d4c2282d892db4cf3ff3ce1\",\n    \"0x87a316fb213f4c5e30c5e3face049db66be4f28821bd96034714ec23d3e97849d7b301930f90a4323c7ccf53de23050c\",\n    \"0xb9de09a919455070fed6220fc179c8b7a4c753062bcd27acf28f5b9947a659c0b364298daf7c85c4ca6fca7f945add1f\",\n    \"0x806fbd98d411b76979464c40ad88bc07a151628a27fcc1012ba1dfbaf5b5cc9d962fb9b3386008978a12515edce934bc\",\n    \"0xa15268877fae0d21610ae6a31061ed7c20814723385955fac09fdc9693a94c33dea11db98bb89fdfe68f933490f5c381\",\n    \"0x8d633fb0c4da86b2e0b37d8fad5972d62bff2ac663c5ec815d095cd4b7e1fe66ebef2a2590995b57eaf941983c7ad7a4\",\n    \"0x8139e5dd9cf405e8ef65f11164f0440827d98389ce1b418b0c9628be983a9ddd6cf4863036ccb1483b40b8a527acd9ed\",\n    \"0x88b15fa94a08eac291d2b94a2b30eb851ff24addf2cc30b678e72e32cfcb3424cf4b33aa395d741803f3e578ddf524de\",\n    \"0xb5eaf0c8506e101f1646bcf049ee38d99ea1c60169730da893fd6020fd00a289eb2f415947e44677af49e43454a7b1be\",\n    \"0x8489822ad0647a7e06aa2aa5595960811858ddd4542acca419dd2308a8c5477648f4dd969a6740bb78aa26db9bfcc555\",\n    \"0xb1e9a7b9f3423c220330d45f69e45fa03d7671897cf077f913c252e3e99c7b1b1cf6d30caad65e4228d5d7b80eb86e5e\",\n    \"0xb28fe9629592b9e6a55a1406903be76250b1c50c65296c10c5e48c64b539fb08fe11f68cf462a6edcbba71b0cee3feb2\",\n    \"0xa41acf96a02c96cd8744ff6577c244fc923810d17ade133587e4c223beb7b4d99fa56eae311a500d7151979267d0895c\",\n    \"0x880798938fe4ba70721be90e666dfb62fcab4f3556fdb7b0dc8ec5bc34f6b4513df965eae78527136eb391889fe2caf9\",\n    \"0x98d4d89d358e0fb7e212498c73447d94a83c1b66e98fc81427ab13acddb17a20f52308983f3a5a8e0aaacec432359604\",\n    \"0x81430b6d2998fc78ba937a1639c6020199c52da499f68109da227882dc26d005b73d54c5bdcac1a04e8356a8ca0f7017\",\n    \"0xa8d906a4786455eb74613aba4ce1c963c60095ffb8658d368df9266fdd01e30269ce10bf984e7465f34b4fd83beba26a\",\n    \"0xaf54167ac1f954d10131d44a8e0045df00d581dd9e93596a28d157543fbe5fb25d213806ed7fb3cba6b8f5b5423562db\",\n    \"0x8511e373a978a12d81266b9afbd55035d7bc736835cfa921903a92969eeba3624437d1346b55382e61415726ab84a448\",\n    \"0x8cf43eea93508ae586fa9a0f1354a1e16af659782479c2040874a46317f9e8d572a23238efa318fdfb87cc63932602b7\",\n    \"0xb0bdd3bacff077173d302e3a9678d1d37936188c7ecc34950185af6b462b7c679815176f3cce5db19aac8b282f2d60ad\",\n    \"0xa355e9b87f2f2672052f5d4d65b8c1c827d24d89b0d8594641fccfb69aef1b94009105f3242058bb31c8bf51caae5a41\",\n    \"0xb8baa9e4b950b72ff6b88a6509e8ed1304bc6fd955748b2e59a523a1e0c5e99f52aec3da7fa9ff407a7adf259652466c\",\n    \"0x840bc3dbb300ea6f27d1d6dd861f15680bd098be5174f45d6b75b094d0635aced539fa03ddbccb453879de77fb5d1fe9\",\n    \"0xb4bc7e7e30686303856472bae07e581a0c0bfc815657c479f9f5931cff208d5c12930d2fd1ff413ebd8424bcd7a9b571\",\n    \"0x89b5d514155d7999408334a50822508b9d689add55d44a240ff2bdde2eee419d117031f85e924e2a2c1ca77db9b91eea\",\n    \"0xa8604b6196f87a04e1350302e8aa745bba8dc162115d22657b37a1d1a98cb14876ddf7f65840b5dbd77e80cd22b4256c\",\n    \"0x83cb7acdb9e03247515bb2ce0227486ccf803426717a14510f0d59d45e998b245797d356f10abca94f7a14e1a2f0d552\",\n    \"0xaeb3266a9f16649210ab2df0e1908ac259f34ce1f01162c22b56cf1019096ee4ea5854c36e30bb2feb06c21a71e8a45c\",\n    \"0x89e72e86edf2aa032a0fc9acf4d876a40865fbb2c8f87cb7e4d88856295c4ac14583e874142fd0c314a49aba68c0aa3c\",\n    \"0x8c3576eba0583c2a7884976b4ed11fe1fda4f6c32f6385d96c47b0e776afa287503b397fa516a455b4b8c3afeedc76db\",\n    \"0xa31e5b633bda9ffa174654fee98b5d5930a691c3c42fcf55673d927dbc8d91c58c4e42e615353145431baa646e8bbb30\",\n    \"0x89f2f3f7a8da1544f24682f41c68114a8f78c86bd36b066e27da13acb70f18d9f548773a16bd8e24789420e17183f137\",\n    \"0xada27fa4e90a086240c9164544d2528621a415a5497badb79f8019dc3dce4d12eb6b599597e47ec6ac39c81efda43520\",\n    \"0x90dc1eb21bf21c0187f359566fc4bf5386abea52799306a0e5a1151c0817c5f5bc60c86e76b1929c092c0f3ff48cedd2\",\n    \"0xb702a53ebcc17ae35d2e735a347d2c700e9cbef8eadbece33cac83df483b2054c126593e1f462cfc00a3ce9d737e2af5\",\n    \"0x9891b06455ec925a6f8eafffba05af6a38cc5e193acaaf74ffbf199df912c5197106c5e06d72942bbb032ce277b6417f\",\n    \"0x8c0ee71eb01197b019275bcf96cae94e81d2cdc3115dbf2d8e3080074260318bc9303597e8f72b18f965ad601d31ec43\",\n    \"0x8aaf580aaf75c1b7a5f99ccf60503506e62058ef43b28b02f79b8536a96be3f019c9f71caf327b4e6730134730d1bef5\",\n    \"0xae6f9fc21dd7dfa672b25a87eb0a41644f7609fab5026d5cedb6e43a06dbbfd6d6e30322a2598c8dedde88c52eaed626\",\n    \"0x8159b953ffece5693edadb2e906ebf76ff080ee1ad22698950d2d3bfc36ac5ea78f58284b2ca180664452d55bd54716c\",\n    \"0xab7647c32ca5e9856ac283a2f86768d68de75ceeba9e58b74c5324f8298319e52183739aba4340be901699d66ac9eb3f\",\n    \"0xa4d85a5701d89bcfaf1572db83258d86a1a0717603d6f24ac2963ffcf80f1265e5ab376a4529ca504f4396498791253c\",\n    \"0x816080c0cdbfe61b4d726c305747a9eb58ac26d9a35f501dd32ba43c098082d20faf3ccd41aad24600aa73bfa453dfac\",\n    \"0x84f3afac024f576b0fd9acc6f2349c2fcefc3f77dbe5a2d4964d14b861b88e9b1810334b908cf3427d9b67a8aee74b18\",\n    \"0x94b390655557b1a09110018e9b5a14490681ade275bdc83510b6465a1218465260d9a7e2a6e4ec700f58c31dc3659962\",\n    \"0xa8c66826b1c04a2dd4c682543242e7a57acae37278bd09888a3d17747c5b5fec43548101e6f46d703638337e2fd3277b\",\n    \"0x86e6f4608a00007fa533c36a5b054c5768ccafe41ad52521d772dcae4c8a4bcaff8f7609be30d8fab62c5988cbbb6830\",\n    \"0x837da4cf09ae8aa0bceb16f8b3bfcc3b3367aecac9eed6b4b56d7b65f55981ef066490764fb4c108792623ecf8cad383\",\n    \"0x941ff3011462f9b5bf97d8cbdb0b6f5d37a1b1295b622f5485b7d69f2cb2bcabc83630dae427f0259d0d9539a77d8424\",\n    \"0xb99e5d6d82aa9cf7d5970e7f710f4039ac32c2077530e4c2779250c6b9b373bc380adb0a03b892b652f649720672fc8c\",\n    \"0xa791c78464b2d65a15440b699e1e30ebd08501d6f2720adbc8255d989a82fcded2f79819b5f8f201bed84a255211b141\",\n    \"0x84af7ad4a0e31fcbb3276ab1ad6171429cf39adcf78dc03750dc5deaa46536d15591e26d53e953dfb31e1622bc0743ab\",\n    \"0xa833e62fe97e1086fae1d4917fbaf09c345feb6bf1975b5cb863d8b66e8d621c7989ab3dbecda36bc9eaffc5eaa6fa66\",\n    \"0xb4ef79a46a2126f53e2ebe62770feb57fd94600be29459d70a77c5e9cc260fa892be06cd60f886bf48459e48eb50d063\",\n    \"0xb43b8f61919ea380bf151c294e54d3a3ff98e20d1ee5efbfe38aa2b66fafbc6a49739793bd5cb1c809f8b30466277c3a\",\n    \"0xab37735af2412d2550e62df9d8b3b5e6f467f20de3890bf56faf1abf2bf3bd1d98dc3fa0ad5e7ab3fce0fa20409eb392\",\n    \"0x82416b74b1551d484250d85bb151fabb67e29cce93d516125533df585bc80779ab057ea6992801a3d7d5c6dcff87a018\",\n    \"0x8145d0787f0e3b5325190ae10c1d6bee713e6765fb6a0e9214132c6f78f4582bb2771aaeae40d3dad4bafb56bf7e36d8\",\n    \"0xb6935886349ecbdd5774e12196f4275c97ec8279fdf28ccf940f6a022ebb6de8e97d6d2173c3fe402cbe9643bed3883b\",\n    \"0x87ef9b4d3dc71ac86369f8ed17e0dd3b91d16d14ae694bc21a35b5ae37211b043d0e36d8ff07dcc513fb9e6481a1f37f\",\n    \"0xae1d0ded32f7e6f1dc8fef495879c1d9e01826f449f903c1e5034aeeabc5479a9e323b162b688317d46d35a42d570d86\",\n    \"0xa40d16497004db4104c6794e2f4428d75bdf70352685944f3fbe17526df333e46a4ca6de55a4a48c02ecf0bde8ba03c0\",\n    \"0x8d45121efba8cc308a498e8ee39ea6fa5cae9fb2e4aab1c2ff9d448aa8494ccbec9a078f978a86fcd97b5d5e7be7522a\",\n    \"0xa8173865c64634ba4ac2fa432740f5c05056a9deaf6427cb9b4b8da94ca5ddbc8c0c5d3185a89b8b28878194de9cdfcd\",\n    \"0xb6ec06a74d690f6545f0f0efba236e63d1fdfba54639ca2617408e185177ece28901c457d02b849fd00f1a53ae319d0a\",\n    \"0xb69a12df293c014a40070e3e760169b6f3c627caf9e50b35a93f11ecf8df98b2bc481b410eecb7ab210bf213bbe944de\",\n    \"0x97e7dc121795a533d4224803e591eef3e9008bab16f12472210b73aaf77890cf6e3877e0139403a0d3003c12c8f45636\",\n    \"0xacdfa6fdd4a5acb7738cc8768f7cba84dbb95c639399b291ae8e4e63df37d2d4096900a84d2f0606bf534a9ccaa4993f\",\n    \"0x86ee253f3a9446a33e4d1169719b7d513c6b50730988415382faaf751988c10a421020609f7bcdef91be136704b906e2\",\n    \"0xaac9438382a856caf84c5a8a234282f71b5fc5f65219103b147e7e6cf565522285fbfd7417b513bdad8277a00f652ca1\",\n    \"0x83f3799d8e5772527930f5dc071a2e0a65471618993ec8990a96ccdeee65270e490bda9d26bb877612475268711ffd80\",\n    \"0x93f28a81ac8c0ec9450b9d762fae9c7f8feaace87a6ee6bd141ef1d2d0697ef1bbd159fe6e1de640dbdab2b0361fca8a\",\n    \"0xa0825c95ba69999b90eac3a31a3fd830ea4f4b2b7409bde5f202b61d741d6326852ce790f41de5cb0eccec7af4db30c1\",\n    \"0x83924b0e66233edd603c3b813d698daa05751fc34367120e3cf384ea7432e256ccee4d4daf13858950549d75a377107d\",\n    \"0x956fd9fa58345277e06ba2ec72f49ed230b8d3d4ff658555c52d6cddeb84dd4e36f1a614f5242d5ca0192e8daf0543c2\",\n    \"0x944869912476baae0b114cced4ff65c0e4c90136f73ece5656460626599051b78802df67d7201c55d52725a97f5f29fe\",\n    \"0x865cb25b64b4531fb6fe4814d7c8cd26b017a6c6b72232ff53defc18a80fe3b39511b23f9e4c6c7249d06e03b2282ed2\",\n    \"0x81e09ff55214960775e1e7f2758b9a6c4e4cd39edf7ec1adfaad51c52141182b79fe2176b23ddc7df9fd153e5f82d668\",\n    \"0xb31006896f02bc90641121083f43c3172b1039334501fbaf1672f7bf5d174ddd185f945adf1a9c6cf77be34c5501483d\",\n    \"0x88b92f6f42ae45e9f05b16e52852826e933efd0c68b0f2418ac90957fd018df661bc47c8d43c2a7d7bfcf669dab98c3c\",\n    \"0x92fc68f595853ee8683930751789b799f397135d002eda244fe63ecef2754e15849edde3ba2f0cc8b865c9777230b712\",\n    \"0x99ca06a49c5cd0bb097c447793fcdd809869b216a34c66c78c7e41e8c22f05d09168d46b8b1f3390db9452d91bc96dea\",\n    \"0xb48b9490a5d65296802431852d548d81047bbefc74fa7dc1d4e2a2878faacdfcb365ae59209cb0ade01901a283cbd15d\",\n    \"0xaff0fdbef7c188b120a02bc9085d7b808e88f73973773fef54707bf2cd772cd066740b1b6f4127b5c349f657bd97e738\",\n    \"0x966fd4463b4f43dd8ccba7ad50baa42292f9f8b2e70da23bb6780e14155d9346e275ef03ddaf79e47020dcf43f3738bd\",\n    \"0x9330c3e1fadd9e08ac85f4839121ae20bbeb0a5103d84fa5aadbd1213805bdcda67bf2fb75fc301349cbc851b5559d20\",\n    \"0x993bb99867bd9041a71a55ad5d397755cfa7ab6a4618fc526179bfc10b7dc8b26e4372fe9a9b4a15d64f2b63c1052dda\",\n    \"0xa29b59bcfab51f9b3c490a3b96f0bf1934265c315349b236012adbd64a56d7f6941b2c8cc272b412044bc7731f71e1dc\",\n    \"0xa65c9cefe1fc35d089fe8580c2e7671ebefdb43014ac291528ff4deefd4883fd4df274af83711dad610dad0d615f9d65\",\n    \"0x944c78c56fb227ae632805d448ca3884cd3d2a89181cead3d2b7835e63297e6d740aa79a112edb1d4727824991636df5\",\n    \"0xa73d782da1db7e4e65d7b26717a76e16dd9fab4df65063310b8e917dc0bc24e0d6755df5546c58504d04d9e68c3b474a\",\n    \"0xaf80f0b87811ae3124f68108b4ca1937009403f87928bbc53480e7c5408d072053ace5eeaf5a5aba814dab8a45502085\",\n    \"0x88aaf1acfc6e2e19b8387c97da707cb171c69812fefdd4650468e9b2c627bd5ccfb459f4d8e56bdfd84b09ddf87e128f\",\n    \"0x92c97276ff6f72bab6e9423d02ad6dc127962dbce15a0dd1e4a393b4510c555df6aa27be0f697c0d847033a9ca8b8dfd\",\n    \"0xa0e07d43d96e2d85b6276b3c60aadb48f0aedf2de8c415756dc597249ea64d2093731d8735231dadc961e5682ac59479\",\n    \"0xadc9e6718a8f9298957d1da3842a7751c5399bbdf56f8de6c1c4bc39428f4aee6f1ba6613d37bf46b9403345e9d6fc81\",\n    \"0x951da434da4b20d949b509ceeba02e24da7ed2da964c2fcdf426ec787779c696b385822c7dbea4df3e4a35921f1e912c\",\n    \"0xa04cbce0d2b2e87bbf038c798a12ec828423ca6aca08dc8d481cf6466e3c9c73d4d4a7fa47df9a7e2e15aae9e9f67208\",\n    \"0x8f855cca2e440d248121c0469de1f94c2a71b8ee2682bbad3a78243a9e03da31d1925e6760dbc48a1957e040fae9abe8\",\n    \"0xb642e5b17c1df4a4e101772d73851180b3a92e9e8b26c918050f51e6dd3592f102d20b0a1e96f0e25752c292f4c903ff\",\n    \"0xa92454c300781f8ae1766dbbb50a96192da7d48ef4cbdd72dd8cbb44c6eb5913c112cc38e9144615fdc03684deb99420\",\n    \"0x8b74f7e6c2304f8e780df4649ef8221795dfe85fdbdaa477a1542d135b75c8be45bf89adbbb6f3ddf54ca40f02e733e9\",\n    \"0x85cf66292cbb30cec5fd835ab10c9fcb3aea95e093aebf123e9a83c26f322d76ebc89c4e914524f6c5f6ee7d74fc917d\",\n    \"0xae0bfe0cdc97c09542a7431820015f2d16067b30dca56288013876025e81daa8c519e5e347268e19aa1a85fa1dc28793\",\n    \"0x921322fc6a47dc091afa0ad6df18ed14cde38e48c6e71550aa513918b056044983aee402de21051235eecf4ce8040fbe\",\n    \"0x96c030381e97050a45a318d307dcb3c8377b79b4dd5daf6337cded114de26eb725c14171b9b8e1b3c08fe1f5ea6b49e0\",\n    \"0x90c23b86b6111818c8baaf53a13eaee1c89203b50e7f9a994bf0edf851919b48edbac7ceef14ac9414cf70c486174a77\",\n    \"0x8bf6c301240d2d1c8d84c71d33a6dfc6d9e8f1cfae66d4d0f7a256d98ae12b0bcebfa94a667735ee89f810bcd7170cff\",\n    \"0xa41a4ffbbea0e36874d65c009ee4c3feffff322f6fc0e30d26ee4dbc1f46040d05e25d9d0ecb378cef0d24a7c2c4b850\",\n    \"0xa8d4cdd423986bb392a0a92c12a8bd4da3437eec6ef6af34cf5310944899287452a2eb92eb5386086d5063381189d10e\",\n    \"0xa81dd26ec057c4032a4ed7ad54d926165273ed51d09a1267b2e477535cf6966835a257c209e4e92d165d74fa75695fa3\",\n    \"0x8d7f708c3ee8449515d94fc26b547303b53d8dd55f177bc3b25d3da2768accd9bc8e9f09546090ebb7f15c66e6c9c723\",\n    \"0x839ba65cffcd24cfffa7ab3b21faabe3c66d4c06324f07b2729c92f15cad34e474b0f0ddb16cd652870b26a756b731d3\",\n    \"0x87f1a3968afec354d92d77e2726b702847c6afcabb8438634f9c6f7766de4c1504317dc4fa9a4a735acdbf985e119564\",\n    \"0x91a8a7fd6542f3e0673f07f510d850864b34ac087eb7eef8845a1d14b2b1b651cbdc27fa4049bdbf3fea54221c5c8549\",\n    \"0xaef3cf5f5e3a2385ead115728d7059e622146c3457d266c612e778324b6e06fbfb8f98e076624d2f3ce1035d65389a07\",\n    \"0x819915d6232e95ccd7693fdd78d00492299b1983bc8f96a08dcb50f9c0a813ed93ae53c0238345d5bea0beda2855a913\",\n    \"0x8e9ba68ded0e94935131b392b28218315a185f63bf5e3c1a9a9dd470944509ca0ba8f6122265f8da851b5cc2abce68f1\",\n    \"0xb28468e9b04ee9d69003399a3cf4457c9bf9d59f36ab6ceeb8e964672433d06b58beeea198fedc7edbaa1948577e9fa2\",\n    \"0xa633005e2c9f2fd94c8bce2dd5bb708fe946b25f1ec561ae65e54e15cdd88dc339f1a083e01f0d39610c8fe24151aaf0\",\n    \"0x841d0031e22723f9328dd993805abd13e0c99b0f59435d2426246996b08d00ce73ab906f66c4eab423473b409e972ce0\",\n    \"0x85758d1b084263992070ec8943f33073a2d9b86a8606672550c17545507a5b3c88d87382b41916a87ee96ff55a7aa535\",\n    \"0x8581b06b0fc41466ef94a76a1d9fb8ae0edca6d018063acf6a8ca5f4b02d76021902feba58972415691b4bdbc33ae3b4\",\n    \"0x83539597ff5e327357ee62bc6bf8c0bcaec2f227c55c7c385a4806f0d37fb461f1690bad5066b8a5370950af32fafbef\",\n    \"0xaee3557290d2dc10827e4791d00e0259006911f3f3fce4179ed3c514b779160613eca70f720bff7804752715a1266ffa\",\n    \"0xb48d2f0c4e90fc307d5995464e3f611a9b0ef5fe426a289071f4168ed5cc4f8770c9332960c2ca5c8c427f40e6bb389f\",\n    \"0x847af8973b4e300bb06be69b71b96183fd1a0b9d51b91701bef6fcfde465068f1eb2b1503b07afda380f18d69de5c9e1\",\n    \"0xa70a6a80ce407f07804c0051ac21dc24d794b387be94eb24e1db94b58a78e1bcfb48cd0006db8fc1f9bedaece7a44fbe\",\n    \"0xb40e942b8fa5336910ff0098347df716bff9d1fa236a1950c16eeb966b3bc1a50b8f7b0980469d42e75ae13ced53cead\",\n    \"0xb208fabaa742d7db3148515330eb7a3577487845abdb7bd9ed169d0e081db0a5816595c33d375e56aeac5b51e60e49d3\",\n    \"0xb7c8194b30d3d6ef5ab66ec88ad7ebbc732a3b8a41731b153e6f63759a93f3f4a537eab9ad369705bd730184bdbbdc34\",\n    \"0x9280096445fe7394d04aa1bc4620c8f9296e991cc4d6c131bd703cb1cc317510e6e5855ac763f4d958c5edfe7eebeed7\",\n    \"0xabc2aa4616a521400af1a12440dc544e3c821313d0ab936c86af28468ef8bbe534837e364598396a81cf8d06274ed5a6\",\n    \"0xb18ca8a3325adb0c8c18a666d4859535397a1c3fe08f95eebfac916a7a99bbd40b3c37b919e8a8ae91da38bc00fa56c0\",\n    \"0x8a40c33109ecea2a8b3558565877082f79121a432c45ec2c5a5e0ec4d1c203a6788e6b69cb37f1fd5b8c9a661bc5476d\",\n    \"0x88c47301dd30998e903c84e0b0f2c9af2e1ce6b9f187dab03528d44f834dc991e4c86d0c474a2c63468cf4020a1e24a0\",\n    \"0x920c832853e6ab4c851eecfa9c11d3acc7da37c823be7aa1ab15e14dfd8beb5d0b91d62a30cec94763bd8e4594b66600\",\n    \"0x98e1addbe2a6b8edc7f12ecb9be81c3250aeeca54a1c6a7225772ca66549827c15f3950d01b8eb44aecb56fe0fff901a\",\n    \"0x8cfb0fa1068be0ec088402f5950c4679a2eb9218c729da67050b0d1b2d7079f3ddf4bf0f57d95fe2a8db04bc6bcdb20c\",\n    \"0xb70f381aafe336b024120453813aeab70baac85b9c4c0f86918797b6aee206e6ed93244a49950f3d8ec9f81f4ac15808\",\n    \"0xa4c8edf4aa33b709a91e1062939512419711c1757084e46f8f4b7ed64f8e682f4e78b7135920c12f0eb0422fe9f87a6a\",\n    \"0xb4817e85fd0752d7ebb662d3a51a03367a84bac74ebddfba0e5af5e636a979500f72b148052d333b3dedf9edd2b4031b\",\n    \"0xa87430169c6195f5d3e314ff2d1c2f050e766fd5d2de88f5207d72dba4a7745bb86d0baca6e9ae156582d0d89e5838c7\",\n    \"0x991b00f8b104566b63a12af4826b61ce7aa40f4e5b8fff3085e7a99815bdb4471b6214da1e480214fac83f86a0b93cc5\",\n    \"0xb39966e3076482079de0678477df98578377a094054960ee518ef99504d6851f8bcd3203e8da5e1d4f6f96776e1fe6eb\",\n    \"0xa448846d9dc2ab7a0995fa44b8527e27f6b3b74c6e03e95edb64e6baa4f1b866103f0addb97c84bef1d72487b2e21796\",\n    \"0x894bec21a453ae84b592286e696c35bc30e820e9c2fd3e63dd4fbe629e07df16439c891056070faa490155f255bf7187\",\n    \"0xa9ec652a491b11f6a692064e955f3f3287e7d2764527e58938571469a1e29b5225b9415bd602a45074dfbfe9c131d6ca\",\n    \"0xb39d37822e6cbe28244b5f42ce467c65a23765bd16eb6447c5b3e942278069793763483dafd8c4dd864f8917aad357fe\",\n    \"0x88dba51133f2019cb266641c56101e3e5987d3b77647a2e608b5ff9113dfc5f85e2b7c365118723131fbc0c9ca833c9c\",\n    \"0xb566579d904b54ecf798018efcb824dccbebfc6753a0fd2128ac3b4bd3b038c2284a7c782b5ca6f310eb7ea4d26a3f0a\",\n    \"0xa97a55c0a492e53c047e7d6f9d5f3e86fb96f3dddc68389c0561515343b66b4bc02a9c0d5722dff1e3445308240b27f7\",\n    \"0xa044028ab4bcb9e1a2b9b4ca4efbf04c5da9e4bf2fff0e8bd57aa1fc12a71e897999c25d9117413faf2f45395dee0f13\",\n    \"0xa78dc461decbeaeed8ebd0909369b491a5e764d6a5645a7dac61d3140d7dc0062526f777b0eb866bff27608429ebbdde\",\n    \"0xb2c2a8991f94c39ca35fea59f01a92cb3393e0eccb2476dfbf57261d406a68bd34a6cff33ed80209991688c183609ef4\",\n    \"0x84189eefb521aff730a4fd3fd5b10ddfd29f0d365664caef63bb015d07e689989e54c33c2141dd64427805d37a7e546e\",\n    \"0x85ac80bd734a52235da288ff042dea9a62e085928954e8eacd2c751013f61904ed110e5b3afe1ab770a7e6485efb7b5e\",\n    \"0x9183a560393dcb22d0d5063e71182020d0fbabb39e32493eeffeb808df084aa243eb397027f150b55a247d1ed0c8513e\",\n    \"0x81c940944df7ecc58d3c43c34996852c3c7915ed185d7654627f7af62abae7e0048dd444a6c09961756455000bd96d09\",\n    \"0xaa8c34e164019743fd8284b84f06c3b449aae7996e892f419ee55d82ad548cb300fd651de329da0384243954c0ef6a60\",\n    \"0x89a7b7bdfc7e300d06a14d463e573d6296d8e66197491900cc9ae49504c4809ff6e61b758579e9091c61085ba1237b83\",\n    \"0x878d21809ba540f50bd11f4c4d9590fb6f3ab9de5692606e6e2ef4ed9d18520119e385be5e1f4b3f2e2b09c319f0e8fc\",\n    \"0x8eb248390193189cf0355365e630b782cd15751e672dc478b39d75dc681234dcd9309df0d11f4610dbb249c1e6be7ef9\",\n    \"0xa1d7fb3aecb896df3a52d6bd0943838b13f1bd039c936d76d03de2044c371d48865694b6f532393b27fd10a4cf642061\",\n    \"0xa34bca58a24979be442238cbb5ece5bee51ae8c0794dd3efb3983d4db713bc6f28a96e976ac3bd9a551d3ed9ba6b3e22\",\n    \"0x817c608fc8cacdd178665320b5a7587ca21df8bdd761833c3018b967575d25e3951cf3d498a63619a3cd2ad4406f5f28\",\n    \"0x86c95707db0495689afd0c2e39e97f445f7ca0edffad5c8b4cacd1421f2f3cc55049dfd504f728f91534e20383955582\",\n    \"0x99c3b0bb15942c301137765d4e19502f65806f3b126dc01a5b7820c87e8979bce6a37289a8f6a4c1e4637227ad5bf3bf\",\n    \"0x8aa1518a80ea8b074505a9b3f96829f5d4afa55a30efe7b4de4e5dbf666897fdd2cf31728ca45921e21a78a80f0e0f10\",\n    \"0x8d74f46361c79e15128ac399e958a91067ef4cec8983408775a87eca1eed5b7dcbf0ddf30e66f51780457413496c7f07\",\n    \"0xa41cde4a786b55387458a1db95171aca4fd146507b81c4da1e6d6e495527c3ec83fc42fad1dfe3d92744084a664fd431\",\n    \"0x8c352852c906fae99413a84ad11701f93f292fbf7bd14738814f4c4ceab32db02feb5eb70bc73898b0bc724a39d5d017\",\n    \"0xa5993046e8f23b71ba87b7caa7ace2d9023fb48ce4c51838813174880d918e9b4d2b0dc21a2b9c6f612338c31a289df8\",\n    \"0x83576d3324bf2d8afbfb6eaecdc5d767c8e22e7d25160414924f0645491df60541948a05e1f4202e612368e78675de8a\",\n    \"0xb43749b8df4b15bc9a3697e0f1c518e6b04114171739ef1a0c9c65185d8ec18e40e6954d125cbc14ebc652cf41ad3109\",\n    \"0xb4eebd5d80a7327a040cafb9ccdb12b2dfe1aa86e6bc6d3ac8a57fadfb95a5b1a7332c66318ff72ba459f525668af056\",\n    \"0x9198be7f1d413c5029b0e1c617bcbc082d21abe2c60ec8ce9b54ca1a85d3dba637b72fda39dae0c0ae40d047eab9f55a\",\n    \"0x8d96a0232832e24d45092653e781e7a9c9520766c3989e67bbe86b3a820c4bf621ea911e7cd5270a4bfea78b618411f6\",\n    \"0x8d7160d0ea98161a2d14d46ef01dff72d566c330cd4fabd27654d300e1bc7644c68dc8eabf2a20a59bfe7ba276545f9b\",\n    \"0xabb60fce29dec7ba37e3056e412e0ec3e05538a1fc0e2c68877378c867605966108bc5742585ab6a405ce0c962b285b6\",\n    \"0x8fabffa3ed792f05e414f5839386f6449fd9f7b41a47595c5d71074bd1bb3784cc7a1a7e1ad6b041b455035957e5b2dc\",\n    \"0x90ff017b4804c2d0533b72461436b10603ab13a55f86fd4ec11b06a70ef8166f958c110519ca1b4cc7beba440729fe2d\",\n    \"0xb340cfd120f6a4623e3a74cf8c32bfd7cd61a280b59dfd17b15ca8fae4d82f64a6f15fbde4c02f424debc72b7db5fe67\",\n    \"0x871311c9c7220c932e738d59f0ecc67a34356d1429fe570ca503d340c9996cb5ee2cd188fad0e3bd16e4c468ec1dbebd\",\n    \"0xa772470262186e7b94239ba921b29f2412c148d6f97c4412e96d21e55f3be73f992f1ad53c71008f0558ec3f84e2b5a7\",\n    \"0xb2a897dcb7ffd6257f3f2947ec966f2077d57d5191a88840b1d4f67effebe8c436641be85524d0a21be734c63ab5965d\",\n    \"0xa044f6eacc48a4a061fa149500d96b48cbf14853469aa4d045faf3dca973be1bd4b4ce01646d83e2f24f7c486d03205d\",\n    \"0x981af5dc2daa73f7fa9eae35a93d81eb6edba4a7f673b55d41f6ecd87a37685d31bb40ef4f1c469b3d72f2f18b925a17\",\n    \"0x912d2597a07864de9020ac77083eff2f15ceb07600f15755aba61251e8ce3c905a758453b417f04d9c38db040954eb65\",\n    \"0x9642b7f6f09394ba5e0805734ef6702c3eddf9eea187ba98c676d5bbaec0e360e3e51dc58433aaa1e2da6060c8659cb7\",\n    \"0x8ab3836e0a8ac492d5e707d056310c4c8e0489ca85eb771bff35ba1d658360084e836a6f51bb990f9e3d2d9aeb18fbb5\",\n    \"0x879e058e72b73bb1f4642c21ffdb90544b846868139c6511f299aafe59c2d0f0b944dffc7990491b7c4edcd6a9889250\",\n    \"0xb9e60b737023f61479a4a8fd253ed0d2a944ea6ba0439bbc0a0d3abf09b0ad1f18d75555e4a50405470ae4990626f390\",\n    \"0xb9c2535d362796dcd673640a9fa2ebdaec274e6f8b850b023153b0a7a30fffc87f96e0b72696f647ebe7ab63099a6963\",\n    \"0x94aeff145386a087b0e91e68a84a5ede01f978f9dd9fe7bebca78941938469495dc30a96bba9508c0d017873aeea9610\",\n    \"0x98b179f8a3d9f0d0a983c30682dd425a2ddc7803be59bd626c623c8951a5179117d1d2a68254c95c9952989877d0ee55\",\n    \"0x889ecf5f0ee56938273f74eb3e9ecfb5617f04fb58e83fe4c0e4aef51615cf345bc56f3f61b17f6eed3249d4afd54451\",\n    \"0xa0f2b2c39bcea4b50883e2587d16559e246248a66ecb4a4b7d9ab3b51fb39fe98d83765e087eee37a0f86b0ba4144c02\",\n    \"0xb2a61e247ed595e8a3830f7973b07079cbda510f28ad8c78c220b26cb6acde4fbb5ee90c14a665f329168ee951b08cf0\",\n    \"0x95bd0fcfb42f0d6d8a8e73d7458498a85bcddd2fb132fd7989265648d82ac2707d6d203fac045504977af4f0a2aca4b7\",\n    \"0x843e5a537c298666e6cf50fcc044f13506499ef83c802e719ff2c90e85003c132024e04711be7234c04d4b0125512d5d\",\n    \"0xa46d1797c5959dcd3a5cfc857488f4d96f74277c3d13b98b133620192f79944abcb3a361d939a100187f1b0856eae875\",\n    \"0xa1c7786736d6707a48515c38660615fcec67eb8a2598f46657855215f804fd72ab122d17f94fcffad8893f3be658dca7\",\n    \"0xb23dc9e610abc7d8bd21d147e22509a0fa49db5be6ea7057b51aae38e31654b3aa044df05b94b718153361371ba2f622\",\n    \"0xb00cc8f257d659c22d30e6d641f79166b1e752ea8606f558e4cad6fc01532e8319ea4ee12265ba4140ac45aa4613c004\",\n    \"0xac7019af65221b0cc736287b32d7f1a3561405715ba9a6a122342e04e51637ba911c41573de53e4781f2230fdcb2475f\",\n    \"0x81a630bc41b3da8b3eb4bf56cba10cd9f93153c3667f009dc332287baeb707d505fb537e6233c8e53d299ec0f013290c\",\n    \"0xa6b7aea5c545bb76df0f230548539db92bc26642572cb7dd3d5a30edca2b4c386f44fc8466f056b42de2a452b81aff5b\",\n    \"0x8271624ff736b7b238e43943c81de80a1612207d32036d820c11fc830c737972ccc9c60d3c2359922b06652311e3c994\",\n    \"0x8a684106458cb6f4db478170b9ad595d4b54c18bf63b9058f095a2fa1b928c15101472c70c648873d5887880059ed402\",\n    \"0xa5cc3c35228122f410184e4326cf61a37637206e589fcd245cb5d0cec91031f8f7586b80503070840fdfd8ce75d3c88b\",\n    \"0x9443fc631aed8866a7ed220890911057a1f56b0afe0ba15f0a0e295ab97f604b134b1ed9a4245e46ee5f9a93aa74f731\",\n    \"0x984b6f7d79835dffde9558c6bb912d992ca1180a2361757bdba4a7b69dc74b056e303adc69fe67414495dd9c2dd91e64\",\n    \"0xb15a5c8cba5de080224c274d31c68ed72d2a7126d347796569aef0c4e97ed084afe3da4d4b590b9dda1a07f0c2ff3dfb\",\n    \"0x991708fe9650a1f9a4e43938b91d45dc68c230e05ee999c95dbff3bf79b1c1b2bb0e7977de454237c355a73b8438b1d9\",\n    \"0xb4f7edc7468b176a4a7c0273700c444fa95c726af6697028bed4f77eee887e3400f9c42ee15b782c0ca861c4c3b8c98a\",\n    \"0x8c60dcc16c51087eb477c13e837031d6c6a3dc2b8bf8cb43c23f48006bc7173151807e866ead2234b460c2de93b31956\",\n    \"0x83ad63e9c910d1fc44bc114accfb0d4d333b7ebe032f73f62d25d3e172c029d5e34a1c9d547273bf6c0fead5c8801007\",\n    \"0x85de73213cc236f00777560756bdbf2b16841ba4b55902cf2cad9742ecaf5d28209b012ceb41f337456dfeca93010cd7\",\n    \"0xa7561f8827ccd75b6686ba5398bb8fc3083351c55a589b18984e186820af7e275af04bcd4c28e1dc11be1e8617a0610b\",\n    \"0x88c0a4febd4068850557f497ea888035c7fc9f404f6cc7794e7cc8722f048ad2f249e7dc62743e7a339eb7473ad3b0cd\",\n    \"0x932b22b1d3e6d5a6409c34980d176feb85ada1bf94332ef5c9fc4d42b907dabea608ceef9b5595ef3feee195151f18d8\",\n    \"0xa2867bb3f5ab88fbdae3a16c9143ab8a8f4f476a2643c505bb9f37e5b1fd34d216cab2204c9a017a5a67b7ad2dda10e8\",\n    \"0xb573d5f38e4e9e8a3a6fd82f0880dc049efa492a946d00283019bf1d5e5516464cf87039e80aef667cb86fdea5075904\",\n    \"0xb948f1b5ab755f3f5f36af27d94f503b070696d793b1240c1bdfd2e8e56890d69e6904688b5f8ff5a4bdf5a6abfe195f\",\n    \"0x917eae95ebc4109a2e99ddd8fec7881d2f7aaa0e25fda44dec7ce37458c2ee832f1829db7d2dcfa4ca0f06381c7fe91d\",\n    \"0x95751d17ed00a3030bce909333799bb7f4ab641acf585807f355b51d6976dceee410798026a1a004ef4dcdff7ec0f5b8\",\n    \"0xb9b7bd266f449a79bbfe075e429613e76c5a42ac61f01c8f0bbbd34669650682efe01ff9dbbc400a1e995616af6aa278\",\n    \"0xac1722d097ce9cd7617161f8ec8c23d68f1fb1c9ca533e2a8b4f78516c2fd8fb38f23f834e2b9a03bb06a9d655693ca9\",\n    \"0xa7ad9e96ffd98db2ecdb6340c5d592614f3c159abfd832fe27ee9293519d213a578e6246aae51672ee353e3296858873\",\n    \"0x989b8814d5de7937c4acafd000eec2b4cd58ba395d7b25f98cafd021e8efa37029b29ad8303a1f6867923f5852a220eb\",\n    \"0xa5bfe6282c771bc9e453e964042d44eff4098decacb89aecd3be662ea5b74506e1357ab26f3527110ba377711f3c9f41\",\n    \"0x8900a7470b656639721d2abbb7b06af0ac4222ab85a1976386e2a62eb4b88bfb5b72cf7921ddb3cf3a395d7eeb192a2e\",\n    \"0x95a71b55cd1f35a438cf5e75f8ff11c5ec6a2ebf2e4dba172f50bfad7d6d5dca5de1b1afc541662c81c858f7604c1163\",\n    \"0x82b5d62fea8db8d85c5bc3a76d68dedd25794cf14d4a7bc368938ffca9e09f7e598fdad2a5aac614e0e52f8112ae62b9\",\n    \"0x997173f07c729202afcde3028fa7f52cefc90fda2d0c8ac2b58154a5073140683e54c49ed1f254481070d119ce0ce02a\",\n    \"0xaeffb91ccc7a72bbd6ffe0f9b99c9e66e67d59cec2e02440465e9636a613ab3017278cfa72ea8bc4aba9a8dc728cb367\",\n    \"0x952743b06e8645894aeb6440fc7a5f62dd3acf96dab70a51e20176762c9751ea5f2ba0b9497ccf0114dc4892dc606031\",\n    \"0x874c63baeddc56fbbca2ff6031f8634b745f6e34ea6791d7c439201aee8f08ef5ee75f7778700a647f3b21068513fce6\",\n    \"0x85128fec9c750c1071edfb15586435cc2f317e3e9a175bb8a9697bcda1eb9375478cf25d01e7fed113483b28f625122d\",\n    \"0x85522c9576fd9763e32af8495ae3928ed7116fb70d4378448926bc9790e8a8d08f98cf47648d7da1b6e40d6a210c7924\",\n    \"0x97d0f37a13cfb723b848099ca1c14d83e9aaf2f7aeb71829180e664b7968632a08f6a85f557d74b55afe6242f2a36e7c\",\n    \"0xabaa472d6ad61a5fccd1a57c01aa1bc081253f95abbcba7f73923f1f11c4e79b904263890eeb66926de3e2652f5d1c70\",\n    \"0xb3c04945ba727a141e5e8aec2bf9aa3772b64d8fd0e2a2b07f3a91106a95cbcb249adcd074cbe498caf76fffac20d4ef\",\n    \"0x82c46781a3d730d9931bcabd7434a9171372dde57171b6180e5516d4e68db8b23495c8ac3ab96994c17ddb1cf249b9fb\",\n    \"0xa202d8b65613c42d01738ccd68ed8c2dbc021631f602d53f751966e04182743ebc8e0747d600b8a8676b1da9ae7f11ab\",\n    \"0xae73e7256e9459db04667a899e0d3ea5255211fb486d084e6550b6dd64ca44af6c6b2d59d7aa152de9f96ce9b58d940d\",\n    \"0xb67d87b176a9722945ec7593777ee461809861c6cfd1b945dde9ee4ff009ca4f19cf88f4bbb5c80c9cbab2fe25b23ac8\",\n    \"0x8f0b7a317a076758b0dac79959ee4a06c08b07d0f10538a4b53d3da2eda16e2af26922feb32c090330dc4d969cf69bd3\",\n    \"0x90b36bf56adbd8c4b6cb32febc3a8d5f714370c2ac3305c10fa6d168dffb2a026804517215f9a2d4ec8310cdb6bb459b\",\n    \"0xaa80c19b0682ead69934bf18cf476291a0beddd8ef4ed75975d0a472e2ab5c70f119722a8574ae4973aceb733d312e57\",\n    \"0xa3fc9abb12574e5c28dcb51750b4339b794b8e558675eef7d26126edf1de920c35e992333bcbffcbf6a5f5c0d383ce62\",\n    \"0xa1573ff23ab972acdcd08818853b111fc757fdd35aa070186d3e11e56b172fb49d840bf297ac0dd222e072fc09f26a81\",\n    \"0x98306f2be4caa92c2b4392212d0cbf430b409b19ff7d5b899986613bd0e762c909fc01999aa94be3bd529d67f0113d7f\",\n    \"0x8c1fc42482a0819074241746d17dc89c0304a2acdae8ed91b5009e9e3e70ff725ba063b4a3e68fdce05b74f5180c545e\",\n    \"0xa6c6113ebf72d8cf3163b2b8d7f3fa24303b13f55752522c660a98cd834d85d8c79214d900fa649499365e2e7641f77a\",\n    \"0xab95eea424f8a2cfd9fb1c78bb724e5b1d71a0d0d1e4217c5d0f98b0d8bbd3f8400a2002abc0a0e4576d1f93f46fefad\",\n    \"0x823c5a4fd8cf4a75fdc71d5f2dd511b6c0f189b82affeacd2b7cfcad8ad1a5551227dcc9bfdb2e34b2097eaa00efbb51\",\n    \"0xb97314dfff36d80c46b53d87a61b0e124dc94018a0bb680c32765b9a2d457f833a7c42bbc90b3b1520c33a182580398d\",\n    \"0xb17566ee3dcc6bb3b004afe4c0136dfe7dd27df9045ae896dca49fb36987501ae069eb745af81ba3fc19ff037e7b1406\",\n    \"0xb0bdc0f55cfd98d331e3a0c4fbb776a131936c3c47c6bffdc3aaf7d8c9fa6803fbc122c2fefbb532e634228687d52174\",\n    \"0xaa5d9e60cc9f0598559c28bb9bdd52aa46605ab4ffe3d192ba982398e72cec9a2a44c0d0d938ce69935693cabc0887ea\",\n    \"0x802b6459d2354fa1d56c592ac1346c428dadea6b6c0a87bf7d309bab55c94e1cf31dd98a7a86bd92a840dd51f218b91b\",\n    \"0xa526914efdc190381bf1a73dd33f392ecf01350b9d3f4ae96b1b1c3d1d064721c7d6eec5788162c933245a3943f5ee51\",\n    \"0xb3b8fcf637d8d6628620a1a99dbe619eabb3e5c7ce930d6efd2197e261bf394b74d4e5c26b96c4b8009c7e523ccfd082\",\n    \"0x8f7510c732502a93e095aba744535f3928f893f188adc5b16008385fb9e80f695d0435bfc5b91cdad4537e87e9d2551c\",\n    \"0x97b90beaa56aa936c3ca45698f79273a68dd3ccd0076eab48d2a4db01782665e63f33c25751c1f2e070f4d1a8525bf96\",\n    \"0xb9fb798324b1d1283fdc3e48288e3861a5449b2ab5e884b34ebb8f740225324af86e4711da6b5cc8361c1db15466602f\",\n    \"0xb6d52b53cea98f1d1d4c9a759c25bf9d8a50b604b144e4912acbdbdc32aab8b9dbb10d64a29aa33a4f502121a6fb481c\",\n    \"0x9174ffff0f2930fc228f0e539f5cfd82c9368d26b074467f39c07a774367ff6cccb5039ac63f107677d77706cd431680\",\n    \"0xa33b6250d4ac9e66ec51c063d1a6a31f253eb29bbaed12a0d67e2eccfffb0f3a52750fbf52a1c2aaba8c7692346426e7\",\n    \"0xa97025fd5cbcebe8ef865afc39cd3ea707b89d4e765ec817fd021d6438e02fa51e3544b1fd45470c58007a08efac6edd\",\n    \"0xb32a78480edd9ff6ba2f1eec4088db5d6ceb2d62d7e59e904ecaef7bb4a2e983a4588e51692b3be76e6ffbc0b5f911a5\",\n    \"0xb5ab590ef0bb77191f00495b33d11c53c65a819f7d0c1f9dc4a2caa147a69c77a4fff7366a602d743ee1f395ce934c1e\",\n    \"0xb3fb0842f9441fb1d0ee0293b6efbc70a8f58d12d6f769b12872db726b19e16f0f65efbc891cf27a28a248b0ef9c7e75\",\n    \"0x9372ad12856fefb928ccb0d34e198df99e2f8973b07e9d417a3134d5f69e12e79ff572c4e03ccd65415d70639bc7c73e\",\n    \"0xaa8d6e83d09ce216bfe2009a6b07d0110d98cf305364d5529c170a23e693aabb768b2016befb5ada8dabdd92b4d012bb\",\n    \"0xa954a75791eeb0ce41c85200c3763a508ed8214b5945a42c79bfdcfb1ec4f86ad1dd7b2862474a368d4ac31911a2b718\",\n    \"0x8e2081cfd1d062fe3ab4dab01f68062bac802795545fede9a188f6c9f802cb5f884e60dbe866710baadbf55dc77c11a4\",\n    \"0xa2f06003b9713e7dd5929501ed485436b49d43de80ea5b15170763fd6346badf8da6de8261828913ee0dacd8ff23c0e1\",\n    \"0x98eecc34b838e6ffd1931ca65eec27bcdb2fdcb61f33e7e5673a93028c5865e0d1bf6d3bec040c5e96f9bd08089a53a4\",\n    \"0x88cc16019741b341060b95498747db4377100d2a5bf0a5f516f7dec71b62bcb6e779de2c269c946d39040e03b3ae12b7\",\n    \"0xad1135ccbc3019d5b2faf59a688eef2500697642be8cfbdf211a1ab59abcc1f24483e50d653b55ff1834675ac7b4978f\",\n    \"0xa946f05ed9972f71dfde0020bbb086020fa35b482cce8a4cc36dd94355b2d10497d7f2580541bb3e81b71ac8bba3c49f\",\n    \"0xa83aeed488f9a19d8cfd743aa9aa1982ab3723560b1cd337fc2f91ad82f07afa412b3993afb845f68d47e91ba4869840\",\n    \"0x95eebe006bfc316810cb71da919e5d62c2cebb4ac99d8e8ef67be420302320465f8b69873470982de13a7c2e23516be9\",\n    \"0xa55f8961295a11e91d1e5deadc0c06c15dacbfc67f04ccba1d069cba89d72aa3b3d64045579c3ea8991b150ac29366ae\",\n    \"0xb321991d12f6ac07a5de3c492841d1a27b0d3446082fbce93e7e1f9e8d8fe3b45d41253556261c21b70f5e189e1a7a6f\",\n    \"0xa0b0822f15f652ce7962a4f130104b97bf9529797c13d6bd8e24701c213cc37f18157bd07f3d0f3eae6b7cd1cb40401f\",\n    \"0x96e2fa4da378aa782cc2d5e6e465fc9e49b5c805ed01d560e9b98abb5c0de8b74a2e7bec3aa5e2887d25cccb12c66f0c\",\n    \"0x97e4ab610d414f9210ed6f35300285eb3ccff5b0b6a95ed33425100d7725e159708ea78704497624ca0a2dcabce3a2f9\",\n    \"0x960a375b17bdb325761e01e88a3ea57026b2393e1d887b34b8fa5d2532928079ce88dc9fd06a728b26d2bb41b12b9032\",\n    \"0x8328a1647398e832aadc05bd717487a2b6fcdaa0d4850d2c4da230c6a2ed44c3e78ec4837b6094f3813f1ee99414713f\",\n    \"0xaa283834ebd18e6c99229ce4b401eda83f01d904f250fedd4e24f1006f8fa0712a6a89a7296a9bf2ce8de30e28d1408e\",\n    \"0xb29e097f2caadae3e0f0ae3473c072b0cd0206cf6d2e9b22c1a5ad3e07d433e32bd09ed1f4e4276a2da4268633357b7f\",\n    \"0x9539c5cbba14538b2fe077ecf67694ef240da5249950baaabea0340718b882a966f66d97f08556b08a4320ceb2cc2629\",\n    \"0xb4529f25e9b42ae8cf8338d2eface6ba5cd4b4d8da73af502d081388135c654c0b3afb3aa779ffc80b8c4c8f4425dd2b\",\n    \"0x95be0739c4330619fbe7ee2249c133c91d6c07eab846c18c5d6c85fc21ac5528c5d56dcb0145af68ed0c6a79f68f2ccd\",\n    \"0xac0c83ea802227bfc23814a24655c9ff13f729619bcffdb487ccbbf029b8eaee709f8bddb98232ef33cd70e30e45ca47\",\n    \"0xb503becb90acc93b1901e939059f93e671900ca52c6f64ae701d11ac891d3a050b505d89324ce267bc43ab8275da6ffe\",\n    \"0x98e3811b55b1bacb70aa409100abb1b870f67e6d059475d9f278c751b6e1e2e2d6f2e586c81a9fb6597fda06e7923274\",\n    \"0xb0b0f61a44053fa6c715dbb0731e35d48dba257d134f851ee1b81fd49a5c51a90ebf5459ec6e489fce25da4f184fbdb1\",\n    \"0xb1d2117fe811720bb997c7c93fe9e4260dc50fca8881b245b5e34f724aaf37ed970cdad4e8fcb68e05ac8cf55a274a53\",\n    \"0xa10f502051968f14b02895393271776dee7a06db9de14effa0b3471825ba94c3f805302bdddac4d397d08456f620999d\",\n    \"0xa3dbad2ef060ae0bb7b02eaa4a13594f3f900450faa1854fc09620b01ac94ab896321dfb1157cf2374c27e5718e8026a\",\n    \"0xb550fdec503195ecb9e079dcdf0cad559d64d3c30818ef369b4907e813e689da316a74ad2422e391b4a8c2a2bef25fc0\",\n    \"0xa25ba865e2ac8f28186cea497294c8649a201732ecb4620c4e77b8e887403119910423df061117e5f03fc5ba39042db1\",\n    \"0xb3f88174e03fdb443dd6addd01303cf88a4369352520187c739fc5ae6b22fa99629c63c985b4383219dab6acc5f6f532\",\n    \"0x97a7503248e31e81b10eb621ba8f5210c537ad11b539c96dfb7cf72b846c7fe81bd7532c5136095652a9618000b7f8d3\",\n    \"0xa8bcdc1ce5aa8bfa683a2fc65c1e79de8ff5446695dcb8620f7350c26d2972a23da22889f9e2b1cacb3f688c6a2953dc\",\n    \"0x8458c111df2a37f5dd91a9bee6c6f4b79f4f161c93fe78075b24a35f9817da8dde71763218d627917a9f1f0c4709c1ed\",\n    \"0xac5f061a0541152b876cbc10640f26f1cc923c9d4ae1b6621e4bb3bf2cec59bbf87363a4eb72fb0e5b6d4e1c269b52d5\",\n    \"0xa9a25ca87006e8a9203cbb78a93f50a36694aa4aad468b8d80d3feff9194455ca559fcc63838128a0ab75ad78c07c13a\",\n    \"0xa450b85f5dfffa8b34dfd8bc985f921318efacf8857cf7948f93884ba09fb831482ee90a44224b1a41e859e19b74962f\",\n    \"0x8ed91e7f92f5c6d7a71708b6132f157ac226ecaf8662af7d7468a4fa25627302efe31e4620ad28719318923e3a59bf82\",\n    \"0xab524165fd4c71b1fd395467a14272bd2b568592deafa039d8492e9ef36c6d3f96927c95c72d410a768dc0b6d1fbbc9b\",\n    \"0xb662144505aa8432c75ffb8d10318526b6d5777ac7af9ebfad87d9b0866c364f7905a6352743bd8fd79ffd9d5dd4f3e6\",\n    \"0xa48f1677550a5cd40663bb3ba8f84caaf8454f332d0ceb1d94dbea52d0412fe69c94997f7749929712fd3995298572f7\",\n    \"0x8391cd6e2f6b0c242de1117a612be99776c3dc95cb800b187685ea5bf7e2722275eddb79fd7dfc8be8e389c4524cdf70\",\n    \"0x875d3acb9af47833b72900bc0a2448999d638f153c5e97e8a14ec02d0c76f6264353a7e275e1f1a5855daced523d243b\",\n    \"0x91f1823657d30b59b2f627880a9a9cb530f5aca28a9fd217fe6f2f5133690dfe7ad5a897872e400512db2e788b3f7628\",\n    \"0xad3564332aa56cea84123fc7ca79ea70bb4fef2009fa131cb44e4b15e8613bd11ca1d83b9d9bf456e4b7fee9f2e8b017\",\n    \"0x8c530b84001936d5ab366c84c0b105241a26d1fb163669f17c8f2e94776895c2870edf3e1bc8ccd04d5e65531471f695\",\n    \"0x932d01fa174fdb0c366f1230cffde2571cc47485f37f23ba5a1825532190cc3b722aeb1f15aed62cf83ccae9403ba713\",\n    \"0x88b28c20585aca50d10752e84b901b5c2d58efef5131479fbbe53de7bce2029e1423a494c0298e1497669bd55be97a5d\",\n    \"0xb914148ca717721144ebb3d3bf3fcea2cd44c30c5f7051b89d8001502f3856fef30ec167174d5b76265b55d70f8716b5\",\n    \"0x81d0173821c6ddd2a068d70766d9103d1ee961c475156e0cbd67d54e668a796310474ef698c7ab55abe6f2cf76c14679\",\n    \"0x8f28e8d78e2fe7fa66340c53718e0db4b84823c8cfb159c76eac032a62fb53da0a5d7e24ca656cf9d2a890cb2a216542\",\n    \"0x8a26360335c73d1ab51cec3166c3cf23b9ea51e44a0ad631b0b0329ef55aaae555420348a544e18d5760969281759b61\",\n    \"0x94f326a32ed287545b0515be9e08149eb0a565025074796d72387cc3a237e87979776410d78339e23ef3172ca43b2544\",\n    \"0xa785d2961a2fa5e70bffa137858a92c48fe749fee91b02599a252b0cd50d311991a08efd7fa5e96b78d07e6e66ffe746\",\n    \"0x94af9030b5ac792dd1ce517eaadcec1482206848bea4e09e55cc7f40fd64d4c2b3e9197027c5636b70d6122c51d2235d\",\n    \"0x9722869f7d1a3992850fe7be405ec93aa17dc4d35e9e257d2e469f46d2c5a59dbd504056c85ab83d541ad8c13e8bcd54\",\n    \"0xb13c4088b61a06e2c03ac9813a75ff1f68ffdfee9df6a8f65095179a475e29cc49119cad2ce05862c3b1ac217f3aace9\",\n    \"0x8c64d51774753623666b10ca1b0fe63ae42f82ed6aa26b81dc1d48c86937c5772eb1402624c52a154b86031854e1fb9f\",\n    \"0xb47e4df18002b7dac3fee945bf9c0503159e1b8aafcce2138818e140753011b6d09ef1b20894e08ba3006b093559061b\",\n    \"0x93cb5970076522c5a0483693f6a35ffd4ea2aa7aaf3730c4eccd6af6d1bebfc1122fc4c67d53898ae13eb6db647be7e2\",\n    \"0xa68873ef80986795ea5ed1a597d1cd99ed978ec25e0abb57fdcc96e89ef0f50aeb779ff46e3dce21dc83ada3157a8498\",\n    \"0x8cab67f50949cc8eee6710e27358aea373aae3c92849f8f0b5531c080a6300cdf2c2094fe6fecfef6148de0d28446919\",\n    \"0x993e932bcb616dbaa7ad18a4439e0565211d31071ef1b85a0627db74a05d978c60d507695eaeea5c7bd9868a21d06923\",\n    \"0xacdadff26e3132d9478a818ef770e9fa0d2b56c6f5f48bd3bd674436ccce9bdfc34db884a73a30c04c5f5e9764cb2218\",\n    \"0xa0d3e64c9c71f84c0eef9d7a9cb4fa184224b969db5514d678e93e00f98b41595588ca802643ea225512a4a272f5f534\",\n    \"0x91c9140c9e1ba6e330cb08f6b2ce4809cd0d5a0f0516f70032bf30e912b0ed684d07b413b326ab531ee7e5b4668c799b\",\n    \"0x87bc2ee7a0c21ba8334cd098e35cb703f9af57f35e091b8151b9b63c3a5b0f89bd7701dbd44f644ea475901fa6d9ef08\",\n    \"0x9325ccbf64bf5d71b303e31ee85d486298f9802c5e55b2c3d75427097bf8f60fa2ab4fcaffa9b60bf922c3e24fbd4b19\",\n    \"0x95d0506e898318f3dc8d28d16dfd9f0038b54798838b3c9be2a2ae3c2bf204eb496166353fc042220b0bd4f6673b9285\",\n    \"0x811de529416331fe9c416726d45df9434c29dcd7e949045eb15740f47e97dde8f31489242200e19922cac2a8b7c6fd1f\",\n    \"0xade632d04a4c8bbab6ca7df370b2213cb9225023e7973f0e29f4f5e52e8aeaabc65171306bbdd12a67b195dfbb96d48f\",\n    \"0x88b7f029e079b6ae956042c0ea75d53088c5d0efd750dd018adaeacf46be21bf990897c58578c491f41afd3978d08073\",\n    \"0x91f477802de507ffd2be3f4319903119225b277ad24f74eb50f28b66c14d32fae53c7edb8c7590704741af7f7f3e3654\",\n    \"0x809838b32bb4f4d0237e98108320d4b079ee16ed80c567e7548bd37e4d7915b1192880f4812ac0e00476d246aec1dbc8\",\n    \"0x84183b5fc4a7997a8ae5afedb4d21dce69c480d5966b5cbdafd6dd10d29a9a6377f3b90ce44da0eb8b176ac3af0253bb\",\n    \"0x8508abbf6d3739a16b9165caf0f95afb3b3ac1b8c38d6d374cf0c91296e2c1809a99772492b539cda184510bce8a0271\",\n    \"0x8722054e59bab2062e6419a6e45fc803af77fde912ef2cd23055ad0484963de65a816a2debe1693d93c18218d2b8e81a\",\n    \"0x8e895f80e485a7c4f56827bf53d34b956281cdc74856c21eb3b51f6288c01cc3d08565a11cc6f3e2604775885490e8c5\",\n    \"0xafc92714771b7aa6e60f3aee12efd9c2595e9659797452f0c1e99519f67c8bc3ac567119c1ddfe82a3e961ee9defea9a\",\n    \"0x818ff0fd9cefd32db87b259e5fa32967201016fc02ef44116cdca3c63ce5e637756f60477a408709928444a8ad69c471\",\n    \"0x8251e29af4c61ae806fc5d032347fb332a94d472038149225298389495139ce5678fae739d02dfe53a231598a992e728\",\n    \"0xa0ea39574b26643f6f1f48f99f276a8a64b5481989cfb2936f9432a3f8ef5075abfe5c067dc5512143ce8bf933984097\",\n    \"0xaf67a73911b372bf04e57e21f289fc6c3dfac366c6a01409b6e76fea4769bdb07a6940e52e8d7d3078f235c6d2f632c6\",\n    \"0xb5291484ef336024dd2b9b4cf4d3a6b751133a40656d0a0825bcc6d41c21b1c79cb50b0e8f4693f90c29c8f4358641f9\",\n    \"0x8bc0d9754d70f2cb9c63f991902165a87c6535a763d5eece43143b5064ae0bcdce7c7a8f398f2c1c29167b2d5a3e6867\",\n    \"0x8d7faff53579ec8f6c92f661c399614cc35276971752ce0623270f88be937c414eddcb0997e14724a783905a026c8883\",\n    \"0x9310b5f6e675fdf60796f814dbaa5a6e7e9029a61c395761e330d9348a7efab992e4e115c8be3a43d08e90d21290c892\",\n    \"0xb5eb4f3eb646038ad2a020f0a42202532d4932e766da82b2c1002bf9c9c2e5336b54c8c0ffcc0e02d19dde2e6a35b6cc\",\n    \"0x91dabfd30a66710f1f37a891136c9be1e23af4abf8cb751f512a40c022a35f8e0a4fb05b17ec36d4208de02d56f0d53a\",\n    \"0xb3ded14e82d62ac7a5a036122a62f00ff8308498f3feae57d861babaff5a6628d43f0a0c5fc903f10936bcf4e2758ceb\",\n    \"0xa88e8348fed2b26acca6784d19ef27c75963450d99651d11a950ea81d4b93acd2c43e0ecce100eaf7e78508263d5baf3\",\n    \"0xb1f5bbf7c4756877b87bb42163ac570e08c6667c4528bf68b5976680e19beeff7c5effd17009b0718797077e2955457a\",\n    \"0xad2e7b516243f915d4d1415326e98b1a7390ae88897d0b03b66c2d9bd8c3fba283d7e8fe44ed3333296a736454cef6d8\",\n    \"0x8f82eae096d5b11f995de6724a9af895f5e1c58d593845ad16ce8fcae8507e0d8e2b2348a0f50a1f66a17fd6fac51a5c\",\n    \"0x890e4404d0657c6c1ee14e1aac132ecf7a568bb3e04137b85ac0f84f1d333bd94993e8750f88eee033a33fb00f85dcc7\",\n    \"0x82ac7d3385e035115f1d39a99fc73e5919de44f5e6424579776d118d711c8120b8e5916372c6f27bed4cc64cac170b6c\",\n    \"0x85ee16d8901c272cfbbe966e724b7a891c1bd5e68efd5d863043ad8520fc409080af61fd726adc680b3f1186fe0ac8b8\",\n    \"0x86dc564c9b545567483b43a38f24c41c6551a49cabeebb58ce86404662a12dbfafd0778d30d26e1c93ce222e547e3898\",\n    \"0xa29f5b4522db26d88f5f95f18d459f8feefab02e380c2edb65aa0617a82a3c1a89474727a951cef5f15050bcf7b380fb\",\n    \"0xa1ce039c8f6cac53352899edb0e3a72c76da143564ad1a44858bd7ee88552e2fe6858d1593bbd74aeee5a6f8034b9b9d\",\n    \"0x97f10d77983f088286bd7ef3e7fdd8fa275a56bec19919adf33cf939a90c8f2967d2b1b6fc51195cb45ad561202a3ed7\",\n    \"0xa25e2772e8c911aaf8712bdac1dd40ee061c84d3d224c466cfaae8e5c99604053f940cde259bd1c3b8b69595781dbfec\",\n    \"0xb31bb95a0388595149409c48781174c340960d59032ab2b47689911d03c68f77a2273576fbe0c2bf4553e330656058c7\",\n    \"0xb8b2e9287ad803fb185a13f0d7456b397d4e3c8ad5078f57f49e8beb2e85f661356a3392dbd7bcf6a900baa5582b86a1\",\n    \"0xa3d0893923455eb6e96cc414341cac33d2dbc88fba821ac672708cce131761d85a0e08286663a32828244febfcae6451\",\n    \"0x82310cb42f647d99a136014a9f881eb0b9791efd2e01fc1841907ad3fc8a9654d3d1dab6689c3607214b4dc2aca01cee\",\n    \"0x874022d99c16f60c22de1b094532a0bc6d4de700ad01a31798fac1d5088b9a42ad02bef8a7339af7ed9c0d4f16b186ee\",\n    \"0x94981369e120265aed40910eebc37eded481e90f4596b8d57c3bec790ab7f929784bd33ddd05b7870aad6c02e869603b\",\n    \"0xa4f1f50e1e2a73f07095e0dd31cb45154f24968dae967e38962341c1241bcd473102fff1ff668b20c6547e9732d11701\",\n    \"0xae2328f3b0ad79fcda807e69a1b5278145225083f150f67511dafc97e079f860c3392675f1752ae7e864c056e592205b\",\n    \"0x875d8c971e593ca79552c43d55c8c73b17cd20c81ff2c2fed1eb19b1b91e4a3a83d32df150dbfd5db1092d0aebde1e1f\",\n    \"0xadd2e80aa46aae95da73a11f130f4bda339db028e24c9b11e5316e75ba5e63bc991d2a1da172c7c8e8fee038baae3433\",\n    \"0xb46dbe1cb3424002aa7de51e82f600852248e251465c440695d52538d3f36828ff46c90ed77fc1d11534fe3c487df8ef\",\n    \"0xa5e5045d28b4e83d0055863c30c056628c58d4657e6176fd0536f5933f723d60e851bb726d5bf3c546b8ce4ac4a57ef8\",\n    \"0x91fec01e86dd1537e498fff7536ea3ca012058b145f29d9ada49370cd7b7193ac380e116989515df1b94b74a55c45df3\",\n    \"0xa7428176d6918cd916a310bdc75483c72de660df48cac4e6e7478eef03205f1827ea55afc0df5d5fa7567d14bbea7fc9\",\n    \"0x851d89bef45d9761fe5fdb62972209335193610015e16a675149519f9911373bac0919add226ef118d9f3669cfdf4734\",\n    \"0xb74acf5c149d0042021cb2422ea022be4c4f72a77855f42393e71ffd12ebb3eec16bdf16f812159b67b79a9706e7156d\",\n    \"0x99f35dce64ec99aa595e7894b55ce7b5a435851b396e79036ffb249c28206087db4c85379df666c4d95857db02e21ff9\",\n    \"0xb6b9a384f70db9e298415b8ab394ee625dafff04be2886476e59df8d052ca832d11ac68a9b93fba7ab055b7bc36948a4\",\n    \"0x898ee4aefa923ffec9e79f2219c7389663eb11eb5b49014e04ed4a336399f6ea1691051d86991f4c46ca65bcd4fdf359\",\n    \"0xb0f948217b0d65df7599a0ba4654a5e43c84db477936276e6f11c8981efc6eaf14c90d3650107ed4c09af4cc8ec11137\",\n    \"0xaa6286e27ac54f73e63dbf6f41865dd94d24bc0cf732262fcaff67319d162bb43af909f6f8ee27b1971939cfbba08141\",\n    \"0x8bca7cdf730cf56c7b2c8a2c4879d61361a6e1dba5a3681a1a16c17a56e168ace0e99cf0d15826a1f5e67e6b8a8a049a\",\n    \"0xa746d876e8b1ce225fcafca603b099b36504846961526589af977a88c60d31ba2cc56e66a3dec8a77b3f3531bf7524c9\",\n    \"0xa11e2e1927e6704cdb8874c75e4f1842cef84d7d43d7a38e339e61dc8ba90e61bbb20dd3c12e0b11d2471d58eed245be\",\n    \"0xa36395e22bc1d1ba8b0459a235203177737397da5643ce54ded3459d0869ff6d8d89f50c73cb62394bf66a959cde9b90\",\n    \"0x8b49f12ba2fdf9aca7e5f81d45c07d47f9302a2655610e7634d1e4bd16048381a45ef2c95a8dd5b0715e4b7cf42273af\",\n    \"0x91cffa2a17e64eb7f76bccbe4e87280ee1dd244e04a3c9eac12e15d2d04845d876eb24fe2ec6d6d266cce9efb281077f\",\n    \"0xa6b8afabf65f2dee01788114e33a2f3ce25376fb47a50b74da7c3c25ff1fdc8aa9f41307534abbf48acb6f7466068f69\",\n    \"0x8d13db896ccfea403bd6441191995c1a65365cab7d0b97fbe9526da3f45a877bd1f4ef2edef160e8a56838cd1586330e\",\n    \"0x98c717de9e01bef8842c162a5e757fe8552d53269c84862f4d451e7c656ae6f2ae473767b04290b134773f63be6fdb9d\",\n    \"0x8c2036ace1920bd13cf018e82848c49eb511fad65fd0ff51f4e4b50cf3bfc294afb63cba682c16f52fb595a98fa84970\",\n    \"0xa3520fdff05dbad9e12551b0896922e375f9e5589368bcb2cc303bde252743b74460cb5caf99629325d3620f13adc796\",\n    \"0x8d4f83a5bfec05caf5910e0ce538ee9816ee18d0bd44c1d0da2a87715a23cd2733ad4d47552c6dc0eb397687d611dd19\",\n    \"0xa7b39a0a6a02823452d376533f39d35029867b3c9a6ad6bca181f18c54132d675613a700f9db2440fb1b4fa13c8bf18a\",\n    \"0x80bcb114b2544b80f404a200fc36860ed5e1ad31fe551acd4661d09730c452831751baa9b19d7d311600d267086a70bc\",\n    \"0x90dcce03c6f88fc2b08f2b42771eedde90cc5330fe0336e46c1a7d1b5a6c1641e5fcc4e7b3d5db00bd8afca9ec66ed81\",\n    \"0xaec15f40805065c98e2965b1ae12a6c9020cfdb094c2d0549acfc7ea2401a5fb48d3ea7d41133cf37c4e096e7ff53eb9\",\n    \"0x80e129b735dba49fa627a615d6c273119acec8e219b2f2c4373a332b5f98d66cbbdd688dfbe72a8f8bfefaccc02c50c1\",\n    \"0xa9b596da3bdfe23e6799ece5f7975bf7a1979a75f4f546deeaf8b34dfe3e0d623217cb4cf4ccd504cfa3625b88cd53f1\",\n    \"0xabcbbb70b16f6e517c0ab4363ab76b46e4ff58576b5f8340e5c0e8cc0e02621b6e23d742d73b015822a238b17cfd7665\",\n    \"0xa046937cc6ea6a2e1adae543353a9fe929c1ae4ad655be1cc051378482cf88b041e28b1e9a577e6ccff2d3570f55e200\",\n    \"0x831279437282f315e65a60184ef158f0a3dddc15a648dc552bdc88b3e6fe8288d3cfe9f0031846d81350f5e7874b4b33\",\n    \"0x993d7916fa213c6d66e7c4cafafc1eaec9a2a86981f91c31eb8a69c5df076c789cbf498a24c84e0ee77af95b42145026\",\n    \"0x823907a3b6719f8d49b3a4b7c181bd9bb29fcf842d7c70660c4f351852a1e197ca46cf5e879b47fa55f616fa2b87ce5e\",\n    \"0x8d228244e26132b234930ee14c75d88df0943cdb9c276a8faf167d259b7efc1beec2a87c112a6c608ad1600a239e9aae\",\n    \"0xab6e55766e5bfb0cf0764ed909a8473ab5047d3388b4f46faeba2d1425c4754c55c6daf6ad4751e634c618b53e549529\",\n    \"0xab0cab6860e55a84c5ad2948a7e0989e2b4b1fd637605634b118361497332df32d9549cb854b2327ca54f2bcb85eed8f\",\n    \"0xb086b349ae03ef34f4b25a57bcaa5d1b29bd94f9ebf87e22be475adfe475c51a1230c1ebe13506cb72c4186192451658\",\n    \"0x8a0b49d8a254ca6d91500f449cbbfbb69bb516c6948ac06808c65595e46773e346f97a5ce0ef7e5a5e0de278af22709c\",\n    \"0xac49de11edaaf04302c73c578cc0824bdd165c0d6321be1c421c1950e68e4f3589aa3995448c9699e93c6ebae8803e27\",\n    \"0x884f02d841cb5d8f4c60d1402469216b114ab4e93550b5bc1431756e365c4f870a9853449285384a6fa49e12ce6dc654\",\n    \"0xb75f3a28fa2cc8d36b49130cb7448a23d73a7311d0185ba803ad55c8219741d451c110f48b786e96c728bc525903a54f\",\n    \"0x80ae04dbd41f4a35e33f9de413b6ad518af0919e5a30cb0fa1b061b260420780bb674f828d37fd3b52b5a31673cbd803\",\n    \"0xb9a8011eb5fcea766907029bf743b45262db3e49d24f84503687e838651ed11cb64c66281e20a0ae9f6aa51acc552263\",\n    \"0x90bfdd75e2dc9cf013e22a5d55d2d2b8a754c96103a17524488e01206e67f8b6d52b1be8c4e3d5307d4fe06d0e51f54c\",\n    \"0xb4af353a19b06203a815ec43e79a88578cc678c46f5a954b85bc5c53b84059dddba731f3d463c23bfd5273885c7c56a4\",\n    \"0xaa125e96d4553b64f7140e5453ff5d2330318b69d74d37d283e84c26ad672fa00e3f71e530eb7e28be1e94afb9c4612e\",\n    \"0xa18e060aee3d49cde2389b10888696436bb7949a79ca7d728be6456a356ea5541b55492b2138da90108bd1ce0e6f5524\",\n    \"0x93e55f92bdbccc2de655d14b1526836ea2e52dba65eb3f87823dd458a4cb5079bf22ce6ef625cb6d6bfdd0995ab9a874\",\n    \"0x89f5a683526b90c1c3ceebbb8dc824b21cff851ce3531b164f6626e326d98b27d3e1d50982e507d84a99b1e04e86a915\",\n    \"0x83d1c38800361633a3f742b1cb2bfc528129496e80232611682ddbe403e92c2ac5373aea0bca93ecb5128b0b2b7a719e\",\n    \"0x8ecba560ac94905e19ce8d9c7af217bf0a145d8c8bd38e2db82f5e94cc3f2f26f55819176376b51f154b4aab22056059\",\n    \"0xa7e2a4a002b60291924850642e703232994acb4cfb90f07c94d1e0ecd2257bb583443283c20fc6017c37e6bfe85b7366\",\n    \"0x93ed7316fa50b528f1636fc6507683a672f4f4403e55e94663f91221cc198199595bd02eef43d609f451acc9d9b36a24\",\n    \"0xa1220a8ebc5c50ceed76a74bc3b7e0aa77f6884c71b64b67c4310ac29ce5526cb8992d6abc13ef6c8413ce62486a6795\",\n    \"0xb2f6eac5c869ad7f4a25161d3347093e2f70e66cd925032747e901189355022fab3038bca4d610d2f68feb7e719c110b\",\n    \"0xb703fa11a4d511ca01c7462979a94acb40b5d933759199af42670eb48f83df202fa0c943f6ab3b4e1cc54673ea3aab1e\",\n    \"0xb5422912afbfcb901f84791b04f1ddb3c3fbdc76d961ee2a00c5c320e06d3cc5b5909c3bb805df66c5f10c47a292b13d\",\n    \"0xad0934368da823302e1ac08e3ede74b05dfdbfffca203e97ffb0282c226814b65c142e6e15ec1e754518f221f01b30f7\",\n    \"0xa1dd302a02e37df15bf2f1147efe0e3c06933a5a767d2d030e1132f5c3ce6b98e216b6145eb39e1e2f74e76a83165b8d\",\n    \"0xa346aab07564432f802ae44738049a36f7ca4056df2d8f110dbe7fef4a3e047684dea609b2d03dc6bf917c9c2a47608f\",\n    \"0xb96c5f682a5f5d02123568e50f5d0d186e4b2c4c9b956ec7aabac1b3e4a766d78d19bd111adb5176b898e916e49be2aa\",\n    \"0x8a96676d56876fc85538db2e806e1cba20fd01aeb9fa3cb43ca6ca94a2c102639f65660db330e5d74a029bb72d6a0b39\",\n    \"0xab0048336bd5c3def1a4064eadd49e66480c1f2abb4df46e03afbd8a3342c2c9d74ee35d79f08f4768c1646681440984\",\n    \"0x888427bdf76caec90814c57ee1c3210a97d107dd88f7256f14f883ad0f392334b82be11e36dd8bfec2b37935177c7831\",\n    \"0xb622b282becf0094a1916fa658429a5292ba30fb48a4c8066ce1ddcefb71037948262a01c95bab6929ed3a76ba5db9fe\",\n    \"0xb5b9e005c1f456b6a368a3097634fb455723abe95433a186e8278dceb79d4ca2fbe21f8002e80027b3c531e5bf494629\",\n    \"0xa3c6707117a1e48697ed41062897f55d8119403eea6c2ee88f60180f6526f45172664bfee96bf61d6ec0b7fbae6aa058\",\n    \"0xb02a9567386a4fbbdb772d8a27057b0be210447348efe6feb935ceec81f361ed2c0c211e54787dc617cdffed6b4a6652\",\n    \"0xa9b8364e40ef15c3b5902e5534998997b8493064fa2bea99600def58279bb0f64574c09ba11e9f6f669a8354dd79dc85\",\n    \"0x9998a2e553a9aa9a206518fae2bc8b90329ee59ab23005b10972712389f2ec0ee746033c733092ffe43d73d33abbb8ef\",\n    \"0x843a4b34d9039bf79df96d79f2d15e8d755affb4d83d61872daf540b68c0a3888cf8fc00d5b8b247b38524bcb3b5a856\",\n    \"0x84f7128920c1b0bb40eee95701d30e6fc3a83b7bb3709f16d97e72acbb6057004ee7ac8e8f575936ca9dcb7866ab45f7\",\n    \"0x918d3e2222e10e05edb34728162a899ad5ada0aaa491aeb7c81572a9c0d506e31d5390e1803a91ff3bd8e2bb15d47f31\",\n    \"0x9442d18e2489613a7d47bb1cb803c8d6f3259d088cd079460976d87f7905ee07dea8f371b2537f6e1d792d36d7e42723\",\n    \"0xb491976970fe091995b2ed86d629126523ccf3e9daf8145302faca71b5a71a5da92e0e05b62d7139d3efac5c4e367584\",\n    \"0xaa628006235dc77c14cef4c04a308d66b07ac92d377df3de1a2e6ecfe3144f2219ad6d7795e671e1cb37a3641910b940\",\n    \"0x99d386adaea5d4981d7306feecac9a555b74ffdc218c907c5aa7ac04abaead0ec2a8237300d42a3fbc464673e417ceed\",\n    \"0x8f78e8b1556f9d739648ea3cab9606f8328b52877fe72f9305545a73b74d49884044ba9c1f1c6db7d9b7c7b7c661caba\",\n    \"0x8fb357ae49932d0babdf74fc7aa7464a65d3b6a2b3acf4f550b99601d3c0215900cfd67f2b6651ef94cfc323bac79fae\",\n    \"0x9906f2fa25c0290775aa001fb6198113d53804262454ae8b83ef371b5271bde189c0460a645829cb6c59f9ee3a55ce4d\",\n    \"0x8f4379b3ebb50e052325b27655ca6a82e6f00b87bf0d2b680d205dd2c7afdc9ff32a9047ae71a1cdf0d0ce6b9474d878\",\n    \"0xa85534e88c2bd43c043792eaa75e50914b21741a566635e0e107ae857aed0412035f7576cf04488ade16fd3f35fdbb87\",\n    \"0xb4ce93199966d3c23251ca7f28ec5af7efea1763d376b0385352ffb2e0a462ef95c69940950278cf0e3dafd638b7bd36\",\n    \"0xb10cb3d0317dd570aa73129f4acf63c256816f007607c19b423fb42f65133ce21f2f517e0afb41a5378cccf893ae14d0\",\n    \"0xa9b231c9f739f7f914e5d943ed9bff7eba9e2c333fbd7c34eb1648a362ee01a01af6e2f7c35c9fe962b11152cddf35de\",\n    \"0x99ff6a899e156732937fb81c0cced80ae13d2d44c40ba99ac183aa246103b31ec084594b1b7feb96da58f4be2dd5c0ed\",\n    \"0x8748d15d18b75ff2596f50d6a9c4ce82f61ecbcee123a6ceae0e43cab3012a29b6f83cf67b48c22f6f9d757c6caf76b2\",\n    \"0xb88ab05e4248b7fb634cf640a4e6a945d13e331237410f7217d3d17e3e384ddd48897e7a91e4516f1b9cbd30f35f238b\",\n    \"0x8d826deaeeb84a3b2d2c04c2300ca592501f992810582d6ae993e0d52f6283a839dba66c6c72278cff5871802b71173b\",\n    \"0xb36fed027c2f05a5ef625ca00b0364b930901e9e4420975b111858d0941f60e205546474bb25d6bfa6928d37305ae95f\",\n    \"0xaf2fcfc6b87967567e8b8a13a4ed914478185705724e56ce68fb2df6d1576a0cf34a61e880997a0d35dc2c3276ff7501\",\n    \"0xac351b919cd1fbf106feb8af2c67692bfcddc84762d18cea681cfa7470a5644839caace27efee5f38c87d3df306f4211\",\n    \"0x8d6665fb1d4d8d1fa23bd9b8a86e043b8555663519caac214d1e3e3effbc6bee7f2bcf21e645f77de0ced279d69a8a8b\",\n    \"0xa9fc1c2061756b2a1a169c1b149f212ff7f0d2488acd1c5a0197eba793cffa593fc6d1d1b40718aa75ca3ec77eff10e1\",\n    \"0xaff64f0fa009c7a6cf0b8d7a22ddb2c8170c3cb3eec082e60d5aadb00b0040443be8936d728d99581e33c22178c41c87\",\n    \"0x82e0b181adc5e3b1c87ff8598447260e839d53debfae941ebea38265575546c3a74a14b4325a030833a62ff6c52d9365\",\n    \"0xb7ad43cbb22f6f892c2a1548a41dc120ab1f4e1b8dea0cb6272dd9cb02054c542ecabc582f7e16de709d48f5166cae86\",\n    \"0x985e0c61094281532c4afb788ecb2dfcba998e974b5d4257a22040a161883908cdd068fe80f8eb49b8953cfd11acf43a\",\n    \"0xae46895c6d67ea6d469b6c9c07b9e5d295d9ae73b22e30da4ba2c973ba83a130d7eef39717ec9d0f36e81d56bf742671\",\n    \"0x8600177ea1f7e7ef90514b38b219a37dedfc39cb83297e4c7a5b479817ef56479d48cf6314820960c751183f6edf8b0e\",\n    \"0xb9208ec1c1d7a1e99b59c62d3e4e61dfb706b0e940d09d3abfc3454c19749083260614d89cfd7e822596c3cdbcc6bb95\",\n    \"0xa1e94042c796c2b48bc724352d2e9f3a22291d9a34705993357ddb6adabd76da6fc25dac200a8cb0b5bbd99ecddb7af6\",\n    \"0xb29c3adedd0bcad8a930625bc4dfdc3552a9afd5ca6dd9c0d758f978068c7982b50b711aa0eb5b97f2b84ee784637835\",\n    \"0xaf0632a238bb1f413c7ea8e9b4c3d68f2827bd2e38cd56024391fba6446ac5d19a780d0cfd4a78fe497d537b766a591a\",\n    \"0xaaf6e7f7d54f8ef5e2e45dd59774ecbeecf8683aa70483b2a75be6a6071b5981bbaf1627512a65d212817acdfab2e428\",\n    \"0x8c751496065da2e927cf492aa5ca9013b24f861d5e6c24b30bbf52ec5aaf1905f40f9a28175faef283dd4ed4f2182a09\",\n    \"0x8952377d8e80a85cf67d6b45499f3bad5fd452ea7bcd99efc1b066c4720d8e5bff1214cea90fd1f972a7f0baac3d29be\",\n    \"0xa1946ee543d1a6e21f380453be4d446e4130950c5fc3d075794eb8260f6f52d0a795c1ff91d028a648dc1ce7d9ab6b47\",\n    \"0x89f3fefe37af31e0c17533d2ca1ce0884cc1dc97c15cbfab9c331b8debd94781c9396abef4bb2f163d09277a08d6adf0\",\n    \"0xa2753f1e6e1a154fb117100a5bd9052137add85961f8158830ac20541ab12227d83887d10acf7fd36dcaf7c2596d8d23\",\n    \"0x814955b4198933ee11c3883863b06ff98c7eceb21fc3e09df5f916107827ccf3323141983e74b025f46ae00284c9513b\",\n    \"0x8cc5c6bb429073bfef47cae7b3bfccb0ffa076514d91a1862c6bda4d581e0df87db53cc6c130bf8a7826304960f5a34e\",\n    \"0x909f22c1f1cdc87f7be7439c831a73484a49acbf8f23d47087d7cf867c64ef61da3bde85dc57d705682b4c3fc710d36e\",\n    \"0x8048fee7f276fcd504aed91284f28e73693615e0eb3858fa44bcf79d7285a9001c373b3ef71d9a3054817ba293ebe28c\",\n    \"0x94400e5cf5d2700ca608c5fe35ce14623f71cc24959f2bc27ca3684092850f76b67fb1f07ca9e5b2ca3062cf8ad17bd4\",\n    \"0x81c2ae7d4d1b17f8b6de6a0430acc0d58260993980fe48dc2129c4948269cdc74f9dbfbf9c26b19360823fd913083d48\",\n    \"0x8c41fe765128e63f6889d6a979f6a4342300327c8b245a8cfe3ecfbcac1e09c3da30e2a1045b24b78efc6d6d50c8c6ac\",\n    \"0xa5dd4ae51ae48c8be4b218c312ade226cffce671cf121cb77810f6c0990768d6dd767badecb5c69921d5574d5e8433d3\",\n    \"0xb7642e325f4ba97ae2a39c1c9d97b35aafd49d53dba36aed3f3cb0ca816480b3394079f46a48252d46596559c90f4d58\",\n    \"0xae87375b40f35519e7bd4b1b2f73cd0b329b0c2cb9d616629342a71c6c304338445eda069b78ea0fbe44087f3de91e09\",\n    \"0xb08918cb6f736855e11d3daca1ddfbdd61c9589b203b5493143227bf48e2c77c2e8c94b0d1aa2fab2226e0eae83f2681\",\n    \"0xac36b84a4ac2ebd4d6591923a449c564e3be8a664c46092c09e875c2998eba16b5d32bfd0882fd3851762868e669f0b1\",\n    \"0xa44800a3bb192066fa17a3f29029a23697240467053b5aa49b9839fb9b9b8b12bcdcbfc557f024b61f4f51a9aacdefcb\",\n    \"0x9064c688fec23441a274cdf2075e5a449caf5c7363cc5e8a5dc9747183d2e00a0c69f2e6b3f6a7057079c46014c93b3b\",\n    \"0xaa367b021469af9f5b764a79bb3afbe2d87fe1e51862221672d1a66f954b165778b7c27a705e0f93841fab4c8468344d\",\n    \"0xa1a8bfc593d4ab71f91640bc824de5c1380ab2591cfdafcbc78a14b32de3c0e15f9d1b461d85c504baa3d4232c16bb53\",\n    \"0x97df48da1799430f528184d30b6baa90c2a2f88f34cdfb342d715339c5ebd6d019aa693cea7c4993daafc9849063a3aa\",\n    \"0xabd923831fbb427e06e0dd335253178a9e5791395c84d0ab1433c07c53c1209161097e9582fb8736f8a60bde62d8693e\",\n    \"0x84cd1a43f1a438b43dc60ffc775f646937c4f6871438163905a3cebf1115f814ccd38a6ccb134130bff226306e412f32\",\n    \"0x91426065996b0743c5f689eb3ca68a9f7b9e4d01f6c5a2652b57fa9a03d8dc7cd4bdbdab0ca5a891fee1e97a7f00cf02\",\n    \"0xa4bee50249db3df7fd75162b28f04e57c678ba142ce4d3def2bc17bcb29e4670284a45f218dad3969af466c62a903757\",\n    \"0x83141ebcc94d4681404e8b67a12a46374fded6df92b506aff3490d875919631408b369823a08b271d006d5b93136f317\",\n    \"0xa0ea1c8883d58d5a784da3d8c8a880061adea796d7505c1f903d07c287c5467f71e4563fc0faafbc15b5a5538b0a7559\",\n    \"0x89d9d480574f201a87269d26fb114278ed2c446328df431dc3556e3500e80e4cd01fcac196a2459d8646361ebda840df\",\n    \"0x8bf302978973632dd464bec819bdb91304712a3ec859be071e662040620422c6e75eba6f864f764cffa2799272efec39\",\n    \"0x922f666bc0fd58b6d7d815c0ae4f66d193d32fc8382c631037f59eeaeae9a8ca6c72d08e72944cf9e800b8d639094e77\",\n    \"0x81ad8714f491cdff7fe4399f2eb20e32650cff2999dd45b9b3d996d54a4aba24cc6c451212e78c9e5550368a1a38fb3f\",\n    \"0xb58fcf4659d73edb73175bd9139d18254e94c3e32031b5d4b026f2ed37aa19dca17ec2eb54c14340231615277a9d347e\",\n    \"0xb365ac9c2bfe409b710928c646ea2fb15b28557e0f089d39878e365589b9d1c34baf5566d20bb28b33bb60fa133f6eff\",\n    \"0x8fcae1d75b53ab470be805f39630d204853ca1629a14158bac2f52632277d77458dec204ff84b7b2d77e641c2045be65\",\n    \"0xa03efa6bebe84f4f958a56e2d76b5ba4f95dd9ed7eb479edc7cc5e646c8d4792e5b0dfc66cc86aa4b4afe2f7a4850760\",\n    \"0xaf1c823930a3638975fb0cc5c59651771b2719119c3cd08404fbd4ce77a74d708cefbe3c56ea08c48f5f10e6907f338f\",\n    \"0x8260c8299b17898032c761c325ac9cabb4c5b7e735de81eacf244f647a45fb385012f4f8df743128888c29aefcaaad16\",\n    \"0xab2f37a573c82e96a8d46198691cd694dfa860615625f477e41f91b879bc58a745784fccd8ffa13065834ffd150d881d\",\n    \"0x986c746c9b4249352d8e5c629e8d7d05e716b3c7aab5e529ca969dd1e984a14b5be41528baef4c85d2369a42d7209216\",\n    \"0xb25e32da1a8adddf2a6080725818b75bc67240728ad1853d90738485d8924ea1e202df0a3034a60ffae6f965ec55cf63\",\n    \"0xa266e627afcebcefea6b6b44cbc50f5c508f7187e87d047b0450871c2a030042c9e376f3ede0afcf9d1952f089582f71\",\n    \"0x86c3bbca4c0300606071c0a80dbdec21ce1dd4d8d4309648151c420854032dff1241a1677d1cd5de4e4de4385efda986\",\n    \"0xb9a21a1fe2d1f3273a8e4a9185abf2ff86448cc98bfa435e3d68306a2b8b4a6a3ea33a155be3cb62a2170a86f77679a5\",\n    \"0xb117b1ea381adce87d8b342cba3a15d492ff2d644afa28f22424cb9cbc820d4f7693dfc1a4d1b3697046c300e1c9b4c8\",\n    \"0x9004c425a2e68870d6c69b658c344e3aa3a86a8914ee08d72b2f95c2e2d8a4c7bb0c6e7e271460c0e637cec11117bf8e\",\n    \"0x86a18aa4783b9ebd9131580c8b17994825f27f4ac427b0929a1e0236907732a1c8139e98112c605488ee95f48bbefbfc\",\n    \"0x84042243b955286482ab6f0b5df4c2d73571ada00716d2f737ca05a0d2e88c6349e8ee9e67934cfee4a1775dbf7f4800\",\n    \"0x92c2153a4733a62e4e1d5b60369f3c26777c7d01cd3c8679212660d572bd3bac9b8a8a64e1f10f7dbf5eaa7579c4e423\",\n    \"0x918454b6bb8e44a2afa144695ba8d48ae08d0cdfef4ad078f67709eddf3bb31191e8b006f04e82ea45a54715ef4d5817\",\n    \"0xacf0b54f6bf34cf6ed6c2b39cf43194a40d68de6bcf1e4b82c34c15a1343e9ac3737885e1a30b78d01fa3a5125463db8\",\n    \"0xa7d60dbe4b6a7b054f7afe9ee5cbbfeca0d05dc619e6041fa2296b549322529faddb8a11e949562309aecefb842ac380\",\n    \"0x91ffb53e6d7e5f11159eaf13e783d6dbdfdb1698ed1e6dbf3413c6ea23492bbb9e0932230a9e2caac8fe899a17682795\",\n    \"0xb6e8d7be5076ee3565d5765a710c5ecf17921dd3cf555c375d01e958a365ae087d4a88da492a5fb81838b7b92bf01143\",\n    \"0xa8c6b763de2d4b2ed42102ef64eccfef31e2fb2a8a2776241c82912fa50fc9f77f175b6d109a97ede331307c016a4b1a\",\n    \"0x99839f86cb700c297c58bc33e28d46b92931961548deac29ba8df91d3e11721b10ea956c8e16984f9e4acf1298a79b37\",\n    \"0x8c2e2c338f25ea5c25756b7131cde0d9a2b35abf5d90781180a00fe4b8e64e62590dc63fe10a57fba3a31c76d784eb01\",\n    \"0x9687d7df2f41319ca5469d91978fed0565a5f11f829ebadaa83db92b221755f76c6eacd7700735e75c91e257087512e3\",\n    \"0x8795fdfb7ff8439c58b9bf58ed53873d2780d3939b902b9ddaaa4c99447224ced9206c3039a23c2c44bcc461e2bb637f\",\n    \"0xa803697b744d2d087f4e2307218d48fa88620cf25529db9ce71e2e3bbcc65bac5e8bb9be04777ef7bfb5ed1a5b8e6170\",\n    \"0x80f3d3efbbb9346ddd413f0a8e36b269eb5d7ff6809d5525ff9a47c4bcab2c01b70018b117f6fe05253775612ff70c6b\",\n    \"0x9050e0e45bcc83930d4c505af35e5e4d7ca01cd8681cba92eb55821aececcebe32bb692ebe1a4daac4e7472975671067\",\n    \"0x8d206812aac42742dbaf233e0c080b3d1b30943b54b60283515da005de05ea5caa90f91fedcfcba72e922f64d7040189\",\n    \"0xa2d44faaeb2eff7915c83f32b13ca6f31a6847b1c1ce114ea240bac3595eded89f09b2313b7915ad882292e2b586d5b4\",\n    \"0x961776c8576030c39f214ea6e0a3e8b3d32f023d2600958c098c95c8a4e374deeb2b9dc522adfbd6bda5949bdc09e2a2\",\n    \"0x993fa7d8447407af0fbcd9e6d77f815fa5233ab00674efbcf74a1f51c37481445ae291cc7b76db7c178f9cb0e570e0fc\",\n    \"0xabd5b1c78e05f9d7c8cc99bdaef8b0b6a57f2daf0f02bf492bec48ea4a27a8f1e38b5854da96efff11973326ff980f92\",\n    \"0x8f15af4764bc275e6ccb892b3a4362cacb4e175b1526a9a99944e692fe6ccb1b4fc19abf312bb2a089cb1f344d91a779\",\n    \"0xa09b27ccd71855512aba1d0c30a79ffbe7f6707a55978f3ced50e674b511a79a446dbc6d7946add421ce111135a460af\",\n    \"0x94b2f98ce86a9271fbd4153e1fc37de48421fe3490fb3840c00f2d5a4d0ba8810c6a32880b002f6374b59e0a7952518b\",\n    \"0x8650ac644f93bbcb88a6a0f49fee2663297fd4bc6fd47b6a89b9d8038d32370438ab3a4775ec9b58cb10aea8a95ef7b6\",\n    \"0x95e5c2f2e84eed88c6980bbba5a1c0bb375d5a628bff006f7516d45bb7d723da676add4fdd45956f312e7bab0f052644\",\n    \"0xb3278a3fa377ac93af7cfc9453f8cb594aae04269bbc99d2e0e45472ff4b6a2f97a26c4c57bf675b9d86f5e77a5d55d1\",\n    \"0xb4bcbe6eb666a206e2ea2f877912c1d3b5bdbd08a989fc4490eb06013e1a69ad1ba08bcdac048bf29192312be399077b\",\n    \"0xa76d70b78c99fffcbf9bb9886eab40f1ea4f99a309710b660b64cbf86057cbcb644d243f6e341711bb7ef0fedf0435a7\",\n    \"0xb2093c1ee945dca7ac76ad5aed08eae23af31dd5a77c903fd7b6f051f4ab84425d33a03c3d45bf2907bc93c02d1f3ad8\",\n    \"0x904b1f7534e053a265b22d20be859912b9c9ccb303af9a8d6f1d8f6ccdc5c53eb4a45a1762b880d8444d9be0cd55e7f9\",\n    \"0x8f664a965d65bc730c9ef1ec7467be984d4b8eb46bd9b0d64e38e48f94e6e55dda19aeac82cbcf4e1473440e64c4ca18\",\n    \"0x8bcee65c4cc7a7799353d07b114c718a2aae0cd10a3f22b7eead5185d159dafd64852cb63924bf87627d176228878bce\",\n    \"0x8c78f2e3675096fef7ebaa898d2615cd50d39ca3d8f02b9bdfb07e67da648ae4be3da64838dffc5935fd72962c4b96c7\",\n    \"0x8c40afd3701629421fec1df1aac4e849384ef2e80472c0e28d36cb1327acdf2826f99b357f3d7afdbc58a6347fc40b3c\",\n    \"0xa197813b1c65a8ea5754ef782522a57d63433ef752215ecda1e7da76b0412ee619f58d904abd2e07e0c097048b6ae1dd\",\n    \"0xa670542629e4333884ad7410f9ea3bd6f988df4a8f8a424ca74b9add2312586900cf9ae8bd50411f9146e82626b4af56\",\n    \"0xa19875cc07ab84e569d98b8b67fb1dbbdfb59093c7b748fae008c8904a6fd931a63ca8d03ab5fea9bc8d263568125a9b\",\n    \"0xb57e7f68e4eb1bd04aafa917b1db1bdab759a02aa8a9cdb1cba34ba8852b5890f655645c9b4e15d5f19bf37e9f2ffe9f\",\n    \"0x8abe4e2a4f6462b6c64b3f10e45db2a53c2b0d3c5d5443d3f00a453e193df771eda635b098b6c8604ace3557514027af\",\n    \"0x8459e4fb378189b22b870a6ef20183deb816cefbf66eca1dc7e86d36a2e011537db893729f500dc154f14ce24633ba47\",\n    \"0x930851df4bc7913c0d8c0f7bd3b071a83668987ed7c397d3d042fdc0d9765945a39a3bae83da9c88cb6b686ed8aeeb26\",\n    \"0x8078c9e5cd05e1a8c932f8a1d835f61a248b6e7133fcbb3de406bf4ffc0e584f6f9f95062740ba6008d98348886cf76b\",\n    \"0xaddff62bb29430983fe578e3709b0949cdc0d47a13a29bc3f50371a2cb5c822ce53e2448cfaa01bcb6e0aa850d5a380e\",\n    \"0x9433add687b5a1e12066721789b1db2edf9b6558c3bdc0f452ba33b1da67426abe326e9a34d207bfb1c491c18811bde1\",\n    \"0x822beda3389963428cccc4a2918fa9a8a51cf0919640350293af70821967108cded5997adae86b33cb917780b097f1ca\",\n    \"0xa7a9f52bda45e4148ed56dd176df7bd672e9b5ed18888ccdb405f47920fdb0844355f8565cefb17010b38324edd8315f\",\n    \"0xb35c3a872e18e607b2555c51f9696a17fa18da1f924d503b163b4ec9fe22ed0c110925275cb6c93ce2d013e88f173d6a\",\n    \"0xadf34b002b2b26ab84fc1bf94e05bd8616a1d06664799ab149363c56a6e0c807fdc473327d25632416e952ea327fcd95\",\n    \"0xae4a6b9d22a4a3183fac29e2551e1124a8ce4a561a9a2afa9b23032b58d444e6155bb2b48f85c7b6d70393274e230db7\",\n    \"0xa2ea3be4fc17e9b7ce3110284038d46a09e88a247b6971167a7878d9dcf36925d613c382b400cfa4f37a3ebea3699897\",\n    \"0x8e5863786b641ce3140fbfe37124d7ad3925472e924f814ebfc45959aaf3f61dc554a597610b5defaecc85b59a99b50f\",\n    \"0xaefde3193d0f700d0f515ab2aaa43e2ef1d7831c4f7859f48e52693d57f97fa9e520090f3ed700e1c966f4b76048e57f\",\n    \"0x841a50f772956622798e5cd208dc7534d4e39eddee30d8ce133383d66e5f267e389254a0cdae01b770ecd0a9ca421929\",\n    \"0x8fbc2bfd28238c7d47d4c03b1b910946c0d94274a199575e5b23242619b1de3497784e646a92aa03e3e24123ae4fcaba\",\n    \"0x926999579c8eec1cc47d7330112586bdca20b4149c8b2d066f527c8b9f609e61ce27feb69db67eea382649c6905efcf9\",\n    \"0xb09f31f305efcc65589adf5d3690a76cf339efd67cd43a4e3ced7b839507466e4be72dd91f04e89e4bbef629d46e68c0\",\n    \"0xb917361f6b95f759642638e0b1d2b3a29c3bdef0b94faa30de562e6078c7e2d25976159df3edbacbf43614635c2640b4\",\n    \"0x8e7e8a1253bbda0e134d62bfe003a2669d471b47bd2b5cde0ff60d385d8e62279d54022f5ac12053b1e2d3aaa6910b4c\",\n    \"0xb69671a3c64e0a99d90b0ed108ce1912ff8ed983e4bddd75a370e9babde25ee1f5efb59ec707edddd46793207a8b1fe7\",\n    \"0x910b2f4ebd37b7ae94108922b233d0920b4aba0bd94202c70f1314418b548d11d8e9caa91f2cd95aff51b9432d122b7f\",\n    \"0x82f645c90dfb52d195c1020346287c43a80233d3538954548604d09fbab7421241cde8593dbc4acc4986e0ea39a27dd9\",\n    \"0x8fee895f0a140d88104ce442fed3966f58ff9d275e7373483f6b4249d64a25fb5374bbdc6bce6b5ab0270c2847066f83\",\n    \"0x84f5bd7aab27b2509397aeb86510dd5ac0a53f2c8f73799bf720f2f87a52277f8d6b0f77f17bc80739c6a7119b7eb062\",\n    \"0x9903ceced81099d7e146e661bcf01cbaccab5ba54366b85e2177f07e2d8621e19d9c9c3eee14b9266de6b3f9b6ea75ae\",\n    \"0xb9c16ea2a07afa32dd6c7c06df0dec39bca2067a9339e45475c98917f47e2320f6f235da353fd5e15b477de97ddc68dd\",\n    \"0x9820a9bbf8b826bec61ebf886de2c4f404c1ebdc8bab82ee1fea816d9de29127ce1852448ff717a3fe8bbfe9e92012e5\",\n    \"0x817224d9359f5da6f2158c2c7bf9165501424f063e67ba9859a07ab72ee2ee62eb00ca6da821cfa19065c3282ca72c74\",\n    \"0x94b95c465e6cb00da400558a3c60cfec4b79b27e602ca67cbc91aead08de4b6872d8ea096b0dc06dca4525c8992b8547\",\n    \"0xa2b539a5bccd43fa347ba9c15f249b417997c6a38c63517ca38394976baa08e20be384a360969ff54e7e721db536b3e5\",\n    \"0x96caf707e34f62811ee8d32ccf28d8d6ec579bc33e424d0473529af5315c456fd026aa910c1fed70c91982d51df7d3ca\",\n    \"0x8a77b73e890b644c6a142bdbac59b22d6a676f3b63ddafb52d914bb9d395b8bf5aedcbcc90429337df431ebd758a07a6\",\n    \"0x8857830a7351025617a08bc44caec28d2fae07ebf5ffc9f01d979ce2a53839a670e61ae2783e138313929129790a51a1\",\n    \"0xaa3e420321ed6f0aa326d28d1a10f13facec6f605b6218a6eb9cbc074801f3467bf013a456d1415a5536f12599efa3d3\",\n    \"0x824aed0951957b00ea2f3d423e30328a3527bf6714cf9abbae84cf27e58e5c35452ba89ccc011de7c68c75d6e021d8f1\",\n    \"0xa2e87cc06bf202e953fb1081933d8b4445527dde20e38ed1a4f440144fd8fa464a2b73e068b140562e9045e0f4bd3144\",\n    \"0xae3b8f06ad97d7ae3a5e5ca839efff3e4824dc238c0c03fc1a8d2fc8aa546cdfd165b784a31bb4dec7c77e9305b99a4b\",\n    \"0xb30c3e12395b1fb8b776f3ec9f87c70e35763a7b2ddc68f0f60a4982a84017f27c891a98561c830038deb033698ed7fc\",\n    \"0x874e507757cd1177d0dff0b0c62ce90130324442a33da3b2c8ee09dbca5d543e3ecfe707e9f1361e7c7db641c72794bb\",\n    \"0xb53012dd10b5e7460b57c092eaa06d6502720df9edbbe3e3f61a9998a272bf5baaac4a5a732ad4efe35d6fac6feca744\",\n    \"0x85e6509d711515534d394e6cacbed6c81da710074d16ef3f4950bf2f578d662a494d835674f79c4d6315bced4defc5f0\",\n    \"0xb6132b2a34b0905dcadc6119fd215419a7971fe545e52f48b768006944b4a9d7db1a74b149e2951ea48c083b752d0804\",\n    \"0x989867da6415036d19b4bacc926ce6f4df7a556f50a1ba5f3c48eea9cefbb1c09da81481c8009331ee83f0859185e164\",\n    \"0x960a6c36542876174d3fbc1505413e29f053ed87b8d38fef3af180491c7eff25200b45dd5fe5d4d8e63c7e8c9c00f4c8\",\n    \"0x9040b59bd739d9cc2e8f6e894683429e4e876a8106238689ff4c22770ae5fdae1f32d962b30301fa0634ee163b524f35\",\n    \"0xaf3fcd0a45fe9e8fe256dc7eab242ef7f582dd832d147444483c62787ac820fafc6ca55d639a73f76bfa5e7f5462ab8f\",\n    \"0xb934c799d0736953a73d91e761767fdb78454355c4b15c680ce08accb57ccf941b13a1236980001f9e6195801cffd692\",\n    \"0x8871e8e741157c2c326b22cf09551e78da3c1ec0fc0543136f581f1550f8bab03b0a7b80525c1e99812cdbf3a9698f96\",\n    \"0xa8a977f51473a91d178ee8cfa45ffef8d6fd93ab1d6e428f96a3c79816d9c6a93cd70f94d4deda0125fd6816e30f3bea\",\n    \"0xa7688b3b0a4fc1dd16e8ba6dc758d3cfe1b7cf401c31739484c7fa253cce0967df1b290769bcefc9d23d3e0cb19e6218\",\n    \"0x8ae84322662a57c6d729e6ff9d2737698cc2da2daeb1f39e506618750ed23442a6740955f299e4a15dda6db3e534d2c6\",\n    \"0xa04a961cdccfa4b7ef83ced17ab221d6a043b2c718a0d6cc8e6f798507a31f10bf70361f70a049bc8058303fa7f96864\",\n    \"0xb463e39732a7d9daec8a456fb58e54b30a6e160aa522a18b9a9e836488cce3342bcbb2e1deab0f5e6ec0a8796d77197d\",\n    \"0xb1434a11c6750f14018a2d3bcf94390e2948f4f187e93bb22070ca3e5393d339dc328cbfc3e48815f51929465ffe7d81\",\n    \"0x84ff81d73f3828340623d7e3345553610aa22a5432217ef0ebd193cbf4a24234b190c65ca0873c22d10ea7b63bd1fbed\",\n    \"0xb6fe2723f0c47757932c2ddde7a4f8434f665612f7b87b4009c2635d56b6e16b200859a8ade49276de0ef27a2b6c970a\",\n    \"0x9742884ed7cd52b4a4a068a43d3faa02551a424136c85a9313f7cb58ea54c04aa83b0728fd741d1fe39621e931e88f8f\",\n    \"0xb7d2d65ea4d1ad07a5dee39e40d6c03a61264a56b1585b4d76fc5b2a68d80a93a42a0181d432528582bf08d144c2d6a9\",\n    \"0x88c0f66bada89f8a43e5a6ead2915088173d106c76f724f4a97b0f6758aed6ae5c37c373c6b92cdd4aea8f6261f3a374\",\n    \"0x81f9c43582cb42db3900747eb49ec94edb2284999a499d1527f03315fd330e5a509afa3bff659853570e9886aab5b28b\",\n    \"0x821f9d27d6beb416abf9aa5c79afb65a50ed276dbda6060103bc808bcd34426b82da5f23e38e88a55e172f5c294b4d40\",\n    \"0x8ba307b9e7cb63a6c4f3851b321aebfdb6af34a5a4c3bd949ff7d96603e59b27ff4dc4970715d35f7758260ff942c9e9\",\n    \"0xb142eb6c5f846de33227d0bda61d445a7c33c98f0a8365fe6ab4c1fabdc130849be597ef734305894a424ea715372d08\",\n    \"0xa732730ae4512e86a741c8e4c87fee8a05ee840fec0e23b2e037d58dba8dde8d10a9bc5191d34d00598941becbbe467f\",\n    \"0xadce6f7c30fd221f6b10a0413cc76435c4bb36c2d60bca821e5c67409fe9dbb2f4c36ef85eb3d734695e4be4827e9fd3\",\n    \"0xa74f00e0f9b23aff7b2527ce69852f8906dab9d6abe62ecd497498ab21e57542e12af9918d4fd610bb09e10b0929c510\",\n    \"0xa593b6b0ef26448ce4eb3ab07e84238fc020b3cb10d542ff4b16d4e2be1bcde3797e45c9cf753b8dc3b0ffdb63984232\",\n    \"0xaed3913afccf1aa1ac0eb4980eb8426d0baccebd836d44651fd72af00d09fac488a870223c42aca3ceb39752070405ae\",\n    \"0xb2c44c66a5ea7fde626548ba4cef8c8710191343d3dadfd3bb653ce715c0e03056a5303a581d47dde66e70ea5a2d2779\",\n    \"0x8e5029b2ccf5128a12327b5103f7532db599846e422531869560ceaff392236434d87159f597937dbf4054f810c114f4\",\n    \"0x82beed1a2c4477e5eb39fc5b0e773b30cfec77ef2b1bf17eadaf60eb35b6d0dd9d8cf06315c48d3546badb3f21cd0cca\",\n    \"0x90077bd6cc0e4be5fff08e5d07a5a158d36cebd1d1363125bc4fae0866ffe825b26f933d4ee5427ba5cd0c33c19a7b06\",\n    \"0xa7ec0d8f079970e8e34f0ef3a53d3e0e45428ddcef9cc776ead5e542ef06f3c86981644f61c5a637e4faf001fb8c6b3e\",\n    \"0xae6d4add6d1a6f90b22792bc9d40723ee6850c27d0b97eefafd5b7fd98e424aa97868b5287cc41b4fbd7023bca6a322c\",\n    \"0x831aa917533d077da07c01417feaa1408846363ba2b8d22c6116bb858a95801547dd88b7d7fa1d2e3f0a02bdeb2e103d\",\n    \"0x96511b860b07c8a5ed773f36d4aa9d02fb5e7882753bf56303595bcb57e37ccc60288887eb83bef08c657ec261a021a2\",\n    \"0x921d2a3e7e9790f74068623de327443666b634c8443aba80120a45bba450df920b2374d96df1ce3fb1b06dd06f8cf6e3\",\n    \"0xaa74451d51fe82b4581ead8e506ec6cd881010f7e7dd51fc388eb9a557db5d3c6721f81c151d08ebd9c2591689fbc13e\",\n    \"0xa972bfbcf4033d5742d08716c927c442119bdae336bf5dff914523b285ccf31953da2733759aacaa246a9af9f698342c\",\n    \"0xad1fcd0cae0e76840194ce4150cb8a56ebed728ec9272035f52a799d480dfc85840a4d52d994a18b6edb31e79be6e8ad\",\n    \"0xa2c69fe1d36f235215432dad48d75887a44c99dfa0d78149acc74087da215a44bdb5f04e6eef88ff7eff80a5a7decc77\",\n    \"0xa94ab2af2b6ee1bc6e0d4e689ca45380d9fbd3c5a65b9bd249d266a4d4c07bf5d5f7ef2ae6000623aee64027892bf8fe\",\n    \"0x881ec1fc514e926cdc66480ac59e139148ff8a2a7895a49f0dff45910c90cdda97b66441a25f357d6dd2471cddd99bb3\",\n    \"0x884e6d3b894a914c8cef946a76d5a0c8351843b2bffa2d1e56c6b5b99c84104381dd1320c451d551c0b966f4086e60f9\",\n    \"0x817c6c10ce2677b9fc5223500322e2b880583254d0bb0d247d728f8716f5e05c9ff39f135854342a1afecd9fbdcf7c46\",\n    \"0xaaf4a9cb686a14619aa1fc1ac285dd3843ac3dd99f2b2331c711ec87b03491c02f49101046f3c5c538dc9f8dba2a0ac2\",\n    \"0x97ecea5ce53ca720b5d845227ae61d70269a2f53540089305c86af35f0898bfd57356e74a8a5e083fa6e1ea70080bd31\",\n    \"0xa22d811e1a20a75feac0157c418a4bfe745ccb5d29466ffa854dca03e395b6c3504a734341746b2846d76583a780b32e\",\n    \"0x940cbaa0d2b2db94ae96b6b9cf2deefbfd059e3e5745de9aec4a25f0991b9721e5cd37ef71c631575d1a0c280b01cd5b\",\n    \"0xae33cb4951191258a11044682de861bf8d92d90ce751b354932dd9f3913f542b6a0f8a4dc228b3cd9244ac32c4582832\",\n    \"0xa580df5e58c4274fe0f52ac2da1837e32f5c9db92be16c170187db4c358f43e5cfdda7c5911dcc79d77a5764e32325f5\",\n    \"0x81798178cb9d8affa424f8d3be67576ba94d108a28ccc01d330c51d5a63ca45bb8ca63a2f569b5c5fe1303cecd2d777f\",\n    \"0x89975b91b94c25c9c3660e4af4047a8bacf964783010820dbc91ff8281509379cb3b24c25080d5a01174dd9a049118d5\",\n    \"0xa7327fcb3710ed3273b048650bde40a32732ef40a7e58cf7f2f400979c177944c8bc54117ba6c80d5d4260801dddab79\",\n    \"0x92b475dc8cb5be4b90c482f122a51bcb3b6c70593817e7e2459c28ea54a7845c50272af38119406eaadb9bcb993368d0\",\n    \"0x9645173e9ecefc4f2eae8363504f7c0b81d85f8949a9f8a6c01f2d49e0a0764f4eacecf3e94016dd407fc14494fce9f9\",\n    \"0x9215fd8983d7de6ae94d35e6698226fc1454977ae58d42d294be9aad13ac821562ad37d5e7ee5cdfe6e87031d45cd197\",\n    \"0x810360a1c9b88a9e36f520ab5a1eb8bed93f52deefbe1312a69225c0a08edb10f87cc43b794aced9c74220cefcc57e7d\",\n    \"0xad7e810efd61ed4684aeda9ed8bb02fb9ae4b4b63fda8217d37012b94ff1b91c0087043bfa4e376f961fff030c729f3b\",\n    \"0x8b07c95c6a06db8738d10bb03ec11b89375c08e77f0cab7e672ce70b2685667ca19c7e1c8b092821d31108ea18dfd4c7\",\n    \"0x968825d025ded899ff7c57245250535c732836f7565eab1ae23ee7e513201d413c16e1ba3f5166e7ac6cf74de8ceef4f\",\n    \"0x908243370c5788200703ade8164943ad5f8c458219186432e74dbc9904a701ea307fd9b94976c866e6c58595fd891c4b\",\n    \"0x959969d16680bc535cdc6339e6186355d0d6c0d53d7bbfb411641b9bf4b770fd5f575beef5deec5c4fa4d192d455c350\",\n    \"0xad177f4f826a961adeac76da40e2d930748effff731756c797eddc4e5aa23c91f070fb69b19221748130b0961e68a6bb\",\n    \"0x82f8462bcc25448ef7e0739425378e9bb8a05e283ce54aae9dbebaf7a3469f57833c9171672ad43a79778366c72a5e37\",\n    \"0xa28fb275b1845706c2814d9638573e9bc32ff552ebaed761fe96fdbce70395891ca41c400ae438369264e31a2713b15f\",\n    \"0x8a9c613996b5e51dadb587a787253d6081ea446bf5c71096980bf6bd3c4b69905062a8e8a3792de2d2ece3b177a71089\",\n    \"0x8d5aefef9f60cb27c1db2c649221204dda48bb9bf8bf48f965741da051340e8e4cab88b9d15c69f3f84f4c854709f48a\",\n    \"0x93ebf2ca6ad85ab6deace6de1a458706285b31877b1b4d7dcb9d126b63047efaf8c06d580115ec9acee30c8a7212fa55\",\n    \"0xb3ee46ce189956ca298057fa8223b7fd1128cf52f39159a58bca03c71dd25161ac13f1472301f72aef3e1993fe1ab269\",\n    \"0xa24d7a8d066504fc3f5027ccb13120e2f22896860e02c45b5eba1dbd512d6a17c28f39155ea581619f9d33db43a96f92\",\n    \"0xae9ceacbfe12137db2c1a271e1b34b8f92e4816bad1b3b9b6feecc34df0f8b3b0f7ed0133acdf59c537d43d33fc8d429\",\n    \"0x83967e69bf2b361f86361bd705dce0e1ad26df06da6c52b48176fe8dfcbeb03c462c1a4c9e649eff8c654b18c876fdef\",\n    \"0x9148e6b814a7d779c19c31e33a068e97b597de1f8100513db3c581190513edc4d544801ce3dd2cf6b19e0cd6daedd28a\",\n    \"0x94ccdafc84920d320ed22de1e754adea072935d3c5f8c2d1378ebe53d140ea29853f056fb3fb1e375846061a038cc9bc\",\n    \"0xafb43348498c38b0fa5f971b8cdd3a62c844f0eb52bc33daf2f67850af0880fce84ecfb96201b308d9e6168a0d443ae3\",\n    \"0x86d5736520a83538d4cd058cc4b4e84213ed00ebd6e7af79ae787adc17a92ba5359e28ba6c91936d967b4b28d24c3070\",\n    \"0xb5210c1ff212c5b1e9ef9126e08fe120a41e386bb12c22266f7538c6d69c7fd8774f11c02b81fd4e88f9137b020801fe\",\n    \"0xb78cfd19f94d24e529d0f52e18ce6185cb238edc6bd43086270fd51dd99f664f43dd4c7d2fe506762fbd859028e13fcf\",\n    \"0xa6e7220598c554abdcc3fdc587b988617b32c7bb0f82c06205467dbedb58276cc07cae317a190f19d19078773f4c2bbb\",\n    \"0xb88862809487ee430368dccd85a5d72fa4d163ca4aad15c78800e19c1a95be2192719801e315d86cff7795e0544a77e4\",\n    \"0x87ecb13a03921296f8c42ceb252d04716f10e09c93962239fcaa0a7fef93f19ab3f2680bc406170108bc583e9ff2e721\",\n    \"0xa810cd473832b6581c36ec4cb403f2849357ba2d0b54df98ef3004b8a530c078032922a81d40158f5fb0043d56477f6e\",\n    \"0xa247b45dd85ca7fbb718b328f30a03f03c84aef2c583fbdc9fcc9eb8b52b34529e8c8f535505c10598b1b4dac3d7c647\",\n    \"0x96ee0b91313c68bac4aa9e065ce9e1d77e51ca4cff31d6a438718c58264dee87674bd97fc5c6b8008be709521e4fd008\",\n    \"0x837567ad073e42266951a9a54750919280a2ac835a73c158407c3a2b1904cf0d17b7195a393c71a18ad029cbd9cf79ee\",\n    \"0xa6a469c44b67ebf02196213e7a63ad0423aab9a6e54acc6fcbdbb915bc043586993454dc3cd9e4be8f27d67c1050879b\",\n    \"0x8712d380a843b08b7b294f1f06e2f11f4ad6bcc655fdde86a4d8bc739c23916f6fad2b902fe47d6212f03607907e9f0e\",\n    \"0x920adfb644b534789943cdae1bdd6e42828dda1696a440af2f54e6b97f4f97470a1c6ea9fa6a2705d8f04911d055acd1\",\n    \"0xa161c73adf584a0061e963b062f59d90faac65c9b3a936b837a10d817f02fcabfa748824607be45a183dd40f991fe83f\",\n    \"0x874f4ecd408c76e625ea50bc59c53c2d930ee25baf4b4eca2440bfbffb3b8bc294db579caa7c68629f4d9ec24187c1ba\",\n    \"0x8bff18087f112be7f4aa654e85c71fef70eee8ae480f61d0383ff6f5ab1a0508f966183bb3fc4d6f29cb7ca234aa50d3\",\n    \"0xb03b46a3ca3bc743a173cbc008f92ab1aedd7466b35a6d1ca11e894b9482ea9dc75f8d6db2ddd1add99bfbe7657518b7\",\n    \"0x8b4f3691403c3a8ad9e097f02d130769628feddfa8c2b3dfe8cff64e2bed7d6e5d192c1e2ba0ac348b8585e94acd5fa1\",\n    \"0xa0d9ca4a212301f97591bf65d5ef2b2664766b427c9dd342e23cb468426e6a56be66b1cb41fea1889ac5d11a8e3c50a5\",\n    \"0x8c93ed74188ca23b3df29e5396974b9cc135c91fdefdea6c0df694c8116410e93509559af55533a3776ac11b228d69b1\",\n    \"0x82dd331fb3f9e344ebdeeb557769b86a2cc8cc38f6c298d7572a33aea87c261afa9dbd898989139b9fc16bc1e880a099\",\n    \"0xa65faedf326bcfd8ef98a51410c78b021d39206704e8291cd1f09e096a66b9b0486be65ff185ca224c45918ac337ddeb\",\n    \"0xa188b37d363ac072a766fd5d6fa27df07363feff1342217b19e3c37385e42ffde55e4be8355aceaa2f267b6d66b4ac41\",\n    \"0x810fa3ba3e96d843e3bafd3f2995727f223d3567c8ba77d684c993ba1773c66551eb5009897c51b3fe9b37196984f5ec\",\n    \"0x87631537541852da323b4353af45a164f68b304d24c01183bf271782e11687f3fcf528394e1566c2a26cb527b3148e64\",\n    \"0xb721cb2b37b3c477a48e3cc0044167d51ff568a5fd2fb606e5aec7a267000f1ddc07d3db919926ae12761a8e017c767c\",\n    \"0x904dfad4ba2cc1f6e60d1b708438a70b1743b400164cd981f13c064b8328d5973987d4fb9cf894068f29d3deaf624dfb\",\n    \"0xa70491538893552c20939fae6be2f07bfa84d97e2534a6bbcc0f1729246b831103505e9f60e97a8fa7d2e6c1c2384579\",\n    \"0x8726cf1b26b41f443ff7485adcfddc39ace2e62f4d65dd0bb927d933e262b66f1a9b367ded5fbdd6f3b0932553ac1735\",\n    \"0xae8a11cfdf7aa54c08f80cb645e3339187ab3886babe9fae5239ba507bb3dd1c0d161ca474a2df081dcd3d63e8fe445e\",\n    \"0x92328719e97ce60e56110f30a00ac5d9c7a2baaf5f8d22355d53c1c77941e3a1fec7d1405e6fbf8959665fe2ba7a8cad\",\n    \"0x8d9d6255b65798d0018a8cccb0b6343efd41dc14ff2058d3eed9451ceaad681e4a0fa6af67b0a04318aa628024e5553d\",\n    \"0xb70209090055459296006742d946a513f0cba6d83a05249ee8e7a51052b29c0ca9722dc4af5f9816a1b7938a5dac7f79\",\n    \"0xaab7b766b9bf91786dfa801fcef6d575dc6f12b77ecc662eb4498f0312e54d0de9ea820e61508fc8aeee5ab5db529349\",\n    \"0xa8104b462337748b7f086a135d0c3f87f8e51b7165ca6611264b8fb639d9a2f519926cb311fa2055b5fadf03da70c678\",\n    \"0xb0d2460747d5d8b30fc6c6bd0a87cb343ddb05d90a51b465e8f67d499cfc5e3a9e365da05ae233bbee792cdf90ec67d5\",\n    \"0xaa55f5bf3815266b4a149f85ed18e451c93de9163575e3ec75dd610381cc0805bb0a4d7c4af5b1f94d10231255436d2c\",\n    \"0x8d4c6a1944ff94426151909eb5b99cfd92167b967dabe2bf3aa66bb3c26c449c13097de881b2cfc1bf052862c1ef7b03\",\n    \"0x8862296162451b9b6b77f03bf32e6df71325e8d7485cf3335d66fd48b74c2a8334c241db8263033724f26269ad95b395\",\n    \"0x901aa96deb26cda5d9321190ae6624d357a41729d72ef1abfd71bebf6139af6d690798daba53b7bc5923462115ff748a\",\n    \"0x96c195ec4992728a1eb38cdde42d89a7bce150db43adbc9e61e279ea839e538deec71326b618dd39c50d589f78fc0614\",\n    \"0xb6ff8b8aa0837b99a1a8b46fb37f20ad4aecc6a98381b1308697829a59b8442ffc748637a88cb30c9b1f0f28a926c4f6\",\n    \"0x8d807e3dca9e7bef277db1d2cfb372408dd587364e8048b304eff00eacde2c723bfc84be9b98553f83cba5c7b3cba248\",\n    \"0x8800c96adb0195c4fc5b24511450dee503c32bf47044f5e2e25bd6651f514d79a2dd9b01cd8c09f3c9d3859338490f57\",\n    \"0x89fe366096097e38ec28dd1148887112efa5306cc0c3da09562aafa56f4eb000bf46ff79bf0bdd270cbde6bf0e1c8957\",\n    \"0xaf409a90c2776e1e7e3760b2042507b8709e943424606e31e791d42f17873a2710797f5baaab4cc4a19998ef648556b0\",\n    \"0x8d761863c9b6edbd232d35ab853d944f5c950c2b643f84a1a1327ebb947290800710ff01dcfa26dc8e9828481240e8b1\",\n    \"0x90b95e9be1e55c463ed857c4e0617d6dc3674e99b6aa62ed33c8e79d6dfcf7d122f4f4cc2ee3e7c5a49170cb617d2e2e\",\n    \"0xb3ff381efefabc4db38cc4727432e0301949ae4f16f8d1dea9b4f4de611cf5a36d84290a0bef160dac4e1955e516b3b0\",\n    \"0xa8a84564b56a9003adcadb3565dc512239fc79572762cda7b5901a255bc82656bb9c01212ad33d6bef4fbbce18dacc87\",\n    \"0x90a081890364b222eef54bf0075417f85e340d2fec8b7375995f598aeb33f26b44143ebf56fca7d8b4ebb36b5747b0eb\",\n    \"0xade6ee49e1293224ddf2d8ab7f14bb5be6bc6284f60fd5b3a1e0cf147b73cff57cf19763b8a36c5083badc79c606b103\",\n    \"0xb2fa99806dd2fa3de09320b615a2570c416c9bcdb052e592b0aead748bbe407ec9475a3d932ae48b71c2627eb81986a6\",\n    \"0x91f3b7b73c8ccc9392542711c45fe6f236057e6efad587d661ad5cb4d6e88265f86b807bb1151736b1009ab74fd7acb4\",\n    \"0x8800e2a46af96696dfbdcbf2ca2918b3dcf28ad970170d2d1783b52b8d945a9167d052beeb55f56c126da7ffa7059baa\",\n    \"0x9862267a1311c385956b977c9aa08548c28d758d7ba82d43dbc3d0a0fd1b7a221d39e8399997fea9014ac509ff510ac4\",\n    \"0xb7d24f78886fd3e2d283e18d9ad5a25c1a904e7d9b9104bf47da469d74f34162e27e531380dbbe0a9d051e6ffd51d6e7\",\n    \"0xb0f445f9d143e28b9df36b0f2c052da87ee2ca374d9d0fbe2eff66ca6fe5fe0d2c1951b428d58f7314b7e74e45d445ea\",\n    \"0xb63fc4083eabb8437dafeb6a904120691dcb53ce2938b820bb553da0e1eecd476f72495aacb72600cf9cad18698fd3db\",\n    \"0xb9ffd8108eaebd582d665f8690fe8bb207fd85185e6dd9f0b355a09bac1bbff26e0fdb172bc0498df025414e88fe2eda\",\n    \"0x967ed453e1f1a4c5b7b6834cc9f75c13f6889edc0cc91dc445727e9f408487bbf05c337103f61397a10011dfbe25d61d\",\n    \"0x98ceb673aff36e1987d5521a3984a07079c3c6155974bb8b413e8ae1ce84095fe4f7862fba7aefa14753eb26f2a5805f\",\n    \"0x85f01d28603a8fdf6ce6a50cb5c44f8a36b95b91302e3f4cd95c108ce8f4d212e73aec1b8d936520d9226802a2bd9136\",\n    \"0x88118e9703200ca07910345fbb789e7a8f92bd80bbc79f0a9e040e8767d33df39f6eded403a9b636eabf9101e588482a\",\n    \"0x90833a51eef1b10ed74e8f9bbd6197e29c5292e469c854eed10b0da663e2bceb92539710b1858bbb21887bd538d28d89\",\n    \"0xb513b905ec19191167c6193067b5cfdf5a3d3828375360df1c7e2ced5815437dfd37f0c4c8f009d7fb29ff3c8793f560\",\n    \"0xb1b6d405d2d18f9554b8a358cc7e2d78a3b34269737d561992c8de83392ac9a2857be4bf15de5a6c74e0c9d0f31f393c\",\n    \"0xb828bd3e452b797323b798186607849f85d1fb20c616833c0619360dfd6b3e3aa000fd09dafe4b62d74abc41072ff1a9\",\n    \"0x8efde67d0cca56bb2c464731879c9ac46a52e75bac702a63200a5e192b4f81c641f855ca6747752b84fe469cb7113b6c\",\n    \"0xb2762ba1c89ac3c9a983c242e4d1c2610ff0528585ed5c0dfc8a2c0253551142af9b59f43158e8915a1da7cc26b9df67\",\n    \"0x8a3f1157fb820d1497ef6b25cd70b7e16bb8b961b0063ad340d82a79ee76eb2359ca9e15e6d42987ed7f154f5eeaa2da\",\n    \"0xa75e29f29d38f09c879f971c11beb5368affa084313474a5ecafa2896180b9e47ea1995c2733ec46f421e395a1d9cffe\",\n    \"0x8e8c3dd3e7196ef0b4996b531ec79e4a1f211db5d5635e48ceb80ff7568b2ff587e845f97ee703bb23a60945ad64314a\",\n    \"0x8e7f32f4a3e3c584af5e3d406924a0aa34024c42eca74ef6cc2a358fd3c9efaf25f1c03aa1e66bb94b023a2ee2a1cace\",\n    \"0xab7dce05d59c10a84feb524fcb62478906b3fa045135b23afbede3bb32e0c678d8ebe59feabccb5c8f3550ea76cae44b\",\n    \"0xb38bb4b44d827f6fd3bd34e31f9186c59e312dbfadd4a7a88e588da10146a78b1f8716c91ad8b806beb8da65cab80c4c\",\n    \"0x9490ce9442bbbd05438c7f5c4dea789f74a7e92b1886a730544b55ba377840740a3ae4f2f146ee73f47c9278b0e233bc\",\n    \"0x83c003fab22a7178eed1a668e0f65d4fe38ef3900044e9ec63070c23f2827d36a1e73e5c2b883ec6a2afe2450171b3b3\",\n    \"0x9982f02405978ddc4fca9063ebbdb152f524c84e79398955e66fe51bc7c1660ec1afc3a86ec49f58d7b7dde03505731c\",\n    \"0xab337bd83ccdd2322088ffa8d005f450ced6b35790f37ab4534313315ee84312adc25e99cce052863a8bedee991729ed\",\n    \"0x8312ce4bec94366d88f16127a17419ef64285cd5bf9e5eda010319b48085966ed1252ed2f5a9fd3e0259b91bb65f1827\",\n    \"0xa60d5a6327c4041b0c00a1aa2f0af056520f83c9ce9d9ccd03a0bd4d9e6a1511f26a422ea86bd858a1f77438adf07e6c\",\n    \"0xb84a0a0b030bdad83cf5202aa9afe58c9820e52483ab41f835f8c582c129ee3f34aa096d11c1cd922eda02ea1196a882\",\n    \"0x8077d105317f4a8a8f1aadeb05e0722bb55f11abcb490c36c0904401107eb3372875b0ac233144829e734f0c538d8c1d\",\n    \"0x9202503bd29a6ec198823a1e4e098f9cfe359ed51eb5174d1ca41368821bfeebcbd49debfd02952c41359d1c7c06d2b1\",\n    \"0xabc28c155e09365cb77ffead8dc8f602335ef93b2f44e4ef767ce8fc8ef9dd707400f3a722e92776c2e0b40192c06354\",\n    \"0xb0f6d1442533ca45c9399e0a63a11f85ff288d242cea6cb3b68c02e77bd7d158047cae2d25b3bcd9606f8f66d9b32855\",\n    \"0xb01c3d56a0db84dc94575f4b6ee2de4beca3230e86bed63e2066beb22768b0a8efb08ebaf8ac3dedb5fe46708b084807\",\n    \"0x8c8634b0432159f66feaabb165842d1c8ac378f79565b1b90c381aa8450eb4231c3dad11ec9317b9fc2b155c3a771e32\",\n    \"0x8e67f623d69ecd430c9ee0888520b6038f13a2b6140525b056dc0951f0cfed2822e62cf11d952a483107c5c5acac4826\",\n    \"0x9590bb1cba816dd6acd5ac5fba5142c0a19d53573e422c74005e0bcf34993a8138c83124cad35a3df65879dba6134edd\",\n    \"0x801cd96cde0749021a253027118d3ea135f3fcdbe895db08a6c145641f95ebd368dd6a1568d995e1d0084146aebe224a\",\n    \"0x848b5d196427f6fc1f762ee3d36e832b64a76ec1033cfedc8b985dea93932a7892b8ef1035c653fb9dcd9ab2d9a44ac8\",\n    \"0xa1017eb83d5c4e2477e7bd2241b2b98c4951a3b391081cae7d75965cadc1acaec755cf350f1f3d29741b0828e36fedea\",\n    \"0x8d6d2785e30f3c29aad17bd677914a752f831e96d46caf54446d967cb2432be2c849e26f0d193a60bee161ea5c6fe90a\",\n    \"0x935c0ba4290d4595428e034b5c8001cbd400040d89ab00861108e8f8f4af4258e41f34a7e6b93b04bc253d3b9ffc13bf\",\n    \"0xaac02257146246998477921cef2e9892228590d323b839f3e64ea893b991b463bc2f47e1e5092ddb47e70b2f5bce7622\",\n    \"0xb921fde9412970a5d4c9a908ae8ce65861d06c7679af577cf0ad0d5344c421166986bee471fd6a6cecb7d591f06ec985\",\n    \"0x8ef4c37487b139d6756003060600bb6ebac7ea810b9c4364fc978e842f13ac196d1264fbe5af60d76ff6d9203d8e7d3f\",\n    \"0x94b65e14022b5cf6a9b95f94be5ace2711957c96f4211c3f7bb36206bd39cfbd0ea82186cab5ad0577a23214a5c86e9e\",\n    \"0xa31c166d2a2ca1d5a75a5920fef7532681f62191a50d8555fdaa63ba4581c3391cc94a536fc09aac89f64eafceec3f90\",\n    \"0x919a8cc128de01e9e10f5d83b08b52293fdd41bde2b5ae070f3d95842d4a16e5331cf2f3d61c765570c8022403610fa4\",\n    \"0xb23d6f8331eef100152d60483cfa14232a85ee712c8538c9b6417a5a7c5b353c2ac401390c6c215cb101f5cee6b5f43e\",\n    \"0xab357160c08a18319510a571eafff154298ce1020de8e1dc6138a09fcb0fcbcdd8359f7e9386bda00b7b9cdea745ffdc\",\n    \"0xab55079aea34afa5c0bd1124b9cdfe01f325b402fdfa017301bf87812eaa811ea5798c3aaf818074d420d1c782b10ada\",\n    \"0xade616010dc5009e7fc4f8d8b00dc716686a5fa0a7816ad9e503e15839d3b909b69d9dd929b7575376434ffec0d2bea8\",\n    \"0x863997b97ed46898a8a014599508fa3079f414b1f4a0c4fdc6d74ae8b444afa350f327f8bfc2a85d27f9e2d049c50135\",\n    \"0x8d602ff596334efd4925549ed95f2aa762b0629189f0df6dbb162581657cf3ea6863cd2287b4d9c8ad52813d87fcd235\",\n    \"0xb70f68c596dcdeed92ad5c6c348578b26862a51eb5364237b1221e840c47a8702f0fbc56eb520a22c0eed99795d3903e\",\n    \"0x9628088f8e0853cefadee305a8bf47fa990c50fa96a82511bbe6e5dc81ef4b794e7918a109070f92fc8384d77ace226f\",\n    \"0x97e26a46e068b605ce96007197ecd943c9a23881862f4797a12a3e96ba2b8d07806ad9e2a0646796b1889c6b7d75188c\",\n    \"0xb1edf467c068cc163e2d6413cc22b16751e78b3312fe47b7ea82b08a1206d64415b2c8f2a677fa89171e82cc49797150\",\n    \"0xa44d15ef18745b251429703e3cab188420e2d974de07251501799b016617f9630643fcd06f895634d8ecdd579e1bf000\",\n    \"0xabd126df3917ba48c618ee4dbdf87df506193462f792874439043fa1b844466f6f4e0ff2e42516e63b5b23c0892b2695\",\n    \"0xa2a67f57c4aa3c2aa1eeddbfd5009a89c26c2ce8fa3c96a64626aba19514beb125f27df8559506f737de3eae0f1fc18f\",\n    \"0xa633e0132197e6038197304b296ab171f1d8e0d0f34dcf66fe9146ac385b0239232a8470b9205a4802ab432389f4836d\",\n    \"0xa914b3a28509a906c3821463b936455d58ff45dcbe158922f9efb2037f2eb0ce8e92532d29b5d5a3fcd0d23fa773f272\",\n    \"0xa0e1412ce4505daf1a2e59ce4f0fc0e0023e335b50d2b204422f57cd65744cc7a8ed35d5ef131a42c70b27111d3115b7\",\n    \"0xa2339e2f2b6072e88816224fdd612c04d64e7967a492b9f8829db15367f565745325d361fd0607b0def1be384d010d9e\",\n    \"0xa7309fc41203cb99382e8193a1dcf03ac190a7ce04835304eb7e341d78634e83ea47cb15b885601956736d04cdfcaa01\",\n    \"0x81f3ccd6c7f5b39e4e873365f8c37b214e8ab122d04a606fbb7339dc3298c427e922ec7418002561d4106505b5c399ee\",\n    \"0x92c121cf914ca549130e352eb297872a63200e99b148d88fbc9506ad882bec9d0203d65f280fb5b0ba92e336b7f932e8\",\n    \"0xa4b330cf3f064f5b131578626ad7043ce2a433b6f175feb0b52d36134a454ca219373fd30d5e5796410e005b69082e47\",\n    \"0x86fe5774112403ad83f9c55d58317eeb17ad8e1176d9f2f69c2afb7ed83bc718ed4e0245ceab4b377f5f062dcd4c00e7\",\n    \"0x809d152a7e2654c7fd175b57f7928365a521be92e1ed06c05188a95864ddb25f7cab4c71db7d61bbf4cae46f3a1d96ce\",\n    \"0xb82d663e55c2a5ada7e169e9b1a87bc1c0177baf1ec1c96559b4cb1c5214ce1ddf2ab8d345014cab6402f3774235cf5a\",\n    \"0x86580af86df1bd2c385adb8f9a079e925981b7184db66fc5fe5b14cddb82e7d836b06eaeef14924ac529487b23dae111\",\n    \"0xb5f5f4c5c94944ecc804df6ab8687d64e27d988cbfeae1ba7394e0f6adbf778c5881ead7cd8082dd7d68542b9bb4ecd5\",\n    \"0xa6016916146c2685c46e8fdd24186394e2d5496e77e08c0c6a709d4cd7dfa97f1efcef94922b89196819076a91ad37b5\",\n    \"0xb778e7367ded3b6eab53d5fc257f7a87e8faf74a593900f2f517220add2125be3f6142022660d8181df8d164ad9441ce\",\n    \"0x8581b2d36abe6f553add4d24be761bec1b8efaa2929519114346615380b3c55b59e6ad86990e312f7e234d0203bdf59b\",\n    \"0x9917e74fd45c3f71a829ff5498a7f6b5599b48c098dda2339bf04352bfc7f368ccf1a407f5835901240e76452ae807d7\",\n    \"0xafd196ce6f9335069138fd2e3d133134da253978b4ce373152c0f26affe77a336505787594022e610f8feb722f7cc1fb\",\n    \"0xa477491a1562e329764645e8f24d8e228e5ef28c9f74c6b5b3abc4b6a562c15ffb0f680d372aed04d9e1bf944dece7be\",\n    \"0x9767440d58c57d3077319d3a330e5322b9ba16981ec74a5a14d53462eab59ae7fd2b14025bfc63b268862094acb444e6\",\n    \"0x80986d921be3513ef69264423f351a61cb48390c1be8673aee0f089076086aaebea7ebe268fd0aa7182695606116f679\",\n    \"0xa9554c5c921c07b450ee04e34ec58e054ac1541b26ce2ce5a393367a97348ba0089f53db6660ad76b60278b66fd12e3e\",\n    \"0x95097e7d2999b3e84bf052c775581cf361325325f4a50192521d8f4693c830bed667d88f482dc1e3f833aa2bd22d2cbf\",\n    \"0x9014c91d0f85aefd28436b5228c12f6353c055a9326c7efbf5e071e089e2ee7c070fcbc84c5fafc336cbb8fa6fec1ca1\",\n    \"0x90f57ba36ee1066b55d37384942d8b57ae00f3cf9a3c1d6a3dfee1d1af42d4b5fa9baeb0cd7e46687d1d6d090ddb931d\",\n    \"0x8e4b1db12fd760a17214c9e47f1fce6e43c0dbb4589a827a13ac61aaae93759345697bb438a00edab92e0b7b62414683\",\n    \"0x8022a959a513cdc0e9c705e0fc04eafd05ff37c867ae0f31f6d01cddd5df86138a426cab2ff0ac8ff03a62e20f7e8f51\",\n    \"0x914e9a38829834c7360443b8ed86137e6f936389488eccf05b4b4db7c9425611705076ecb3f27105d24b85c852be7511\",\n    \"0x957fb10783e2bd0db1ba66b18e794df710bc3b2b05776be146fa5863c15b1ebdd39747b1a95d9564e1772cdfc4f37b8a\",\n    \"0xb6307028444daed8ed785ac9d0de76bc3fe23ff2cc7e48102553613bbfb5afe0ebe45e4212a27021c8eb870721e62a1f\",\n    \"0x8f76143597777d940b15a01b39c5e1b045464d146d9a30a6abe8b5d3907250e6c7f858ff2308f8591e8b0a7b3f3c568a\",\n    \"0x96163138ac0ce5fd00ae9a289648fd9300a0ca0f63a88481d703ecd281c06a52a3b5178e849e331f9c85ca4ba398f4cc\",\n    \"0xa63ef47c3e18245b0482596a09f488a716df3cbd0f9e5cfabed0d742843e65db8961c556f45f49762f3a6ac8b627b3ef\",\n    \"0x8cb595466552e7c4d42909f232d4063e0a663a8ef6f6c9b7ce3a0542b2459cde04e0e54c7623d404acb5b82775ac04f6\",\n    \"0xb47fe69960eb45f399368807cff16d941a5a4ebad1f5ec46e3dc8a2e4d598a7e6114d8f0ca791e9720fd786070524e2b\",\n    \"0x89eb5ff83eea9df490e5beca1a1fbbbbcf7184a37e2c8c91ede7a1e654c81e8cd41eceece4042ea7918a4f4646b67fd6\",\n    \"0xa84f5d155ed08b9054eecb15f689ba81e44589e6e7207a99790c598962837ca99ec12344105b16641ca91165672f7153\",\n    \"0xa6cc8f25c2d5b2d2f220ec359e6a37a52b95fa6af6e173c65e7cd55299eff4aa9e6d9e6f2769e6459313f1f2aecb0fab\",\n    \"0xafcde944411f017a9f7979755294981e941cc41f03df5e10522ef7c7505e5f1babdd67b3bf5258e8623150062eb41d9b\",\n    \"0x8fab39f39c0f40182fcd996ade2012643fe7731808afbc53f9b26900b4d4d1f0f5312d9d40b3df8baa4739970a49c732\",\n    \"0xae193af9726da0ebe7df1f9ee1c4846a5b2a7621403baf8e66c66b60f523e719c30c6b4f897bb14b27d3ff3da8392eeb\",\n    \"0x8ac5adb82d852eba255764029f42e6da92dcdd0e224d387d1ef94174038db9709ac558d90d7e7c57ad4ce7f89bbfc38c\",\n    \"0xa2066b3458fdf678ee487a55dd5bfb74fde03b54620cb0e25412a89ee28ad0d685e309a51e3e4694be2fa6f1593a344c\",\n    \"0x88d031745dd0ae07d61a15b594be5d4b2e2a29e715d081649ad63605e3404b0c3a5353f0fd9fad9c05c18e93ce674fa1\",\n    \"0x8283cfb0ef743a043f2b77ecaeba3005e2ca50435585b5dd24777ee6bce12332f85e21b446b536da38508807f0f07563\",\n    \"0xb376de22d5f6b0af0b59f7d9764561f4244cf8ffe22890ecd3dcf2ff1832130c9b821e068c9d8773136f4796721e5963\",\n    \"0xae3afc50c764f406353965363840bf28ee85e7064eb9d5f0bb3c31c64ab10f48c853e942ee2c9b51bae59651eaa08c2f\",\n    \"0x948b204d103917461a01a6c57a88f2d66b476eae5b00be20ec8c747650e864bc8a83aee0aff59cb7584b7a3387e0ee48\",\n    \"0x81ab098a082b07f896c5ffd1e4446cb7fb44804cbbf38d125208b233fc82f8ec9a6a8d8dd1c9a1162dc28ffeec0dde50\",\n    \"0xa149c6f1312821ced2969268789a3151bdda213451760b397139a028da609c4134ac083169feb0ee423a0acafd10eceb\",\n    \"0xb0ac9e27a5dadaf523010f730b28f0ebac01f460d3bbbe277dc9d44218abb5686f4fac89ae462682fef9edbba663520a\",\n    \"0x8d0e0073cca273daaaa61b6fc54bfe5a009bc3e20ae820f6c93ba77b19eca517d457e948a2de5e77678e4241807157cb\",\n    \"0xad61d3a2edf7c7533a04964b97499503fd8374ca64286dba80465e68fe932e96749b476f458c6fc57cb1a7ca85764d11\",\n    \"0x90eb5e121ae46bc01a30881eaa556f46bd8457a4e80787cf634aab355082de34ac57d7f497446468225f7721e68e2a47\",\n    \"0x8cdac557de7c42d1f3780e33dec1b81889f6352279be81c65566cdd4952d4c15d79e656cbd46035ab090b385e90245ef\",\n    \"0x82b67e61b88b84f4f4d4f65df37b3e3dcf8ec91ea1b5c008fdccd52da643adbe6468a1cfdb999e87d195afe2883a3b46\",\n    \"0x8503b467e8f5d6048a4a9b78496c58493a462852cab54a70594ae3fd064cfd0deb4b8f336a262155d9fedcaa67d2f6fd\",\n    \"0x8db56c5ac763a57b6ce6832930c57117058e3e5a81532b7d19346346205e2ec614eb1a2ee836ef621de50a7bc9b7f040\",\n    \"0xad344699198f3c6e8c0a3470f92aaffc805b76266734414c298e10b5b3797ca53578de7ccb2f458f5e0448203f55282b\",\n    \"0x80602032c43c9e2a09154cc88b83238343b7a139f566d64cb482d87436b288a98f1ea244fd3bff8da3c398686a900c14\",\n    \"0xa6385bd50ecd548cfb37174cdbb89e10025b5cadaf3cff164c95d7aef5a33e3d6a9bf0c681b9e11db9ef54ebeee2a0c1\",\n    \"0xabf2d95f4aa34b0581eb9257a0cc8462b2213941a5deb8ba014283293e8b36613951b61261cc67bbd09526a54cbbff76\",\n    \"0xa3d5de52f48df72c289ff713e445991f142390798cd42bd9d9dbefaee4af4f5faf09042d126b975cf6b98711c3072553\",\n    \"0x8e627302ff3d686cff8872a1b7c2a57b35f45bf2fc9aa42b049d8b4d6996a662b8e7cbac6597f0cb79b0cc4e29fbf133\",\n    \"0x8510702e101b39a1efbf4e504e6123540c34b5689645e70d0bac1ecc1baf47d86c05cef6c4317a4e99b4edaeb53f2d00\",\n    \"0xaa173f0ecbcc6088f878f8726d317748c81ebf501bba461f163b55d66099b191ec7c55f7702f351a9c8eb42cfa3280e2\",\n    \"0xb560a697eafab695bcef1416648a0a664a71e311ecbe5823ae903bd0ed2057b9d7574b9a86d3fe22aa3e6ddce38ea513\",\n    \"0x8df6304a3d9cf40100f3f687575419c998cd77e5cc27d579cf4f8e98642de3609af384a0337d145dd7c5635172d26a71\",\n    \"0x8105c7f3e4d30a29151849673853b457c1885c186c132d0a98e63096c3774bc9deb956cf957367e633d0913680bda307\",\n    \"0x95373fc22c0917c3c2044ac688c4f29a63ed858a45c0d6d2d0fe97afd6f532dcb648670594290c1c89010ecc69259bef\",\n    \"0x8c2fae9bcadab341f49b55230310df93cac46be42d4caa0d42e45104148a91e527af1b4209c0d972448162aed28fab64\",\n    \"0xb05a77baab70683f76209626eaefdda2d36a0b66c780a20142d23c55bd479ddd4ad95b24579384b6cf62c8eb4c92d021\",\n    \"0x8e6bc6a7ea2755b4aaa19c1c1dee93811fcde514f03485fdc3252f0ab7f032c315614f6336e57cea25dcfb8fb6084eeb\",\n    \"0xb656a27d06aade55eadae2ad2a1059198918ea6cc3fd22c0ed881294d34d5ac7b5e4700cc24350e27d76646263b223aa\",\n    \"0xa296469f24f6f56da92d713afcd4dd606e7da1f79dc4e434593c53695847eefc81c7c446486c4b3b8c8d00c90c166f14\",\n    \"0x87a326f57713ac2c9dffeb3af44b9f3c613a8f952676fc46343299122b47ee0f8d792abaa4b5db6451ced5dd153aabd0\",\n    \"0xb689e554ba9293b9c1f6344a3c8fcb6951d9f9eac4a2e2df13de021aade7c186be27500e81388e5b8bcab4c80f220a31\",\n    \"0x87ae0aa0aa48eac53d1ca5a7b93917de12db9e40ceabf8fdb40884ae771cfdf095411deef7c9f821af0b7070454a2608\",\n    \"0xa71ffa7eae8ace94e6c3581d4cb2ad25d48cbd27edc9ec45baa2c8eb932a4773c3272b2ffaf077b40f76942a1f3af7f2\",\n    \"0x94c218c91a9b73da6b7a495b3728f3028df8ad9133312fc0c03e8c5253b7ccb83ed14688fd4602e2fd41f29a0bc698bd\",\n    \"0xae1e77b90ca33728af07a4c03fb2ef71cd92e2618e7bf8ed4d785ce90097fc4866c29999eb84a6cf1819d75285a03af2\",\n    \"0xb7a5945b277dab9993cf761e838b0ac6eaa903d7111fca79f9fde3d4285af7a89bf6634a71909d095d7619d913972c9c\",\n    \"0x8c43b37be02f39b22029b20aca31bff661abce4471dca88aa3bddefd9c92304a088b2dfc8c4795acc301ca3160656af2\",\n    \"0xb32e5d0fba024554bd5fe8a793ebe8003335ddd7f585876df2048dcf759a01285fecb53daae4950ba57f3a282a4d8495\",\n    \"0x85ea7fd5e10c7b659df5289b2978b2c89e244f269e061b9a15fcab7983fc1962b63546e82d5731c97ec74b6804be63ef\",\n    \"0x96b89f39181141a7e32986ac02d7586088c5a9662cec39843f397f3178714d02f929af70630c12cbaba0268f8ba2d4fa\",\n    \"0x929ab1a2a009b1eb37a2817c89696a06426529ebe3f306c586ab717bd34c35a53eca2d7ddcdef36117872db660024af9\",\n    \"0xa696dccf439e9ca41511e16bf3042d7ec0e2f86c099e4fc8879d778a5ea79e33aa7ce96b23dc4332b7ba26859d8e674d\",\n    \"0xa8fe69a678f9a194b8670a41e941f0460f6e2dbc60470ab4d6ae2679cc9c6ce2c3a39df2303bee486dbfde6844e6b31a\",\n    \"0x95f58f5c82de2f2a927ca99bf63c9fc02e9030c7e46d0bf6b67fe83a448d0ae1c99541b59caf0e1ccab8326231af09a5\",\n    \"0xa57badb2c56ca2c45953bd569caf22968f76ed46b9bac389163d6fe22a715c83d5e94ae8759b0e6e8c2f27bff7748f3f\",\n    \"0x868726fd49963b24acb5333364dffea147e98f33aa19c7919dc9aca0fd26661cfaded74ede7418a5fadbe7f5ae67b67b\",\n    \"0xa8d8550dcc64d9f1dd7bcdab236c4122f2b65ea404bb483256d712c7518f08bb028ff8801f1da6aed6cbfc5c7062e33b\",\n    \"0x97e25a87dae23155809476232178538d4bc05d4ff0882916eb29ae515f2a62bfce73083466cc0010ca956aca200aeacc\",\n    \"0xb4ea26be3f4bd04aa82d7c4b0913b97bcdf5e88b76c57eb1a336cbd0a3eb29de751e1bc47c0e8258adec3f17426d0c71\",\n    \"0x99ee555a4d9b3cf2eb420b2af8e3bc99046880536116d0ce7193464ac40685ef14e0e3c442f604e32f8338cb0ef92558\",\n    \"0x8c64efa1da63cd08f319103c5c7a761221080e74227bbc58b8fb35d08aa42078810d7af3e60446cbaff160c319535648\",\n    \"0x8d9fd88040076c28420e3395cbdfea402e4077a3808a97b7939d49ecbcf1418fe50a0460e1c1b22ac3f6e7771d65169a\",\n    \"0xae3c19882d7a9875d439265a0c7003c8d410367627d21575a864b9cb4918de7dbdb58a364af40c5e045f3df40f95d337\",\n    \"0xb4f7bfacab7b2cafe393f1322d6dcc6f21ffe69cd31edc8db18c06f1a2b512c27bd0618091fd207ba8df1808e9d45914\",\n    \"0x94f134acd0007c623fb7934bcb65ef853313eb283a889a3ffa79a37a5c8f3665f3d5b4876bc66223610c21dc9b919d37\",\n    \"0xaa15f74051171daacdc1f1093d3f8e2d13da2833624b80a934afec86fc02208b8f55d24b7d66076444e7633f46375c6a\",\n    \"0xa32d6bb47ef9c836d9d2371807bafbbbbb1ae719530c19d6013f1d1f813c49a60e4fa51d83693586cba3a840b23c0404\",\n    \"0xb61b3599145ea8680011aa2366dc511a358b7d67672d5b0c5be6db03b0efb8ca5a8294cf220ea7409621f1664e00e631\",\n    \"0x859cafc3ee90b7ececa1ed8ef2b2fc17567126ff10ca712d5ffdd16aa411a5a7d8d32c9cab1fbf63e87dce1c6e2f5f53\",\n    \"0xa2fef1b0b2874387010e9ae425f3a9676d01a095d017493648bcdf3b31304b087ccddb5cf76abc4e1548b88919663b6b\",\n    \"0x939e18c73befc1ba2932a65ede34c70e4b91e74cc2129d57ace43ed2b3af2a9cc22a40fbf50d79a63681b6d98852866d\",\n    \"0xb3b4259d37b1b14aee5b676c9a0dd2d7f679ab95c120cb5f09f9fbf10b0a920cb613655ddb7b9e2ba5af4a221f31303c\",\n    \"0x997255fe51aaca6e5a9cb3359bcbf25b2bb9e30649bbd53a8a7c556df07e441c4e27328b38934f09c09d9500b5fabf66\",\n    \"0xabb91be2a2d860fd662ed4f1c6edeefd4da8dc10e79251cf87f06029906e7f0be9b486462718f0525d5e049472692cb7\",\n    \"0xb2398e593bf340a15f7801e1d1fbda69d93f2a32a889ec7c6ae5e8a37567ac3e5227213c1392ee86cfb3b56ec2787839\",\n    \"0x8ddf10ccdd72922bed36829a36073a460c2118fc7a56ff9c1ac72581c799b15c762cb56cb78e3d118bb9f6a7e56cb25e\",\n    \"0x93e6bc0a4708d16387cacd44cf59363b994dc67d7ada7b6d6dbd831c606d975247541b42b2a309f814c1bfe205681fc6\",\n    \"0xb93fc35c05998cffda2978e12e75812122831523041f10d52f810d34ff71944979054b04de0117e81ddf5b0b4b3e13c0\",\n    \"0x92221631c44d60d68c6bc7b287509f37ee44cbe5fdb6935cee36b58b17c7325098f98f7910d2c3ca5dc885ad1d6dabc7\",\n    \"0xa230124424a57fad3b1671f404a94d7c05f4c67b7a8fbacfccea28887b78d7c1ed40b92a58348e4d61328891cd2f6cee\",\n    \"0xa6a230edb8518a0f49d7231bc3e0bceb5c2ac427f045819f8584ba6f3ae3d63ed107a9a62aad543d7e1fcf1f20605706\",\n    \"0x845be1fe94223c7f1f97d74c49d682472585d8f772762baad8a9d341d9c3015534cc83d102113c51a9dea2ab10d8d27b\",\n    \"0xb44262515e34f2db597c8128c7614d33858740310a49cdbdf9c8677c5343884b42c1292759f55b8b4abc4c86e4728033\",\n    \"0x805592e4a3cd07c1844bc23783408310accfdb769cca882ad4d07d608e590a288b7370c2cb327f5336e72b7083a0e30f\",\n    \"0x95153e8b1140df34ee864f4ca601cb873cdd3efa634af0c4093fbaede36f51b55571ab271e6a133020cd34db8411241f\",\n    \"0x82878c1285cfa5ea1d32175c9401f3cc99f6bb224d622d3fd98cc7b0a27372f13f7ab463ce3a33ec96f9be38dbe2dfe3\",\n    \"0xb7588748f55783077c27fc47d33e20c5c0f5a53fc0ac10194c003aa09b9f055d08ec971effa4b7f760553997a56967b3\",\n    \"0xb36b4de6d1883b6951f59cfae381581f9c6352fcfcf1524fccdab1571a20f80441d9152dc6b48bcbbf00371337ca0bd5\",\n    \"0x89c5523f2574e1c340a955cbed9c2f7b5fbceb260cb1133160dabb7d41c2f613ec3f6e74bbfab3c4a0a6f0626dbe068f\",\n    \"0xa52f58cc39f968a9813b1a8ddc4e83f4219e4dd82c7aa1dd083bea7edf967151d635aa9597457f879771759b876774e4\",\n    \"0x8300a67c2e2e123f89704abfde095463045dbd97e20d4c1157bab35e9e1d3d18f1f4aaba9cbe6aa2d544e92578eaa1b6\",\n    \"0xac6a7f2918768eb6a43df9d3a8a04f8f72ee52f2e91c064c1c7d75cad1a3e83e5aba9fe55bb94f818099ac91ccf2e961\",\n    \"0x8d64a2b0991cf164e29835c8ddef6069993a71ec2a7de8157bbfa2e00f6367be646ed74cbaf524f0e9fe13fb09fa15fd\",\n    \"0x8b2ffe5a545f9f680b49d0a9797a4a11700a2e2e348c34a7a985fc278f0f12def6e06710f40f9d48e4b7fbb71e072229\",\n    \"0x8ab8f71cd337fa19178924e961958653abf7a598e3f022138b55c228440a2bac4176cea3aea393549c03cd38a13eb3fc\",\n    \"0x8419d28318c19ea4a179b7abb43669fe96347426ef3ac06b158d79c0acf777a09e8e770c2fb10e14b3a0421705990b23\",\n    \"0x8bacdac310e1e49660359d0a7a17fe3d334eb820e61ae25e84cb52f863a2f74cbe89c2e9fc3283745d93a99b79132354\",\n    \"0xb57ace3fa2b9f6b2db60c0d861ace7d7e657c5d35d992588aeed588c6ce3a80b6f0d49f8a26607f0b17167ab21b675e4\",\n    \"0x83e265cde477f2ecc164f49ddc7fb255bb05ff6adc347408353b7336dc3a14fdedc86d5a7fb23f36b8423248a7a67ed1\",\n    \"0xa60ada971f9f2d79d436de5d3d045f5ab05308cae3098acaf5521115134b2a40d664828bb89895840db7f7fb499edbc5\",\n    \"0xa63eea12efd89b62d3952bf0542a73890b104dd1d7ff360d4755ebfa148fd62de668edac9eeb20507967ea37fb220202\",\n    \"0xa0275767a270289adc991cc4571eff205b58ad6d3e93778ddbf95b75146d82517e8921bd0d0564e5b75fa0ccdab8e624\",\n    \"0xb9b03fd3bf07201ba3a039176a965d736b4ef7912dd9e9bf69fe1b57c330a6aa170e5521fe8be62505f3af81b41d7806\",\n    \"0xa95f640e26fb1106ced1729d6053e41a16e4896acac54992279ff873e5a969aad1dcfa10311e28b8f409ac1dab7f03bb\",\n    \"0xb144778921742418053cb3c70516c63162c187f00db2062193bb2c14031075dbe055d020cde761b26e8c58d0ea6df2c1\",\n    \"0x8432fbb799e0435ef428d4fefc309a05dd589bce74d7a87faf659823e8c9ed51d3e42603d878e80f439a38be4321c2fa\",\n    \"0xb08ddef14e42d4fd5d8bf39feb7485848f0060d43b51ed5bdda39c05fe154fb111d29719ee61a23c392141358c0cfcff\",\n    \"0x8ae3c5329a5e025b86b5370e06f5e61177df4bda075856fade20a17bfef79c92f54ed495f310130021ba94fb7c33632b\",\n    \"0x92b6d3c9444100b4d7391febfc1dddaa224651677c3695c47a289a40d7a96d200b83b64e6d9df51f534564f272a2c6c6\",\n    \"0xb432bc2a3f93d28b5e506d68527f1efeb2e2570f6be0794576e2a6ef9138926fdad8dd2eabfa979b79ab7266370e86bc\",\n    \"0x8bc315eacedbcfc462ece66a29662ca3dcd451f83de5c7626ef8712c196208fb3d8a0faf80b2e80384f0dd9772f61a23\",\n    \"0xa72375b797283f0f4266dec188678e2b2c060dfed5880fc6bb0c996b06e91a5343ea2b695adaab0a6fd183b040b46b56\",\n    \"0xa43445036fbaa414621918d6a897d3692fdae7b2961d87e2a03741360e45ebb19fcb1703d23f1e15bb1e2babcafc56ac\",\n    \"0xb9636b2ffe305e63a1a84bd44fb402442b1799bd5272638287aa87ca548649b23ce8ce7f67be077caed6aa2dbc454b78\",\n    \"0x99a30bf0921d854c282b83d438a79f615424f28c2f99d26a05201c93d10378ab2cd94a792b571ddae5d4e0c0013f4006\",\n    \"0x8648e3c2f93d70b392443be116b48a863e4b75991bab5db656a4ef3c1e7f645e8d536771dfe4e8d1ceda3be8d32978b0\",\n    \"0xab50dc9e6924c1d2e9d2e335b2d679fc7d1a7632e84964d3bac0c9fe57e85aa5906ec2e7b0399d98ddd022e9b19b5904\",\n    \"0xab729328d98d295f8f3272afaf5d8345ff54d58ff9884da14f17ecbdb7371857fdf2f3ef58080054e9874cc919b46224\",\n    \"0x83fa5da7592bd451cad3ad7702b4006332b3aae23beab4c4cb887fa6348317d234bf62a359e665b28818e5410c278a09\",\n    \"0x8bdbff566ae9d368f114858ef1f009439b3e9f4649f73efa946e678d6c781d52c69af195df0a68170f5f191b2eac286b\",\n    \"0x91245e59b4425fd4edb2a61d0d47c1ccc83d3ced8180de34887b9655b5dcda033d48cde0bdc3b7de846d246c053a02e8\",\n    \"0xa2cb00721e68f1cad8933947456f07144dc69653f96ceed845bd577d599521ba99cdc02421118971d56d7603ed118cbf\",\n    \"0xaf8cd66d303e808b22ec57860dd909ca64c27ec2c60e26ffecfdc1179d8762ffd2739d87b43959496e9fee4108df71df\",\n    \"0x9954136812dffcd5d3f167a500e7ab339c15cfc9b3398d83f64b0daa3dd5b9a851204f424a3493b4e326d3de81e50a62\",\n    \"0x93252254d12511955f1aa464883ad0da793f84d900fea83e1df8bca0f2f4cf5b5f9acbaec06a24160d33f908ab5fea38\",\n    \"0x997cb55c26996586ba436a95566bd535e9c22452ca5d2a0ded2bd175376557fa895f9f4def4519241ff386a063f2e526\",\n    \"0xa12c78ad451e0ac911260ade2927a768b50cb4125343025d43474e7f465cdc446e9f52a84609c5e7e87ae6c9b3f56cda\",\n    \"0xa789d4ca55cbba327086563831b34487d63d0980ba8cf55197c016702ed6da9b102b1f0709ce3da3c53ff925793a3d73\",\n    \"0xa5d76acbb76741ce85be0e655b99baa04f7f587347947c0a30d27f8a49ae78cce06e1cde770a8b618d3db402be1c0c4b\",\n    \"0x873c0366668c8faddb0eb7c86f485718d65f8c4734020f1a18efd5fa123d3ea8a990977fe13592cd01d17e60809cb5ff\",\n    \"0xb659b71fe70f37573ff7c5970cc095a1dc0da3973979778f80a71a347ef25ad5746b2b9608bad4ab9a4a53a4d7df42d7\",\n    \"0xa34cbe05888e5e5f024a2db14cb6dcdc401a9cbd13d73d3c37b348f68688f87c24ca790030b8f84fef9e74b4eab5e412\",\n    \"0x94ce8010f85875c045b0f014db93ef5ab9f1f6842e9a5743dce9e4cb872c94affd9e77c1f1d1ab8b8660b52345d9acb9\",\n    \"0xadefa9b27a62edc0c5b019ddd3ebf45e4de846165256cf6329331def2e088c5232456d3de470fdce3fa758bfdd387512\",\n    \"0xa6b83821ba7c1f83cc9e4529cf4903adb93b26108e3d1f20a753070db072ad5a3689643144bdd9c5ea06bb9a7a515cd0\",\n    \"0xa3a9ddedc2a1b183eb1d52de26718151744db6050f86f3580790c51d09226bf05f15111691926151ecdbef683baa992c\",\n    \"0xa64bac89e7686932cdc5670d07f0b50830e69bfb8c93791c87c7ffa4913f8da881a9d8a8ce8c1a9ce5b6079358c54136\",\n    \"0xa77b5a63452cb1320b61ab6c7c2ef9cfbcade5fd4727583751fb2bf3ea330b5ca67757ec1f517bf4d503ec924fe32fbd\",\n    \"0x8746fd8d8eb99639d8cd0ca34c0d9c3230ed5a312aab1d3d925953a17973ee5aeb66e68667e93caf9cb817c868ea8f3d\",\n    \"0x88a2462a26558fc1fbd6e31aa8abdc706190a17c27fdc4217ffd2297d1b1f3321016e5c4b2384c5454d5717dc732ed03\",\n    \"0xb78893a97e93d730c8201af2e0d3b31cb923d38dc594ffa98a714e627c473d42ea82e0c4d2eeb06862ee22a9b2c54588\",\n    \"0x920cc8b5f1297cf215a43f6fc843e379146b4229411c44c0231f6749793d40f07b9af7699fd5d21fd69400b97febe027\",\n    \"0xa0f0eafce1e098a6b58c7ad8945e297cd93aaf10bc55e32e2e32503f02e59fc1d5776936577d77c0b1162cb93b88518b\",\n    \"0x98480ba0064e97a2e7a6c4769b4d8c2a322cfc9a3b2ca2e67e9317e2ce04c6e1108169a20bd97692e1cb1f1423b14908\",\n    \"0x83dbbb2fda7e287288011764a00b8357753a6a44794cc8245a2275237f11affdc38977214e463ad67aec032f3dfa37e9\",\n    \"0x86442fff37598ce2b12015ff19b01bb8a780b40ad353d143a0f30a06f6d23afd5c2b0a1253716c855dbf445cc5dd6865\",\n    \"0xb8a4c60c5171189414887847b9ed9501bff4e4c107240f063e2d254820d2906b69ef70406c585918c4d24f1dd052142b\",\n    \"0x919f33a98e84015b2034b57b5ffe9340220926b2c6e45f86fd79ec879dbe06a148ae68b77b73bf7d01bd638a81165617\",\n    \"0x95c13e78d89474a47fbc0664f6f806744b75dede95a479bbf844db4a7f4c3ae410ec721cb6ffcd9fa9c323da5740d5ae\",\n    \"0xab7151acc41fffd8ec6e90387700bcd7e1cde291ea669567295bea1b9dd3f1df2e0f31f3588cd1a1c08af8120aca4921\",\n    \"0x80e74c5c47414bd6eeef24b6793fb1fa2d8fb397467045fcff887c52476741d5bc4ff8b6d3387cb53ad285485630537f\",\n    \"0xa296ad23995268276aa351a7764d36df3a5a3cffd7dbeddbcea6b1f77adc112629fdeffa0918b3242b3ccd5e7587e946\",\n    \"0x813d2506a28a2b01cb60f49d6bd5e63c9b056aa56946faf2f33bd4f28a8d947569cfead3ae53166fc65285740b210f86\",\n    \"0x924b265385e1646287d8c09f6c855b094daaee74b9e64a0dddcf9ad88c6979f8280ba30c8597b911ef58ddb6c67e9fe3\",\n    \"0x8d531513c70c2d3566039f7ca47cd2352fd2d55b25675a65250bdb8b06c3843db7b2d29c626eed6391c238fc651cf350\",\n    \"0x82b338181b62fdc81ceb558a6843df767b6a6e3ceedc5485664b4ea2f555904b1a45fbb35f6cf5d96f27da10df82a325\",\n    \"0x92e62faaedea83a37f314e1d3cb4faaa200178371d917938e59ac35090be1db4b4f4e0edb78b9c991de202efe4f313d8\",\n    \"0x99d645e1b642c2dc065bac9aaa0621bc648c9a8351efb6891559c3a41ba737bd155fb32d7731950514e3ecf4d75980e4\",\n    \"0xb34a13968b9e414172fb5d5ece9a39cf2eb656128c3f2f6cc7a9f0c69c6bae34f555ecc8f8837dc34b5e470e29055c78\",\n    \"0xa2a0bb7f3a0b23a2cbc6585d59f87cd7e56b2bbcb0ae48f828685edd9f7af0f5edb4c8e9718a0aaf6ef04553ba71f3b7\",\n    \"0x8e1a94bec053ed378e524b6685152d2b52d428266f2b6eadd4bcb7c4e162ed21ab3e1364879673442ee2162635b7a4d8\",\n    \"0x9944adaff14a85eab81c73f38f386701713b52513c4d4b838d58d4ffa1d17260a6d056b02334850ea9a31677c4b078bd\",\n    \"0xa450067c7eceb0854b3eca3db6cf38669d72cb7143c3a68787833cbca44f02c0be9bfbe082896f8a57debb13deb2afb1\",\n    \"0x8be4ad3ac9ef02f7df09254d569939757101ee2eda8586fefcd8c847adc1efe5bdcb963a0cafa17651befaafb376a531\",\n    \"0x90f6de91ea50255f148ac435e08cf2ac00c772a466e38155bd7e8acf9197af55662c7b5227f88589b71abe9dcf7ba343\",\n    \"0x86e5a24f0748b106dee2d4d54e14a3b0af45a96cbee69cac811a4196403ebbee17fd24946d7e7e1b962ac7f66dbaf610\",\n    \"0xafdd96fbcda7aa73bf9eeb2292e036c25753d249caee3b9c013009cc22e10d3ec29e2aa6ddbb21c4e949b0c0bccaa7f4\",\n    \"0xb5a4e7436d5473647c002120a2cb436b9b28e27ad4ebdd7c5f122b91597c507d256d0cbd889d65b3a908531936e53053\",\n    \"0xb632414c3da704d80ac2f3e5e0e9f18a3637cdc2ebeb613c29300745582427138819c4e7b0bec3099c1b8739dac1807b\",\n    \"0xa28df1464d3372ce9f37ef1db33cc010f752156afae6f76949d98cd799c0cf225c20228ae86a4da592d65f0cffe3951b\",\n    \"0x898b93d0a31f7d3f11f253cb7a102db54b669fd150da302d8354d8e02b1739a47cb9bd88015f3baf12b00b879442464e\",\n    \"0x96fb88d89a12049091070cb0048a381902965e67a8493e3991eaabe5d3b7ff7eecd5c94493a93b174df3d9b2c9511755\",\n    \"0xb899cb2176f59a5cfba3e3d346813da7a82b03417cad6342f19cc8f12f28985b03bf031e856a4743fd7ebe16324805b0\",\n    \"0xa60e2d31bc48e0c0579db15516718a03b73f5138f15037491f4dae336c904e312eda82d50862f4debd1622bb0e56d866\",\n    \"0x979fc8b987b5cef7d4f4b58b53a2c278bd25a5c0ea6f41c715142ea5ff224c707de38451b0ad3aa5e749aa219256650a\",\n    \"0xb2a75bff18e1a6b9cf2a4079572e41205741979f57e7631654a3c0fcec57c876c6df44733c9da3d863db8dff392b44a3\",\n    \"0xb7a0f0e811222c91e3df98ff7f286b750bc3b20d2083966d713a84a2281744199e664879401e77470d44e5a90f3e5181\",\n    \"0x82b74ba21c9d147fbc338730e8f1f8a6e7fc847c3110944eb17a48bea5e06eecded84595d485506d15a3e675fd0e5e62\",\n    \"0xa7f44eef817d5556f0d1abcf420301217d23c69dd2988f44d91ea1f1a16c322263cbacd0f190b9ba22b0f141b9267b4f\",\n    \"0xaadb68164ede84fc1cb3334b3194d84ba868d5a88e4c9a27519eef4923bc4abf81aab8114449496c073c2a6a0eb24114\",\n    \"0xb5378605fabe9a8c12a5dc55ef2b1de7f51aedb61960735c08767a565793cea1922a603a6983dc25f7cea738d0f7c40d\",\n    \"0xa97a4a5cd8d51302e5e670aee78fe6b5723f6cc892902bbb4f131e82ca1dfd5de820731e7e3367fb0c4c1922a02196e3\",\n    \"0x8bdfeb15c29244d4a28896f2b2cb211243cd6a1984a3f5e3b0ebe5341c419beeab3304b390a009ffb47588018034b0ea\",\n    \"0xa9af3022727f2aa2fca3b096968e97edad3f08edcbd0dbca107b892ae8f746a9c0485e0d6eb5f267999b23a845923ed0\",\n    \"0x8e7594034feef412f055590fbb15b6322dc4c6ab7a4baef4685bd13d71a83f7d682b5781bdfa0d1c659489ce9c2b8000\",\n    \"0x84977ca6c865ebee021c58106c1a4ad0c745949ecc5332948002fd09bd9b890524878d0c29da96fd11207621136421fe\",\n    \"0x8687551a79158e56b2375a271136756313122132a6670fa51f99a1b5c229ed8eea1655a734abae13228b3ebfd2a825dd\",\n    \"0xa0227d6708979d99edfc10f7d9d3719fd3fc68b0d815a7185b60307e4c9146ad2f9be2b8b4f242e320d4288ceeb9504c\",\n    \"0x89f75583a16735f9dd8b7782a130437805b34280ccea8dac6ecaee4b83fe96947e7b53598b06fecfffdf57ffc12cc445\",\n    \"0xa0056c3353227f6dd9cfc8e3399aa5a8f1d71edf25d3d64c982910f50786b1e395c508d3e3727ac360e3e040c64b5298\",\n    \"0xb070e61a6d813626144b312ded1788a6d0c7cec650a762b2f8df6e4743941dd82a2511cd956a3f141fc81e15f4e092da\",\n    \"0xb4e6db232e028a1f989bb5fc13416711f42d389f63564d60851f009dcffac01acfd54efa307aa6d4c0f932892d4e62b0\",\n    \"0x89b5991a67db90024ddd844e5e1a03ef9b943ad54194ae0a97df775dde1addf31561874f4e40fbc37a896630f3bbda58\",\n    \"0xad0e8442cb8c77d891df49cdb9efcf2b0d15ac93ec9be1ad5c3b3cca1f4647b675e79c075335c1f681d56f14dc250d76\",\n    \"0xb5d55a6ae65bb34dd8306806cb49b5ccb1c83a282ee47085cf26c4e648e19a52d9c422f65c1cd7e03ca63e926c5e92ea\",\n    \"0xb749501347e5ec07e13a79f0cb112f1b6534393458b3678a77f02ca89dca973fa7b30e55f0b25d8b92b97f6cb0120056\",\n    \"0x94144b4a3ffc5eec6ba35ce9c245c148b39372d19a928e236a60e27d7bc227d18a8cac9983851071935d8ffb64b3a34f\",\n    \"0x92bb4f9f85bc8c028a3391306603151c6896673135f8a7aefedd27acb322c04ef5dac982fc47b455d6740023e0dd3ea3\",\n    \"0xb9633a4a101461a782fc2aa092e9dbe4e2ad00987578f18cd7cf0021a909951d60fe79654eb7897806795f93c8ff4d1c\",\n    \"0x809f0196753024821b48a016eca5dbb449a7c55750f25981bb7a4b4c0e0846c09b8f6128137905055fc43a3f0deb4a74\",\n    \"0xa27dc9cdd1e78737a443570194a03d89285576d3d7f3a3cf15cc55b3013e42635d4723e2e8fe1d0b274428604b630db9\",\n    \"0x861f60f0462e04cd84924c36a28163def63e777318d00884ab8cb64c8df1df0bce5900342163edb60449296484a6c5bf\",\n    \"0xb7bc23fb4e14af4c4704a944253e760adefeca8caee0882b6bbd572c84434042236f39ae07a8f21a560f486b15d82819\",\n    \"0xb9a6eb492d6dd448654214bd01d6dc5ff12067a11537ab82023fc16167507ee25eed2c91693912f4155d1c07ed9650b3\",\n    \"0x97678af29c68f9a5e213bf0fb85c265303714482cfc4c2c00b4a1e8a76ed08834ee6af52357b143a1ca590fb0265ea5a\",\n    \"0x8a15b499e9eca5b6cac3070b5409e8296778222018ad8b53a5d1f6b70ad9bb10c68a015d105c941ed657bf3499299e33\",\n    \"0xb487fefede2e8091f2c7bfe85770db2edff1db83d4effe7f7d87bff5ab1ace35e9b823a71adfec6737fede8d67b3c467\",\n    \"0x8b51b916402aa2c437fce3bcad6dad3be8301a1a7eab9d163085b322ffb6c62abf28637636fe6114573950117fc92898\",\n    \"0xb06a2106d031a45a494adec0881cb2f82275dff9dcdd2bc16807e76f3bec28a6734edd3d54f0be8199799a78cd6228ad\",\n    \"0xaf0a185391bbe2315eb97feac98ad6dd2e5d931d012c621abd6e404a31cc188b286fef14871762190acf086482b2b5e2\",\n    \"0x8e78ee8206506dd06eb7729e32fceda3bebd8924a64e4d8621c72e36758fda3d0001af42443851d6c0aea58562870b43\",\n    \"0xa1ba52a569f0461aaf90b49b92be976c0e73ec4a2c884752ee52ffb62dd137770c985123d405dfb5de70692db454b54a\",\n    \"0x8d51b692fa1543c51f6b62b9acb8625ed94b746ef96c944ca02859a4133a5629da2e2ce84e111a7af8d9a5b836401c64\",\n    \"0xa7a20d45044cf6492e0531d0b8b26ffbae6232fa05a96ed7f06bdb64c2b0f5ca7ec59d5477038096a02579e633c7a3ff\",\n    \"0x84df867b98c53c1fcd4620fef133ee18849c78d3809d6aca0fb6f50ff993a053a455993f216c42ab6090fa5356b8d564\",\n    \"0xa7227c439f14c48e2577d5713c97a5205feb69acb0b449152842e278fa71e8046adfab468089c8b2288af1fc51fa945b\",\n    \"0x855189b3a105670779997690876dfaa512b4a25a24931a912c2f0f1936971d2882fb4d9f0b3d9daba77eaf660e9d05d5\",\n    \"0xb5696bd6706de51c502f40385f87f43040a5abf99df705d6aac74d88c913b8ecf7a99a63d7a37d9bdf3a941b9e432ff5\",\n    \"0xab997beb0d6df9c98d5b49864ef0b41a2a2f407e1687dfd6089959757ba30ed02228940b0e841afe6911990c74d536c4\",\n    \"0xb36b65f85546ebfdbe98823d5555144f96b4ab39279facd19c0de3b8919f105ba0315a0784dce4344b1bc62d8bb4a5a3\",\n    \"0xb8371f0e4450788720ac5e0f6cd3ecc5413d33895083b2c168d961ec2b5c3de411a4cc0712481cbe8df8c2fa1a7af006\",\n    \"0x98325d8026b810a8b7a114171ae59a57e8bbc9848e7c3df992efc523621729fd8c9f52114ce01d7730541a1ada6f1df1\",\n    \"0x8d0e76dbd37806259486cd9a31bc8b2306c2b95452dc395546a1042d1d17863ef7a74c636b782e214d3aa0e8d717f94a\",\n    \"0xa4e15ead76da0214d702c859fb4a8accdcdad75ed08b865842bd203391ec4cba2dcc916455e685f662923b96ee0c023f\",\n    \"0x8618190972086ebb0c4c1b4a6c94421a13f378bc961cc8267a301de7390c5e73c3333864b3b7696d81148f9d4843fd02\",\n    \"0x85369d6cc7342e1aa15b59141517d8db8baaaeb7ab9670f3ba3905353948d575923d283b7e5a05b13a30e7baf1208a86\",\n    \"0x87c51ef42233c24a6da901f28c9a075d9ba3c625687c387ad6757b72ca6b5a8885e6902a3082da7281611728b1e45f26\",\n    \"0xaa6348a4f71927a3106ad0ea8b02fc8d8c65531e4ab0bd0a17243e66f35afe252e40ab8eef9f13ae55a72566ffdaff5c\",\n    \"0x96a3bc976e9d03765cc3fee275fa05b4a84c94fed6b767e23ca689394501e96f56f7a97cffddc579a6abff632bf153be\",\n    \"0x97dbf96c6176379fdb2b888be4e757b2bca54e74124bd068d3fa1dbd82a011bbeb75079da38e0cd22a761fe208ecad9b\",\n    \"0xb70cf0a1d14089a4129ec4e295313863a59da8c7e26bf74cc0e704ed7f0ee4d7760090d0ddf7728180f1bf2c5ac64955\",\n    \"0x882d664714cc0ffe53cbc9bef21f23f3649824f423c4dbad1f893d22c4687ab29583688699efc4d5101aa08b0c3e267a\",\n    \"0x80ecb7cc963e677ccaddbe3320831dd6ee41209acf4ed41b16dc4817121a3d86a1aac9c4db3d8c08a55d28257088af32\",\n    \"0xa25ba667d832b145f9ce18c3f9b1bd00737aa36db020e1b99752c8ef7d27c6c448982bd8d352e1b6df266b8d8358a8d5\",\n    \"0x83734841c13dee12759d40bdd209b277e743b0d08cc0dd1e0b7afd2d65bfa640400eefcf6be4a52e463e5b3d885eeac6\",\n    \"0x848d16505b04804afc773aebabb51b36fd8aacfbb0e09b36c0d5d57df3c0a3b92f33e7d5ad0a7006ec46ebb91df42b8c\",\n    \"0x909a8d793f599e33bb9f1dc4792a507a97169c87cd5c087310bc05f30afcd247470b4b56dec59894c0fb1d48d39bb54e\",\n    \"0x8e558a8559df84a1ba8b244ece667f858095c50bb33a5381e60fcc6ba586b69693566d8819b4246a27287f16846c1dfa\",\n    \"0x84d6b69729f5aaa000cd710c2352087592cfbdf20d5e1166977e195818e593fa1a50d1e04566be23163a2523dc1612f1\",\n    \"0x9536d262b7a42125d89f4f32b407d737ba8d9242acfc99d965913ab3e043dcac9f7072a43708553562cac4cba841df30\",\n    \"0x9598548923ca119d6a15fd10861596601dd1dedbcccca97bb208cdc1153cf82991ea8cc17686fbaa867921065265970c\",\n    \"0xb87f2d4af6d026e4d2836bc3d390a4a18e98a6e386282ce96744603bab74974272e97ac2da281afa21885e2cbb3a8001\",\n    \"0x991ece62bf07d1a348dd22191868372904b9f8cf065ae7aa4e44fd24a53faf6d851842e35fb472895963aa1992894918\",\n    \"0xa8c53dea4c665b30e51d22ca6bc1bc78aaf172b0a48e64a1d4b93439b053877ec26cb5221c55efd64fa841bbf7d5aff4\",\n    \"0x93487ec939ed8e740f15335b58617c3f917f72d07b7a369befd479ae2554d04deb240d4a14394b26192efae4d2f4f35d\",\n    \"0xa44793ab4035443f8f2968a40e043b4555960193ffa3358d22112093aadfe2c136587e4139ffd46d91ed4107f61ea5e0\",\n    \"0xb13fe033da5f0d227c75927d3dacb06dbaf3e1322f9d5c7c009de75cdcba5e308232838785ab69a70f0bedea755e003f\",\n    \"0x970a29b075faccd0700fe60d1f726bdebf82d2cc8252f4a84543ebd3b16f91be42a75c9719a39c4096139f0f31393d58\",\n    \"0xa4c3eb1f7160f8216fc176fb244df53008ff32f2892363d85254002e66e2de21ccfe1f3b1047589abee50f29b9d507e3\",\n    \"0x8c552885eab04ba40922a8f0c3c38c96089c95ff1405258d3f1efe8d179e39e1295cbf67677894c607ae986e4e6b1fb0\",\n    \"0xb3671746fa7f848c4e2ae6946894defadd815230b906b419143523cc0597bc1d6c0a4c1e09d49b66b4a2c11cde3a4de3\",\n    \"0x937a249a95813a5e2ef428e355efd202e15a37d73e56cfb7e57ea9f943f2ce5ca8026f2f1fd25bf164ba89d07077d858\",\n    \"0x83646bdf6053a04aa9e2f112499769e5bd5d0d10f2e13db3ca89bd45c0b3b7a2d752b7d137fb3909f9c62b78166c9339\",\n    \"0xb4eac4b91e763666696811b7ed45e97fd78310377ebea1674b58a2250973f80492ac35110ed1240cd9bb2d17493d708c\",\n    \"0x82db43a99bc6573e9d92a3fd6635dbbb249ac66ba53099c3c0c8c8080b121dd8243cd5c6e36ba0a4d2525bae57f5c89c\",\n    \"0xa64d6a264a681b49d134c655d5fc7756127f1ee7c93d328820f32bca68869f53115c0d27fef35fe71f7bc4fdaed97348\",\n    \"0x8739b7a9e2b4bc1831e7f04517771bc7cde683a5e74e052542517f8375a2f64e53e0d5ac925ef722327e7bb195b4d1d9\",\n    \"0x8f337cdd29918a2493515ebb5cf702bbe8ecb23b53c6d18920cc22f519e276ca9b991d3313e2d38ae17ae8bdfa4f8b7e\",\n    \"0xb0edeab9850e193a61f138ef2739fc42ceec98f25e7e8403bfd5fa34a7bc956b9d0898250d18a69fa4625a9b3d6129da\",\n    \"0xa9920f26fe0a6d51044e623665d998745c9eca5bce12051198b88a77d728c8238f97d4196f26e43b24f8841500b998d0\",\n    \"0x86e655d61502b979eeeeb6f9a7e1d0074f936451d0a1b0d2fa4fb3225b439a3770767b649256fe481361f481a8dbc276\",\n    \"0x84d3b32fa62096831cc3bf013488a9f3f481dfe293ae209ed19585a03f7db8d961a7a9dd0db82bd7f62d612707575d9c\",\n    \"0x81c827826ec9346995ffccf62a241e3b2d32f7357acd1b1f8f7a7dbc97022d3eb51b8a1230e23ce0b401d2e535e8cd78\",\n    \"0x94a1e40c151191c5b055b21e86f32e69cbc751dcbdf759a48580951834b96a1eed75914c0d19a38aefd21fb6c8d43d0c\",\n    \"0xab890222b44bc21b71f7c75e15b6c6e16bb03371acce4f8d4353ff3b8fcd42a14026589c5ed19555a3e15e4d18bfc3a3\",\n    \"0xaccb0be851e93c6c8cc64724cdb86887eea284194b10e7a43c90528ed97e9ec71ca69c6fac13899530593756dd49eab2\",\n    \"0xb630220aa9e1829c233331413ee28c5efe94ea8ea08d0c6bfd781955078b43a4f92915257187d8526873e6c919c6a1de\",\n    \"0xadd389a4d358c585f1274b73f6c3c45b58ef8df11f9d11221f620e241bf3579fba07427b288c0c682885a700cc1fa28d\",\n    \"0xa9fe6ca8bf2961a3386e8b8dcecc29c0567b5c0b3bcf3b0f9169f88e372b80151af883871fc5229815f94f43a6f5b2b0\",\n    \"0xad839ae003b92b37ea431fa35998b46a0afc3f9c0dd54c3b3bf7a262467b13ff3c323ada1c1ae02ac7716528bdf39e3e\",\n    \"0x9356d3fd0edcbbb65713c0f2a214394f831b26f792124b08c5f26e7f734b8711a87b7c4623408da6a091c9aef1f6af3c\",\n    \"0x896b25b083c35ac67f0af3784a6a82435b0e27433d4d74cd6d1eafe11e6827827799490fb1c77c11de25f0d75f14e047\",\n    \"0x8bfa019391c9627e8e5f05c213db625f0f1e51ec68816455f876c7e55b8f17a4f13e5aae9e3fb9e1cf920b1402ee2b40\",\n    \"0x8ba3a6faa6a860a8f3ce1e884aa8769ceded86380a86520ab177ab83043d380a4f535fe13884346c5e51bee68da6ab41\",\n    \"0xa8292d0844084e4e3bb7af92b1989f841a46640288c5b220fecfad063ee94e86e13d3d08038ec2ac82f41c96a3bfe14d\",\n    \"0x8229bb030b2fc566e11fd33c7eab7a1bb7b49fed872ea1f815004f7398cb03b85ea14e310ec19e1f23e0bdaf60f8f76c\",\n    \"0x8cfbf869ade3ec551562ff7f63c2745cc3a1f4d4dc853a0cd42dd5f6fe54228f86195ea8fe217643b32e9f513f34a545\",\n    \"0xac52a3c8d3270ddfe1b5630159da9290a5ccf9ccbdef43b58fc0a191a6c03b8a5974cf6e2bbc7bd98d4a40a3581482d7\",\n    \"0xab13decb9e2669e33a7049b8eca3ca327c40dea15ad6e0e7fa63ed506db1d258bc36ac88b35f65cae0984e937eb6575d\",\n    \"0xb5e748eb1a7a1e274ff0cc56311c198f2c076fe4b7e73e5f80396fe85358549df906584e6bb2c8195b3e2be7736850a5\",\n    \"0xb5cb911325d8f963c41f691a60c37831c7d3bbd92736efa33d1f77a22b3fde7f283127256c2f47e197571e6fe0b46149\",\n    \"0x8a01dc6ed1b55f26427a014faa347130738b191a06b800e32042a46c13f60b49534520214359d68eb2e170c31e2b8672\",\n    \"0xa72fa874866e19b2efb8e069328362bf7921ec375e3bcd6b1619384c3f7ee980f6cf686f3544e9374ff54b4d17a1629c\",\n    \"0x8db21092f7c5f110fba63650b119e82f4b42a997095d65f08f8237b02dd66fdf959f788df2c35124db1dbd330a235671\",\n    \"0x8c65d50433d9954fe28a09fa7ba91a70a590fe7ba6b3060f5e4be0f6cef860b9897fa935fb4ebc42133524eb071dd169\",\n    \"0xb4614058e8fa21138fc5e4592623e78b8982ed72aa35ee4391b164f00c68d277fa9f9eba2eeefc890b4e86eba5124591\",\n    \"0xab2ad3a1bce2fbd55ca6b7c23786171fe1440a97d99d6df4d80d07dd56ac2d7203c294b32fc9e10a6c259381a73f24a1\",\n    \"0x812ae3315fdc18774a8da3713a4679e8ed10b9405edc548c00cacbe25a587d32040566676f135e4723c5dc25df5a22e9\",\n    \"0xa464b75f95d01e5655b54730334f443c8ff27c3cb79ec7af4b2f9da3c2039c609908cd128572e1fd0552eb597e8cef8d\",\n    \"0xa0db3172e93ca5138fe419e1c49a1925140999f6eff7c593e5681951ee0ec1c7e454c851782cbd2b8c9bc90d466e90e0\",\n    \"0x806db23ba7d00b87d544eed926b3443f5f9c60da6b41b1c489fba8f73593b6e3b46ebfcab671ee009396cd77d5e68aa1\",\n    \"0x8bfdf2c0044cc80260994e1c0374588b6653947b178e8b312be5c2a05e05767e98ea15077278506aee7df4fee1aaf89e\",\n    \"0x827f6558c16841b5592ff089c9c31e31eb03097623524394813a2e4093ad2d3f8f845504e2af92195aaa8a1679d8d692\",\n    \"0x925c4f8eab2531135cd71a4ec88e7035b5eea34ba9d799c5898856080256b4a15ed1a746e002552e2a86c9c157e22e83\",\n    \"0xa9f9a368f0e0b24d00a35b325964c85b69533013f9c2cfad9708be5fb87ff455210f8cb8d2ce3ba58ca3f27495552899\",\n    \"0x8ac0d3bebc1cae534024187e7c71f8927ba8fcc6a1926cb61c2b6c8f26bb7831019e635a376146c29872a506784a4aaa\",\n    \"0x97c577be2cbbfdb37ad754fae9df2ada5fc5889869efc7e18a13f8e502fbf3f4067a509efbd46fd990ab47ce9a70f5a8\",\n    \"0x935e7d82bca19f16614aa43b4a3474e4d20d064e4bfdf1cea2909e5c9ab72cfe3e54dc50030e41ee84f3588cebc524e9\",\n    \"0x941aafc08f7c0d94cebfbb1f0aad5202c02e6e37f2c12614f57e727efa275f3926348f567107ee6d8914dd71e6060271\",\n    \"0xaf0fbc1ba05b4b5b63399686df3619968be5d40073de0313cbf5f913d3d4b518d4c249cdd2176468ccaa36040a484f58\",\n    \"0xa0c414f23f46ca6d69ce74c6f8a00c036cb0edd098af0c1a7d39c802b52cfb2d5dbdf93fb0295453d4646e2af7954d45\",\n    \"0x909cf39e11b3875bb63b39687ae1b5d1f5a15445e39bf164a0b14691b4ddb39a8e4363f584ef42213616abc4785b5d66\",\n    \"0xa92bac085d1194fbd1c88299f07a061d0bdd3f980b663e81e6254dbb288bf11478c0ee880e28e01560f12c5ccb3c0103\",\n    \"0x841705cd5cd76b943e2b7c5e845b9dd3c8defe8ef67e93078d6d5e67ade33ad4b0fd413bc196f93b0a4073c855cd97d4\",\n    \"0x8e7eb8364f384a9161e81d3f1d52ceca9b65536ae49cc35b48c3e2236322ba4ae9973e0840802d9fa4f4d82ea833544f\",\n    \"0xaed3ab927548bc8bec31467ba80689c71a168e34f50dcb6892f19a33a099f5aa6b3f9cb79f5c0699e837b9a8c7f27efe\",\n    \"0xb8fbf7696210a36e20edabd77839f4dfdf50d6d015cdf81d587f90284a9bcef7d2a1ff520728d7cc69a4843d6c20dedd\",\n    \"0xa9d533769ce6830211c884ae50a82a7bf259b44ac71f9fb11f0296fdb3981e6b4c1753fe744647b247ebc433a5a61436\",\n    \"0x8b4bdf90d33360b7f428c71cde0a49fb733badba8c726876945f58c620ce7768ae0e98fc8c31fa59d8955a4823336bb1\",\n    \"0x808d42238e440e6571c59e52a35ae32547d502dc24fd1759d8ea70a7231a95859baf30b490a4ba55fa2f3aaa11204597\",\n    \"0x85594701f1d2fee6dc1956bc44c7b31db93bdeec2f3a7d622c1a08b26994760773e3d57521a44cfd7e407ac3fd430429\",\n    \"0xa66de045ce7173043a6825e9dc440ac957e2efb6df0a337f4f8003eb0c719d873a52e6eba3cb0d69d977ca37d9187674\",\n    \"0x87a1c6a1fdff993fa51efa5c3ba034c079c0928a7d599b906336af7c2dcab9721ceaf3108c646490af9dff9a754f54b3\",\n    \"0x926424223e462ceb75aed7c22ade8a7911a903b7e5dd4bc49746ddce8657f4616325cd12667d4393ac52cdd866396d0e\",\n    \"0xb5dc96106593b42b30f06f0b0a1e0c1aafc70432e31807252d3674f0b1ea5e58eac8424879d655c9488d85a879a3e572\",\n    \"0x997ca0987735cc716507cb0124b1d266d218b40c9d8e0ecbf26a1d65719c82a637ce7e8be4b4815d307df717bde7c72a\",\n    \"0x92994d3f57a569b7760324bb5ae4e8e14e1633d175dab06aa57b8e391540e05f662fdc08b8830f489a063f59b689a688\",\n    \"0xa8087fcc6aa4642cb998bea11facfe87eb33b90a9aa428ab86a4124ad032fc7d2e57795311a54ec9f55cc120ebe42df1\",\n    \"0xa9bd7d1de6c0706052ca0b362e2e70e8c8f70f1f026ea189b4f87a08ce810297ebfe781cc8004430776c54c1a05ae90c\",\n    \"0x856d33282e8a8e33a3d237fb0a0cbabaf77ba9edf2fa35a831fdafcadf620561846aa6cbb6bdc5e681118e1245834165\",\n    \"0x9524a7aa8e97a31a6958439c5f3339b19370f03e86b89b1d02d87e4887309dbbe9a3a8d2befd3b7ed5143c8da7e0a8ad\",\n    \"0x824fdf433e090f8acbd258ac7429b21f36f9f3b337c6d0b71d1416a5c88a767883e255b2888b7c906dd2e9560c4af24c\",\n    \"0x88c7fee662ca7844f42ed5527996b35723abffd0d22d4ca203b9452c639a5066031207a5ae763dbc0865b3299d19b1ec\",\n    \"0x919dca5c5595082c221d5ab3a5bc230f45da7f6dec4eb389371e142c1b9c6a2c919074842479c2844b72c0d806170c0c\",\n    \"0xb939be8175715e55a684578d8be3ceff3087f60fa875fff48e52a6e6e9979c955efef8ff67cfa2b79499ea23778e33b0\",\n    \"0x873b6db725e7397d11bc9bed9ac4468e36619135be686790a79bc6ed4249058f1387c9a802ea86499f692cf635851066\",\n    \"0xaeae06db3ec47e9e5647323fa02fac44e06e59b885ad8506bf71b184ab3895510c82f78b6b22a5d978e8218e7f761e9f\",\n    \"0xb99c0a8359c72ab88448bae45d4bf98797a26bca48b0d4460cd6cf65a4e8c3dd823970ac3eb774ae5d0cea4e7fadf33e\",\n    \"0x8f10c8ec41cdfb986a1647463076a533e6b0eec08520c1562401b36bb063ac972aa6b28a0b6ce717254e35940b900e3c\",\n    \"0xa106d9be199636d7add43b942290269351578500d8245d4aae4c083954e4f27f64740a3138a66230391f2d0e6043a8de\",\n    \"0xa469997908244578e8909ff57cffc070f1dbd86f0098df3cfeb46b7a085cfecc93dc69ee7cad90ff1dc5a34d50fe580c\",\n    \"0xa4ef087bea9c20eb0afc0ee4caba7a9d29dfa872137828c721391273e402fb6714afc80c40e98bbd8276d3836bffa080\",\n    \"0xb07a013f73cd5b98dae0d0f9c1c0f35bff8a9f019975c4e1499e9bee736ca6fcd504f9bc32df1655ff333062382cff04\",\n    \"0xb0a77188673e87cc83348c4cc5db1eecf6b5184e236220c8eeed7585e4b928db849944a76ec60ef7708ef6dac02d5592\",\n    \"0xb1284b37e59b529f0084c0dacf0af6c0b91fc0f387bf649a8c74819debf606f7b07fc3e572500016fb145ec2b24e9f17\",\n    \"0x97b20b5b4d6b9129da185adfbf0d3d0b0faeba5b9715f10299e48ea0521709a8296a9264ce77c275a59c012b50b6519a\",\n    \"0xb9d37e946fae5e4d65c1fbfacc8a62e445a1c9d0f882e60cca649125af303b3b23af53c81d7bac544fb7fcfc7a314665\",\n    \"0x8e5acaac379f4bb0127efbef26180f91ff60e4c525bc9b798fc50dfaf4fe8a5aa84f18f3d3cfb8baead7d1e0499af753\",\n    \"0xb0c0b8ab1235bf1cda43d4152e71efc1a06c548edb964eb4afceb201c8af24240bf8ab5cae30a08604e77432b0a5faf0\",\n    \"0x8cc28d75d5c8d062d649cbc218e31c4d327e067e6dbd737ec0a35c91db44fbbd0d40ec424f5ed79814add16947417572\",\n    \"0x95ae6219e9fd47efaa9cb088753df06bc101405ba50a179d7c9f7c85679e182d3033f35b00dbba71fdcd186cd775c52e\",\n    \"0xb5d28fa09f186ebc5aa37453c9b4d9474a7997b8ae92748ecb940c14868792292ac7d10ade01e2f8069242b308cf97e5\",\n    \"0x8c922a0faa14cc6b7221f302df3342f38fc8521ec6c653f2587890192732c6da289777a6cd310747ea7b7d104af95995\",\n    \"0xb9ad5f660b65230de54de535d4c0fcae5bc6b59db21dea5500fdc12eea4470fb8ea003690fdd16d052523418d5e01e8c\",\n    \"0xa39a9dd41a0ff78c82979483731f1cd68d3921c3e9965869662c22e02dde3877802e180ba93f06e7346f96d9fa9261d2\",\n    \"0x8b32875977ec372c583b24234c27ed73aef00cdff61eb3c3776e073afbdeade548de9497c32ec6d703ff8ad0a5cb7fe4\",\n    \"0x9644cbe755a5642fe9d26cfecf170d3164f1848c2c2e271d5b6574a01755f3980b3fc870b98cf8528fef6ecef4210c16\",\n    \"0x81ea9d1fdd9dd66d60f40ce0712764b99da9448ae0b300f8324e1c52f154e472a086dda840cb2e0b9813dc8ce8afd4b5\",\n    \"0x906aaa4a7a7cdf01909c5cfbc7ded2abc4b869213cbf7c922d4171a4f2e637e56f17020b852ad339d83b8ac92f111666\",\n    \"0x939b5f11acbdeff998f2a080393033c9b9d8d5c70912ea651c53815c572d36ee822a98d6dfffb2e339f29201264f2cf4\",\n    \"0xaba4898bf1ccea9b9e2df1ff19001e05891581659c1cbbde7ee76c349c7fc7857261d9785823c9463a8aea3f40e86b38\",\n    \"0x83ca1a56b8a0be4820bdb5a9346357c68f9772e43f0b887729a50d2eb2a326bbcede676c8bf2e51d7c89bbd8fdb778a6\",\n    \"0x94e86e9fe6addfe2c3ee3a547267ed921f4230d877a85bb4442c2d9350c2fa9a9c54e6fe662de82d1a2407e4ab1691c2\",\n    \"0xa0cc3bdef671a59d77c6984338b023fa2b431b32e9ed2abe80484d73edc6540979d6f10812ecc06d4d0c5d4eaca7183c\",\n    \"0xb5343413c1b5776b55ea3c7cdd1f3af1f6bd802ea95effe3f2b91a523817719d2ecc3f8d5f3cc2623ace7e35f99ca967\",\n    \"0x92085d1ed0ed28d8cabe3e7ff1905ed52c7ceb1eac5503760c52fb5ee3a726aba7c90b483c032acc3f166b083d7ec370\",\n    \"0x8ec679520455275cd957fca8122724d287db5df7d29f1702a322879b127bff215e5b71d9c191901465d19c86c8d8d404\",\n    \"0xb65eb2c63d8a30332eb24ee8a0c70156fc89325ebbb38bacac7cf3f8636ad8a472d81ccca80423772abc00192d886d8a\",\n    \"0xa9fe1c060b974bee4d590f2873b28635b61bfcf614e61ff88b1be3eee4320f4874e21e8d666d8ac8c9aba672efc6ecae\",\n    \"0xb3fe2a9a389c006a831dea7e777062df84b5c2803f9574d7fbe10b7e1c125817986af8b6454d6be9d931a5ac94cfe963\",\n    \"0x95418ad13b734b6f0d33822d9912c4c49b558f68d08c1b34a0127fcfa666bcae8e6fda8832d2c75bb9170794a20e4d7c\",\n    \"0xa9a7df761e7f18b79494bf429572140c8c6e9d456c4d4e336184f3f51525a65eb9582bea1e601bdb6ef8150b7ca736a5\",\n    \"0xa0de03b1e75edf7998c8c1ac69b4a1544a6fa675a1941950297917366682e5644a4bda9cdeedfaf9473d7fccd9080b0c\",\n    \"0xa61838af8d95c95edf32663a68f007d95167bf6e41b0c784a30b22d8300cfdd5703bd6d16e86396638f6db6ae7e42a85\",\n    \"0x8866d62084d905c145ff2d41025299d8b702ac1814a7dec4e277412c161bc9a62fed735536789cb43c88693c6b423882\",\n    \"0x91da22c378c81497fe363e7f695c0268443abee50f8a6625b8a41e865638a643f07b157ee566de09ba09846934b4e2d7\",\n    \"0x941d21dd57c9496aa68f0c0c05507405fdd413acb59bc668ce7e92e1936c68ec4b065c3c30123319884149e88228f0b2\",\n    \"0xa77af9b094bc26966ddf2bf9e1520c898194a5ccb694915950dadc204facbe3066d3d89f50972642d76b14884cfbaa21\",\n    \"0x8e76162932346869f4618bde744647f7ab52ab498ad654bdf2a4feeb986ac6e51370841e5acbb589e38b6e7142bb3049\",\n    \"0xb60979ace17d6937ece72e4f015da4657a443dd01cebc7143ef11c09e42d4aa8855999a65a79e2ea0067f31c9fc2ab0f\",\n    \"0xb3e2ffdd5ee6fd110b982fd4fad4b93d0fca65478f986d086eeccb0804960bfaa1919afa743c2239973ea65091fe57d2\",\n    \"0x8ce0ce05e7d7160d44574011da687454dbd3c8b8290aa671731b066e2c82f8cf2d63cb8e932d78c6122ec610e44660e6\",\n    \"0xab005dd8d297045c39e2f72fb1c48edb501ccf3575d3d04b9817b3afee3f0bb0f3f53f64bda37d1d9cde545aae999bae\",\n    \"0x95bd7edb4c4cd60e3cb8a72558845a3cce6bb7032ccdf33d5a49ebb6ddf203bc3c79e7b7e550735d2d75b04c8b2441e8\",\n    \"0x889953ee256206284094e4735dbbb17975bafc7c3cb94c9fbfee4c3e653857bfd49e818f64a47567f721b98411a3b454\",\n    \"0xb188423e707640ab0e75a061e0b62830cde8afab8e1ad3dae30db69ffae4e2fc005bababbdcbd7213b918ed4f70e0c14\",\n    \"0xa97e0fafe011abd70d4f99a0b36638b3d6e7354284588f17a88970ed48f348f88392779e9a038c6cbc9208d998485072\",\n    \"0x87db11014a91cb9b63e8dfaa82cdebca98272d89eb445ee1e3ff9dbaf2b3fad1a03b888cffc128e4fe208ed0dddece0f\",\n    \"0xaad2e40364edd905d66ea4ac9d51f9640d6fda9a54957d26ba233809851529b32c85660fa401dbee3679ec54fa6dd966\",\n    \"0x863e99336ca6edf03a5a259e59a2d0f308206e8a2fb320cfc0be06057366df8e0f94b33a28f574092736b3c5ada84270\",\n    \"0xb34bcc56a057589f34939a1adc51de4ff6a9f4fee9c7fa9aa131e28d0cf0759a0c871b640162acdfbf91f3f1b59a3703\",\n    \"0x935dd28f2896092995c5eff1618e5b6efe7a40178888d7826da9b0503c2d6e68a28e7fac1a334e166d0205f0695ef614\",\n    \"0xb842cd5f8f5de5ca6c68cb4a5c1d7b451984930eb4cc18fd0934d52fdc9c3d2d451b1c395594d73bc3451432bfba653f\",\n    \"0x9014537885ce2debad736bc1926b25fdab9f69b216bf024f589c49dc7e6478c71d595c3647c9f65ff980b14f4bb2283b\",\n    \"0x8e827ccca1dd4cd21707140d10703177d722be0bbe5cac578db26f1ef8ad2909103af3c601a53795435b27bf95d0c9ed\",\n    \"0x8a0b8ad4d466c09d4f1e9167410dbe2edc6e0e6229d4b3036d30f85eb6a333a18b1c968f6ca6d6889bb08fecde017ef4\",\n    \"0x9241ee66c0191b06266332dc9161dede384c4bb4e116dbd0890f3c3790ec5566da4568243665c4725b718ac0f6b5c179\",\n    \"0xaeb4d5fad81d2b505d47958a08262b6f1b1de9373c2c9ba6362594194dea3e002ab03b8cbb43f867be83065d3d370f19\",\n    \"0x8781bc83bb73f7760628629fe19e4714b494dbed444c4e4e4729b7f6a8d12ee347841a199888794c2234f51fa26fc2b9\",\n    \"0xb58864f0acd1c2afa29367e637cbde1968d18589245d9936c9a489c6c495f54f0113ecdcbe4680ac085dd3c397c4d0c3\",\n    \"0x94a24284afaeead61e70f3e30f87248d76e9726759445ca18cdb9360586c60cc9f0ec1c397f9675083e0b56459784e2e\",\n    \"0xaed358853f2b54dcbddf865e1816c2e89be12e940e1abfa661e2ee63ffc24a8c8096be2072fa83556482c0d89e975124\",\n    \"0xb95374e6b4fc0765708e370bc881e271abf2e35c08b056a03b847e089831ef4fe3124b9c5849d9c276eb2e35b3daf264\",\n    \"0xb834cdbcfb24c8f84bfa4c552e7fadc0028a140952fd69ed13a516e1314a4cd35d4b954a77d51a1b93e1f5d657d0315d\",\n    \"0x8fb6d09d23bfa90e7443753d45a918d91d75d8e12ec7d016c0dfe94e5c592ba6aaf483d2f16108d190822d955ad9cdc3\",\n    \"0xaa315cd3c60247a6ad4b04f26c5404c2713b95972843e4b87b5a36a89f201667d70f0adf20757ebe1de1b29ae27dda50\",\n    \"0xa116862dca409db8beff5b1ccd6301cdd0c92ca29a3d6d20eb8b87f25965f42699ca66974dd1a355200157476b998f3b\",\n    \"0xb4c2f5fe173c4dc8311b60d04a65ce1be87f070ac42e13cd19c6559a2931c6ee104859cc2520edebbc66a13dc7d30693\",\n    \"0x8d4a02bf99b2260c334e7d81775c5cf582b00b0c982ce7745e5a90624919028278f5e9b098573bad5515ce7fa92a80c8\",\n    \"0x8543493bf564ce6d97bd23be9bff1aba08bd5821ca834f311a26c9139c92a48f0c2d9dfe645afa95fec07d675d1fd53b\",\n    \"0x9344239d13fde08f98cb48f1f87d34cf6abe8faecd0b682955382a975e6eed64e863fa19043290c0736261622e00045c\",\n    \"0xaa49d0518f343005ca72b9e6c7dcaa97225ce6bb8b908ebbe7b1a22884ff8bfb090890364e325a0d414ad180b8f161d1\",\n    \"0x907d7fd3e009355ab326847c4a2431f688627faa698c13c03ffdd476ecf988678407f029b8543a475dcb3dafdf2e7a9c\",\n    \"0x845f1f10c6c5dad2adc7935f5cd2e2b32f169a99091d4f1b05babe7317b9b1cdce29b5e62f947dc621b9acbfe517a258\",\n    \"0x8f3be8e3b380ea6cdf9e9c237f5e88fd5a357e5ded80ea1fc2019810814de82501273b4da38916881125b6fa0cfd4459\",\n    \"0xb9c7f487c089bf1d20c822e579628db91ed9c82d6ca652983aa16d98b4270c4da19757f216a71b9c13ddee3e6e43705f\",\n    \"0x8ba2d8c88ad2b872db104ea8ddbb006ec2f3749fd0e19298a804bb3a5d94de19285cc7fb19fee58a66f7851d1a66c39f\",\n    \"0x9375ecd3ed16786fe161af5d5c908f56eeb467a144d3bbddfc767e90065b7c94fc53431adebecba2b6c9b5821184d36e\",\n    \"0xa49e069bfadb1e2e8bff6a4286872e2a9765d62f0eaa4fcb0e5af4bbbed8be3510fb19849125a40a8a81d1e33e81c3eb\",\n    \"0x9522cc66757b386aa6b88619525c8ce47a5c346d590bb3647d12f991e6c65c3ab3c0cfc28f0726b6756c892eae1672be\",\n    \"0xa9a0f1f51ff877406fa83a807aeb17b92a283879f447b8a2159653db577848cc451cbadd01f70441e351e9ed433c18bc\",\n    \"0x8ff7533dcff6be8714df573e33f82cf8e9f2bcaaa43e939c4759d52b754e502717950de4b4252fb904560fc31dce94a4\",\n    \"0x959724671e265a28d67c29d95210e97b894b360da55e4cf16e6682e7912491ed8ca14bfaa4dce9c25a25b16af580494f\",\n    \"0x92566730c3002f4046c737032487d0833c971e775de59fe02d9835c9858e2e3bc37f157424a69764596c625c482a2219\",\n    \"0xa84b47ceff13ed9c3e5e9cdf6739a66d3e7c2bd8a6ba318fefb1a9aecf653bb2981da6733ddb33c4b0a4523acc429d23\",\n    \"0xb4ddf571317e44f859386d6140828a42cf94994e2f1dcbcc9777f4eebbfc64fc1e160b49379acc27c4672b8e41835c5d\",\n    \"0x8ab95c94072b853d1603fdd0a43b30db617d13c1d1255b99075198e1947bfa5f59aed2b1147548a1b5e986cd9173d15c\",\n    \"0x89511f2eab33894fd4b3753d24249f410ff7263052c1fef6166fc63a79816656b0d24c529e45ccce6be28de6e375d916\",\n    \"0xa0866160ca63d4f2be1b4ea050dac6b59db554e2ebb4e5b592859d8df339b46fd7cb89aaed0951c3ee540aee982c238a\",\n    \"0x8fcc5cbba1b94970f5ff2eb1922322f5b0aa7d918d4b380c9e7abfd57afd8b247c346bff7b87af82efbce3052511cd1b\",\n    \"0x99aeb2a5e846b0a2874cca02c66ed40d5569eb65ab2495bc3f964a092e91e1517941f2688e79f8cca49cd3674c4e06dc\",\n    \"0xb7a096dc3bad5ca49bee94efd884aa3ff5615cf3825cf95fbe0ce132e35f46581d6482fa82666c7ef5f1643eaee8f1ca\",\n    \"0x94393b1da6eaac2ffd186b7725eca582f1ddc8cdd916004657f8a564a7c588175cb443fc6943b39029f5bbe0add3fad8\",\n    \"0x884b85fe012ccbcd849cb68c3ad832d83b3ef1c40c3954ffdc97f103b1ed582c801e1a41d9950f6bddc1d11f19d5ec76\",\n    \"0xb00061c00131eded8305a7ce76362163deb33596569afb46fe499a7c9d7a0734c084d336b38d168024c2bb42b58e7660\",\n    \"0xa439153ac8e6ca037381e3240e7ba08d056c83d7090f16ed538df25901835e09e27de2073646e7d7f3c65056af6e4ce7\",\n    \"0x830fc9ca099097d1f38b90e6843dc86f702be9d20bdacc3e52cae659dc41df5b8d2c970effa6f83a5229b0244a86fe22\",\n    \"0xb81ea2ffaaff2bb00dd59a9ab825ba5eed4db0d8ac9c8ed1a632ce8f086328a1cddd045fbe1ace289083c1325881b7e7\",\n    \"0xb51ea03c58daf2db32c99b9c4789b183365168cb5019c72c4cc91ac30b5fb7311d3db76e6fa41b7cd4a8c81e2f6cdc94\",\n    \"0xa4170b2c6d09ca5beb08318730419b6f19215ce6c631c854116f904be3bc30dd85a80c946a8ab054d3e307afaa3f8fbc\",\n    \"0x897cc42ff28971ff54d2a55dd6b35cfb8610ac902f3c06e3a5cea0e0a257e870c471236a8e84709211c742a09c5601a6\",\n    \"0xa18f2e98d389dace36641621488664ecbb422088ab03b74e67009b8b8acacaaa24fdcf42093935f355207d934adc52a8\",\n    \"0x92adcfb678cc2ba19c866f3f2b988fdcb4610567f3ab436cc0cb9acaf5a88414848d71133ebdbec1983e38e6190f1b5f\",\n    \"0xa86d43c2ce01b366330d3b36b3ca85f000c3548b8297e48478da1ee7d70d8576d4650cba7852ed125c0d7cb6109aa7f3\",\n    \"0x8ed31ceed9445437d7732dce78a762d72ff32a7636bfb3fd7974b7ae15db414d8184a1766915244355deb354fbc5803b\",\n    \"0x9268f70032584f416e92225d65af9ea18c466ebc7ae30952d56a4e36fd9ea811dde0a126da9220ba3c596ec54d8a335e\",\n    \"0x9433b99ee94f2d3fbdd63b163a2bdf440379334c52308bd24537f7defd807145a062ff255a50d119a7f29f4b85d250e3\",\n    \"0x90ce664f5e4628a02278f5cf5060d1a34f123854634b1870906e5723ac9afd044d48289be283b267d45fcbf3f4656aaf\",\n    \"0xaaf21c4d59378bb835d42ae5c5e5ab7a3c8c36a59e75997989313197752b79a472d866a23683b329ea69b048b87fa13e\",\n    \"0xb83c0589b304cec9ede549fde54f8a7c2a468c6657da8c02169a6351605261202610b2055c639b9ed2d5b8c401fb8f56\",\n    \"0x9370f326ea0f170c2c05fe2c5a49189f20aec93b6b18a5572a818cd4c2a6adb359e68975557b349fb54f065d572f4c92\",\n    \"0xac3232fa5ce6f03fca238bef1ce902432a90b8afce1c85457a6bee5571c033d4bceefafc863af04d4e85ac72a4d94d51\",\n    \"0x80d9ea168ff821b22c30e93e4c7960ce3ad3c1e6deeebedd342a36d01bd942419b187e2f382dbfd8caa34cca08d06a48\",\n    \"0xa387a3c61676fb3381eefa2a45d82625635a666e999aba30e3b037ec9e040f414f9e1ad9652abd3bcad63f95d85038db\",\n    \"0xa1b229fe32121e0b391b0f6e0180670b9dc89d79f7337de4c77ea7ad0073e9593846f06797c20e923092a08263204416\",\n    \"0x92164a9d841a2b828cedf2511213268b698520f8d1285852186644e9a0c97512cafa4bfbe29af892c929ebccd102e998\",\n    \"0x82ee2fa56308a67c7db4fd7ef539b5a9f26a1c2cc36da8c3206ba4b08258fbb3cec6fe5cdbd111433fb1ba2a1e275927\",\n    \"0x8c77bfe9e191f190a49d46f05600603fa42345592539b82923388d72392404e0b29a493a15e75e8b068dddcd444c2928\",\n    \"0x80b927f93ccf79dcf5c5b20bcf5a7d91d7a17bc0401bb7cc9b53a6797feac31026eb114257621f5a64a52876e4474cc1\",\n    \"0xb6b68b6501c37804d4833d5a063dd108a46310b1400549074e3cac84acc6d88f73948b7ad48d686de89c1ec043ae8c1a\",\n    \"0xab3da00f9bdc13e3f77624f58a3a18fc3728956f84b5b549d62f1033ae4b300538e53896e2d943f160618e05af265117\",\n    \"0xb6830e87233b8eace65327fdc764159645b75d2fd4024bf8f313b2dd5f45617d7ecfb4a0b53ccafb5429815a9a1adde6\",\n    \"0xb9251cfe32a6dc0440615aadcd98b6b1b46e3f4e44324e8f5142912b597ee3526bea2431e2b0282bb58f71be5b63f65e\",\n    \"0xaf8d70711e81cdddfb39e67a1b76643292652584c1ce7ce4feb1641431ad596e75c9120e85f1a341e7a4da920a9cdd94\",\n    \"0x98cd4e996594e89495c078bfd52a4586b932c50a449a7c8dfdd16043ca4cda94dafbaa8ad1b44249c99bbcc52152506e\",\n    \"0xb9fc6d1c24f48404a4a64fbe3e43342738797905db46e4132aee5f086aaa4c704918ad508aaefa455cfe1b36572e6242\",\n    \"0xa365e871d30ba9291cedaba1be7b04e968905d003e9e1af7e3b55c5eb048818ae5b913514fb08b24fb4fbdccbb35d0b8\",\n    \"0x93bf99510971ea9af9f1e364f1234c898380677c8e8de9b0dd24432760164e46c787bc9ec42a7ad450500706cf247b2d\",\n    \"0xb872f825a5b6e7b9c7a9ddfeded3516f0b1449acc9b4fd29fc6eba162051c17416a31e5be6d3563f424d28e65bab8b8f\",\n    \"0xb06b780e5a5e8eb4f4c9dc040f749cf9709c8a4c9ef15e925f442b696e41e5095db0778a6c73bcd329b265f2c6955c8b\",\n    \"0x848f1a981f5fc6cd9180cdddb8d032ad32cdfa614fc750d690dbae36cc0cd355cbf1574af9b3ffc8b878f1b2fafb9544\",\n    \"0xa03f48cbff3e9e8a3a655578051a5ae37567433093ac500ed0021c6250a51b767afac9bdb194ee1e3eac38a08c0eaf45\",\n    \"0xb5be78ce638ff8c4aa84352b536628231d3f7558c5be3bf010b28feac3022e64691fa672f358c8b663904aebe24a54ed\",\n    \"0xa9d4da70ff676fa55d1728ba6ab03b471fa38b08854d99e985d88c2d050102d8ccffbe1c90249a5607fa7520b15fe791\",\n    \"0x8fe9f7092ffb0b69862c8e972fb1ecf54308c96d41354ed0569638bb0364f1749838d6d32051fff1599112978c6e229c\",\n    \"0xae6083e95f37770ecae0df1e010456f165d96cfe9a7278c85c15cffd61034081ce5723e25e2bede719dc9341ec8ed481\",\n    \"0xa260891891103089a7afbd9081ea116cfd596fd1015f5b65e10b0961eb37fab7d09c69b7ce4be8bf35e4131848fb3fe4\",\n    \"0x8d729fa32f6eb9fd2f6a140bef34e8299a2f3111bffd0fe463aa8622c9d98bfd31a1df3f3e87cd5abc52a595f96b970e\",\n    \"0xa30ec6047ae4bc7da4daa7f4c28c93aedb1112cfe240e681d07e1a183782c9ff6783ac077c155af23c69643b712a533f\",\n    \"0xac830726544bfe7b5467339e5114c1a75f2a2a8d89453ce86115e6a789387e23551cd64620ead6283dfa4538eb313d86\",\n    \"0x8445c135b7a48068d8ed3e011c6d818cfe462b445095e2fbf940301e50ded23f272d799eea47683fc027430ce14613ef\",\n    \"0x95785411715c9ae9d8293ce16a693a2aa83e3cb1b4aa9f76333d0da2bf00c55f65e21e42e50e6c5772ce213dd7b4f7a0\",\n    \"0xb273b024fa18b7568c0d1c4d2f0c4e79ec509dafac8c5951f14192d63ddbcf2d8a7512c1c1b615cc38fa3e336618e0c5\",\n    \"0xa78b9d3ea4b6a90572eb27956f411f1d105fdb577ee2ffeec9f221da9b45db84bfe866af1f29597220c75e0c37a628d8\",\n    \"0xa4be2bf058c36699c41513c4d667681ce161a437c09d81383244fc55e1c44e8b1363439d0cce90a3e44581fb31d49493\",\n    \"0xb6eef13040f17dd4eba22aaf284d2f988a4a0c4605db44b8d2f4bf9567ac794550b543cc513c5f3e2820242dd704152e\",\n    \"0x87eb00489071fa95d008c5244b88e317a3454652dcb1c441213aa16b28cd3ecaa9b22fec0bdd483c1df71c37119100b1\",\n    \"0x92d388acdcb49793afca329cd06e645544d2269234e8b0b27d2818c809c21726bc9cf725651b951e358a63c83dedee24\",\n    \"0xae27e219277a73030da27ab5603c72c8bd81b6224b7e488d7193806a41343dff2456132274991a4722fdb0ef265d04cd\",\n    \"0x97583e08ecb82bbc27c0c8476d710389fa9ffbead5c43001bd36c1b018f29faa98de778644883e51870b69c5ffb558b5\",\n    \"0x90a799a8ce73387599babf6b7da12767c0591cadd36c20a7990e7c05ea1aa2b9645654ec65308ee008816623a2757a6a\",\n    \"0xa1b47841a0a2b06efd9ab8c111309cc5fc9e1d5896b3e42ed531f6057e5ade8977c29831ce08dbda40348386b1dcc06d\",\n    \"0xb92b8ef59bbddb50c9457691bc023d63dfcc54e0fd88bd5d27a09e0d98ac290fc90e6a8f6b88492043bf7c87fac8f3e4\",\n    \"0xa9d6240b07d62e22ec8ab9b1f6007c975a77b7320f02504fc7c468b4ee9cfcfd945456ff0128bc0ef2174d9e09333f8d\",\n    \"0x8e96534c94693226dc32bca79a595ca6de503af635f802e86442c67e77564829756961d9b701187fe91318da515bf0e6\",\n    \"0xb6ba290623cd8dd5c2f50931c0045d1cfb0c30877bc8fe58cbc3ff61ee8da100045a39153916efa1936f4aee0892b473\",\n    \"0xb43baa7717fac02d4294f5b3bb5e58a65b3557747e3188b482410388daac7a9c177f762d943fd5dcf871273921213da8\",\n    \"0xb9cf00f8fb5e2ef2b836659fece15e735060b2ea39b8e901d3dcbdcf612be8bf82d013833718c04cd46ffaa70b85f42e\",\n    \"0x8017d0c57419e414cbba504368723e751ef990cc6f05dad7b3c2de6360adc774ad95512875ab8337d110bf39a42026fa\",\n    \"0xae7401048b838c0dcd4b26bb6c56d79d51964a0daba780970b6c97daee4ea45854ea0ac0e4139b3fe60dac189f84df65\",\n    \"0x887b237b0cd0f816b749b21db0b40072f9145f7896c36916296973f9e6990ede110f14e5976c906d08987c9836cca57f\",\n    \"0xa88c3d5770148aee59930561ca1223aceb2c832fb5417e188dca935905301fc4c6c2c9270bc1dff7add490a125eb81c6\",\n    \"0xb6cf9b02c0cd91895ad209e38c54039523f137b5848b9d3ad33ae43af6c20c98434952db375fe378de7866f2d0e8b18a\",\n    \"0x84ef3d322ff580c8ad584b1fe4fe346c60866eb6a56e982ba2cf3b021ecb1fdb75ecc6c29747adda86d9264430b3f816\",\n    \"0xa0561c27224baf0927ad144cb71e31e54a064c598373fcf0d66aebf98ab7af1d8e2f343f77baefff69a6da750a219e11\",\n    \"0xaa5cc43f5b8162b016f5e1b61214c0c9d15b1078911c650b75e6cdfb49b85ee04c6739f5b1687d15908444f691f732de\",\n    \"0xad4ac099b935589c7b8fdfdf3db332b7b82bb948e13a5beb121ebd7db81a87d278024a1434bcf0115c54ca5109585c3d\",\n    \"0x8a00466abf3f109a1dcd19e643b603d3af23d42794ef8ca2514dd507ecea44a031ac6dbc18bd02f99701168b25c1791e\",\n    \"0xb00b5900dfad79645f8bee4e5adc7b84eb22e5b1e67df77ccb505b7fc044a6c08a8ea5faca662414eb945f874f884cea\",\n    \"0x950e204e5f17112250b22ea6bb8423baf522fc0af494366f18fe0f949f51d6e6812074a80875cf1ed9c8e7420058d541\",\n    \"0x91e5cbf8bb1a1d50c81608c9727b414d0dd2fb467ebc92f100882a3772e54f94979cfdf8e373fdef7c7fcdd60fec9e00\",\n    \"0xa093f6a857b8caaff80599c2e89c962b415ecbaa70d8fd973155fa976a284c6b29a855f5f7a3521134d00d2972755188\",\n    \"0xb4d55a3551b00da54cc010f80d99ddd2544bde9219a3173dfaadf3848edc7e4056ab532fb75ac26f5f7141e724267663\",\n    \"0xa03ea050fc9b011d1b04041b5765d6f6453a93a1819cd9bd6328637d0b428f08526466912895dcc2e3008ee58822e9a7\",\n    \"0x99b12b3665e473d01bc6985844f8994fb65cb15745024fb7af518398c4a37ff215da8f054e8fdf3286984ae36a73ca5e\",\n    \"0x9972c7e7a7fb12e15f78d55abcaf322c11249cd44a08f62c95288f34f66b51f146302bce750ff4d591707075d9123bd2\",\n    \"0xa64b4a6d72354e596d87cda213c4fc2814009461570ccb27d455bbe131f8d948421a71925425b546d8cf63d5458cd64b\",\n    \"0x91c215c73b195795ede2228b7ed1f6e37892e0c6b0f4a0b5a16c57aa1100c84df9239054a173b6110d6c2b7f4bf1ce52\",\n    \"0x88807198910ec1303480f76a3683870246a995e36adaeadc29c22f0bdba8152fe705bd070b75de657b04934f7d0ccf80\",\n    \"0xb37c0026c7b32eb02cacac5b55cb5fe784b8e48b2945c64d3037af83ece556a117f0ff053a5968c2f5fa230e291c1238\",\n    \"0x94c768384ce212bc2387e91ce8b45e4ff120987e42472888a317abc9dcdf3563b62e7a61c8e98d7cdcbe272167d91fc6\",\n    \"0xa10c2564936e967a390cb14ef6e8f8b04ea9ece5214a38837eda09e79e0c7970b1f83adf017c10efd6faa8b7ffa2c567\",\n    \"0xa5085eed3a95f9d4b1269182ea1e0d719b7809bf5009096557a0674bde4201b0ddc1f0f16a908fc468846b3721748ce3\",\n    \"0x87468eb620b79a0a455a259a6b4dfbc297d0d53336537b771254dd956b145dc816b195b7002647ea218552e345818a3f\",\n    \"0xace2b77ffb87366af0a9cb5d27d6fc4a14323dbbf1643f5f3c4559306330d86461bb008894054394cbfaefeaa0bc2745\",\n    \"0xb27f56e840a54fbd793f0b7a7631aa4cee64b5947e4382b2dfb5eb1790270288884c2a19afebe5dc0c6ef335d4531c1c\",\n    \"0x876e438633931f7f895062ee16c4b9d10428875f7bc79a8e156a64d379a77a2c45bf5430c5ab94330f03da352f1e9006\",\n    \"0xa2512a252587d200d2092b44c914df54e04ff8bcef36bf631f84bde0cf5a732e3dc7f00f662842cfd74b0b0f7f24180e\",\n    \"0x827f1bc8f54a35b7a4bd8154f79bcc055e45faed2e74adf7cf21cca95df44d96899e847bd70ead6bb27b9c0ed97bbd8b\",\n    \"0xa0c92cf5a9ed843714f3aea9fe7b880f622d0b4a3bf66de291d1b745279accf6ba35097849691370f41732ba64b5966b\",\n    \"0xa63f5c1e222775658421c487b1256b52626c6f79cb55a9b7deb2352622cedffb08502042d622eb3b02c97f9c09f9c957\",\n    \"0x8cc093d52651e65fb390e186db6cc4de559176af4624d1c44cb9b0e836832419dacac7b8db0627b96288977b738d785d\",\n    \"0xaa7b6a17dfcec146134562d32a12f7bd7fe9522e300859202a02939e69dbd345ed7ff164a184296268f9984f9312e8fc\",\n    \"0x8ac76721f0d2b679f023d06cbd28c85ae5f4b43c614867ccee88651d4101d4fd352dbdb65bf36bfc3ebc0109e4b0c6f9\",\n    \"0x8d350f7c05fc0dcd9a1170748846fb1f5d39453e4cb31e6d1457bed287d96fc393b2ecc53793ca729906a33e59c6834a\",\n    \"0xb9913510dfc5056d7ec5309f0b631d1ec53e3a776412ada9aefdaf033c90da9a49fdde6719e7c76340e86599b1f0eec2\",\n    \"0x94955626bf4ce87612c5cfffcf73bf1c46a4c11a736602b9ba066328dc52ad6d51e6d4f53453d4ed55a51e0aad810271\",\n    \"0xb0fcab384fd4016b2f1e53f1aafd160ae3b1a8865cd6c155d7073ecc1664e05b1d8bca1def39c158c7086c4e1103345e\",\n    \"0x827de3f03edfbde08570b72de6662c8bfa499b066a0a27ebad9b481c273097d17a5a0a67f01553da5392ec3f149b2a78\",\n    \"0xab7940384c25e9027c55c40df20bd2a0d479a165ced9b1046958353cd69015eeb1e44ed2fd64e407805ba42df10fc7bf\",\n    \"0x8ad456f6ff8cd58bd57567d931f923d0c99141978511b17e03cab7390a72b9f62498b2893e1b05c7c22dd274e9a31919\",\n    \"0xac75399e999effe564672db426faa17a839e57c5ef735985c70cd559a377adec23928382767b55ed5a52f7b11b54b756\",\n    \"0xb17f975a00b817299ac7af5f2024ea820351805df58b43724393bfb3920a8cd747a3bbd4b8286e795521489db3657168\",\n    \"0xa2bed800a6d95501674d9ee866e7314063407231491d794f8cf57d5be020452729c1c7cefd8c50dc1540181f5caab248\",\n    \"0x9743f5473171271ffdd3cc59a3ae50545901a7b45cd4bc3570db487865f3b73c0595bebabbfe79268809ee1862e86e4a\",\n    \"0xb7eab77c2d4687b60d9d7b04e842b3880c7940140012583898d39fcc22d9b9b0a9be2c2e3788b3e6f30319b39c338f09\",\n    \"0x8e2b8f797a436a1b661140e9569dcf3e1eea0a77c7ff2bc4ff0f3e49af04ed2de95e255df8765f1d0927fb456a9926b1\",\n    \"0x8aefea201d4a1f4ff98ffce94e540bb313f2d4dfe7e9db484a41f13fc316ed02b282e1acc9bc6f56cad2dc2e393a44c9\",\n    \"0xb950c17c0e5ca6607d182144aa7556bb0efe24c68f06d79d6413a973b493bfdf04fd147a4f1ab03033a32004cc3ea66f\",\n    \"0xb7b8dcbb179a07165f2dc6aa829fad09f582a71b05c3e3ea0396bf9e6fe73076f47035c031c2101e8e38e0d597eadd30\",\n    \"0xa9d77ed89c77ec1bf8335d08d41c3c94dcca9fd1c54f22837b4e54506b212aa38d7440126c80648ab7723ff18e65ed72\",\n    \"0xa819d6dfd4aef70e52b8402fe5d135f8082d40eb7d3bb5c4d7997395b621e2bb10682a1bad2c9caa33dd818550fc3ec6\",\n    \"0x8f6ee34128fac8bbf13ce2d68b2bb363eb4fd65b297075f88e1446ddeac242500eeb4ef0735e105882ff5ba8c44c139b\",\n    \"0xb4440e48255c1644bcecf3a1e9958f1ec4901cb5b1122ee5b56ffd02cad1c29c4266999dbb85aa2605c1b125490074d4\",\n    \"0xa43304a067bede5f347775d5811cf65a6380a8d552a652a0063580b5c5ef12a0867a39c7912fa219e184f4538eba1251\",\n    \"0xa891ad67a790089ffc9f6d53e6a3d63d3556f5f693e0cd8a7d0131db06fd4520e719cfcc3934f0a8f62a95f90840f1d4\",\n    \"0xaea6df8e9bb871081aa0fc5a9bafb00be7d54012c5baf653791907d5042a326aeee966fd9012a582cc16695f5baf7042\",\n    \"0x8ffa2660dc52ed1cd4eff67d6a84a8404f358a5f713d04328922269bee1e75e9d49afeec0c8ad751620f22352a438e25\",\n    \"0x87ec6108e2d63b06abed350f8b363b7489d642486f879a6c3aa90e5b0f335efc2ff2834eef9353951a42136f8e6a1b32\",\n    \"0x865619436076c2760d9e87ddc905023c6de0a8d56eef12c98a98c87837f2ca3f27fd26a2ad752252dbcbe2b9f1d5a032\",\n    \"0x980437dce55964293cb315c650c5586ffd97e7a944a83f6618af31c9d92c37b53ca7a21bb5bc557c151b9a9e217e7098\",\n    \"0x95d128fc369df4ad8316b72aea0ca363cbc7b0620d6d7bb18f7076a8717a6a46956ff140948b0cc4f6d2ce33b5c10054\",\n    \"0x8c7212d4a67b9ec70ebbca04358ad2d36494618d2859609163526d7b3acc2fc935ca98519380f55e6550f70a9bc76862\",\n    \"0x893a2968819401bf355e85eee0f0ed0406a6d4a7d7f172d0017420f71e00bb0ba984f6020999a3cdf874d3cd8ebcd371\",\n    \"0x9103c1af82dece25d87274e89ea0acd7e68c2921c4af3d8d7c82ab0ed9990a5811231b5b06113e7fa43a6bd492b4564f\",\n    \"0x99cfd87a94eab7d35466caa4ed7d7bb45e5c932b2ec094258fb14bf205659f83c209b83b2f2c9ccb175974b2a33e7746\",\n    \"0x874b6b93e4ee61be3f00c32dd84c897ccd6855c4b6251eb0953b4023634490ed17753cd3223472873cbc6095b2945075\",\n    \"0x84a32c0dc4ea60d33aac3e03e70d6d639cc9c4cc435c539eff915017be3b7bdaba33349562a87746291ebe9bc5671f24\",\n    \"0xa7057b24208928ad67914e653f5ac1792c417f413d9176ba635502c3f9c688f7e2ee81800d7e3dc0a340c464da2fd9c5\",\n    \"0xa03fb9ed8286aacfa69fbd5d953bec591c2ae4153400983d5dbb6cd9ea37fff46ca9e5cceb9d117f73e9992a6c055ad2\",\n    \"0x863b2de04e89936c9a4a2b40380f42f20aefbae18d03750fd816c658aee9c4a03df7b12121f795c85d01f415baaeaa59\",\n    \"0x8526eb9bd31790fe8292360d7a4c3eed23be23dd6b8b8f01d2309dbfdc0cfd33ad1568ddd7f8a610f3f85a9dfafc6a92\",\n    \"0xb46ab8c5091a493d6d4d60490c40aa27950574a338ea5bbc045be3a114af87bdcb160a8c80435a9b7ad815f3cb56a3f3\",\n    \"0xaeadc47b41a8d8b4176629557646202f868b1d728b2dda58a347d937e7ffc8303f20d26d6c00b34c851b8aeec547885d\",\n    \"0xaebb19fc424d72c1f1822aa7adc744cd0ef7e55727186f8df8771c784925058c248406ebeeaf3c1a9ee005a26e9a10c6\",\n    \"0x8ff96e81c1a4a2ab1b4476c21018fae0a67e92129ee36120cae8699f2d7e57e891f5c624902cb1b845b944926a605cc3\",\n    \"0x8251b8d2c43fadcaa049a9e7aff838dae4fb32884018d58d46403ac5f3beb5c518bfd45f03b8abb710369186075eb71c\",\n    \"0xa8b2a64f865f51a5e5e86a66455c093407933d9d255d6b61e1fd81ffafc9538d73caaf342338a66ba8ee166372a3d105\",\n    \"0xaad915f31c6ba7fdc04e2aaac62e84ef434b7ee76a325f07dc430d12c84081999720181067b87d792efd0117d7ee1eab\",\n    \"0xa13db3bb60389883fd41d565c54fb5180d9c47ce2fe7a169ae96e01d17495f7f4fa928d7e556e7c74319c4c25d653eb2\",\n    \"0xa4491b0198459b3f552855d680a59214eb74e6a4d6c5fa3b309887dc50ebea2ecf6d26c040550f7dc478b452481466fb\",\n    \"0x8f017f13d4b1e3f0c087843582b52d5f8d13240912254d826dd11f8703a99a2f3166dfbdfdffd9a3492979d77524276b\",\n    \"0x96c3d5dcd032660d50d7cd9db2914f117240a63439966162b10c8f1f3cf74bc83b0f15451a43b31dbd85e4a7ce0e4bb1\",\n    \"0xb479ec4bb79573d32e0ec93b92bdd7ec8c26ddb5a2d3865e7d4209d119fd3499eaac527615ffac78c440e60ef3867ae0\",\n    \"0xb2c49c4a33aa94b52b6410b599e81ff15490aafa7e43c8031c865a84e4676354a9c81eb4e7b8be6825fdcefd1e317d44\",\n    \"0x906dc51d6a90c089b6704b47592805578a6eed106608eeb276832f127e1b8e858b72e448edcbefb497d152447e0e68ff\",\n    \"0xb0e81c63b764d7dfbe3f3fddc9905aef50f3633e5d6a4af6b340495124abedcff5700dfd1577bbbed7b6bf97d02719cb\",\n    \"0x9304c64701e3b4ed6d146e48a881f7d83a17f58357cca0c073b2bb593afd2d94f6e2a7a1ec511d0a67ad6ff4c3be5937\",\n    \"0xb6fdbd12ba05aa598d80b83f70a15ef90e5cba7e6e75fa038540ee741b644cd1f408a6cecfd2a891ef8d902de586c6b5\",\n    \"0xb80557871a6521b1b3c74a1ba083ae055b575df607f1f7b04c867ba8c8c181ea68f8d90be6031f4d25002cca27c44da2\",\n    \"0xaa7285b8e9712e06b091f64163f1266926a36607f9d624af9996856ed2aaf03a580cb22ce407d1ade436c28b44ca173f\",\n    \"0x8148d72b975238b51e6ea389e5486940d22641b48637d7dfadfa603a605bfc6d74a016480023945d0b85935e396aea5d\",\n    \"0x8a014933a6aea2684b5762af43dcf4bdbb633cd0428d42d71167a2b6fc563ece5e618bff22f1db2ddb69b845b9a2db19\",\n    \"0x990d91740041db770d0e0eb9d9d97d826f09fd354b91c41e0716c29f8420e0e8aac0d575231efba12fe831091ec38d5a\",\n    \"0x9454d0d32e7e308ddec57cf2522fb1b67a2706e33fb3895e9e1f18284129ab4f4c0b7e51af25681d248d7832c05eb698\",\n    \"0xa5bd434e75bac105cb3e329665a35bce6a12f71dd90c15165777d64d4c13a82bceedb9b48e762bd24034e0fc9fbe45f4\",\n    \"0xb09e3b95e41800d4dc29c6ffdaab2cd611a0050347f6414f154a47ee20ee59bf8cf7181454169d479ebce1eb5c777c46\",\n    \"0xb193e341d6a047d15eea33766d656d807b89393665a783a316e9ba10518e5515c8e0ade3d6e15641d917a8a172a5a635\",\n    \"0xade435ec0671b3621dde69e07ead596014f6e1daa1152707a8c18877a8b067bde2895dd47444ffa69db2bbef1f1d8816\",\n    \"0xa7fd3d6d87522dfc56fb47aef9ce781a1597c56a8bbfd796baba907afdc872f753d732bfda1d3402aee6c4e0c189f52d\",\n    \"0xa298cb4f4218d0464b2fab393e512bbc477c3225aa449743299b2c3572f065bc3a42d07e29546167ed9e1b6b3b3a3af3\",\n    \"0xa9ee57540e1fd9c27f4f0430d194b91401d0c642456c18527127d1f95e2dba41c2c86d1990432eb38a692fda058fafde\",\n    \"0x81d6c1a5f93c04e6d8e5a7e0678c1fc89a1c47a5c920bcd36180125c49fcf7c114866b90e90a165823560b19898a7c16\",\n    \"0xa4b7a1ec9e93c899b9fd9aaf264c50e42c36c0788d68296a471f7a3447af4dbc81e4fa96070139941564083ec5b5b5a1\",\n    \"0xb3364e327d381f46940c0e11e29f9d994efc6978bf37a32586636c0070b03e4e23d00650c1440f448809e1018ef9f6d8\",\n    \"0x8056e0913a60155348300e3a62e28b5e30629a90f7dd4fe11289097076708110a1d70f7855601782a3cdc5bdb1ca9626\",\n    \"0xb4980fd3ea17bac0ba9ee1c470b17e575bb52e83ebdd7d40c93f4f87bebeaff1c8a679f9d3d09d635f068d37d5bd28bd\",\n    \"0x905a9299e7e1853648e398901dfcd437aa575c826551f83520df62984f5679cb5f0ea86aa45ed3e18b67ddc0dfafe809\",\n    \"0xab99553bf31a84f2e0264eb34a08e13d8d15e2484aa9352354becf9a15999c76cc568d68274b70a65e49703fc23540d0\",\n    \"0xa43681597bc574d2dae8964c9a8dc1a07613d7a1272bdcb818d98c85d44e16d744250c33f3b5e4d552d97396b55e601f\",\n    \"0xa54e5a31716fccb50245898c99865644405b8dc920ded7a11f3d19bdc255996054b268e16f2e40273f11480e7145f41e\",\n    \"0x8134f3ad5ef2ad4ba12a8a4e4d8508d91394d2bcdc38b7c8c8c0b0a820357ac9f79d286c65220f471eb1adca1d98fc68\",\n    \"0x94e2f755e60471578ab2c1adb9e9cea28d4eec9b0e92e0140770bca7002c365fcabfe1e5fb4fe6cfe79a0413712aa3ef\",\n    \"0xad48f8d0ce7eb3cc6e2a3086ad96f562e5bed98a360721492ae2e74dc158586e77ec8c35d5fd5927376301b7741bad2b\",\n    \"0x8614f0630bdd7fbad3a31f55afd9789f1c605dc85e7dc67e2edfd77f5105f878bb79beded6e9f0b109e38ea7da67e8d5\",\n    \"0x9804c284c4c5e77dabb73f655b12181534ca877c3e1e134aa3f47c23b7ec92277db34d2b0a5d38d2b69e5d1c3008a3e3\",\n    \"0xa51b99c3088e473afdaa9e0a9f7e75a373530d3b04e44e1148da0726b95e9f5f0c7e571b2da000310817c36f84b19f7f\",\n    \"0xac4ff909933b3b76c726b0a382157cdc74ab851a1ac6cef76953c6444441804cc43abb883363f416592e8f6cfbc4550b\",\n    \"0xae7d915eb9fc928b65a29d6edbc75682d08584d0014f7bcf17d59118421ae07d26a02137d1e4de6938bcd1ab8ef48fad\",\n    \"0x852f7e453b1af89b754df6d11a40d5d41ea057376e8ecacd705aacd2f917457f4a093d6b9a8801837fa0f62986ad7149\",\n    \"0x92c6bf5ada5d0c3d4dd8058483de36c215fa98edab9d75242f3eff9db07c734ad67337da6f0eefe23a487bf75a600dee\",\n    \"0xa2b42c09d0db615853763552a48d2e704542bbd786aae016eb58acbf6c0226c844f5fb31e428cb6450b9db855f8f2a6f\",\n    \"0x880cc07968266dbfdcfbc21815cd69e0eddfee239167ac693fb0413912d816f2578a74f7716eecd6deefa68c6eccd394\",\n    \"0xb885b3ace736cd373e8098bf75ba66fa1c6943ca1bc4408cd98ac7074775c4478594f91154b8a743d9c697e1b29f5840\",\n    \"0xa51ce78de512bd87bfa0835de819941dffbf18bec23221b61d8096fc9436af64e0693c335b54e7bfc763f287bdca2db6\",\n    \"0xa3c76166a3bdb9b06ef696e57603b58871bc72883ee9d45171a30fe6e1d50e30bc9c51b4a0f5a7270e19a77b89733850\",\n    \"0xacefc5c6f8a1e7c24d7b41e0fc7f6f3dc0ede6cf3115ffb9a6e54b1d954cbca9bda8ad7a084be9be245a1b8e9770d141\",\n    \"0xb420ed079941842510e31cfad117fa11fb6b4f97dfbc6298cb840f27ebaceba23eeaf3f513bcffbf5e4aae946310182d\",\n    \"0x95c3bb5ef26c5ed2f035aa5d389c6b3c15a6705b9818a3fefaed28922158b35642b2e8e5a1a620fdad07e75ad4b43af4\",\n    \"0x825149f9081ecf07a2a4e3e8b5d21bade86c1a882475d51c55ee909330b70c5a2ac63771c8600c6f38df716af61a3ea1\",\n    \"0x873b935aae16d9f08adbc25353cee18af2f1b8d5f26dec6538d6bbddc515f2217ed7d235dcfea59ae61b428798b28637\",\n    \"0x9294150843a2bedcedb3bb74c43eb28e759cf9499582c5430bccefb574a8ddd4f11f9929257ff4c153990f9970a2558f\",\n    \"0xb619563a811cc531da07f4f04e5c4c6423010ff9f8ed7e6ec9449162e3d501b269fb1c564c09c0429431879b0f45df02\",\n    \"0x91b509b87eb09f007d839627514658c7341bc76d468920fe8a740a8cb96a7e7e631e0ea584a7e3dc1172266f641d0f5c\",\n    \"0x8b8aceace9a7b9b4317f1f01308c3904d7663856946afbcea141a1c615e21ccad06b71217413e832166e9dd915fbe098\",\n    \"0x87b3b36e725833ea0b0f54753c3728c0dbc87c52d44d705ffc709f2d2394414c652d3283bab28dcce09799504996cee0\",\n    \"0xb2670aad5691cbf308e4a6a77a075c4422e6cbe86fdba24e9f84a313e90b0696afb6a067eebb42ba2d10340d6a2f6e51\",\n    \"0x876784a9aff3d54faa89b2bacd3ff5862f70195d0b2edc58e8d1068b3c9074c0da1cfa23671fe12f35e33b8a329c0ccd\",\n    \"0x8b48b9e758e8a8eae182f5cbec96f67d20cca6d3eee80a2d09208eb1d5d872e09ef23d0df8ebbb9b01c7449d0e3e3650\",\n    \"0xb79303453100654c04a487bdcadc9e3578bc80930c489a7069a52e8ca1dba36c492c8c899ce025f8364599899baa287d\",\n    \"0x961b35a6111da54ece6494f24dacd5ea46181f55775b5f03df0e370c34a5046ac2b4082925855325bb42bc2a2c98381d\",\n    \"0xa31feb1be3f5a0247a1f7d487987eb622e34fca817832904c6ee3ee60277e5847945a6f6ea1ac24542c72e47bdf647df\",\n    \"0xa12a2aa3e7327e457e1aae30e9612715dd2cfed32892c1cd6dcda4e9a18203af8a44afb46d03b2eed89f6b9c5a2c0c23\",\n    \"0xa08265a838e69a2ca2f80fead6ccf16f6366415b920c0b22ee359bcd8d4464ecf156f400a16a7918d52e6d733dd64211\",\n    \"0xb723d6344e938d801cca1a00032af200e541d4471fd6cbd38fb9130daa83f6a1dffbbe7e67fc20f9577f884acd7594b2\",\n    \"0xa6733d83ec78ba98e72ddd1e7ff79b7adb0e559e256760d0c590a986e742445e8cdf560d44b29439c26d87edd0b07c8c\",\n    \"0xa61c2c27d3f7b9ff4695a17afedf63818d4bfba390507e1f4d0d806ce8778d9418784430ce3d4199fd3bdbc2504d2af3\",\n    \"0x8332f3b63a6dc985376e8b1b25eeae68be6160fbe40053ba7bcf6f073204f682da72321786e422d3482fd60c9e5aa034\",\n    \"0xa280f44877583fbb6b860d500b1a3f572e3ee833ec8f06476b3d8002058e25964062feaa1e5bec1536d734a5cfa09145\",\n    \"0xa4026a52d277fcea512440d2204f53047718ebfcae7b48ac57ea7f6bfbc5de9d7304db9a9a6cbb273612281049ddaec5\",\n    \"0x95cdf69c831ab2fad6c2535ede9c07e663d2ddccc936b64e0843d2df2a7b1c31f1759c3c20f1e7a57b1c8f0dbb21b540\",\n    \"0x95c96cec88806469c277ab567863c5209027cecc06c7012358e5f555689c0d9a5ffb219a464f086b45817e8536b86d2f\",\n    \"0xafe38d4684132a0f03d806a4c8df556bf589b25271fbc6fe2e1ed16de7962b341c5003755da758d0959d2e6499b06c68\",\n    \"0xa9b77784fda64987f97c3a23c5e8f61b918be0f7c59ba285084116d60465c4a2aaafc8857eb16823282cc83143eb9126\",\n    \"0xa830f05881ad3ce532a55685877f529d32a5dbe56cea57ffad52c4128ee0fad0eeaf0da4362b55075e77eda7babe70e5\",\n    \"0x992b3ad190d6578033c13ed5abfee4ef49cbc492babb90061e3c51ee4b5790cdd4c8fc1abff1fa2c00183b6b64f0bbbe\",\n    \"0xb1015424d9364aeff75de191652dc66484fdbec3e98199a9eb9671ec57bec6a13ff4b38446e28e4d8aedb58dd619cd90\",\n    \"0xa745304604075d60c9db36cada4063ac7558e7ec2835d7da8485e58d8422e817457b8da069f56511b02601289fbb8981\",\n    \"0xa5ba4330bc5cb3dbe0486ddf995632a7260a46180a08f42ae51a2e47778142132463cc9f10021a9ad36986108fefa1a9\",\n    \"0xb419e9fd4babcaf8180d5479db188bb3da232ae77a1c4ed65687c306e6262f8083070a9ac32220cddb3af2ec73114092\",\n    \"0xa49e23dc5f3468f3bf3a0bb7e4a114a788b951ff6f23a3396ae9e12cbff0abd1240878a3d1892105413dbc38818e807c\",\n    \"0xb7ecc7b4831f650202987e85b86bc0053f40d983f252e9832ef503aea81c51221ce93279da4aa7466c026b2d2070e55d\",\n    \"0x96a8c35cb87f84fa84dcd6399cc2a0fd79cc9158ef4bdde4bae31a129616c8a9f2576cd19baa3f497ca34060979aed7d\",\n    \"0x8681b2c00aa62c2b519f664a95dcb8faef601a3b961bb4ce5d85a75030f40965e2983871d41ea394aee934e859581548\",\n    \"0x85c229a07efa54a713d0790963a392400f55fbb1a43995a535dc6c929f20d6a65cf4efb434e0ad1cb61f689b8011a3bc\",\n    \"0x90856f7f3444e5ad44651c28e24cc085a5db4d2ffe79aa53228c26718cf53a6e44615f3c5cda5aa752d5f762c4623c66\",\n    \"0x978999b7d8aa3f28a04076f74d11c41ef9c89fdfe514936c4238e0f13c38ec97e51a5c078ebc6409e517bfe7ccb42630\",\n    \"0xa099914dd7ed934d8e0d363a648e9038eb7c1ec03fa04dbcaa40f7721c618c3ef947afef7a16b4d7ac8c12aa46637f03\",\n    \"0xab2a104fed3c83d16f2cda06878fa5f30c8c9411de71bfb67fd2fc9aa454dcbcf3d299d72f8cc12e919466a50fcf7426\",\n    \"0xa4471d111db4418f56915689482f6144efc4664cfb0311727f36c864648d35734351becc48875df96f4abd3cfcf820f9\",\n    \"0x83be11727cd30ea94ccc8fa31b09b81c9d6a9a5d3a4686af9da99587332fe78c1f94282f9755854bafd6033549afec91\",\n    \"0x88020ff971dc1a01a9e993cd50a5d2131ffdcbb990c1a6aaa54b20d8f23f9546a70918ea57a21530dcc440c1509c24ad\",\n    \"0xae24547623465e87905eaffa1fa5d52bb7c453a8dbd89614fa8819a2abcedaf455c2345099b7324ae36eb0ad7c8ef977\",\n    \"0xb59b0c60997de1ee00b7c388bc7101d136c9803bf5437b1d589ba57c213f4f835a3e4125b54738e78abbc21b000f2016\",\n    \"0xa584c434dfe194546526691b68fa968c831c31da42303a1d735d960901c74011d522246f37f299555416b8cf25c5a548\",\n    \"0x80408ce3724f4837d4d52376d255e10f69eb8558399ae5ca6c11b78b98fe67d4b93157d2b9b639f1b5b64198bfe87713\",\n    \"0xabb941e8d406c2606e0ddc35c113604fdd9d249eacc51cb64e2991e551b8639ce44d288cc92afa7a1e7fc599cfc84b22\",\n    \"0xb223173f560cacb1c21dba0f1713839e348ad02cbfdef0626748604c86f89e0f4c919ed40b583343795bdd519ba952c8\",\n    \"0xaf1c70512ec3a19d98b8a1fc3ff7f7f5048a27d17d438d43f561974bbdd116fcd5d5c21040f3447af3f0266848d47a15\",\n    \"0x8a44809568ebe50405bede19b4d2607199159b26a1b33e03d180e6840c5cf59d991a4fb150d111443235d75ecad085b7\",\n    \"0xb06207cdca46b125a27b3221b5b50cf27af4c527dd7c80e2dbcebbb09778a96df3af67e50f07725239ce3583dad60660\",\n    \"0x993352d9278814ec89b26a11c4a7c4941bf8f0e6781ae79559d14749ee5def672259792db4587f85f0100c7bb812f933\",\n    \"0x9180b8a718b971fd27bc82c8582d19c4b4f012453e8c0ffeeeffe745581fc6c07875ab28be3af3fa3896d19f0c89ac5b\",\n    \"0x8b8e1263eb48d0fe304032dd5ea1f30e73f0121265f7458ba9054d3626894e8a5fef665340abd2ede9653045c2665938\",\n    \"0x99a2beee4a10b7941c24b2092192faf52b819afd033e4a2de050fd6c7f56d364d0cf5f99764c3357cf32399e60fc5d74\",\n    \"0x946a4aad7f8647ea60bee2c5fcdeb6f9a58fb2cfca70c4d10e458027a04846e13798c66506151be3df9454b1e417893f\",\n    \"0xa672a88847652d260b5472d6908d1d57e200f1e492d30dd1cecc441cdfc9b76e016d9bab560efd4d7f3c30801de884a9\",\n    \"0x9414e1959c156cde1eb24e628395744db75fc24b9df4595350aaad0bc38e0246c9b4148f6443ef68b8e253a4a6bcf11c\",\n    \"0x9316e9e4ec5fab4f80d6540df0e3a4774db52f1d759d2e5b5bcd3d7b53597bb007eb1887cb7dc61f62497d51ffc8d996\",\n    \"0x902d6d77bb49492c7a00bc4b70277bc28c8bf9888f4307bb017ac75a962decdedf3a4e2cf6c1ea9f9ba551f4610cbbd7\",\n    \"0xb07025a18b0e32dd5e12ec6a85781aa3554329ea12c4cd0d3b2c22e43d777ef6f89876dd90a9c8fb097ddf61cf18adc5\",\n    \"0xb355a849ad3227caa4476759137e813505ec523cbc2d4105bc7148a4630f9e81918d110479a2d5f5e4cd9ccec9d9d3e3\",\n    \"0xb49532cfdf02ee760109881ad030b89c48ee3bb7f219ccafc13c93aead754d29bdafe345be54c482e9d5672bd4505080\",\n    \"0x9477802410e263e4f938d57fa8f2a6cac7754c5d38505b73ee35ea3f057aad958cb9722ba6b7b3cfc4524e9ca93f9cdc\",\n    \"0x9148ea83b4436339580f3dbc9ba51509e9ab13c03063587a57e125432dd0915f5d2a8f456a68f8fff57d5f08c8f34d6e\",\n    \"0xb00b6b5392b1930b54352c02b1b3b4f6186d20bf21698689bbfc7d13e86538a4397b90e9d5c93fd2054640c4dbe52a4f\",\n    \"0x926a9702500441243cd446e7cbf15dde16400259726794694b1d9a40263a9fc9e12f7bcbf12a27cb9aaba9e2d5848ddc\",\n    \"0xa0c6155f42686cbe7684a1dc327100962e13bafcf3db97971fc116d9f5c0c8355377e3d70979cdbd58fd3ea52440901c\",\n    \"0xa277f899f99edb8791889d0817ea6a96c24a61acfda3ad8c3379e7c62b9d4facc4b965020b588651672fd261a77f1bfc\",\n    \"0x8f528cebb866b501f91afa50e995234bef5bf20bff13005de99cb51eaac7b4f0bf38580cfd0470de40f577ead5d9ba0f\",\n    \"0x963fc03a44e9d502cc1d23250efef44d299befd03b898d07ce63ca607bb474b5cf7c965a7b9b0f32198b04a8393821f7\",\n    \"0xab087438d0a51078c378bf4a93bd48ef933ff0f1fa68d02d4460820df564e6642a663b5e50a5fe509527d55cb510ae04\",\n    \"0xb0592e1f2c54746bb076be0fa480e1c4bebc4225e1236bcda3b299aa3853e3afb401233bdbcfc4a007b0523a720fbf62\",\n    \"0x851613517966de76c1c55a94dc4595f299398a9808f2d2f0a84330ba657ab1f357701d0895f658c18a44cb00547f6f57\",\n    \"0xa2fe9a1dd251e72b0fe4db27be508bb55208f8f1616b13d8be288363ec722826b1a1fd729fc561c3369bf13950bf1fd6\",\n    \"0xb896cb2bc2d0c77739853bc59b0f89b2e008ba1f701c9cbe3bef035f499e1baee8f0ff1e794854a48c320586a2dfc81a\",\n    \"0xa1b60f98e5e5106785a9b81a85423452ee9ef980fa7fa8464f4366e73f89c50435a0c37b2906052b8e58e212ebd366cf\",\n    \"0xa853b0ebd9609656636df2e6acd5d8839c0fda56f7bf9288a943b06f0b67901a32b95e016ca8bc99bd7b5eab31347e72\",\n    \"0xb290fa4c1346963bd5225235e6bdf7c542174dab4c908ab483d1745b9b3a6015525e398e1761c90e4b49968d05e30eea\",\n    \"0xb0f65a33ad18f154f1351f07879a183ad62e5144ad9f3241c2d06533dad09cbb2253949daff1bb02d24d16a3569f7ef0\",\n    \"0xa00db59b8d4218faf5aeafcd39231027324408f208ec1f54d55a1c41228b463b88304d909d16b718cfc784213917b71e\",\n    \"0xb8d695dd33dc2c3bc73d98248c535b2770ad7fa31aa726f0aa4b3299efb0295ba9b4a51c71d314a4a1bd5872307534d1\",\n    \"0xb848057cca2ca837ee49c42b88422303e58ea7d2fc76535260eb5bd609255e430514e927cc188324faa8e657396d63ec\",\n    \"0x92677836061364685c2aaf0313fa32322746074ed5666fd5f142a7e8f87135f45cd10e78a17557a4067a51dfde890371\",\n    \"0xa854b22c9056a3a24ab164a53e5c5cf388616c33e67d8ebb4590cb16b2e7d88b54b1393c93760d154208b5ca822dc68f\",\n    \"0x86fff174920388bfab841118fb076b2b0cdec3fdb6c3d9a476262f82689fb0ed3f1897f7be9dbf0932bb14d346815c63\",\n    \"0x99661cf4c94a74e182752bcc4b98a8c2218a8f2765642025048e12e88ba776f14f7be73a2d79bd21a61def757f47f904\",\n    \"0x8a8893144d771dca28760cba0f950a5d634195fd401ec8cf1145146286caffb0b1a6ba0c4c1828d0a5480ce49073c64c\",\n    \"0x938a59ae761359ee2688571e7b7d54692848eb5dde57ffc572b473001ea199786886f8c6346a226209484afb61d2e526\",\n    \"0x923f68a6aa6616714cf077cf548aeb845bfdd78f2f6851d8148cba9e33a374017f2f3da186c39b82d14785a093313222\",\n    \"0xac923a93d7da7013e73ce8b4a2b14b8fd0cc93dc29d5de941a70285bdd19be4740fedfe0c56b046689252a3696e9c5bc\",\n    \"0xb49b32c76d4ec1a2c68d4989285a920a805993bc6fcce6dacd3d2ddae73373050a5c44ba8422a3781050682fa0ef6ba2\",\n    \"0x8a367941c07c3bdca5712524a1411bad7945c7c48ffc7103b1d4dff2c25751b0624219d1ccde8c3f70c465f954be5445\",\n    \"0xb838f029df455efb6c530d0e370bbbf7d87d61a9aea3d2fe5474c5fe0a39cf235ceecf9693c5c6c5820b1ba8f820bd31\",\n    \"0xa8983b7c715eaac7f13a001d2abc462dfc1559dab4a6b554119c271aa8fe00ffcf6b6949a1121f324d6d26cb877bcbae\",\n    \"0xa2afb24ad95a6f14a6796315fbe0d8d7700d08f0cfaf7a2abe841f5f18d4fecf094406cbd54da7232a159f9c5b6e805e\",\n    \"0x87e8e95ad2d62f947b2766ff405a23f7a8afba14e7f718a691d95369c79955cdebe24c54662553c60a3f55e6322c0f6f\",\n    \"0x87c2cbcecb754e0cc96128e707e5c5005c9de07ffd899efa3437cadc23362f5a1d3fcdd30a1f5bdc72af3fb594398c2a\",\n    \"0x91afd6ee04f0496dc633db88b9370d41c428b04fd991002502da2e9a0ef051bcd7b760e860829a44fbe5539fa65f8525\",\n    \"0x8c50e5d1a24515a9dd624fe08b12223a75ca55196f769f24748686315329b337efadca1c63f88bee0ac292dd0a587440\",\n    \"0x8a07e8f912a38d94309f317c32068e87f68f51bdfa082d96026f5f5f8a2211621f8a3856dda8069386bf15fb2d28c18f\",\n    \"0x94ad1dbe341c44eeaf4dc133eed47d8dbfe752575e836c075745770a6679ff1f0e7883b6aa917462993a7f469d74cab5\",\n    \"0x8745f8bd86c2bb30efa7efb7725489f2654f3e1ac4ea95bd7ad0f3cfa223055d06c187a16192d9d7bdaea7b050c6a324\",\n    \"0x900d149c8d79418cda5955974c450a70845e02e5a4ecbcc584a3ca64d237df73987c303e3eeb79da1af83bf62d9e579f\",\n    \"0x8f652ab565f677fb1a7ba03b08004e3cda06b86c6f1b0b9ab932e0834acf1370abb2914c15b0d08327b5504e5990681c\",\n    \"0x9103097d088be1f75ab9d3da879106c2f597e2cc91ec31e73430647bdd5c33bcfd771530d5521e7e14df6acda44f38a6\",\n    \"0xb0fec7791cfb0f96e60601e1aeced9a92446b61fedab832539d1d1037558612d78419efa87ff5f6b7aab8fd697d4d9de\",\n    \"0xb9d2945bdb188b98958854ba287eb0480ef614199c4235ce5f15fc670b8c5ffe8eeb120c09c53ea8a543a022e6a321ac\",\n    \"0xa9461bb7d5490973ebaa51afc0bb4a5e42acdccb80e2f939e88b77ac28a98870e103e1042899750f8667a8cc9123bae9\",\n    \"0xa37fdf11d4bcb2aed74b9f460a30aa34afea93386fa4cdb690f0a71bc58f0b8df60bec56e7a24f225978b862626fa00e\",\n    \"0xa214420e183e03d531cf91661466ea2187d84b6e814b8b20b3730a9400a7d25cf23181bb85589ebc982cec414f5c2923\",\n    \"0xad09a45a698a6beb3e0915f540ef16e9af7087f53328972532d6b5dfe98ce4020555ece65c6cbad8bd6be8a4dfefe6fd\",\n    \"0xab6742800b02728c92d806976764cb027413d6f86edd08ad8bb5922a2969ee9836878cd39db70db0bd9a2646862acc4f\",\n    \"0x974ca9305bd5ea1dc1755dff3b63e8bfe9f744321046c1395659bcea2a987b528e64d5aa96ac7b015650b2253b37888d\",\n    \"0x84eee9d6bce039c52c2ebc4fccc0ad70e20c82f47c558098da4be2f386a493cbc76adc795b5488c8d11b6518c2c4fab8\",\n    \"0x875d7bda46efcb63944e1ccf760a20144df3b00d53282b781e95f12bfc8f8316dfe6492c2efbf796f1150e36e436e9df\",\n    \"0xb68a2208e0c587b5c31b5f6cb32d3e6058a9642e2d9855da4f85566e1412db528475892060bb932c55b3a80877ad7b4a\",\n    \"0xba006368ecab5febb6ab348644d9b63de202293085ed468df8bc24d992ae8ce468470aa37f36a73630c789fb9c819b30\",\n    \"0x90a196035150846cd2b482c7b17027471372a8ce7d914c4d82b6ea7fa705d8ed5817bd42d63886242585baf7d1397a1c\",\n    \"0xa223b4c85e0daa8434b015fd9170b5561fe676664b67064974a1e9325066ecf88fc81f97ab5011c59fad28cedd04b240\",\n    \"0x82e8ec43139cf15c6bbeed484b62e06cded8a39b5ce0389e4cbe9c9e9c02f2f0275d8d8d4e8dfec8f69a191bef220408\",\n    \"0x81a3fc07a7b68d92c6ee4b6d28f5653ee9ec85f7e2ee1c51c075c1b130a8c5097dc661cf10c5aff1c7114b1a6a19f11a\",\n    \"0x8ed2ef8331546d98819a5dd0e6c9f8cb2630d0847671314a28f277faf68da080b53891dd75c82cbcf7788b255490785d\",\n    \"0xacecabf84a6f9bbed6b2fc2e7e4b48f02ef2f15e597538a73aea8f98addc6badda15e4695a67ecdb505c1554e8f345ec\",\n    \"0xb8f51019b2aa575f8476e03dcadf86cc8391f007e5f922c2a36b2daa63f5a503646a468990cd5c65148d323942193051\",\n    \"0xaaa595a84b403ec65729bc1c8055a94f874bf9adddc6c507b3e1f24f79d3ad359595a672b93aab3394db4e2d4a7d8970\",\n    \"0x895144c55fcbd0f64d7dd69e6855cfb956e02b5658eadf0f026a70703f3643037268fdd673b0d21b288578a83c6338dd\",\n    \"0xa2e92ae6d0d237d1274259a8f99d4ea4912a299816350b876fba5ebc60b714490e198a916e1c38c6e020a792496fa23c\",\n    \"0xa45795fda3b5bb0ad1d3c628f6add5b2a4473a1414c1a232e80e70d1cfffd7f8a8d9861f8df2946999d7dbb56bf60113\",\n    \"0xb6659bf7f6f2fef61c39923e8c23b8c70e9c903028d8f62516d16755cd3fba2fe41c285aa9432dc75ab08f8a1d8a81fc\",\n    \"0xa735609a6bc5bfd85e58234fc439ff1f58f1ff1dd966c5921d8b649e21f006bf2b8642ad8a75063c159aaf6935789293\",\n    \"0xa3c622eb387c9d15e7bda2e3e84d007cb13a6d50d655c3f2f289758e49d3b37b9a35e4535d3cc53d8efd51f407281f19\",\n    \"0x8afe147b53ad99220f5ef9d763bfc91f9c20caecbcf823564236fb0e6ede49414c57d71eec4772c8715cc65a81af0047\",\n    \"0xb5f0203233cf71913951e9c9c4e10d9243e3e4a1f2cb235bf3f42009120ba96e04aa414c9938ea8873b63148478927e8\",\n    \"0x93c52493361b458d196172d7ba982a90a4f79f03aa8008edc322950de3ce6acf4c3977807a2ffa9e924047e02072b229\",\n    \"0xb9e72b805c8ac56503f4a86c82720afbd5c73654408a22a2ac0b2e5caccdfb0e20b59807433a6233bc97ae58cf14c70a\",\n    \"0xaf0475779b5cee278cca14c82da2a9f9c8ef222eb885e8c50cca2315fea420de6e04146590ed0dd5a29c0e0812964df5\",\n    \"0xb430ccab85690db02c2d0eb610f3197884ca12bc5f23c51e282bf3a6aa7e4a79222c3d8761454caf55d6c01a327595f9\",\n    \"0x830032937418b26ee6da9b5206f3e24dc76acd98589e37937e963a8333e5430abd6ce3dd93ef4b8997bd41440eed75d6\",\n    \"0x8820a6d73180f3fe255199f3f175c5eb770461ad5cfdde2fb11508041ed19b8c4ce66ad6ecebf7d7e836cc2318df47ca\",\n    \"0xaef1393e7d97278e77bbf52ef6e1c1d5db721ccf75fe753cf47a881fa034ca61eaa5098ee5a344c156d2b14ff9e284ad\",\n    \"0x8a4a26c07218948c1196c45d927ef4d2c42ade5e29fe7a91eaebe34a29900072ce5194cf28d51f746f4c4c649daf4396\",\n    \"0x84011dc150b7177abdcb715efbd8c201f9cb39c36e6069af5c50a096021768ba40cef45b659c70915af209f904ede3b6\",\n    \"0xb1bd90675411389bb66910b21a4bbb50edce5330850c5ab0b682393950124252766fc81f5ecfc72fb7184387238c402e\",\n    \"0x8dfdcd30583b696d2c7744655f79809f451a60c9ad5bf1226dc078b19f4585d7b3ef7fa9d54e1ac09520d95cbfd20928\",\n    \"0xb351b4dc6d98f75b8e5a48eb7c6f6e4b78451991c9ba630e5a1b9874c15ac450cd409c1a024713bf2cf82dc400e025ef\",\n    \"0xa462b8bc97ac668b97b28b3ae24b9f5de60e098d7b23ecb600d2194cd35827fb79f77c3e50d358f5bd72ee83fef18fa0\",\n    \"0xa183753265c5f7890270821880cce5f9b2965b115ba783c6dba9769536f57a04465d7da5049c7cf8b3fcf48146173c18\",\n    \"0xa8a771b81ed0d09e0da4d79f990e58eabcd2be3a2680419502dd592783fe52f657fe55125b385c41d0ba3b9b9cf54a83\",\n    \"0xa71ec577db46011689d073245e3b1c3222a9b1fe6aa5b83629adec5733dd48617ebea91346f0dd0e6cdaa86e4931b168\",\n    \"0xa334b8b244f0d598a02da6ae0f918a7857a54dce928376c4c85df15f3b0f2ba3ac321296b8b7c9dd47d770daf16c8f8c\",\n    \"0xa29037f8ef925c417c90c4df4f9fb27fb977d04e2b3dd5e8547d33e92ab72e7a00f5461de21e28835319eae5db145eb7\",\n    \"0xb91054108ae78b00e3298d667b913ebc44d8f26e531eae78a8fe26fdfb60271c97efb2dee5f47ef5a3c15c8228138927\",\n    \"0x926c13efbe90604f6244be9315a34f72a1f8d1aab7572df431998949c378cddbf2fe393502c930fff614ff06ae98a0ce\",\n    \"0x995c758fd5600e6537089b1baa4fbe0376ab274ff3e82a17768b40df6f91c2e443411de9cafa1e65ea88fb8b87d504f4\",\n    \"0x9245ba307a7a90847da75fca8d77ec03fdfc812c871e7a2529c56a0a79a6de16084258e7a9ac4ae8a3756f394336e21c\",\n    \"0x99e0cfa2bb57a7e624231317044c15e52196ecce020db567c8e8cb960354a0be9862ee0c128c60b44777e65ac315e59f\",\n    \"0xad4f6b3d27bbbb744126601053c3dc98c07ff0eb0b38a898bd80dce778372846d67e5ab8fb34fb3ad0ef3f235d77ba7f\",\n    \"0xa0f12cae3722bbbca2e539eb9cc7614632a2aefe51410430070a12b5bc5314ecec5857b7ff8f41e9980cac23064f7c56\",\n    \"0xb487f1bc59485848c98222fd3bc36c8c9bb3d2912e2911f4ceca32c840a7921477f9b1fe00877e05c96c75d3eecae061\",\n    \"0xa6033db53925654e18ecb3ce715715c36165d7035db9397087ac3a0585e587998a53973d011ac6d48af439493029cee6\",\n    \"0xa6b4d09cd01c70a3311fd131d3710ccf97bde3e7b80efd5a8c0eaeffeb48cca0f951ced905290267b115b06d46f2693b\",\n    \"0xa9dff1df0a8f4f218a98b6f818a693fb0d611fed0fc3143537cbd6578d479af13a653a8155e535548a2a0628ae24fa58\",\n    \"0xa58e469f65d366b519f9a394cacb7edaddac214463b7b6d62c2dbc1316e11c6c5184ce45c16de2d77f990dcdd8b55430\",\n    \"0x989e71734f8119103586dc9a3c5f5033ddc815a21018b34c1f876cdfc112efa868d5751bf6419323e4e59fa6a03ece1c\",\n    \"0xa2da00e05036c884369e04cf55f3de7d659cd5fa3f849092b2519dd263694efe0f051953d9d94b7e121f0aee8b6174d7\",\n    \"0x968f3c029f57ee31c4e1adea89a7f92e28483af9a74f30fbdb995dc2d40e8e657dff8f8d340d4a92bf65f54440f2859f\",\n    \"0x932778df6f60ac1639c1453ef0cbd2bf67592759dcccb3e96dcc743ff01679e4c7dd0ef2b0833dda548d32cb4eba49e2\",\n    \"0xa805a31139f8e0d6dae1ac87d454b23a3dc9fc653d4ca18d4f8ebab30fc189c16e73981c2cb7dd6f8c30454a5208109d\",\n    \"0xa9ba0991296caa2aaa4a1ceacfb205544c2a2ec97088eace1d84ee5e2767656a172f75d2f0c4e16a3640a0e0dec316e0\",\n    \"0xb1e49055c968dced47ec95ae934cf45023836d180702e20e2df57e0f62fb85d7ac60d657ba3ae13b8560b67210449459\",\n    \"0xa94e1da570a38809c71e37571066acabff7bf5632737c9ab6e4a32856924bf6211139ab3cedbf083850ff2d0e0c0fcfc\",\n    \"0x88ef1bb322000c5a5515b310c838c9af4c1cdbb32eab1c83ac3b2283191cd40e9573747d663763a28dad0d64adc13840\",\n    \"0xa987ce205f923100df0fbd5a85f22c9b99b9b9cbe6ddfa8dfda1b8fe95b4f71ff01d6c5b64ca02eb24edb2b255a14ef0\",\n    \"0x84fe8221a9e95d9178359918a108de4763ebfa7a6487facb9c963406882a08a9a93f492f8e77cf9e7ea41ae079c45993\",\n    \"0xaa1cf3dc7c5dcfa15bbbc811a4bb6dbac4fba4f97fb1ed344ab60264d7051f6eef19ea9773441d89929ee942ed089319\",\n    \"0x8f6a7d610d59d9f54689bbe6a41f92d9f6096cde919c1ab94c3c7fcecf0851423bc191e5612349e10f855121c0570f56\",\n    \"0xb5af1fa7894428a53ea520f260f3dc3726da245026b6d5d240625380bfb9c7c186df0204bb604efac5e613a70af5106e\",\n    \"0xa5bce6055ff812e72ce105f147147c7d48d7a2313884dd1f488b1240ee320f13e8a33f5441953a8e7a3209f65b673ce1\",\n    \"0xb9b55b4a1422677d95821e1d042ab81bbf0bf087496504021ec2e17e238c2ca6b44fb3b635a5c9eac0871a724b8d47c3\",\n    \"0x941c38e533ce4a673a3830845b56786585e5fe49c427f2e5c279fc6db08530c8f91db3e6c7822ec6bb4f956940052d18\",\n    \"0xa38e191d66c625f975313c7007bbe7431b5a06ed2da1290a7d5d0f2ec73770d476efd07b8e632de64597d47df175cbb0\",\n    \"0x94ba76b667abf055621db4c4145d18743a368d951565632ed4e743dd50dd3333507c0c34f286a5c5fdbf38191a2255cd\",\n    \"0xa5ca38c60be5602f2bfa6e00c687ac96ac36d517145018ddbee6f12eb0faa63dd57909b9eeed26085fe5ac44e55d10ab\",\n    \"0xb00fea3b825e60c1ed1c5deb4b551aa65a340e5af36b17d5262c9cd2c508711e4dc50dc2521a2c16c7c901902266e64a\",\n    \"0x971b86fc4033485e235ccb0997a236206ba25c6859075edbcdf3c943116a5030b7f75ebca9753d863a522ba21a215a90\",\n    \"0xb3b31f52370de246ee215400975b674f6da39b2f32514fe6bd54e747752eedca22bb840493b44a67df42a3639c5f901f\",\n    \"0xaffbbfac9c1ba7cbfa1839d2ae271dd6149869b75790bf103230637da41857fc326ef3552ff31c15bda0694080198143\",\n    \"0xa95d42aa7ef1962520845aa3688f2752d291926f7b0d73ea2ee24f0612c03b43f2b0fe3c9a9a99620ffc8d487b981bc2\",\n    \"0x914a266065caf64985e8c5b1cb2e3f4e3fe94d7d085a1881b1fefa435afef4e1b39a98551d096a62e4f5cc1a7f0fdc2e\",\n    \"0x81a0b4a96e2b75bc1bf2dbd165d58d55cfd259000a35504d1ffb18bc346a3e6f07602c683723864ffb980f840836fd8d\",\n    \"0x91c1556631cddd4c00b65b67962b39e4a33429029d311c8acf73a18600e362304fb68bccb56fde40f49e95b7829e0b87\",\n    \"0x8befbacc19e57f7c885d1b7a6028359eb3d80792fe13b92a8400df21ce48deb0bb60f2ddb50e3d74f39f85d7eab23adc\",\n    \"0x92f9458d674df6e990789690ec9ca73dacb67fc9255b58c417c555a8cc1208ace56e8e538f86ba0f3615573a0fbac00d\",\n    \"0xb4b1b3062512d6ae7417850c08c13f707d5838e43d48eb98dd4621baf62eee9e82348f80fe9b888a12874bfa538771f8\",\n    \"0xa13c4a3ac642ede37d9c883f5319e748d2b938f708c9d779714108a449b343f7b71a6e3ef4080fee125b416762920273\",\n    \"0xaf44983d5fc8cceee0551ef934e6e653f2d3efa385e5c8a27a272463a6f333e290378cc307c2b664eb923c78994e706e\",\n    \"0xa389fd6c59fe2b4031cc244e22d3991e541bd203dd5b5e73a6159e72df1ab41d49994961500dcde7989e945213184778\",\n    \"0x8d2141e4a17836c548de9598d7b298b03f0e6c73b7364979a411c464e0628e21cff6ac3d6decdba5d1c4909eff479761\",\n    \"0x980b22ef53b7bdf188a3f14bc51b0dbfdf9c758826daa3cbc1e3986022406a8aa9a6a79e400567120b88c67faa35ce5f\",\n    \"0xa28882f0a055f96df3711de5d0aa69473e71245f4f3e9aa944e9d1fb166e02caa50832e46da6d3a03b4801735fd01b29\",\n    \"0x8db106a37d7b88f5d995c126abb563934dd8de516af48e85695d02b1aea07f79217e3cdd03c6f5ca57421830186c772b\",\n    \"0xb5a7e50da0559a675c472f7dfaee456caab6695ab7870541b2be8c2b118c63752427184aad81f0e1afc61aef1f28c46f\",\n    \"0x9962118780e20fe291d10b64f28d09442a8e1b5cffd0f3dd68d980d0614050a626c616b44e9807fbee7accecae00686a\",\n    \"0xb38ddf33745e8d2ad6a991aefaf656a33c5f8cbe5d5b6b6fd03bd962153d8fd0e01b5f8f96d80ae53ab28d593ab1d4e7\",\n    \"0x857dc12c0544ff2c0c703761d901aba636415dee45618aba2e3454ff9cbc634a85c8b05565e88520ff9be2d097c8b2b1\",\n    \"0xa80d465c3f8cc63af6d74a6a5086b626c1cb4a8c0fee425964c3bd203d9d7094e299f81ce96d58afc20c8c9a029d9dae\",\n    \"0x89e1c8fbde8563763be483123a3ed702efac189c6d8ab4d16c85e74bbaf856048cc42d5d6e138633a38572ba5ec3f594\",\n    \"0x893a594cf495535f6d216508f8d03c317dcf03446668cba688da90f52d0111ac83d76ad09bf5ea47056846585ee5c791\",\n    \"0xaadbd8be0ae452f7f9450c7d2957598a20cbf10139a4023a78b4438172d62b18b0de39754dd2f8862dbd50a3a0815e53\",\n    \"0xae7d39670ecca3eb6db2095da2517a581b0e8853bdfef619b1fad9aacd443e7e6a40f18209fadd44038a55085c5fe8b2\",\n    \"0x866ef241520eacb6331593cfcb206f7409d2f33d04542e6e52cba5447934e02d44c471f6c9a45963f9307e9809ab91d9\",\n    \"0xb1a09911ad3864678f7be79a9c3c3eb5c84a0a45f8dcb52c67148f43439aeaaa9fd3ed3471276b7e588b49d6ebe3033a\",\n    \"0xadd07b7f0dbb34049cd8feeb3c18da5944bf706871cfd9f14ff72f6c59ad217ebb1f0258b13b167851929387e4e34cfe\",\n    \"0xae048892d5c328eefbdd4fba67d95901e3c14d974bfc0a1fc68155ca9f0d59e61d7ba17c6c9948b120cf35fd26e6fee9\",\n    \"0x9185b4f3b7da0ddb4e0d0f09b8a9e0d6943a4611e43f13c3e2a767ed8592d31e0ba3ebe1914026a3627680274291f6e5\",\n    \"0xa9c022d4e37b0802284ce3b7ee9258628ab4044f0db4de53d1c3efba9de19d15d65cc5e608dbe149c21c2af47d0b07b5\",\n    \"0xb24dbd5852f8f24921a4e27013b6c3fa8885b973266cb839b9c388efad95821d5d746348179dcc07542bd0d0aefad1ce\",\n    \"0xb5fb4f279300876a539a27a441348764908bc0051ebd66dc51739807305e73db3d2f6f0f294ffb91b508ab150eaf8527\",\n    \"0xace50841e718265b290c3483ed4b0fdd1175338c5f1f7530ae9a0e75d5f80216f4de37536adcbc8d8c95982e88808cd0\",\n    \"0xb19cadcde0f63bd1a9c24bd9c2806f53c14c0b9735bf351601498408ba503ddbd2037c891041cbba47f58b8c483f3b21\",\n    \"0xb6061e63558d312eb891b97b39aa552fa218568d79ee26fe6dd5b864aea9e3216d8f2e2f3b093503be274766dac41426\",\n    \"0x89730fdb2876ab6f0fe780d695f6e12090259027e789b819956d786e977518057e5d1d7f5ab24a3ae3d5d4c97773bd2b\",\n    \"0xb6fa841e81f9f2cad0163a02a63ae96dc341f7ae803b616efc6e1da2fbea551c1b96b11ad02c4afbdf6d0cc9f23da172\",\n    \"0x8fb66187182629c861ddb6896d7ed3caf2ad050c3dba8ab8eb0d7a2c924c3d44c48d1a148f9e33fb1f061b86972f8d21\",\n    \"0x86022ac339c1f84a7fa9e05358c1a5b316b4fc0b83dbe9c8c7225dc514f709d66490b539359b084ce776e301024345fa\",\n    \"0xb50b9c321468da950f01480bb62b6edafd42f83c0001d6e97f2bd523a1c49a0e8574fb66380ea28d23a7c4d54784f9f0\",\n    \"0xa31c05f7032f30d1dac06678be64d0250a071fd655e557400e4a7f4c152be4d5c7aa32529baf3e5be7c4bd49820054f6\",\n    \"0xb95ac0848cd322684772119f5b682d90a66bbf9dac411d9d86d2c34844bbd944dbaf8e47aa41380455abd51687931a78\",\n    \"0xae4a6a5ce9553b65a05f7935e61e496a4a0f6fd8203367a2c627394c9ce1e280750297b74cdc48fd1d9a31e93f97bef4\",\n    \"0xa22daf35f6e9b05e52e0b07f7bd1dbbebd2c263033fb0e1b2c804e2d964e2f11bc0ece6aca6af079dd3a9939c9c80674\",\n    \"0x902150e0cb1f16b9b59690db35281e28998ce275acb313900da8b2d8dfd29fa1795f8ca3ff820c31d0697de29df347c1\",\n    \"0xb17b5104a5dc665cdd7d47e476153d715eb78c6e5199303e4b5445c21a7fa7cf85fe7cfd08d7570f4e84e579b005428c\",\n    \"0xa03f49b81c15433f121680aa02d734bb9e363af2156654a62bcb5b2ba2218398ccb0ff61104ea5d7df5b16ea18623b1e\",\n    \"0x802101abd5d3c88876e75a27ffc2f9ddcce75e6b24f23dba03e5201281a7bd5cc7530b6a003be92d225093ca17d3c3bb\",\n    \"0xa4d183f63c1b4521a6b52226fc19106158fc8ea402461a5cccdaa35fee93669df6a8661f45c1750cd01308149b7bf08e\",\n    \"0x8d17c22e0c8403b69736364d460b3014775c591032604413d20a5096a94d4030d7c50b9fe3240e31d0311efcf9816a47\",\n    \"0x947225acfcce5992eab96276f668c3cbe5f298b90a59f2bb213be9997d8850919e8f496f182689b5cbd54084a7332482\",\n    \"0x8df6f4ed216fc8d1905e06163ba1c90d336ab991a18564b0169623eb39b84e627fa267397da15d3ed754d1f3423bff07\",\n    \"0x83480007a88f1a36dea464c32b849a3a999316044f12281e2e1c25f07d495f9b1710b4ba0d88e9560e72433addd50bc2\",\n    \"0xb3019d6e591cf5b33eb972e49e06c6d0a82a73a75d78d383dd6f6a4269838289e6e07c245f54fed67f5c9bb0fd5e1c5f\",\n    \"0x92e8ce05e94927a9fb02debadb99cf30a26172b2705003a2c0c47b3d8002bf1060edb0f6a5750aad827c98a656b19199\",\n    \"0xac2aff801448dbbfc13cca7d603fd9c69e82100d997faf11f465323b97255504f10c0c77401e4d1890339d8b224f5803\",\n    \"0xb0453d9903d08f508ee27e577445dc098baed6cde0ac984b42e0f0efed62760bd58d5816cf1e109d204607b7b175e30c\",\n    \"0xae68dc4ba5067e825d46d2c7c67f1009ceb49d68e8d3e4c57f4bcd299eb2de3575d42ea45e8722f8f28497a6e14a1cfe\",\n    \"0xb22486c2f5b51d72335ce819bbafb7fa25eb1c28a378a658f13f9fc79cd20083a7e573248d911231b45a5cf23b561ca7\",\n    \"0x89d1201d1dbd6921867341471488b4d2fd0fc773ae1d4d074c78ae2eb779a59b64c00452c2a0255826fca6b3d03be2b1\",\n    \"0xa2998977c91c7a53dc6104f5bc0a5b675e5350f835e2f0af69825db8af4aeb68435bdbcc795f3dd1f55e1dd50bc0507f\",\n    \"0xb0be4937a925b3c05056ed621910d535ccabf5ab99fd3b9335080b0e51d9607d0fd36cb5781ff340018f6acfca4a9736\",\n    \"0xaea145a0f6e0ba9df8e52e84bb9c9de2c2dc822f70d2724029b153eb68ee9c17de7d35063dcd6a39c37c59fdd12138f7\",\n    \"0x91cb4545d7165ee8ffbc74c874baceca11fdebbc7387908d1a25877ca3c57f2c5def424dab24148826832f1e880bede0\",\n    \"0xb3b579cb77573f19c571ad5eeeb21f65548d7dff9d298b8d7418c11f3e8cd3727c5b467f013cb87d6861cfaceee0d2e3\",\n    \"0xb98a1eeec2b19fecc8378c876d73645aa52fb99e4819903735b2c7a885b242787a30d1269a04bfb8573d72d9bbc5f0f0\",\n    \"0x940c1f01ed362bd588b950c27f8cc1d52276c71bb153d47f07ec85b038c11d9a8424b7904f424423e714454d5e80d1cd\",\n    \"0xaa343a8ecf09ce11599b8cf22f7279cf80f06dbf9f6d62cb05308dbbb39c46fd0a4a1240b032665fbb488a767379b91b\",\n    \"0x87c3ac72084aca5974599d3232e11d416348719e08443acaba2b328923af945031f86432e170dcdd103774ec92e988c9\",\n    \"0x91d6486eb5e61d2b9a9e742c20ec974a47627c6096b3da56209c2b4e4757f007e793ebb63b2b246857c9839b64dc0233\",\n    \"0xaebcd3257d295747dd6fc4ff910d839dd80c51c173ae59b8b2ec937747c2072fa85e3017f9060aa509af88dfc7529481\",\n    \"0xb3075ba6668ca04eff19efbfa3356b92f0ab12632dcda99cf8c655f35b7928c304218e0f9799d68ef9f809a1492ff7db\",\n    \"0x93ba7468bb325639ec2abd4d55179c69fd04eaaf39fc5340709227bbaa4ad0a54ea8b480a1a3c8d44684e3be0f8d1980\",\n    \"0xa6aef86c8c0d92839f38544d91b767c582568b391071228ff5a5a6b859c87bf4f81a7d926094a4ada1993ddbd677a920\",\n    \"0x91dcd6d14207aa569194aa224d1e5037b999b69ade52843315ca61ba26abe9a76412c9e88259bc5cf5d7b95b97d9c3bc\",\n    \"0xb3b483d31c88f78d49bd065893bc1e3d2aa637e27dedb46d9a7d60be7660ce7a10aaaa7deead362284a52e6d14021178\",\n    \"0x8e5730070acf8371461ef301cc4523e8e672aa0e3d945d438a0e0aa6bdf8cb9c685dcf38df429037b0c8aff3955c6f5b\",\n    \"0xb8c6d769890a8ee18dc4f9e917993315877c97549549b34785a92543cbeec96a08ae3a28d6e809c4aacd69de356c0012\",\n    \"0x95ca86cd384eaceaa7c077c5615736ca31f36824bd6451a16142a1edc129fa42b50724aeed7c738f08d7b157f78b569e\",\n    \"0x94df609c6d71e8eee7ab74226e371ccc77e01738fe0ef1a6424435b4570fe1e5d15797b66ed0f64eb88d4a3a37631f0e\",\n    \"0x89057b9783212add6a0690d6bb99097b182738deff2bd9e147d7fd7d6c8eacb4c219923633e6309ad993c24572289901\",\n    \"0x83a0f9f5f265c5a0e54defa87128240235e24498f20965009fef664f505a360b6fb4020f2742565dfc7746eb185bcec0\",\n    \"0x91170da5306128931349bc3ed50d7df0e48a68b8cc8420975170723ac79d8773e4fa13c5f14dc6e3fafcad78379050b1\",\n    \"0xb7178484d1b55f7e56a4cc250b6b2ec6040437d96bdfddfa7b35ed27435860f3855c2eb86c636f2911b012eb83b00db8\",\n    \"0xac0b00c4322d1e4208e09cd977b4e54d221133ff09551f75b32b0b55d0e2be80941dda26257b0e288c162e63c7e9cf68\",\n    \"0x9690ed9e7e53ed37ff362930e4096b878b12234c332fd19d5d064824084245952eda9f979e0098110d6963e468cf513e\",\n    \"0xb6fa547bb0bb83e5c5be0ed462a8783fba119041c136a250045c09d0d2af330c604331e7de960df976ff76d67f8000cd\",\n    \"0x814603907c21463bcf4e59cfb43066dfe1a50344ae04ef03c87c0f61b30836c3f4dea0851d6fa358c620045b7f9214c8\",\n    \"0x9495639e3939fad2a3df00a88603a5a180f3c3a0fe4d424c35060e2043e0921788003689887b1ed5be424d9a89bb18bb\",\n    \"0xaba4c02d8d57f2c92d5bc765885849e9ff8393d6554f5e5f3e907e5bfac041193a0d8716d7861104a4295d5a03c36b03\",\n    \"0x8ead0b56c1ca49723f94a998ba113b9058059321da72d9e395a667e6a63d5a9dac0f5717cec343f021695e8ced1f72af\",\n    \"0xb43037f7e3852c34ed918c5854cd74e9d5799eeddfe457d4f93bb494801a064735e326a76e1f5e50a339844a2f4a8ec9\",\n    \"0x99db8422bb7302199eb0ff3c3d08821f8c32f53a600c5b6fb43e41205d96adae72be5b460773d1280ad1acb806af9be8\",\n    \"0x8a9be08eae0086c0f020838925984df345c5512ff32e37120b644512b1d9d4fecf0fd30639ca90fc6cf334a86770d536\",\n    \"0x81b43614f1c28aa3713a309a88a782fb2bdfc4261dd52ddc204687791a40cf5fd6a263a8179388596582cccf0162efc2\",\n    \"0xa9f3a8b76912deb61d966c75daf5ddb868702ebec91bd4033471c8e533183df548742a81a2671de5be63a502d827437d\",\n    \"0x902e2415077f063e638207dc7e14109652e42ab47caccd6204e2870115791c9defac5425fd360b37ac0f7bd8fe7011f8\",\n    \"0xaa18e4fdc1381b59c18503ae6f6f2d6943445bd00dd7d4a2ad7e5adad7027f2263832690be30d456e6d772ad76f22350\",\n    \"0xa348b40ba3ba7d81c5d4631f038186ebd5e5f314f1ea737259151b07c3cc8cf0c6ed4201e71bcc1c22fefda81a20cde6\",\n    \"0xaa1306f7ac1acbfc47dc6f7a0cb6d03786cec8c8dc8060388ccda777bca24bdc634d03e53512c23dba79709ff64f8620\",\n    \"0x818ccfe46e700567b7f3eb400e5a35f6a5e39b3db3aa8bc07f58ace35d9ae5a242faf8dbccd08d9a9175bbce15612155\",\n    \"0xb7e3da2282b65dc8333592bb345a473f03bd6df69170055fec60222de9897184536bf22b9388b08160321144d0940279\",\n    \"0xa4d976be0f0568f4e57de1460a1729129252b44c552a69fceec44e5b97c96c711763360d11f9e5bf6d86b4976bf40d69\",\n    \"0x85d185f0397c24c2b875b09b6328a23b87982b84ee880f2677a22ff4c9a1ba9f0fea000bb3f7f66375a00d98ebafce17\",\n    \"0xb4ccbb8c3a2606bd9b87ce022704663af71d418351575f3b350d294f4efc68c26f9a2ce49ff81e6ff29c3b63d746294e\",\n    \"0x93ffd3265fddb63724dfde261d1f9e22f15ecf39df28e4d89e9fea03221e8e88b5dd9b77628bacaa783c6f91802d47cc\",\n    \"0xb1fd0f8d7a01378e693da98d03a2d2fda6b099d03454b6f2b1fa6472ff6bb092751ce6290059826b74ac0361eab00e1e\",\n    \"0xa89f440c71c561641589796994dd2769616b9088766e983c873fae0716b95c386c8483ab8a4f367b6a68b72b7456dd32\",\n    \"0xaf4fe92b01d42d03dd5d1e7fa55e96d4bbcb7bf7d4c8c197acd16b3e0f3455807199f683dcd263d74547ef9c244b35cc\",\n    \"0xa8227f6e0a344dfe76bfbe7a1861be32c4f4bed587ccce09f9ce2cf481b2dda8ae4f566154bc663d15f962f2d41761bd\",\n    \"0xa7b361663f7495939ed7f518ba45ea9ff576c4e628995b7aea026480c17a71d63fc2c922319f0502eb7ef8f14a406882\",\n    \"0x8ddcf382a9f39f75777160967c07012cfa89e67b19714a7191f0c68eaf263935e5504e1104aaabd0899348c972a8d3c6\",\n    \"0x98c95b9f6f5c91f805fb185eedd06c6fc4457d37dd248d0be45a6a168a70031715165ea20606245cbdf8815dc0ac697f\",\n    \"0x805b44f96e001e5909834f70c09be3efcd3b43632bcac5b6b66b6d227a03a758e4b1768ce2a723045681a1d34562aaeb\",\n    \"0xb0e81b07cdc45b3dca60882676d9badb99f25c461b7efe56e3043b80100bb62d29e1873ae25eb83087273160ece72a55\",\n    \"0xb0c53f0abe78ee86c7b78c82ae1f7c070bb0b9c45c563a8b3baa2c515d482d7507bb80771e60b38ac13f78b8af92b4a9\",\n    \"0xa7838ef6696a9e4d2e5dfd581f6c8d6a700467e8fd4e85adabb5f7a56f514785dd4ab64f6f1b48366f7d94728359441b\",\n    \"0x88c76f7700a1d23c30366a1d8612a796da57b2500f97f88fdf2d76b045a9d24e7426a8ffa2f4e86d3046937a841dad58\",\n    \"0xad8964baf98c1f02e088d1d9fcb3af6b1dfa44cdfe0ed2eae684e7187c33d3a3c28c38e8f4e015f9c04d451ed6f85ff6\",\n    \"0x90e9d00a098317ececaa9574da91fc149eda5b772dedb3e5a39636da6603aa007804fa86358550cfeff9be5a2cb7845e\",\n    \"0xa56ff4ddd73d9a6f5ab23bb77efa25977917df63571b269f6a999e1ad6681a88387fcc4ca3b26d57badf91b236503a29\",\n    \"0x97ad839a6302c410a47e245df84c01fb9c4dfef86751af3f9340e86ff8fc3cd52fa5ff0b9a0bd1d9f453e02ca80658a6\",\n    \"0xa4c8c44cbffa804129e123474854645107d1f0f463c45c30fd168848ebea94880f7c0c5a45183e9eb837f346270bdb35\",\n    \"0xa72e53d0a1586d736e86427a93569f52edd2f42b01e78aee7e1961c2b63522423877ae3ac1227a2cf1e69f8e1ff15bc3\",\n    \"0x8559f88a7ef13b4f09ac82ae458bbae6ab25671cfbf52dae7eac7280d6565dd3f0c3286aec1a56a8a16dc3b61d78ce47\",\n    \"0x8221503f4cdbed550876c5dc118a3f2f17800c04e8be000266633c83777b039a432d576f3a36c8a01e8fd18289ebc10b\",\n    \"0x99bfbe5f3e46d4d898a578ba86ed26de7ed23914bd3bcdf3c791c0bcd49398a52419077354a5ab75cea63b6c871c6e96\",\n    \"0xaa134416d8ff46f2acd866c1074af67566cfcf4e8be8d97329dfa0f603e1ff208488831ce5948ac8d75bfcba058ddcaa\",\n    \"0xb02609d65ebfe1fe8e52f21224a022ea4b5ea8c1bd6e7b9792eed8975fc387cdf9e3b419b8dd5bcce80703ab3a12a45f\",\n    \"0xa4f14798508698fa3852e5cac42a9db9797ecee7672a54988aa74037d334819aa7b2ac7b14efea6b81c509134a6b7ad2\",\n    \"0x884f01afecbcb987cb3e7c489c43155c416ed41340f61ecb651d8cba884fb9274f6d9e7e4a46dd220253ae561614e44c\",\n    \"0xa05523c9e71dce1fe5307cc71bd721feb3e1a0f57a7d17c7d1c9fb080d44527b7dbaa1f817b1af1c0b4322e37bc4bb1e\",\n    \"0x8560aec176a4242b39f39433dd5a02d554248c9e49d3179530815f5031fee78ba9c71a35ceeb2b9d1f04c3617c13d8f0\",\n    \"0x996aefd402748d8472477cae76d5a2b92e3f092fc834d5222ae50194dd884c9fb8b6ed8e5ccf8f6ed483ddbb4e80c747\",\n    \"0x8fd09900320000cbabc40e16893e2fcf08815d288ec19345ad7b6bb22f7d78a52b6575a3ca1ca2f8bc252d2eafc928ec\",\n    \"0x939e51f73022bc5dc6862a0adf8fb8a3246b7bfb9943cbb4b27c73743926cc20f615a036c7e5b90c80840e7f1bfee0e7\",\n    \"0xa0a6258700cadbb9e241f50766573bf9bdb7ad380b1079dc3afb4054363d838e177b869cad000314186936e40359b1f2\",\n    \"0x972699a4131c8ed27a2d0e2104d54a65a7ff1c450ad9da3a325c662ab26869c21b0a84d0700b98c8b5f6ce3b746873d7\",\n    \"0xa454c7fe870cb8aa6491eafbfb5f7872d6e696033f92e4991d057b59d70671f2acdabef533e229878b60c7fff8f748b1\",\n    \"0xa167969477214201f09c79027b10221e4707662e0c0fde81a0f628249f2f8a859ce3d30a7dcc03b8ecca8f7828ad85c7\",\n    \"0x8ff6b7265175beb8a63e1dbf18c9153fb2578c207c781282374f51b40d57a84fd2ef2ea2b9c6df4a54646788a62fd17f\",\n    \"0xa3d7ebeccde69d73d8b3e76af0da1a30884bb59729503ff0fb0c3bccf9221651b974a6e72ea33b7956fc3ae758226495\",\n    \"0xb71ef144c9a98ce5935620cb86c1590bd4f48e5a2815d25c0cdb008fde628cf628c31450d3d4f67abbfeb16178a74cfd\",\n    \"0xb5e0a16d115134f4e2503990e3f2035ed66b9ccf767063fe6747870d97d73b10bc76ed668550cb82eedc9a2ca6f75524\",\n    \"0xb30ffaaf94ee8cbc42aa2c413175b68afdb207dbf351fb20be3852cb7961b635c22838da97eaf43b103aff37e9e725cc\",\n    \"0x98aa7d52284f6c1f22e272fbddd8c8698cf8f5fbb702d5de96452141fafb559622815981e50b87a72c2b1190f59a7deb\",\n    \"0x81fbacda3905cfaf7780bb4850730c44166ed26a7c8d07197a5d4dcd969c09e94a0461638431476c16397dd7bdc449f9\",\n    \"0x95e47021c1726eac2e5853f570d6225332c6e48e04c9738690d53e07c6b979283ebae31e2af1fc9c9b3e59f87e5195b1\",\n    \"0xac024a661ba568426bb8fce21780406537f518075c066276197300841e811860696f7588188bc01d90bace7bc73d56e3\",\n    \"0xa4ebcaf668a888dd404988ab978594dee193dad2d0aec5cdc0ccaf4ec9a7a8228aa663db1da8ddc52ec8472178e40c32\",\n    \"0xa20421b8eaf2199d93b083f2aff37fb662670bd18689d046ae976d1db1fedd2c2ff897985ecc6277b396db7da68bcb27\",\n    \"0x8bc33d4b40197fd4d49d1de47489d10b90d9b346828f53a82256f3e9212b0cbc6930b895e879da9cec9fedf026aadb3e\",\n    \"0xaaafdd1bec8b757f55a0433eddc0a39f818591954fd4e982003437fcceb317423ad7ee74dbf17a2960380e7067a6b4e2\",\n    \"0xaad34277ebaed81a6ec154d16736866f95832803af28aa5625bf0461a71d02b1faba02d9d9e002be51c8356425a56867\",\n    \"0x976e9c8b150d08706079945bd0e84ab09a648ecc6f64ded9eb5329e57213149ae409ae93e8fbd8eda5b5c69f5212b883\",\n    \"0x8097fae1653247d2aed4111533bc378171d6b2c6d09cbc7baa9b52f188d150d645941f46d19f7f5e27b7f073c1ebd079\",\n    \"0x83905f93b250d3184eaba8ea7d727c4464b6bdb027e5cbe4f597d8b9dc741dcbea709630bd4fd59ce24023bec32fc0f3\",\n    \"0x8095030b7045cff28f34271386e4752f9a9a0312f8df75de4f424366d78534be2b8e1720a19cb1f9a2d21105d790a225\",\n    \"0xa7b7b73a6ae2ed1009c49960374b0790f93c74ee03b917642f33420498c188a169724945a975e5adec0a1e83e07fb1b2\",\n    \"0x856a41c54df393b6660b7f6354572a4e71c8bfca9cabaffb3d4ef2632c015e7ee2bc10056f3eccb3dbed1ad17d939178\",\n    \"0xa8f7a55cf04b38cd4e330394ee6589da3a07dc9673f74804fdf67b364e0b233f14aec42e783200a2e4666f7c5ff62490\",\n    \"0x82c529f4e543c6bca60016dc93232c115b359eaee2798a9cf669a654b800aafe6ab4ba58ea8b9cdda2b371c8d62fa845\",\n    \"0x8caab020c1baddce77a6794113ef1dfeafc5f5000f48e97f4351b588bf02f1f208101745463c480d37f588d5887e6d8c\",\n    \"0x8fa91b3cc400f48b77b6fd77f3b3fbfb3f10cdff408e1fd22d38f77e087b7683adad258804409ba099f1235b4b4d6fea\",\n    \"0x8aa02787663d6be9a35677d9d8188b725d5fcd770e61b11b64e3def8808ea5c71c0a9afd7f6630c48634546088fcd8e2\",\n    \"0xb5635b7b972e195cab878b97dea62237c7f77eb57298538582a330b1082f6207a359f2923864630136d8b1f27c41b9aa\",\n    \"0x8257bb14583551a65975946980c714ecd6e5b629672bb950b9caacd886fbd22704bc9e3ba7d30778adab65dc74f0203a\",\n    \"0xab5fe1cd12634bfa4e5c60d946e2005cbd38f1063ec9a5668994a2463c02449a0a185ef331bd86b68b6e23a8780cb3ba\",\n    \"0xa7d3487da56cda93570cc70215d438204f6a2709bfb5fda6c5df1e77e2efc80f4235c787e57fbf2c74aaff8cbb510a14\",\n    \"0xb61cff7b4c49d010e133319fb828eb900f8a7e55114fc86b39c261a339c74f630e1a7d7e1350244ada566a0ff3d46c4b\",\n    \"0x8d4d1d55d321d278db7a85522ccceca09510374ca81d4d73e3bb5249ace7674b73900c35a531ec4fa6448fabf7ad00dc\",\n    \"0x966492248aee24f0f56c8cfca3c8ec6ba3b19abb69ae642041d4c3be8523d22c65c4dafcab4c58989ccc4e0bd2f77919\",\n    \"0xb20c320a90cb220b86e1af651cdc1e21315cd215da69f6787e28157172f93fc8285dcd59b039c626ed8ca4633cba1a47\",\n    \"0xaae9e6b22f018ceb5c0950210bb8182cb8cb61014b7e14581a09d36ebd1bbfebdb2b82afb7fdb0cf75e58a293d9c456d\",\n    \"0x875547fb67951ad37b02466b79f0c9b985ccbc500cfb431b17823457dc79fb9597ec42cd9f198e15523fcd88652e63a4\",\n    \"0x92afce49773cb2e20fb21e4f86f18e0959ebb9c33361547ddb30454ee8e36b1e234019cbdca0e964cb292f7f77df6b90\",\n    \"0x8af85343dfe1821464c76ba11c216cbef697b5afc69c4d821342e55afdac047081ec2e3f7b09fc14b518d9a23b78c003\",\n    \"0xb7de4a1648fd63f3a918096ea669502af5357438e69dac77cb8102b6e6c15c76e033cfaa80dafc806e535ede5c1a20aa\",\n    \"0xac80e9b545e8bd762951d96c9ce87f629d01ffcde07efc2ef7879ca011f1d0d8a745abf26c9d452541008871304fac00\",\n    \"0xa4cf0f7ed724e481368016c38ea5816698a5f68eb21af4d3c422d2ba55f96a33e427c2aa40de1b56a7cfac7f7cf43ab0\",\n    \"0x899b0a678bb2db2cae1b44e75a661284844ebcdd87abf308fedeb2e4dbe5c5920c07db4db7284a7af806a2382e8b111a\",\n    \"0xaf0588a2a4afce2b1b13c1230816f59e8264177e774e4a341b289a101dcf6af813638fed14fb4d09cb45f35d5d032609\",\n    \"0xa4b8df79e2be76e9f5fc5845f06fe745a724cf37c82fcdb72719b77bdebea3c0e763f37909373e3a94480cc5e875cba0\",\n    \"0x83e42c46d88930c8f386b19fd999288f142d325e2ebc86a74907d6d77112cb0d449bc511c95422cc810574031a8cbba9\",\n    \"0xb5e39534070de1e5f6e27efbdd3dc917d966c2a9b8cf2d893f964256e95e954330f2442027dc148c776d63a95bcde955\",\n    \"0x958607569dc28c075e658cd4ae3927055c6bc456eef6212a6fea8205e48ed8777a8064f584cda38fe5639c371e2e7fba\",\n    \"0x812adf409fa63575113662966f5078a903212ffb65c9b0bbe62da0f13a133443a7062cb8fd70f5e5dd5559a32c26d2c8\",\n    \"0xa679f673e5ce6a3cce7fa31f22ee3785e96bcb55e5a776e2dd3467bef7440e3555d1a9b87cb215e86ee9ed13a090344b\",\n    \"0xafedbb34508b159eb25eb2248d7fe328f86ef8c7d84c62d5b5607d74aae27cc2cc45ee148eb22153b09898a835c58df4\",\n    \"0xb75505d4f6b67d31e665cfaf5e4acdb5838ae069166b7fbcd48937c0608a59e40a25302fcc1873d2e81c1782808c70f0\",\n    \"0xb62515d539ec21a155d94fc00ea3c6b7e5f6636937bce18ed5b618c12257fb82571886287fd5d1da495296c663ebc512\",\n    \"0xab8e1a9446bbdd588d1690243b1549d230e6149c28f59662b66a8391a138d37ab594df38e7720fae53217e5c3573b5be\",\n    \"0xb31e8abf4212e03c3287bb2c0a153065a7290a16764a0bac8f112a72e632185a654bb4e88fdd6053e6c7515d9719fadb\",\n    \"0xb55165477fe15b6abd2d0f4fddaa9c411710dcc4dd712daba3d30e303c9a3ee5415c256f9dc917ecf18c725b4dbab059\",\n    \"0xa0939d4f57cacaae549b78e87cc234de4ff6a35dc0d9cd5d7410abc30ebcd34c135e008651c756e5a9d2ca79c40ef42b\",\n    \"0x8cf10e50769f3443340844aad4d56ec790850fed5a41fcbd739abac4c3015f0a085a038fbe7fae9f5ad899cce5069f6b\",\n    \"0x924055e804d82a99ea4bb160041ea4dc14b568abf379010bc1922fde5d664718c31d103b8b807e3a1ae809390e708c73\",\n    \"0x8ec0f9d26f71b0f2e60a179e4fd1778452e2ffb129d50815e5d7c7cb9415fa69ae5890578086e8ef6bfde35ad2a74661\",\n    \"0x98c7f12b15ec4426b59f737f73bf5faea4572340f4550b7590dfb7f7ffedb2372e3e555977c63946d579544c53210ad0\",\n    \"0x8a935f7a955c78f69d66f18eee0092e5e833fa621781c9581058e219af4d7ceee48b84e472e159dda6199715fb2f9acf\",\n    \"0xb78d4219f95a2dbfaa7d0c8a610c57c358754f4f43c2af312ab0fe8f10a5f0177e475332fb8fd23604e474fc2abeb051\",\n    \"0x8d086a14803392b7318c28f1039a17e3cfdcece8abcaca3657ec3d0ac330842098a85c0212f889fabb296dfb133ce9aa\",\n    \"0xa53249f417aac82f2c2a50c244ce21d3e08a5e5a8bd33bec2a5ab0d6cd17793e34a17edfa3690899244ce201e2fb9986\",\n    \"0x8619b0264f9182867a1425be514dc4f1ababc1093138a728a28bd7e4ecc99b9faaff68c23792264bc6e4dce5f52a5c52\",\n    \"0x8c171edbbbde551ec19e31b2091eb6956107dd9b1f853e1df23bff3c10a3469ac77a58335eee2b79112502e8e163f3de\",\n    \"0xa9d19ec40f0ca07c238e9337c6d6a319190bdba2db76fb63902f3fb459aeeb50a1ac30db5b25ee1b4201f3ca7164a7f4\",\n    \"0xb9c6ec14b1581a03520b8d2c1fbbc31fb8ceaef2c0f1a0d0080b6b96e18442f1734bea7ef7b635d787c691de4765d469\",\n    \"0x8cb437beb4cfa013096f40ccc169a713dc17afee6daa229a398e45fd5c0645a9ad2795c3f0cd439531a7151945d7064d\",\n    \"0xa6e8740cc509126e146775157c2eb278003e5bb6c48465c160ed27888ca803fa12eee1f6a8dd7f444f571664ed87fdc1\",\n    \"0xb75c1fecc85b2732e96b3f23aefb491dbd0206a21d682aee0225838dc057d7ed3b576176353e8e90ae55663f79e986e4\",\n    \"0xad8d249b0aea9597b08358bce6c77c1fd552ef3fbc197d6a1cfe44e5e6f89b628b12a6fb04d5dcfcbacc51f46e4ae7bb\",\n    \"0xb998b2269932cbd58d04b8e898d373ac4bb1a62e8567484f4f83e224061bc0f212459f1daae95abdbc63816ae6486a55\",\n    \"0x827988ef6c1101cddc96b98f4a30365ff08eea2471dd949d2c0a9b35c3bbfa8c07054ad1f4c88c8fbf829b20bb5a9a4f\",\n    \"0x8692e638dd60babf7d9f2f2d2ce58e0ac689e1326d88311416357298c6a2bffbfebf55d5253563e7b3fbbf5072264146\",\n    \"0xa685d75b91aea04dbc14ab3c1b1588e6de96dae414c8e37b8388766029631b28dd860688079b12d09cd27f2c5af11adf\",\n    \"0xb57eced93eec3371c56679c259b34ac0992286be4f4ff9489d81cf9712403509932e47404ddd86f89d7c1c3b6391b28c\",\n    \"0xa1c8b4e42ebcbd8927669a97f1b72e236fb19249325659e72be7ddaaa1d9e81ca2abb643295d41a8c04a2c01f9c0efd7\",\n    \"0x877c33de20d4ed31674a671ba3e8f01a316581e32503136a70c9c15bf0b7cb7b1cba6cd4eb641fad165fb3c3c6c235fd\",\n    \"0xa2a469d84ec478da40838f775d11ad38f6596eb41caa139cc190d6a10b5108c09febae34ffdafac92271d2e73c143693\",\n    \"0x972f817caedb254055d52e963ed28c206848b6c4cfdb69dbc961c891f8458eaf582a6d4403ce1177d87bc2ea410ef60a\",\n    \"0xaccbd739e138007422f28536381decc54bb6bd71d93edf3890e54f9ef339f83d2821697d1a4ac1f5a98175f9a9ecb9b5\",\n    \"0x8940f8772e05389f823b62b3adc3ed541f91647f0318d7a0d3f293aeeb421013de0d0a3664ea53dd24e5fbe02d7efef6\",\n    \"0x8ecce20f3ef6212edef07ec4d6183fda8e0e8cad2c6ccd0b325e75c425ee1faba00b5c26b4d95204238931598d78f49d\",\n    \"0x97cc72c36335bd008afbed34a3b0c7225933faba87f7916d0a6d2161e6f82e0cdcda7959573a366f638ca75d30e9dab1\",\n    \"0x9105f5de8699b5bdb6bd3bb6cc1992d1eac23929c29837985f83b22efdda92af64d9c574aa9640475087201bbbe5fd73\",\n    \"0x8ffb33c4f6d05c413b9647eb6933526a350ed2e4278ca2ecc06b0e8026d8dbe829c476a40e45a6df63a633090a3f82ef\",\n    \"0x8bfc6421fdc9c2d2aaa68d2a69b1a2728c25b84944cc3e6a57ff0c94bfd210d1cbf4ff3f06702d2a8257024d8be7de63\",\n    \"0xa80e1dc1dddfb41a70220939b96dc6935e00b32fb8be5dff4eed1f1c650002ff95e4af481c43292e3827363b7ec4768a\",\n    \"0x96f714ebd54617198bd636ba7f7a7f8995a61db20962f2165078d9ed8ee764d5946ef3cbdc7ebf8435bb8d5dd4c1deac\",\n    \"0x8cdb0890e33144d66391d2ae73f5c71f5a861f72bc93bff6cc399fc25dd1f9e17d8772592b44593429718784802ac377\",\n    \"0x8ccf9a7f80800ee770b92add734ed45a73ecc31e2af0e04364eefc6056a8223834c7c0dc9dfc52495bdec6e74ce69994\",\n    \"0xaa0875f423bd68b5f10ba978ddb79d3b96ec093bfbac9ff366323193e339ed7c4578760fb60f60e93598bdf1e5cc4995\",\n    \"0xa9214f523957b59c7a4cb61a40251ad72aba0b57573163b0dc0f33e41d2df483fb9a1b85a5e7c080e9376c866790f8cb\",\n    \"0xb6224b605028c6673a536cc8ff9aeb94e7a22e686fda82cf16068d326469172f511219b68b2b3affb7933af0c1f80d07\",\n    \"0xb6d58968d8a017c6a34e24c2c09852f736515a2c50f37232ac6b43a38f8faa7572cc31dade543b594b61b5761c4781d0\",\n    \"0x8a97cefe5120020c38deeb861d394404e6c993c6cbd5989b6c9ebffe24f46ad11b4ba6348e2991cbf3949c28cfc3c99d\",\n    \"0x95bf046f8c3a9c0ce2634be4de3713024daec3fc4083e808903b25ce3ac971145af90686b451efcc72f6b22df0216667\",\n    \"0xa6a4e2f71b8fa28801f553231eff2794c0f10d12e7e414276995e21195abc9c2983a8997e41af41e78d19ff6fbb2680b\",\n    \"0x8e5e62a7ca9c2f58ebaab63db2ff1fb1ff0877ae94b7f5e2897f273f684ae639dff44cc65718f78a9c894787602ab26a\",\n    \"0x8542784383eec4f565fcb8b9fc2ad8d7a644267d8d7612a0f476fc8df3aff458897a38003d506d24142ad18f93554f2b\",\n    \"0xb7db68ba4616ea072b37925ec4fb39096358c2832cc6d35169e032326b2d6614479f765ae98913c267105b84afcb9bf2\",\n    \"0x8b31dbb9457d23d416c47542c786e07a489af35c4a87dadb8ee91bea5ac4a5315e65625d78dad2cf8f9561af31b45390\",\n    \"0xa8545a1d91ac17257732033d89e6b7111db8242e9c6ebb0213a88906d5ef407a2c6fdb444e29504b06368b6efb4f4839\",\n    \"0xb1bd85d29ebb28ccfb05779aad8674906b267c2bf8cdb1f9a0591dd621b53a4ee9f2942687ee3476740c0b4a7621a3ae\",\n    \"0xa2b54534e152e46c50d91fff03ae9cd019ff7cd9f4168b2fe7ac08ef8c3bbc134cadd3f9d6bd33d20ae476c2a8596c8a\",\n    \"0xb19b571ff4ae3e9f5d95acda133c455e72c9ea9973cae360732859836c0341c4c29ab039224dc5bc3deb824e031675d8\",\n    \"0x940b5f80478648bac025a30f3efeb47023ce20ee98be833948a248bca6979f206bb28fc0f17b90acf3bb4abd3d14d731\",\n    \"0x8f106b40588586ac11629b96d57808ad2808915d89539409c97414aded90b4ff23286a692608230a52bff696055ba5d6\",\n    \"0xae6bda03aa10da3d2abbc66d764ca6c8d0993e7304a1bdd413eb9622f3ca1913baa6da1e9f4f9e6cf847f14f44d6924d\",\n    \"0xa18e7796054a340ef826c4d6b5a117b80927afaf2ebd547794c400204ae2caf277692e2eabb55bc2f620763c9e9da66d\",\n    \"0x8d2d25180dc2c65a4844d3e66819ccfcf48858f0cc89e1c77553b463ec0f7feb9a4002ce26bc618d1142549b9850f232\",\n    \"0x863f413a394de42cc8166c1c75d513b91d545fff1de6b359037a742c70b008d34bf8e587afa2d62c844d0c6f0ea753e7\",\n    \"0x83cd0cf62d63475e7fcad18a2e74108499cdbf28af2113cfe005e3b5887794422da450b1944d0a986eb7e1f4c3b18f25\",\n    \"0xb4f8b350a6d88fea5ab2e44715a292efb12eb52df738c9b2393da3f1ddee68d0a75b476733ccf93642154bceb208f2b8\",\n    \"0xb3f52aaa4cd4221cb9fc45936cc67fd3864bf6d26bf3dd86aa85aa55ecfc05f5e392ecce5e7cf9406b4b1c4fce0398c8\",\n    \"0xb33137084422fb643123f40a6df2b498065e65230fc65dc31791c330e898c51c3a65ff738930f32c63d78f3c9315f85b\",\n    \"0x91452bfa75019363976bb7337fe3a73f1c10f01637428c135536b0cdc7da5ce558dae3dfc792aa55022292600814a8ef\",\n    \"0xad6ba94c787cd4361ca642c20793ea44f1f127d4de0bb4a77c7fbfebae0fcadbf28e2cb6f0c12c12a07324ec8c19761d\",\n    \"0x890aa6248b17f1501b0f869c556be7bf2b1d31a176f9978bb97ab7a6bd4138eed32467951c5ef1871944b7f620542f43\",\n    \"0x82111db2052194ee7dd22ff1eafffac0443cf969d3762cceae046c9a11561c0fdce9c0711f88ac01d1bed165f8a7cee3\",\n    \"0xb1527b71df2b42b55832f72e772a466e0fa05743aacc7814f4414e4bcc8d42a4010c9e0fd940e6f254cafedff3cd6543\",\n    \"0x922370fa49903679fc565f09c16a5917f8125e72acfeb060fcdbadbd1644eb9f4016229756019c93c6d609cda5d5d174\",\n    \"0xaa4c7d98a96cab138d2a53d4aee8ebff6ef903e3b629a92519608d88b3bbd94de5522291a1097e6acf830270e64c8ee1\",\n    \"0xb3dc21608a389a72d3a752883a382baaafc61ecc44083b832610a237f6a2363f24195acce529eb4aed4ef0e27a12b66e\",\n    \"0x94619f5de05e07b32291e1d7ab1d8b7337a2235e49d4fb5f3055f090a65e932e829efa95db886b32b153bdd05a53ec8c\",\n    \"0xade1e92722c2ffa85865d2426fb3d1654a16477d3abf580cfc45ea4b92d5668afc9d09275d3b79283e13e6b39e47424d\",\n    \"0xb7201589de7bed094911dd62fcd25c459a8e327ac447b69f541cdba30233063e5ddffad0b67e9c3e34adcffedfd0e13d\",\n    \"0x809d325310f862d6549e7cb40f7e5fc9b7544bd751dd28c4f363c724a0378c0e2adcb5e42ec8f912f5f49f18f3365c07\",\n    \"0xa79c20aa533de7a5d671c99eb9eb454803ba54dd4f2efa3c8fec1a38f8308e9905c71e9282955225f686146388506ff6\",\n    \"0xa85eeacb5e8fc9f3ed06a3fe2dc3108ab9f8c5877b148c73cf26e4e979bf5795edbe2e63a8d452565fd1176ed40402b2\",\n    \"0x97ef55662f8a1ec0842b22ee21391227540adf7708f491436044f3a2eb18c471525e78e1e14fa292507c99d74d7437c6\",\n    \"0x93110d64ed5886f3d16ce83b11425576a3a7a9bb831cd0de3f9a0b0f2270a730d68136b4ef7ff035ede004358f419b5c\",\n    \"0xac9ed0a071517f0ae4f61ce95916a90ba9a77a3f84b0ec50ef7298acdcd44d1b94525d191c39d6bd1bb68f4471428760\",\n    \"0x98abd6a02c7690f5a339adf292b8c9368dfc12e0f8069cf26a5e0ce54b4441638f5c66ea735142f3c28e00a0024267e6\",\n    \"0xb51efb73ba6d44146f047d69b19c0722227a7748b0e8f644d0fc9551324cf034c041a2378c56ce8b58d06038fb8a78de\",\n    \"0x8f115af274ef75c1662b588b0896b97d71f8d67986ae846792702c4742ab855952865ce236b27e2321967ce36ff93357\",\n    \"0xb3c4548f14d58b3ab03c222da09e4381a0afe47a72d18d50a94e0008797f78e39e99990e5b4757be62310d400746e35a\",\n    \"0xa9b1883bd5f31f909b8b1b6dcb48c1c60ed20aa7374b3ffa7f5b2ed036599b5bef33289d23c80a5e6420d191723b92f7\",\n    \"0x85d38dffd99487ae5bb41ab4a44d80a46157bbbe8ef9497e68f061721f74e4da513ccc3422936b059575975f6787c936\",\n    \"0xadf870fcb96e972c033ab7a35d28ae79ee795f82bc49c3bd69138f0e338103118d5529c53f2d72a9c0d947bf7d312af2\",\n    \"0xab4c7a44e2d9446c6ff303eb49aef0e367a58b22cc3bb27b4e69b55d1d9ee639c9234148d2ee95f9ca8079b1457d5a75\",\n    \"0xa386420b738aba2d7145eb4cba6d643d96bda3f2ca55bb11980b318d43b289d55a108f4bc23a9606fb0bccdeb3b3bb30\",\n    \"0x847020e0a440d9c4109773ecca5d8268b44d523389993b1f5e60e541187f7c597d79ebd6e318871815e26c96b4a4dbb1\",\n    \"0xa530aa7e5ca86fcd1bec4b072b55cc793781f38a666c2033b510a69e110eeabb54c7d8cbcb9c61fee531a6f635ffa972\",\n    \"0x87364a5ea1d270632a44269d686b2402da737948dac27f51b7a97af80b66728b0256547a5103d2227005541ca4b7ed04\",\n    \"0x8816fc6e16ea277de93a6d793d0eb5c15e9e93eb958c5ef30adaf8241805adeb4da8ce19c3c2167f971f61e0b361077d\",\n    \"0x8836a72d301c42510367181bb091e4be377777aed57b73c29ef2ce1d475feedd7e0f31676284d9a94f6db01cc4de81a2\",\n    \"0xb0d9d8b7116156d9dde138d28aa05a33e61f8a85839c1e9071ccd517b46a5b4b53acb32c2edd7150c15bc1b4bd8db9e3\",\n    \"0xae931b6eaeda790ba7f1cd674e53dc87f6306ff44951fa0df88d506316a5da240df9794ccbd7215a6470e6b31c5ea193\",\n    \"0x8c6d5bdf87bd7f645419d7c6444e244fe054d437ed1ba0c122fde7800603a5fadc061e5b836cb22a6cfb2b466f20f013\",\n    \"0x90d530c6d0cb654999fa771b8d11d723f54b8a8233d1052dc1e839ea6e314fbed3697084601f3e9bbb71d2b4eaa596df\",\n    \"0xb0d341a1422588c983f767b1ed36c18b141774f67ef6a43cff8e18b73a009da10fc12120938b8bba27f225bdfd3138f9\",\n    \"0xa131b56f9537f460d304e9a1dd75702ace8abd68cb45419695cb8dee76998139058336c87b7afd6239dc20d7f8f940cc\",\n    \"0xaa6c51fa28975f709329adee1bbd35d49c6b878041841a94465e8218338e4371f5cb6c17f44a63ac93644bf28f15d20f\",\n    \"0x88440fb584a99ebd7f9ea04aaf622f6e44e2b43bbb49fb5de548d24a238dc8f26c8da2ccf03dd43102bda9f16623f609\",\n    \"0x9777b8695b790e702159a4a750d5e7ff865425b95fa0a3c15495af385b91c90c00a6bd01d1b77bffe8c47d01baae846f\",\n    \"0x8b9d764ece7799079e63c7f01690c8eff00896a26a0d095773dea7a35967a8c40db7a6a74692f0118bf0460c26739af4\",\n    \"0x85808c65c485520609c9e61fa1bb67b28f4611d3608a9f7a5030ee61c3aa3c7e7dc17fff48af76b4aecee2cb0dbd22ac\",\n    \"0xad2783a76f5b3db008ef5f7e67391fda4e7e36abde6b3b089fc4835b5c339370287935af6bd53998bed4e399eda1136d\",\n    \"0x96f18ec03ae47c205cc4242ca58e2eff185c9dca86d5158817e2e5dc2207ab84aadda78725f8dc080a231efdc093b940\",\n    \"0x97de1ab6c6cc646ae60cf7b86df73b9cf56cc0cd1f31b966951ebf79fc153531af55ca643b20b773daa7cab784b832f7\",\n    \"0x870ba266a9bfa86ef644b1ef025a0f1b7609a60de170fe9508de8fd53170c0b48adb37f19397ee8019b041ce29a16576\",\n    \"0xad990e888d279ac4e8db90619d663d5ae027f994a3992c2fbc7d262b5990ae8a243e19157f3565671d1cb0de17fe6e55\",\n    \"0x8d9d5adcdd94c5ba3be4d9a7428133b42e485f040a28d16ee2384758e87d35528f7f9868de9bd23d1a42a594ce50a567\",\n    \"0x85a33ed75d514ece6ad78440e42f7fcdb59b6f4cff821188236d20edae9050b3a042ce9bc7d2054296e133d033e45022\",\n    \"0x92afd2f49a124aaba90de59be85ff269457f982b54c91b06650c1b8055f9b4b0640fd378df02a00e4fc91f7d226ab980\",\n    \"0x8c0ee09ec64bd831e544785e3d65418fe83ed9c920d9bb4d0bf6dd162c1264eb9d6652d2def0722e223915615931581c\",\n    \"0x8369bedfa17b24e9ad48ebd9c5afea4b66b3296d5770e09b00446c5b0a8a373d39d300780c01dcc1c6752792bccf5fd0\",\n    \"0x8b9e960782576a59b2eb2250d346030daa50bbbec114e95cdb9e4b1ba18c3d34525ae388f859708131984976ca439d94\",\n    \"0xb682bface862008fea2b5a07812ca6a28a58fd151a1d54c708fc2f8572916e0d678a9cb8dc1c10c0470025c8a605249e\",\n    \"0xa38d5e189bea540a824b36815fc41e3750760a52be0862c4cac68214febdc1a754fb194a7415a8fb7f96f6836196d82a\",\n    \"0xb9e7fbda650f18c7eb8b40e42cc42273a7298e65e8be524292369581861075c55299ce69309710e5b843cb884de171bd\",\n    \"0xb6657e5e31b3193874a1bace08f42faccbd3c502fb73ad87d15d18a1b6c2a146f1baa929e6f517db390a5a47b66c0acf\",\n    \"0xae15487312f84ed6265e4c28327d24a8a0f4d2d17d4a5b7c29b974139cf93223435aaebe3af918f5b4bb20911799715f\",\n    \"0x8bb4608beb06bc394e1a70739b872ce5a2a3ffc98c7547bf2698c893ca399d6c13686f6663f483894bccaabc3b9c56ad\",\n    \"0xb58ac36bc6847077584308d952c5f3663e3001af5ecf2e19cb162e1c58bd6c49510205d453cffc876ca1dc6b8e04a578\",\n    \"0x924f65ced61266a79a671ffb49b300f0ea44c50a0b4e3b02064faa99fcc3e4f6061ea8f38168ab118c5d47bd7804590e\",\n    \"0x8d67d43b8a06b0ff4fafd7f0483fa9ed1a9e3e658a03fb49d9d9b74e2e24858dc1bed065c12392037b467f255d4e5643\",\n    \"0xb4d4f87813125a6b355e4519a81657fa97c43a6115817b819a6caf4823f1d6a1169683fd68f8d025cdfa40ebf3069acb\",\n    \"0xa7fd4d2c8e7b59b8eed3d4332ae94b77a89a2616347402f880bc81bde072220131e6dbec8a605be3a1c760b775375879\",\n    \"0x8d4a7d8fa6f55a30df37bcf74952e2fa4fd6676a2e4606185cf154bdd84643fd01619f8fb8813a564f72e3f574f8ce30\",\n    \"0x8086fb88e6260e9a9c42e9560fde76315ff5e5680ec7140f2a18438f15bc2cc7d7d43bfb5880b180b738c20a834e6134\",\n    \"0x916c4c54721de03934fee6f43de50bb04c81f6f8dd4f6781e159e71c40c60408aa54251d457369d133d4ba3ed7c12cb4\",\n    \"0x902e5bf468f11ed9954e2a4a595c27e34abe512f1d6dc08bbca1c2441063f9af3dc5a8075ab910a10ff6c05c1c644a35\",\n    \"0xa1302953015e164bf4c15f7d4d35e3633425a78294406b861675667eec77765ff88472306531e5d3a4ec0a2ff0dd6a9e\",\n    \"0x87874461df3c9aa6c0fa91325576c0590f367075f2f0ecfeb34afe162c04c14f8ce9d608c37ac1adc8b9985bc036e366\",\n    \"0x84b50a8a61d3cc609bfb0417348133e698fe09a6d37357ce3358de189efcf35773d78c57635c2d26c3542b13cc371752\",\n    \"0xacaed2cff8633d12c1d12bb7270c54d65b0b0733ab084fd47f81d0a6e1e9b6f300e615e79538239e6160c566d8bb8d29\",\n    \"0x889e6a0e136372ca4bac90d1ab220d4e1cad425a710e8cdd48b400b73bb8137291ceb36a39440fa84305783b1d42c72f\",\n    \"0x90952e5becec45b2b73719c228429a2c364991cf1d5a9d6845ae5b38018c2626f4308daa322cab1c72e0f6c621bb2b35\",\n    \"0x8f5a97a801b6e9dcd66ccb80d337562c96f7914e7169e8ff0fda71534054c64bf2a9493bb830623d612cfe998789be65\",\n    \"0x84f3df8b9847dcf1d63ca470dc623154898f83c25a6983e9b78c6d2d90a97bf5e622445be835f32c1e55e6a0a562ea78\",\n    \"0x91d12095cd7a88e7f57f254f02fdb1a1ab18984871dead2f107404bcf8069fe68258c4e6f6ebd2477bddf738135400bb\",\n    \"0xb771a28bc04baef68604d4723791d3712f82b5e4fe316d7adc2fc01b935d8e644c06d59b83bcb542afc40ebafbee0683\",\n    \"0x872f6341476e387604a7e93ae6d6117e72d164e38ebc2b825bc6df4fcce815004d7516423c190c1575946b5de438c08d\",\n    \"0x90d6b4aa7d40a020cdcd04e8b016d041795961a8e532a0e1f4041252131089114a251791bf57794cadb7d636342f5d1c\",\n    \"0x899023ba6096a181448d927fed7a0fe858be4eac4082a42e30b3050ee065278d72fa9b9d5ce3bc1372d4cbd30a2f2976\",\n    \"0xa28f176571e1a9124f95973f414d5bdbf5794d41c3839d8b917100902ac4e2171eb940431236cec93928a60a77ede793\",\n    \"0x838dbe5bcd29c4e465d02350270fa0036cd46f8730b13d91e77afb7f5ed16525d0021d3b2ae173a76c378516a903e0cb\",\n    \"0x8e105d012dd3f5d20f0f1c4a7e7f09f0fdd74ce554c3032e48da8cce0a77260d7d47a454851387770f5c256fa29bcb88\",\n    \"0x8f4df0f9feeb7a487e1d138d13ea961459a6402fd8f8cabb226a92249a0d04ded5971f3242b9f90d08da5ff66da28af6\",\n    \"0xad1cfda4f2122a20935aa32fb17c536a3653a18617a65c6836700b5537122af5a8206befe9eaea781c1244c43778e7f1\",\n    \"0x832c6f01d6571964ea383292efc8c8fa11e61c0634a25fa180737cc7ab57bc77f25e614aac9a2a03d98f27b3c1c29de2\",\n    \"0x903f89cc13ec6685ac7728521898781fecb300e9094ef913d530bf875c18bcc3ceed7ed51e7b482d45619ab4b025c2e9\",\n    \"0xa03c474bb915aad94f171e8d96f46abb2a19c9470601f4c915512ec8b9e743c3938450a2a5b077b4618b9df8809e1dc1\",\n    \"0x83536c8456f306045a5f38ae4be2e350878fa7e164ea408d467f8c3bc4c2ee396bd5868008c089183868e4dfad7aa50b\",\n    \"0x88f26b4ea1b236cb326cd7ad7e2517ec8c4919598691474fe15d09cabcfc37a8d8b1b818f4d112432ee3a716b0f37871\",\n    \"0xa44324e3fe96e9c12b40ded4f0f3397c8c7ee8ff5e96441118d8a6bfad712d3ac990b2a6a23231a8f691491ac1fd480f\",\n    \"0xb0de4693b4b9f932191a21ee88629964878680152a82996c0019ffc39f8d9369bbe2fe5844b68d6d9589ace54af947e4\",\n    \"0x8e5d8ba948aea5fd26035351a960e87f0d23efddd8e13236cc8e4545a3dda2e9a85e6521efb8577e03772d3637d213d9\",\n    \"0x93efc82d2017e9c57834a1246463e64774e56183bb247c8fc9dd98c56817e878d97b05f5c8d900acf1fbbbca6f146556\",\n    \"0x8731176363ad7658a2862426ee47a5dce9434216cef60e6045fa57c40bb3ce1e78dac4510ae40f1f31db5967022ced32\",\n    \"0xb10c9a96745722c85bdb1a693100104d560433d45b9ac4add54c7646a7310d8e9b3ca9abd1039d473ae768a18e489845\",\n    \"0xa2ac374dfbb464bf850b4a2caf15b112634a6428e8395f9c9243baefd2452b4b4c61b0cb2836d8eae2d57d4900bf407e\",\n    \"0xb69fe3ded0c4f5d44a09a0e0f398221b6d1bf5dbb8bc4e338b93c64f1a3cac1e4b5f73c2b8117158030ec03787f4b452\",\n    \"0x8852cdbaf7d0447a8c6f211b4830711b3b5c105c0f316e3a6a18dcfbb9be08bd6f4e5c8ae0c3692da08a2dfa532f9d5c\",\n    \"0x93bbf6d7432a7d98ade3f94b57bf9f4da9bc221a180a370b113066dd42601bb9e09edd79e2e6e04e00423399339eebda\",\n    \"0xa80941c391f1eeafc1451c59e4775d6a383946ff22997aeaadf806542ba451d3b0f0c6864eeba954174a296efe2c1550\",\n    \"0xa045fe2bb011c2a2f71a0181a8f457a3078470fb74c628eab8b59aef69ffd0d649723bf74d6885af3f028bc5a104fb39\",\n    \"0xb9d8c35911009c4c8cad64692139bf3fc16b78f5a19980790cb6a7aea650a25df4231a4437ae0c351676a7e42c16134f\",\n    \"0x94c79501ded0cfcbab99e1841abe4a00a0252b3870e20774c3da16c982d74c501916ec28304e71194845be6e3113c7ab\",\n    \"0x900a66418b082a24c6348d8644ddb1817df5b25cb33044a519ef47cc8e1f7f1e38d2465b7b96d32ed472d2d17f8414c6\",\n    \"0xb26f45d393b8b2fcb29bdbb16323dc7f4b81c09618519ab3a39f8ee5bd148d0d9f3c0b5dfab55b5ce14a1cb9206d777b\",\n    \"0xaa1a87735fc493a80a96a9a57ca40a6d9c32702bfcaa9869ce1a116ae65d69cefe2f3e79a12454b4590353e96f8912b4\",\n    \"0xa922b188d3d0b69b4e4ea2a2aa076566962844637da12c0832105d7b31dea4a309eee15d12b7a336be3ea36fcbd3e3b7\",\n    \"0x8f3841fcf4105131d8c4d9885e6e11a46c448226401cf99356c291fadb864da9fa9d30f3a73c327f23f9fd99a11d633e\",\n    \"0x9791d1183fae270e226379af6c497e7da803ea854bb20afa74b253239b744c15f670ee808f708ede873e78d79a626c9a\",\n    \"0xa4cad52e3369491ada61bf28ada9e85de4516d21c882e5f1cd845bea9c06e0b2887b0c5527fcff6fc28acd3c04f0a796\",\n    \"0xb9ac86a900899603452bd11a7892a9bfed8054970bfcbeaa8c9d1930db891169e38d6977f5258c25734f96c8462eee3b\",\n    \"0xa3a154c28e5580656a859f4efc2f5ebfa7eaa84ca40e3f134fa7865e8581586db74992dbfa4036aa252fba103773ddde\",\n    \"0x95cc2a0c1885a029e094f5d737e3ecf4d26b99036453a8773c77e360101f9f98676ee246f6f732a377a996702d55691f\",\n    \"0x842651bbe99720438d8d4b0218feb60481280c05beb17750e9ca0d8c0599a60f873b7fbdcc7d8835ba9a6d57b16eec03\",\n    \"0x81ee54699da98f5620307893dcea8f64670609fa20e5622265d66283adeac122d458b3308c5898e6c57c298db2c8b24f\",\n    \"0xb97868b0b2bc98032d68352a535a1b341b9ff3c7af4e3a7f3ebc82d3419daa1b5859d6aedc39994939623c7cd878bd9b\",\n    \"0xb60325cd5d36461d07ef253d826f37f9ee6474a760f2fff80f9873d01fd2b57711543cdc8d7afa1c350aa753c2e33dea\",\n    \"0x8c205326c11d25a46717b780c639d89714c7736c974ae71287e3f4b02e6605ac2d9b4928967b1684f12be040b7bf2dd3\",\n    \"0x95a392d82db51e26ade6c2ccd3396d7e40aff68fa570b5951466580d6e56dda51775dce5cf3a74a7f28c3cb2eb551c4d\",\n    \"0x8f2cc8071eb56dffb70bda6dd433b556221dc8bba21c53353c865f00e7d4d86c9e39f119ea9a8a12ef583e9a55d9a6b6\",\n    \"0x9449a71af9672aaf8856896d7e3d788b22991a7103f75b08c0abbcc2bfe60fda4ed8ce502cea4511ff0ea52a93e81222\",\n    \"0x857090ab9fdb7d59632d068f3cc8cf27e61f0d8322d30e6b38e780a1f05227199b4cd746aac1311c36c659ef20931f28\",\n    \"0x98a891f4973e7d9aaf9ac70854608d4f7493dffc7e0987d7be9dd6029f6ea5636d24ef3a83205615ca1ff403750058e1\",\n    \"0xa486e1365bbc278dd66a2a25d258dc82f46b911103cb16aab3945b9c95ae87b386313a12b566df5b22322ede0afe25ad\",\n    \"0xa9a1eb399ed95d396dccd8d1ac718043446f8b979ec62bdce51c617c97a312f01376ab7fb87d27034e5f5570797b3c33\",\n    \"0xb7abc3858d7a74bb446218d2f5a037e0fae11871ed9caf44b29b69c500c1fa1dcfad64c9cdccc9d80d5e584f06213deb\",\n    \"0x8cfb09fe2e202faa4cebad932b1d35f5ca204e1c2a0c740a57812ac9a6792130d1312aabd9e9d4c58ca168bfebd4c177\",\n    \"0xa90a305c2cd0f184787c6be596fa67f436afd1f9b93f30e875f817ac2aae8bdd2e6e656f6be809467e6b3ad84adb86b1\",\n    \"0x80a9ef993c2b009ae172cc8f7ec036f5734cf4f4dfa06a7db4d54725e7fbfae5e3bc6f22687bdbb6961939d6f0c87537\",\n    \"0x848ade1901931e72b955d7db1893f07003e1708ff5d93174bac5930b9a732640f0578839203e9b77eb27965c700032d3\",\n    \"0x93fdf4697609c5ae9c33b9ca2f5f1af44abeb2b98dc4fdf732cf7388de086f410730dc384d9b7a7f447bb009653c8381\",\n    \"0x89ce3fb805aea618b5715c0d22a9f46da696b6fa86794f56fdf1d44155a33d42daf1920bcbe36cbacf3cf4c92df9cbc7\",\n    \"0x829ce2c342cf82aa469c65f724f308f7a750bd1494adc264609cd790c8718b8b25b5cab5858cf4ee2f8f651d569eea67\",\n    \"0xaf2f0cee7bf413204be8b9df59b9e4991bc9009e0d6dbe6815181df0ec2ca93ab8f4f3135b1c14d8f53d74bff0bd6f27\",\n    \"0xb87998cecf7b88cde93d1779f10a521edd5574a2fbd240102978639ec57433ba08cdb53849038a329cebbe74657268d2\",\n    \"0xa64542a1261a6ed3d720c2c3a802303aad8c4c110c95d0f12e05c1065e66f42da494792b6bfc5b9272363f3b1d457f58\",\n    \"0x86a6fd042e4f282fadf07a4bfee03fc96a3aea49f7a00f52bf249a20f1ec892326855410e61f37fbb27d9305eb2fc713\",\n    \"0x967ea5bc403b6db269682f7fd0df90659350d7e1aa66bc4fab4c9dfcd75ed0bba4b52f1cebc5f34dc8ba810793727629\",\n    \"0xa52990f9f3b8616ce3cdc2c74cd195029e6a969753dcf2d1630438700e7d6ebde36538532b3525ac516f5f2ce9dd27a3\",\n    \"0xa64f7ff870bab4a8bf0d4ef6f5c744e9bf1021ed08b4c80903c7ad318e80ba1817c3180cc45cb5a1cae1170f0241655f\",\n    \"0xb00f706fa4de1f663f021e8ad3d155e84ce6084a409374b6e6cd0f924a0a0b51bebaaaf1d228c77233a73b0a5a0df0e9\",\n    \"0x8b882cc3bff3e42babdb96df95fb780faded84887a0a9bab896bef371cdcf169d909f5658649e93006aa3c6e1146d62e\",\n    \"0x9332663ef1d1dcf805c3d0e4ce7a07d9863fb1731172e766b3cde030bf81682cc011e26b773fb9c68e0477b4ae2cfb79\",\n    \"0xa8aa8151348dbd4ef40aaeb699b71b4c4bfd3218560c120d85036d14f678f6736f0ec68e80ce1459d3d35feccc575164\",\n    \"0xa16cd8b729768f51881c213434aa28301fa78fcb554ddd5f9012ee1e4eae7b5cb3dd88d269d53146dea92d10790faf0b\",\n    \"0x86844f0ef9d37142faf3b1e196e44fbe280a3ba4189aa05c356778cb9e3b388a2bff95eed305ada8769935c9974e4c57\",\n    \"0xae2eec6b328fccf3b47bcdac32901ac2744a51beb410b04c81dea34dee4912b619466a4f5e2780d87ecefaebbe77b46d\",\n    \"0x915df4c38d301c8a4eb2dc5b1ba0ffaad67cbb177e0a80095614e9c711f4ef24a4cef133f9d982a63d2a943ba6c8669d\",\n    \"0xae6a2a4dedfc2d1811711a8946991fede972fdf2a389b282471280737536ffc0ac3a6d885b1f8bda0366eb0b229b9979\",\n    \"0xa9b628c63d08b8aba6b1317f6e91c34b2382a6c85376e8ef2410a463c6796740ae936fc4e9e0737cb9455d1daa287bd8\",\n    \"0x848e30bf7edf2546670b390d5cf9ab71f98fcb6add3c0b582cb34996c26a446dee5d1bde4fdcde4fc80c10936e117b29\",\n    \"0x907d6096c7c8c087d1808dd995d5d2b9169b3768c3f433475b50c2e2bd4b082f4d543afd8b0b0ddffa9c66222a72d51d\",\n    \"0xa59970a2493b07339124d763ac9d793c60a03354539ecbcf6035bc43d1ea6e35718202ae6d7060b7d388f483d971573c\",\n    \"0xb9cfef2af9681b2318f119d8611ff6d9485a68d8044581b1959ab1840cbca576dbb53eec17863d2149966e9feb21122f\",\n    \"0xad47271806161f61d3afa45cdfe2babceef5e90031a21779f83dc8562e6076680525b4970b2f11fe9b2b23c382768323\",\n    \"0x8e425a99b71677b04fe044625d338811fbb8ee32368a424f6ab2381c52e86ee7a6cecedf777dc97181519d41c351bc22\",\n    \"0x86b55b54d7adefc12954a9252ee23ae83efe8b5b4b9a7dc307904413e5d69868c7087a818b2833f9b004213d629be8ad\",\n    \"0xa14fda6b93923dd11e564ae4457a66f397741527166e0b16a8eb91c6701c244fd1c4b63f9dd3515193ec88fa6c266b35\",\n    \"0xa9b17c36ae6cd85a0ed7f6cabc5b47dc8f80ced605db327c47826476dc1fb8f8669aa7a7dc679fbd4ee3d8e8b4bd6a6f\",\n    \"0x82a0829469c1458d959c821148f15dacae9ea94bf56c59a6ab2d4dd8b3d16d73e313b5a3912a6c1f131d73a8f06730c4\",\n    \"0xb22d56d549a53eaef549595924bdb621ff807aa4513feedf3fdcbf7ba8b6b9cfa4481c2f67fc642db397a6b794a8b63a\",\n    \"0x974c59c24392e2cb9294006cbe3c52163e255f3bd0c2b457bdc68a6338e6d5b6f87f716854492f8d880a6b896ccf757c\",\n    \"0xb70d247ba7cad97c50b57f526c2ba915786e926a94e8f8c3eebc2e1be6f4255411b9670e382060049c8f4184302c40b2\",\n    \"0xad80201fe75ef21c3ddbd98cf23591e0d7a3ba1036dfe77785c32f44755a212c31f0ceb0a0b6f5ee9b6dc81f358d30c3\",\n    \"0x8c656e841f9bb90b9a42d425251f3fdbc022a604d75f5845f479ed4be23e02aaf9e6e56cde351dd7449c50574818a199\",\n    \"0x8b88dd3fa209d3063b7c5b058f7249ee9900fbc2287d16da61a0704a0a1d71e45d9c96e1cda7fdf9654534ec44558b22\",\n    \"0x961da00cc8750bd84d253c08f011970ae1b1158ad6778e8ed943d547bceaf52d6d5a212a7de3bf2706688c4389b827d2\",\n    \"0xa5dd379922549a956033e3d51a986a4b1508e575042b8eaa1df007aa77cf0b8c2ab23212f9c075702788fa9c53696133\",\n    \"0xac8fcfde3a349d1e93fc8cf450814e842005c545c4844c0401bc80e6b96cdb77f29285a14455e167c191d4f312e866cd\",\n    \"0xac63d79c799783a8466617030c59dd5a8f92ee6c5204676fd8d881ce5f7f8663bdbeb0379e480ea9b6340ab0dc88e574\",\n    \"0x805874fde19ce359041ae2bd52a39e2841acabfd31f965792f2737d7137f36d4e4722ede8340d8c95afa6af278af8acb\",\n    \"0x8d2f323a228aa8ba7b7dc1399138f9e6b41df1a16a7069003ab8104b8b68506a45141bc5fe66acf430e23e13a545190b\",\n    \"0xa1610c721a2d9af882bb6b39bea97cff1527a3aea041d25934de080214ae77c959e79957164440686d15ab301e897d4d\",\n    \"0xaba16d29a47fc36f12b654fde513896723e2c700c4190f11b26aa4011da57737ad717daa02794aa3246e4ae5f0b0cc3a\",\n    \"0xa406db2f15fdd135f346cc4846623c47edd195e80ba8c7cb447332095314d565e4040694ca924696bb5ee7f8996ea0ba\",\n    \"0x8b30e2cd9b47d75ba57b83630e40f832249af6c058d4f490416562af451993eec46f3e1f90bc4d389e4c06abd1b32a46\",\n    \"0xaacf9eb7036e248e209adbfc3dd7ce386569ea9b312caa4b240726549db3c68c4f1c8cbf8ed5ea9ea60c7e57c9df3b8e\",\n    \"0xb20fcac63bf6f5ee638a42d7f89be847f348c085ddcbec3fa318f4323592d136c230495f188ef2022aa355cc2b0da6f9\",\n    \"0x811eff750456a79ec1b1249d76d7c1547065b839d8d4aaad860f6d4528eb5b669473dcceeeea676cddbc3980b68461b7\",\n    \"0xb52d14ae33f4ab422f953392ae76a19c618cc31afc96290bd3fe2fb44c954b5c92c4789f3f16e8793f2c0c1691ade444\",\n    \"0xa7826dafeeba0db5b66c4dfcf2b17fd7b40507a5a53ac2e42942633a2cb30b95ba1739a6e9f3b7a0e0f1ec729bf274e2\",\n    \"0x8acfd83ddf7c60dd7c8b20c706a3b972c65d336b8f9b3d907bdd8926ced271430479448100050b1ef17578a49c8fa616\",\n    \"0xaf0c69f65184bb06868029ad46f8465d75c36814c621ac20a5c0b06a900d59305584f5a6709683d9c0e4b6cd08d650a6\",\n    \"0xb6cc8588191e00680ee6c3339bd0f0a17ad8fd7f4be57d5d7075bede0ea593a19e67f3d7c1a20114894ee5bfcab71063\",\n    \"0xa82fd4f58635129dbb6cc3eb9391cf2d28400018b105fc41500fbbd12bd890b918f97d3d359c29dd3b4c4e34391dfab0\",\n    \"0x92fc544ed65b4a3625cf03c41ddff7c039bc22d22c0d59dcc00efd5438401f2606adb125a1d5de294cca216ec8ac35a3\",\n    \"0x906f67e4a32582b71f15940523c0c7ce370336935e2646bdaea16a06995256d25e99df57297e39d6c39535e180456407\",\n    \"0x97510337ea5bbd5977287339197db55c60533b2ec35c94d0a460a416ae9f60e85cee39be82abeeacd5813cf54df05862\",\n    \"0x87e6894643815c0ea48cb96c607266c5ee4f1f82ba5fe352fb77f9b6ed14bfc2b8e09e80a99ac9047dfcf62b2ae26795\",\n    \"0xb6fd55dd156622ad7d5d51b7dde75e47bd052d4e542dd6449e72411f68275775c846dde301e84613312be8c7bce58b07\",\n    \"0xb98461ac71f554b2f03a94e429b255af89eec917e208a8e60edf5fc43b65f1d17a20de3f31d2ce9f0cb573c25f2f4d98\",\n    \"0x96f0dea40ca61cefbee41c4e1fe9a7d81fbe1f49bb153d083ab70f5d0488a1f717fd28cedcf6aa18d07cce2c62801898\",\n    \"0x8d7c3ab310184f7dc34b6ce4684e4d29a31e77b09940448ea4daac730b7eb308063125d4dd229046cf11bfd521b771e0\",\n    \"0x96f0564898fe96687918bbf0a6adead99cf72e3a35ea3347e124af9d006221f8e82e5a9d2fe80094d5e8d48e610f415e\",\n    \"0xad50fcb92c2675a398cf07d4c40a579e44bf8d35f27cc330b57e54d5ea59f7d898af0f75dccfe3726e5471133d70f92b\",\n    \"0x828beed62020361689ae7481dd8f116902b522fb0c6c122678e7f949fdef70ead011e0e6bffd25678e388744e17cdb69\",\n    \"0x8349decac1ca16599eee2efc95bcaabf67631107da1d34a2f917884bd70dfec9b4b08ab7bc4379d6c73b19c0b6e54fb8\",\n    \"0xb2a6a2e50230c05613ace9e58bb2e98d94127f196f02d9dddc53c43fc68c184549ca12d713cb1b025d8260a41e947155\",\n    \"0x94ff52181aadae832aed52fc3b7794536e2a31a21fc8be3ea312ca5c695750d37f08002f286b33f4023dba1e3253ecfa\",\n    \"0xa21d56153c7e5972ee9a319501be4faff199fdf09bb821ea9ce64aa815289676c00f105e6f00311b3a5b627091b0d0fc\",\n    \"0xa27a60d219f1f0c971db73a7f563b371b5c9fc3ed1f72883b2eac8a0df6698400c9954f4ca17d7e94e44bd4f95532afb\",\n    \"0xa2fc56fae99b1f18ba5e4fe838402164ce82f8a7f3193d0bbd360c2bac07c46f9330c4c7681ffb47074c6f81ee6e7ac6\",\n    \"0xb748e530cd3afb96d879b83e89c9f1a444f54e55372ab1dcd46a0872f95ce8f49cf2363fc61be82259e04f555937ed16\",\n    \"0x8bf8993e81080c7cbba1e14a798504af1e4950b2f186ab3335b771d6acaee4ffe92131ae9c53d74379d957cb6344d9cd\",\n    \"0x96774d0ef730d22d7ab6d9fb7f90b9ead44285219d076584a901960542756700a2a1603cdf72be4708b267200f6c36a9\",\n    \"0xb47703c2ab17be1e823cc7bf3460db1d6760c0e33862c90ca058845b2ff234b0f9834ddba2efb2ee1770eb261e7d8ffd\",\n    \"0x84319e67c37a9581f8b09b5e4d4ae88d0a7fb4cbb6908971ab5be28070c3830f040b1de83ee663c573e0f2f6198640e4\",\n    \"0x96811875fa83133e0b3c0e0290f9e0e28bca6178b77fdf5350eb19344d453dbd0d71e55a0ef749025a5a2ca0ad251e81\",\n    \"0x81a423423e9438343879f2bfd7ee9f1c74ebebe7ce3cfffc8a11da6f040cc4145c3b527bd3cf63f9137e714dbcb474ef\",\n    \"0xb8c3535701ddbeec2db08e17a4fa99ba6752d32ece5331a0b8743676f421fcb14798afc7c783815484f14693d2f70db8\",\n    \"0x81aee980c876949bf40782835eec8817d535f6f3f7e00bf402ddd61101fdcd60173961ae90a1cf7c5d060339a18c959d\",\n    \"0x87e67b928d97b62c49dac321ce6cb680233f3a394d4c9a899ac2e8db8ccd8e00418e66cdfd68691aa3cb8559723b580c\",\n    \"0x8eac204208d99a2b738648df96353bbb1b1065e33ee4f6bba174b540bbbd37d205855e1f1e69a6b7ff043ca377651126\",\n    \"0x848e6e7a54ad64d18009300b93ea6f459ce855971dddb419b101f5ac4c159215626fadc20cc3b9ab1701d8f6dfaddd8b\",\n    \"0x88aa123d9e0cf309d46dddb6acf634b1ade3b090a2826d6e5e78669fa1220d6df9a6697d7778cd9b627db17eea846126\",\n    \"0x9200c2a629b9144d88a61151b661b6c4256cc5dadfd1e59a8ce17a013c2d8f7e754aabe61663c3b30f1bc47784c1f8cf\",\n    \"0xb6e1a2827c3bdda91715b0e1b1f10dd363cef337e7c80cac1f34165fc0dea7c8b69747e310563db5818390146ce3e231\",\n    \"0x92c333e694f89f0d306d54105b2a5dcc912dbe7654d9e733edab12e8537350815be472b063e56cfde5286df8922fdecb\",\n    \"0xa6fac04b6d86091158ebb286586ccfec2a95c9786e14d91a9c743f5f05546073e5e3cc717635a0c602cad8334e922346\",\n    \"0xa581b4af77feebc1fb897d49b5b507c6ad513d8f09b273328efbb24ef0d91eb740d01b4d398f2738125dacfe550330cd\",\n    \"0x81c4860cccf76a34f8a2bc3f464b7bfd3e909e975cce0d28979f457738a56e60a4af8e68a3992cf273b5946e8d7f76e2\",\n    \"0x8d1eaa09a3180d8af1cbaee673db5223363cc7229a69565f592fa38ba0f9d582cedf91e15dabd06ebbf2862fc0feba54\",\n    \"0x9832f49b0147f4552402e54593cfa51f99540bffada12759b71fcb86734be8e500eea2d8b3d036710bdf04c901432de9\",\n    \"0x8bdb0e8ec93b11e5718e8c13cb4f5de545d24829fd76161216340108098dfe5148ed25e3b57a89a516f09fa79043734d\",\n    \"0xab96f06c4b9b0b2c0571740b24fca758e6976315053a7ecb20119150a9fa416db2d3a2e0f8168b390bb063f0c1caf785\",\n    \"0xab777f5c52acd62ecf4d1f168b9cc8e1a9b45d4ec6a8ff52c583e867c2239aba98d7d3af977289b367edce03d9c2dfb1\",\n    \"0xa09d3ce5e748da84802436951acc3d3ea5d8ec1d6933505ed724d6b4b0d69973ab0930daec9c6606960f6e541e4a3ce2\",\n    \"0x8ef94f7be4d85d5ad3d779a5cf4d7b2fc3e65c52fb8e1c3c112509a4af77a0b5be994f251e5e40fabeeb1f7d5615c22b\",\n    \"0xa7406a5bf5708d9e10922d3c5c45c03ef891b8d0d74ec9f28328a72be4cdc05b4f2703fa99366426659dfca25d007535\",\n    \"0xb7f52709669bf92a2e070bfe740f422f0b7127392c5589c7f0af71bb5a8428697c762d3c0d74532899da24ea7d8695c2\",\n    \"0xb9dfb0c8df84104dbf9239ccefa4672ef95ddabb8801b74997935d1b81a78a6a5669a3c553767ec19a1281f6e570f4ff\",\n    \"0xae4d5c872156061ce9195ac640190d8d71dd406055ee43ffa6f9893eb24b870075b74c94d65bc1d5a07a6573282b5520\",\n    \"0xafe6bd3eb72266d333f1807164900dcfa02a7eb5b1744bb3c86b34b3ee91e3f05e38fa52a50dc64eeb4bdb1dd62874b8\",\n    \"0x948043cf1bc2ef3c01105f6a78dc06487f57548a3e6ef30e6ebc51c94b71e4bf3ff6d0058c72b6f3ecc37efd7c7fa8c0\",\n    \"0xa22fd17c2f7ffe552bb0f23fa135584e8d2d8d75e3f742d94d04aded2a79e22a00dfe7acbb57d44e1cdb962fb22ae170\",\n    \"0x8cd0f4e9e4fb4a37c02c1bde0f69359c43ab012eb662d346487be0c3758293f1ca560122b059b091fddce626383c3a8f\",\n    \"0x90499e45f5b9c81426f3d735a52a564cafbed72711d9279fdd88de8038e953bc48c57b58cba85c3b2e4ce56f1ddb0e11\",\n    \"0x8c30e4c034c02958384564cac4f85022ef36ab5697a3d2feaf6bf105049675bbf23d01b4b6814711d3d9271abff04cac\",\n    \"0x81f7999e7eeea30f3e1075e6780bbf054f2fb6f27628a2afa4d41872a385b4216dd5f549da7ce6cf39049b2251f27fb7\",\n    \"0xb36a7191f82fc39c283ffe53fc1f5a9a00b4c64eee7792a8443475da9a4d226cf257f226ea9d66e329af15d8f04984ec\",\n    \"0xaad4da528fdbb4db504f3041c747455baff5fcd459a2efd78f15bdf3aea0bdb808343e49df88fe7a7c8620009b7964a3\",\n    \"0x99ebd8c6dd5dd299517fb6381cfc2a7f443e6e04a351440260dd7c2aee3f1d8ef06eb6c18820b394366ecdfd2a3ce264\",\n    \"0x8873725b81871db72e4ec3643084b1cdce3cbf80b40b834b092767728605825c19b6847ad3dcf328438607e8f88b4410\",\n    \"0xb008ee2f895daa6abd35bd39b6f7901ae4611a11a3271194e19da1cdcc7f1e1ea008fe5c5440e50d2c273784541ad9c5\",\n    \"0x9036feafb4218d1f576ef89d0e99124e45dacaa6d816988e34d80f454d10e96809791d5b78f7fd65f569e90d4d7238c5\",\n    \"0x92073c1d11b168e4fa50988b0288638b4868e48bbc668c5a6dddf5499875d53be23a285acb5e4bad60114f6cf6c556e9\",\n    \"0x88c87dfcb8ba6cbfe7e1be081ccfadbd589301db2cb7c99f9ee5d7db90aa297ed1538d5a867678a763f2deede5fd219a\",\n    \"0xb42a562805c661a50f5dea63108002c0f27c0da113da6a9864c9feb5552225417c0356c4209e8e012d9bcc9d182c7611\",\n    \"0x8e6317d00a504e3b79cd47feb4c60f9df186467fe9ca0f35b55c0364db30528f5ff071109dabb2fc80bb9cd4949f0c24\",\n    \"0xb7b1ea6a88694f8d2f539e52a47466695e39e43a5eb9c6f23bca15305fe52939d8755cc3ac9d6725e60f82f994a3772f\",\n    \"0xa3cd55161befe795af93a38d33290fb642b8d80da8b786c6e6fb02d393ea308fbe87f486994039cbd7c7b390414594b6\",\n    \"0xb416d2d45b44ead3b1424e92c73c2cf510801897b05d1724ff31cbd741920cd858282fb5d6040fe1f0aa97a65bc49424\",\n    \"0x950ee01291754feace97c2e933e4681e7ddfbc4fcd079eb6ff830b0e481d929c93d0c7fb479c9939c28ca1945c40da09\",\n    \"0x869bd916aee8d86efe362a49010382674825d49195b413b4b4018e88ce43fe091b475d0b863ff0ba2259400f280c2b23\",\n    \"0x9782f38cd9c9d3385ec286ebbc7cba5b718d2e65a5890b0a5906b10a89dc8ed80d417d71d7c213bf52f2af1a1f513ea7\",\n    \"0x91cd33bc2628d096269b23faf47ee15e14cb7fdc6a8e3a98b55e1031ea0b68d10ba30d97e660f7e967d24436d40fad73\",\n    \"0x8becc978129cc96737034c577ae7225372dd855da8811ae4e46328e020c803833b5bdbc4a20a93270e2b8bd1a2feae52\",\n    \"0xa36b1d8076783a9522476ce17f799d78008967728ce920531fdaf88303321bcaf97ecaa08e0c01f77bc32e53c5f09525\",\n    \"0xb4720e744943f70467983aa34499e76de6d59aa6fadf86f6b787fdce32a2f5b535b55db38fe2da95825c51002cfe142d\",\n    \"0x91ad21fc502eda3945f6de874d1b6bf9a9a7711f4d61354f9e5634fc73f9c06ada848de15ab0a75811d3250be862827d\",\n    \"0x84f78e2ebf5fc077d78635f981712daf17e2475e14c2a96d187913006ad69e234746184a51a06ef510c9455b38acb0d7\",\n    \"0x960aa7906e9a2f11db64a26b5892ac45f20d2ccb5480f4888d89973beb6fa0dfdc06d68d241ff5ffc7f1b82b1aac242d\",\n    \"0xa99365dcd1a00c66c9db6924b97c920f5c723380e823b250db85c07631b320ec4e92e586f7319e67a522a0578f7b6d6c\",\n    \"0xa25d92d7f70cf6a88ff317cfec071e13774516da664f5fac0d4ecaa65b8bf4eb87a64a4d5ef2bd97dfae98d388dbf5cc\",\n    \"0xa7af47cd0041295798f9779020a44653007444e8b4ef0712982b06d0dcdd434ec4e1f7c5f7a049326602cb605c9105b7\",\n    \"0xaefe172eac5568369a05980931cc476bebd9dea573ba276d59b9d8c4420784299df5a910033b7e324a6c2dfc62e3ef05\",\n    \"0xb69bc9d22ffa645baa55e3e02522e9892bb2daa7fff7c15846f13517d0799766883ee09ae0869df4139150c5b843ca8a\",\n    \"0x95a10856140e493354fdd12722c7fdded21b6a2ffbc78aa2697104af8ad0c8e2206f44b0bfee077ef3949d46bbf7c16b\",\n    \"0x891f2fcd2c47cbea36b7fa715968540c233313f05333f09d29aba23c193f462ed490dd4d00969656e89c53155fdfe710\",\n    \"0xa6c33e18115e64e385c843dde34e8a228222795c7ca90bc2cc085705d609025f3351d9be61822c69035a49fb3e48f2d5\",\n    \"0xb87fb12f12c0533b005adad0487f03393ff682e13575e3cb57280c3873b2c38ba96a63c49eef7a442753d26b7005230b\",\n    \"0xb905c02ba451bfd411c135036d92c27af3b0b1c9c2f1309d6948544a264b125f39dd41afeff4666b12146c545adc168a\",\n    \"0x8b29c513f43a78951cf742231cf5457a6d9d55edf45df5481a0f299a418d94effef561b15d2c1a01d1b8067e7153fda9\",\n    \"0xb9941cccd51dc645920d2781c81a317e5a33cb7cf76427b60396735912cb6d2ca9292bb4d36b6392467d390d2c58d9f3\",\n    \"0xa8546b627c76b6ef5c93c6a98538d8593dbe21cb7673fd383d5401b0c935eea0bdeeefeb1af6ad41bad8464fb87bbc48\",\n    \"0xaa286b27de2812de63108a1aec29d171775b69538dc6198640ac1e96767c2b83a50391f49259195957d457b493b667c9\",\n    \"0xa932fb229f641e9abbd8eb2bd874015d97b6658ab6d29769fc23b7db9e41dd4f850382d4c1f08af8f156c5937d524473\",\n    \"0xa1412840fcc86e2aeec175526f2fb36e8b3b8d21a78412b7266daf81e51b3f68584ed8bd42a66a43afdd8c297b320520\",\n    \"0x89c78be9efb624c97ebca4fe04c7704fa52311d183ffd87737f76b7dadc187c12c982bd8e9ed7cd8beb48cdaafd2fd01\",\n    \"0xa3f5ddec412a5bec0ce15e3bcb41c6214c2b05d4e9135a0d33c8e50a78eaba71e0a5a6ea8b45854dec5c2ed300971fc2\",\n    \"0x9721f9cec7a68b7758e3887548790de49fa6a442d0396739efa20c2f50352a7f91d300867556d11a703866def2d5f7b5\",\n    \"0xa23764e140a87e5991573521af039630dd28128bf56eed2edbed130fd4278e090b60cf5a1dca9de2910603d44b9f6d45\",\n    \"0xa1a6494a994215e48ab55c70efa8ffdddce6e92403c38ae7e8dd2f8288cad460c6c7db526bbdf578e96ca04d9fe12797\",\n    \"0xb1705ea4cb7e074efe0405fc7b8ee2ec789af0426142f3ec81241cacd4f7edcd88e39435e4e4d8e7b1df64f3880d6613\",\n    \"0x85595d061d677116089a6064418b93eb44ff79e68d12bd9625078d3bbc440a60d0b02944eff6054433ee34710ae6fbb4\",\n    \"0x9978d5e30bedb7526734f9a1febd973a70bfa20890490e7cc6f2f9328feab1e24f991285dbc3711d892514e2d7d005ad\",\n    \"0xaf30243c66ea43b9f87a061f947f7bce745f09194f6e95f379c7582b9fead920e5d6957eaf05c12ae1282ada4670652f\",\n    \"0xa1930efb473f88001e47aa0b2b2a7566848cccf295792e4544096ecd14ee5d7927c173a8576b405bfa2eec551cd67eb5\",\n    \"0xb0446d1c590ee5a45f7e22d269c044f3848c97aec1d226b44bfd0e94d9729c28a38bccddc3a1006cc5fe4e3c24f001f2\",\n    \"0xb8a8380172df3d84b06176df916cf557966d4f2f716d3e9437e415d75b646810f79f2b2b71d857181b7fc944018883a3\",\n    \"0xa563afec25b7817bfa26e19dc9908bc00aa8fc3d19be7d6de23648701659009d10e3e4486c28e9c6b13d48231ae29ac5\",\n    \"0xa5a8e80579de886fb7d6408f542791876885947b27ad6fa99a8a26e381f052598d7b4e647b0115d4b5c64297e00ce28e\",\n    \"0x8f87afcc7ad33c51ac719bade3cd92da671a37a82c14446b0a2073f4a0a23085e2c8d31913ed2d0be928f053297de8f6\",\n    \"0xa43c455ce377e0bc434386c53c752880687e017b2f5ae7f8a15c044895b242dffde4c92fb8f8bb50b18470b17351b156\",\n    \"0x8368f8b12a5bceb1dba25adb3a2e9c7dc9b1a77a1f328e5a693f5aec195cd1e06b0fe9476b554c1c25dac6c4a5b640a3\",\n    \"0x919878b27f3671fc78396f11531c032f3e2bd132d04cc234fa4858676b15fb1db3051c0b1db9b4fc49038216f11321ce\",\n    \"0xb48cd67fb7f1242696c1f877da4bdf188eac676cd0e561fbac1a537f7b8229aff5a043922441d603a26aae56a15faee4\",\n    \"0xa3e0fdfd4d29ea996517a16f0370b54787fefe543c2fe73bfc6f9e560c1fd30dad8409859e2d7fa2d44316f24746c712\",\n    \"0x8bb156ade8faf149df7bea02c140c7e392a4742ae6d0394d880a849127943e6f26312033336d3b9fdc0092d71b5efe87\",\n    \"0x8845e5d5cc555ca3e0523244300f2c8d7e4d02aaebcb5bd749d791208856c209a6f84dd99fd55968c9f0ab5f82916707\",\n    \"0xa3e90bb5c97b07789c2f32dff1aec61d0a2220928202f5ad5355ae71f8249237799d6c8a22602e32e572cb12eabe0c17\",\n    \"0xb150bcc391884c996149dc3779ce71f15dda63a759ee9cc05871f5a8379dcb62b047098922c0f26c7bd04deb394c33f9\",\n    \"0x95cd4ad88d51f0f2efcfd0c2df802fe252bb9704d1afbf9c26a248df22d55da87bdfaf41d7bc6e5df38bd848f0b13f42\",\n    \"0xa05a49a31e91dff6a52ac8b9c2cfdd646a43f0d488253f9e3cfbce52f26667166bbb9b608fc358763a65cbf066cd6d05\",\n    \"0xa59c3c1227fdd7c2e81f5e11ef5c406da44662987bac33caed72314081e2eed66055d38137e01b2268e58ec85dd986c0\",\n    \"0xb7020ec3bd73a99861f0f1d88cf5a19abab1cbe14b7de77c9868398c84bb8e18dbbe9831838a96b6d6ca06e82451c67b\",\n    \"0x98d1ff2525e9718ee59a21d8900621636fcd873d9a564b8dceb4be80a194a0148daf1232742730b3341514b2e5a5436c\",\n    \"0x886d97b635975fc638c1b6afc493e5998ca139edba131b75b65cfe5a8e814f11bb678e0eeee5e6e5cd913ad3f2fefdfc\",\n    \"0x8fb9fd928d38d5d813b671c924edd56601dd7163b686c13f158645c2f869d9250f3859aa5463a39258c90fef0f41190a\",\n    \"0xaac35e1cd655c94dec3580bb3800bd9c2946c4a9856f7d725af15fbea6a2d8ca51c8ad2772abed60ee0e3fb9cb24046b\",\n    \"0xb8d71fa0fa05ac9e443c9b4929df9e7f09a919be679692682e614d24227e04894bfc14a5c73a62fb927fedff4a0e4aa7\",\n    \"0xa45a19f11fbbb531a704badbb813ed8088ab827c884ee4e4ebf363fa1132ff7cfa9d28be9c85b143e4f7cdbc94e7cf1a\",\n    \"0x82b54703a4f295f5471b255ab59dce00f0fe90c9fb6e06b9ee48b15c91d43f4e2ef4a96c3118aeb03b08767be58181bb\",\n    \"0x8283264c8e6d2a36558f0d145c18576b6600ff45ff99cc93eca54b6c6422993cf392668633e5df396b9331e873d457e5\",\n    \"0x8c549c03131ead601bc30eb6b9537b5d3beb7472f5bb1bcbbfd1e9f3704477f7840ab3ab7f7dc13bbbbcdff886a462d4\",\n    \"0xafbb0c520ac1b5486513587700ad53e314cb74bfbc12e0b5fbdcfdaac36d342e8b59856196a0d84a25cff6e6e1d17e76\",\n    \"0x89e4c22ffb51f2829061b3c7c1983c5c750cad158e3a825d46f7cf875677da5d63f653d8a297022b5db5845c9271b32b\",\n    \"0xafb27a86c4c2373088c96b9adf4433f2ebfc78ac5c526e9f0510670b6e4e5e0057c0a4f75b185e1a30331b9e805c1c15\",\n    \"0xa18e16b57445f88730fc5d3567bf5a176861dc14c7a08ed2996fe80eed27a0e7628501bcb78a1727c5e9ac55f29c12c4\",\n    \"0x93d61bf88b192d6825cf4e1120af1c17aa0f994d158b405e25437eaeefae049f7b721a206e7cc8a04fdc29d3c42580a1\",\n    \"0xa99f2995a2e3ed2fd1228d64166112038de2f516410aa439f4c507044e2017ea388604e2d0f7121256fadf7fbe7023d1\",\n    \"0x914fd91cffc23c32f1c6d0e98bf660925090d873367d543034654389916f65f552e445b0300b71b61b721a72e9a5983c\",\n    \"0xb42a578a7787b71f924e7def425d849c1c777156b1d4170a8ee7709a4a914e816935131afd9a0412c4cb952957b20828\",\n    \"0x82fb30590e84b9e45db1ec475a39971cf554dc01bcc7050bc89265740725c02e2be5a972168c5170c86ae83e5b0ad2c0\",\n    \"0xb14f8d8e1e93a84976289e0cf0dfa6f3a1809e98da16ee5c4932d0e1ed6bf8a07697fdd4dd86a3df84fb0003353cdcc0\",\n    \"0x85d7a2f4bda31aa2cb208b771fe03291a4ebdaf6f1dc944c27775af5caec412584c1f45bc741fca2a6a85acb3f26ad7d\",\n    \"0xaf02e56ce886ff2253bc0a68faad76f25ead84b2144e5364f3fb9b648f03a50ee9dc0b2c33ebacf7c61e9e43201ef9ef\",\n    \"0x87e025558c8a0b0abd06dfc350016847ea5ced7af2d135a5c9eec9324a4858c4b21510fb0992ec52a73447f24945058e\",\n    \"0x80fff0bafcd058118f5e7a4d4f1ae0912efeb281d2cbe4d34ba8945cc3dbe5d8baf47fb077343b90b8d895c90b297aca\",\n    \"0xb6edcf3a40e7b1c3c0148f47a263cd819e585a51ef31c2e35a29ce6f04c53e413f743034c0d998d9c00a08ba00166f31\",\n    \"0xabb87ed86098c0c70a76e557262a494ff51a30fb193f1c1a32f8e35eafa34a43fcc07aa93a3b7a077d9e35afa07b1a3d\",\n    \"0xa280214cd3bb0fb7ecd2d8bcf518cbd9078417f2b91d2533ec2717563f090fb84f2a5fcfdbbeb2a2a1f8a71cc5aa5941\",\n    \"0xa63083ca7238ea2b57d15a475963cf1d4f550d8cd76db290014a0461b90351f1f26a67d674c837b0b773b330c7c3d534\",\n    \"0xa8fa39064cb585ece5263e2f42f430206476bf261bd50f18d2b694889bd79d04d56410664cecad62690e5c5a20b3f6ff\",\n    \"0x85ba52ce9d700a5dcf6c5b00559acbe599d671ce5512467ff4b6179d7fad550567ce2a9c126a50964e3096458ea87920\",\n    \"0xb913501e1008f076e5eac6d883105174f88b248e1c9801e568fefaffa1558e4909364fc6d9512aa4d125cbd7cc895f05\",\n    \"0x8eb33b5266c8f2ed4725a6ad147a322e44c9264cf261c933cbbe230a43d47fca0f29ec39756b20561dabafadd5796494\",\n    \"0x850ebc8b661a04318c9db5a0515066e6454fa73865aa4908767a837857ecd717387f614acb614a88e075d4edc53a2f5a\",\n    \"0xa08d6b92d866270f29f4ce23a3f5d99b36b1e241a01271ede02817c8ec3f552a5c562db400766c07b104a331835c0c64\",\n    \"0x8131804c89bb3e74e9718bfc4afa547c1005ff676bd4db9604335032b203390cfa54478d45c6c78d1fe31a436ed4be9f\",\n    \"0x9106d94f23cc1eacec8316f16d6f0a1cc160967c886f51981fdb9f3f12ee1182407d2bb24e5b873de58cb1a3ee915a6b\",\n    \"0xa13806bfc3eae7a7000c9d9f1bd25e10218d4e67f59ae798b145b098bca3edad2b1040e3fc1e6310e612fb8818f459ac\",\n    \"0x8c69fbca502046cb5f6db99900a47b34117aef3f4b241690cdb3b84ca2a2fc7833e149361995dc41fa78892525bce746\",\n    \"0x852c473150c91912d58ecb05769222fa18312800c3f56605ad29eec9e2d8667b0b81c379048d3d29100ed2773bb1f3c5\",\n    \"0xb1767f6074426a00e01095dbb1795beb4e4050c6411792cbad6537bc444c3165d1058bafd1487451f9c5ddd209e0ae7e\",\n    \"0x80c600a5fe99354ce59ff0f84c760923dc8ff66a30bf47dc0a086181785ceb01f9b951c4e66df800ea6d705e8bc47055\",\n    \"0xb5cf19002fbc88a0764865b82afcb4d64a50196ea361e5c71dff7de084f4dcbbc34ec94a45cc9e0247bd51da565981aa\",\n    \"0x93e67a254ea8ce25e112d93cc927fadaa814152a2c4ec7d9a56eaa1ed47aec99b7e9916b02e64452cc724a6641729bbb\",\n    \"0xace70b32491bda18eee4a4d041c3bc9effae9340fe7e6c2f5ad975ee0874c17f1a7da7c96bd85fccff9312c518fac6e9\",\n    \"0xab4cfa02065017dd7f1aadc66f2c92f78f0f11b8597c03a5d69d82cb2eaf95a4476a836ac102908f137662472c8d914b\",\n    \"0xa40b8cd8deb8ae503d20364d64cab7c2801b7728a9646ed19c65edea6a842756a2f636283494299584ad57f4bb12cd0b\",\n    \"0x8594e11d5fc2396bcd9dbf5509ce4816dbb2b7305168021c426171fb444d111da5a152d6835ad8034542277011c26c0e\",\n    \"0x8024de98c26b4c994a66628dc304bb737f4b6859c86ded552c5abb81fd4c6c2e19d5a30beed398a694b9b2fdea1dd06a\",\n    \"0x8843f5872f33f54df8d0e06166c1857d733995f67bc54abb8dfa94ad92407cf0179bc91b0a50bbb56cdc2b350d950329\",\n    \"0xb8bab44c7dd53ef9edf497dcb228e2a41282c90f00ba052fc52d57e87b5c8ab132d227af1fcdff9a12713d1f980bcaae\",\n    \"0x982b4d7b29aff22d527fd82d2a52601d95549bfb000429bb20789ed45e5abf1f4b7416c7b7c4b79431eb3574b29be658\",\n    \"0x8eb1f571b6a1878e11e8c1c757e0bc084bab5e82e897ca9be9b7f4b47b91679a8190bf0fc8f799d9b487da5442415857\",\n    \"0xa6e74b588e5af935c8b243e888582ef7718f8714569dd4992920740227518305eb35fab674d21a5551cca44b3e511ef2\",\n    \"0xa30fc2f3a4cb4f50566e82307de73cd7bd8fe2c1184e9293c136a9b9e926a018d57c6e4f308c95b9eb8299e94d90a2a1\",\n    \"0xa50c5869ca5d2b40722c056a32f918d47e0b65ca9d7863ca7d2fb4a7b64fe523fe9365cf0573733ceaadebf20b48fff8\",\n    \"0x83bbdd32c04d17581418cf360749c7a169b55d54f2427390defd9f751f100897b2d800ce6636c5bbc046c47508d60c8c\",\n    \"0xa82904bdf614de5d8deaff688c8a5e7ac5b3431687acbcda8fa53960b7c417a39c8b2e462d7af91ce6d79260f412db8e\",\n    \"0xa4362e31ff4b05d278b033cf5eebea20de01714ae16d4115d04c1da4754269873afc8171a6f56c5104bfd7b0db93c3e7\",\n    \"0xb5b8daa63a3735581e74a021b684a1038cea77168fdb7fdf83c670c2cfabcfc3ab2fc7359069b5f9048188351aef26b5\",\n    \"0xb48d723894b7782d96ac8433c48faca1bdfa5238019c451a7f47d958097cce3ae599b876cf274269236b9d6ff8b6d7ca\",\n    \"0x98ffff6a61a3a6205c7820a91ca2e7176fab5dba02bc194c4d14942ac421cb254183c705506ab279e4f8db066f941c6c\",\n    \"0xae7db24731da2eaa6efc4f7fcba2ecc26940ddd68038dce43acf2cee15b72dc4ef42a7bfdd32946d1ed78786dd7696b3\",\n    \"0xa656db14f1de9a7eb84f6301b4acb2fbf78bfe867f48a270e416c974ab92821eb4df1cb881b2d600cfed0034ac784641\",\n    \"0xaa315f8ecba85a5535e9a49e558b15f39520fce5d4bf43131bfbf2e2c9dfccc829074f9083e8d49f405fb221d0bc4c3c\",\n    \"0x90bffba5d9ff40a62f6c8e9fc402d5b95f6077ed58d030c93e321b8081b77d6b8dac3f63a92a7ddc01585cf2c127d66c\",\n    \"0xabdd733a36e0e0f05a570d0504e73801bf9b5a25ff2c78786f8b805704997acb2e6069af342538c581144d53149fa6d3\",\n    \"0xb4a723bb19e8c18a01bd449b1bb3440ddb2017f10bb153da27deb7a6a60e9bb37619d6d5435fbb1ba617687838e01dd0\",\n    \"0x870016b4678bab3375516db0187a2108b2e840bae4d264b9f4f27dbbc7cc9cac1d7dc582d7a04d6fd1ed588238e5e513\",\n    \"0x80d33d2e20e8fc170aa3cb4f69fffb72aeafb3b5bb4ea0bc79ab55da14142ca19b2d8b617a6b24d537366e3b49cb67c3\",\n    \"0xa7ee76aec273aaae03b3b87015789289551969fb175c11557da3ab77e39ab49d24634726f92affae9f4d24003050d974\",\n    \"0x8415ea4ab69d779ebd42d0fe0c6aef531d6a465a5739e429b1fcf433ec45aa8296c527e965a20f0ec9f340c9273ea3cf\",\n    \"0x8c7662520794e8b4405d0b33b5cac839784bc86a5868766c06cbc1fa306dbe334978177417b31baf90ce7b0052a29c56\",\n    \"0x902b2abecc053a3dbdea9897ee21e74821f3a1b98b2d560a514a35799f4680322550fd3a728d4f6d64e1de98033c32b8\",\n    \"0xa05e84ed9ecab8d508d670c39f2db61ad6e08d2795ec32a3c9d0d3737ef3801618f4fc2a95f90ec2f068606131e076c5\",\n    \"0x8b9208ff4d5af0c2e3f53c9375da666773ac57197dfabb0d25b1c8d0588ba7f3c15ee9661bb001297f322ea2fbf6928b\",\n    \"0xa3c827741b34a03254d4451b5ab74a96f2b9f7fb069e2f5adaf54fd97cc7a4d516d378db5ca07da87d8566d6eef13726\",\n    \"0x8509d8a3f4a0ed378e0a1e28ea02f6bf1d7f6c819c6c2f5297c7df54c895b848f841653e32ba2a2c22c2ff739571acb8\",\n    \"0xa0ce988b7d3c40b4e496aa83a09e4b5472a2d98679622f32bea23e6d607bc7de1a5374fb162bce0549a67dad948519be\",\n    \"0xaa8a3dd12bd60e3d2e05f9c683cdcb8eab17fc59134815f8d197681b1bcf65108cba63ac5c58ee632b1e5ed6bba5d474\",\n    \"0x8b955f1d894b3aefd883fb4b65f14cd37fc2b9db77db79273f1700bef9973bf3fd123897ea2b7989f50003733f8f7f21\",\n    \"0xac79c00ddac47f5daf8d9418d798d8af89fc6f1682e7e451f71ea3a405b0d36af35388dd2a332af790bc83ca7b819328\",\n    \"0xa0d44dd2a4438b809522b130d0938c3fe7c5c46379365dbd1810a170a9aa5818e1c783470dd5d0b6d4ac7edbb7330910\",\n    \"0xa30b69e39ad43dd540a43c521f05b51b5f1b9c4eed54b8162374ae11eac25da4f5756e7b70ce9f3c92c2eeceee7431ed\",\n    \"0xac43220b762c299c7951222ea19761ab938bf38e4972deef58ed84f4f9c68c230647cf7506d7cbfc08562fcca55f0485\",\n    \"0xb28233b46a8fb424cfa386a845a3b5399d8489ceb83c8f3e05c22c934798d639c93718b7b68ab3ce24c5358339e41cbb\",\n    \"0xac30d50ee8ce59a10d4b37a3a35e62cdb2273e5e52232e202ca7d7b8d09d28958ee667fae41a7bb6cdc6fe8f6e6c9c85\",\n    \"0xb199842d9141ad169f35cc7ff782b274cbaa645fdb727761e0a89edbf0d781a15f8218b4bf4eead326f2903dd88a9cc1\",\n    \"0x85e018c7ddcad34bb8285a737c578bf741ccd547e68c734bdb3808380e12c5d4ef60fc896b497a87d443ff9abd063b38\",\n    \"0x8c856e6ba4a815bdb891e1276f93545b7072f6cb1a9aa6aa5cf240976f29f4dee01878638500a6bf1daf677b96b54343\",\n    \"0xb8a47555fa8710534150e1a3f13eab33666017be6b41005397afa647ea49708565f2b86b77ad4964d140d9ced6b4d585\",\n    \"0x8cd1f1db1b2f4c85a3f46211599caf512d5439e2d8e184663d7d50166fd3008f0e9253272f898d81007988435f715881\",\n    \"0xb1f34b14612c973a3eceb716dc102b82ab18afef9de7630172c2780776679a7706a4874e1df3eaadf541fb009731807f\",\n    \"0xb25464af9cff883b55be2ff8daf610052c02df9a5e147a2cf4df6ce63edcdee6dc535c533590084cc177da85c5dc0baa\",\n    \"0x91c3c4b658b42d8d3448ae1415d4541d02379a40dc51e36a59bd6e7b9ba3ea51533f480c7c6e8405250ee9b96a466c29\",\n    \"0x86dc027b95deb74c36a58a1333a03e63cb5ae22d3b29d114cfd2271badb05268c9d0c819a977f5e0c6014b00c1512e3a\",\n    \"0xae0e6ff58eb5fa35da5107ebeacf222ab8f52a22bb1e13504247c1dfa65320f40d97b0e6b201cb6613476687cb2f0681\",\n    \"0x8f13415d960b9d7a1d93ef28afc2223e926639b63bdefce0f85e945dfc81670a55df288893a0d8b3abe13c5708f82f91\",\n    \"0x956f67ca49ad27c1e3a68c1faad5e7baf0160c459094bf6b7baf36b112de935fdfd79fa4a9ea87ea8de0ac07272969f4\",\n    \"0x835e45e4a67df9fb51b645d37840b3a15c171d571a10b03a406dd69d3c2f22df3aa9c5cbe1e73f8d767ce01c4914ea9a\",\n    \"0x919b938e56d4b32e2667469d0bdccb95d9dda3341aa907683ee70a14bbbe623035014511c261f4f59b318b610ac90aa3\",\n    \"0x96b48182121ccd9d689bf1dfdc228175564cd68dc904a99c808a7f0053a6f636c9d953e12198bdf2ea49ea92772f2e18\",\n    \"0xac5e5a941d567fa38fdbcfa8cf7f85bb304e3401c52d88752bcd516d1fa9bac4572534ea2205e38423c1df065990790f\",\n    \"0xac0bd594fb85a8d4fc26d6df0fa81f11919401f1ecf9168b891ec7f061a2d9368af99f7fd8d9b43b2ce361e7b8482159\",\n    \"0x83d92c69ca540d298fe80d8162a1c7af3fa9b49dfb69e85c1d136a3ec39fe419c9fa78e0bb6d96878771fbd37fe92e40\",\n    \"0xb35443ae8aa66c763c2db9273f908552fe458e96696b90e41dd509c17a5c04ee178e3490d9c6ba2dc0b8f793c433c134\",\n    \"0x923b2d25aa45b2e580ffd94cbb37dc8110f340f0f011217ee1bd81afb0714c0b1d5fb4db86006cdd2457563276f59c59\",\n    \"0x96c9125d38fca1a61ac21257b696f8ac3dae78def50285e44d90ea293d591d1c58f703540a7e4e99e070afe4646bbe15\",\n    \"0xb57946b2332077fbcdcb406b811779aefd54473b5559a163cd65cb8310679b7e2028aa55c12a1401fdcfcac0e6fae29a\",\n    \"0x845daedc5cf972883835d7e13c937b63753c2200324a3b8082a6c4abb4be06c5f7c629d4abe4bfaf1d80a1f073eb6ce6\",\n    \"0x91a55dfd0efefcd03dc6dacc64ec93b8d296cb83c0ee72400a36f27246e7f2a60e73b7b70ba65819e9cfb73edb7bd297\",\n    \"0x8874606b93266455fe8fdd25df9f8d2994e927460af06f2e97dd4d2d90db1e6b06d441b72c2e76504d753badca87fb37\",\n    \"0x8ee99e6d231274ff9252c0f4e84549da173041299ad1230929c3e3d32399731c4f20a502b4a307642cac9306ccd49d3c\",\n    \"0x8836497714a525118e20849d6933bb8535fb6f72b96337d49e3133d936999c90a398a740f42e772353b5f1c63581df6d\",\n    \"0xa6916945e10628f7497a6cdc5e2de113d25f7ade3e41e74d3de48ccd4fce9f2fa9ab69645275002e6f49399b798c40af\",\n    \"0x9597706983107eb23883e0812e1a2c58af7f3499d50c6e29b455946cb9812fde1aa323d9ed30d1c0ffd455abe32303cd\",\n    \"0xa24ee89f7f515cc33bdbdb822e7d5c1877d337f3b2162303cfc2dae028011c3a267c5cb4194afa63a4856a6e1c213448\",\n    \"0x8cd25315e4318801c2776824ae6e7d543cb85ed3bc2498ba5752df2e8142b37653cf9e60104d674be3aeb0a66912e97a\",\n    \"0xb5085ecbe793180b40dbeb879f4c976eaaccaca3a5246807dced5890e0ed24d35f3f86955e2460e14fb44ff5081c07ba\",\n    \"0x960188cc0b4f908633a6840963a6fa2205fc42c511c6c309685234911c5304ef4c304e3ae9c9c69daa2fb6a73560c256\",\n    \"0xa32d0a70bf15d569b4cda5aebe3e41e03c28bf99cdd34ffa6c5d58a097f322772acca904b3a47addb6c7492a7126ebac\",\n    \"0x977f72d06ad72d4aa4765e0f1f9f4a3231d9f030501f320fe7714cc5d329d08112789fa918c60dd7fdb5837d56bb7fc6\",\n    \"0x99fa038bb0470d45852bb871620d8d88520adb701712fcb1f278fed2882722b9e729e6cdce44c82caafad95e37d0e6f7\",\n    \"0xb855e8f4fc7634ada07e83b6c719a1e37acb06394bc8c7dcab7747a8c54e5df3943915f021364bd019fdea103864e55f\",\n    \"0x88bc2cd7458532e98c596ef59ea2cf640d7cc31b4c33cef9ed065c078d1d4eb49677a67de8e6229cc17ea48bace8ee5a\",\n    \"0xaaa78a3feaa836d944d987d813f9b9741afb076e6aca1ffa42682ab06d46d66e0c07b8f40b9dbd63e75e81efa1ef7b08\",\n    \"0xb7b080420cc4d808723b98b2a5b7b59c81e624ab568ecdfdeb8bf3aa151a581b6f56e983ef1b6f909661e25db40b0c69\",\n    \"0xabee85c462ac9a2c58e54f06c91b3e5cd8c5f9ab5b5deb602b53763c54826ed6deb0d6db315a8d7ad88733407e8d35e2\",\n    \"0x994d075c1527407547590df53e9d72dd31f037c763848d1662eebd4cefec93a24328c986802efa80e038cb760a5300f5\",\n    \"0xab8777640116dfb6678e8c7d5b36d01265dfb16321abbfc277da71556a34bb3be04bc4ae90124ed9c55386d2bfb3bda0\",\n    \"0x967e3a828bc59409144463bcf883a3a276b5f24bf3cbfdd7a42343348cba91e00b46ac285835a9b91eef171202974204\",\n    \"0x875a9f0c4ffe5bb1d8da5e3c8e41d0397aa6248422a628bd60bfae536a651417d4e8a7d2fb98e13f2dad3680f7bd86d3\",\n    \"0xacaa330c3e8f95d46b1880126572b238dbb6d04484d2cd4f257ab9642d8c9fc7b212188b9c7ac9e0fd135c520d46b1bf\",\n    \"0xaceb762edbb0f0c43dfcdb01ea7a1ac5918ca3882b1e7ebc4373521742f1ed5250d8966b498c00b2b0f4d13212e6dd0b\",\n    \"0x81d072b4ad258b3646f52f399bced97c613b22e7ad76373453d80b1650c0ca87edb291a041f8253b649b6e5429bb4cff\",\n    \"0x980a47d27416ac39c7c3a0ebe50c492f8c776ea1de44d5159ac7d889b6d554357f0a77f0e5d9d0ff41aae4369eba1fc2\",\n    \"0x8b4dfd5ef5573db1476d5e43aacfb5941e45d6297794508f29c454fe50ea622e6f068b28b3debe8635cf6036007de2e3\",\n    \"0xa60831559d6305839515b68f8c3bc7abbd8212cc4083502e19dd682d56ca37c9780fc3ce4ec2eae81ab23b221452dc57\",\n    \"0x951f6b2c1848ced9e8a2339c65918e00d3d22d3e59a0a660b1eca667d18f8430d737884e9805865ef3ed0fe1638a22d9\",\n    \"0xb02e38fe790b492aa5e89257c4986c9033a8b67010fa2add9787de857d53759170fdd67715ca658220b4e14b0ca48124\",\n    \"0xa51007e4346060746e6b0e4797fc08ef17f04a34fe24f307f6b6817edbb8ce2b176f40771d4ae8a60d6152cbebe62653\",\n    \"0xa510005b05c0b305075b27b243c9d64bcdce85146b6ed0e75a3178b5ff9608213f08c8c9246f2ca6035a0c3e31619860\",\n    \"0xaaff4ef27a7a23be3419d22197e13676d6e3810ceb06a9e920d38125745dc68a930f1741c9c2d9d5c875968e30f34ab5\",\n    \"0x864522a9af9857de9814e61383bebad1ba9a881696925a0ea6bfc6eff520d42c506bbe5685a9946ed710e889765be4a0\",\n    \"0xb63258c080d13f3b7d5b9f3ca9929f8982a6960bdb1b0f8676f4dca823971601672f15e653917bf5d3746bb220504913\",\n    \"0xb51ce0cb10869121ae310c7159ee1f3e3a9f8ad498827f72c3d56864808c1f21fa2881788f19ece884d3f705cd7bd0c5\",\n    \"0x95d9cecfc018c6ed510e441cf84c712d9909c778c16734706c93222257f64dcd2a9f1bd0b400ca271e22c9c487014274\",\n    \"0x8beff4d7d0140b86380ff4842a9bda94c2d2be638e20ac68a4912cb47dbe01a261857536375208040c0554929ced1ddc\",\n    \"0x891ff49258749e2b57c1e9b8e04b12c77d79c3308b1fb615a081f2aacdfb4b39e32d53e069ed136fdbd43c53b87418fa\",\n    \"0x9625cad224e163d387738825982d1e40eeff35fe816d10d7541d15fdc4d3eee48009090f3faef4024b249205b0b28f72\",\n    \"0x8f3947433d9bd01aa335895484b540a9025a19481a1c40b4f72dd676bfcf332713714fd4010bde936eaf9470fd239ed0\",\n    \"0xa00ec2d67789a7054b53f0e858a8a232706ccc29a9f3e389df7455f1a51a2e75801fd78469a13dbc25d28399ae4c6182\",\n    \"0xa3f65884506d4a62b8775a0ea0e3d78f5f46bc07910a93cd604022154eabdf1d73591e304d61edc869e91462951975e1\",\n    \"0xa14eef4fd5dfac311713f0faa9a60415e3d30b95a4590cbf95f2033dffb4d16c02e7ceff3dcd42148a4e3bc49cce2dd4\",\n    \"0x8afa11c0eef3c540e1e3460bc759bb2b6ea90743623f88e62950c94e370fe4fd01c22b6729beba4dcd4d581198d9358f\",\n    \"0xafb05548a69f0845ffcc5f5dc63e3cdb93cd270f5655173b9a950394b0583663f2b7164ba6df8d60c2e775c1d9f120af\",\n    \"0x97f179e01a947a906e1cbeafa083960bc9f1bade45742a3afee488dfb6011c1c6e2db09a355d77f5228a42ccaa7bdf8e\",\n    \"0x8447fca4d35f74b3efcbd96774f41874ca376bf85b79b6e66c92fa3f14bdd6e743a051f12a7fbfd87f319d1c6a5ce217\",\n    \"0xa57ca39c23617cd2cf32ff93b02161bd7baf52c4effb4679d9d5166406e103bc8f3c6b5209e17c37dbb02deb8bc72ddd\",\n    \"0x9667c7300ff80f0140be002b0e36caab07aaee7cce72679197c64d355e20d96196acaf54e06e1382167d081fe6f739c1\",\n    \"0x828126bb0559ce748809b622677267ca896fa2ee76360fd2c02990e6477e06a667241379ca7e65d61a5b64b96d7867de\",\n    \"0x8b8835dea6ba8cf61c91f01a4b3d2f8150b687a4ee09b45f2e5fc8f80f208ae5d142d8e3a18153f0722b90214e60c5a7\",\n    \"0xa98e8ff02049b4da386e3ee93db23bbb13dfeb72f1cfde72587c7e6d962780b7671c63e8ac3fbaeb1a6605e8d79e2f29\",\n    \"0x87a4892a0026d7e39ef3af632172b88337cb03669dea564bcdb70653b52d744730ebb5d642e20cb627acc9dbb547a26b\",\n    \"0x877352a22fc8052878a57effc159dac4d75fe08c84d3d5324c0bab6d564cdf868f33ceee515eee747e5856b62cfa0cc7\",\n    \"0x8b801ba8e2ff019ee62f64b8cb8a5f601fc35423eb0f9494b401050103e1307dc584e4e4b21249cd2c686e32475e96c3\",\n    \"0xa9e7338d6d4d9bfec91b2af28a8ed13b09415f57a3a00e5e777c93d768fdb3f8e4456ae48a2c6626b264226e911a0e28\",\n    \"0x99c05fedf40ac4726ed585d7c1544c6e79619a0d3fb6bda75a08c7f3c0008e8d5e19ed4da48de3216135f34a15eba17c\",\n    \"0xa61cce8a1a8b13a4a650fdbec0eeea8297c352a8238fb7cac95a0df18ed16ee02a3daa2de108fa122aca733bd8ad7855\",\n    \"0xb97f37da9005b440b4cb05870dd881bf8491fe735844f2d5c8281818583b38e02286e653d9f2e7fa5e74c3c3eb616540\",\n    \"0xa72164a8554da8e103f692ac5ebb4aece55d5194302b9f74b6f2a05335b6e39beede0bf7bf8c5bfd4d324a784c5fb08c\",\n    \"0xb87e8221c5341cd9cc8bb99c10fe730bc105550f25ed4b96c0d45e6142193a1b2e72f1b3857373a659b8c09be17b3d91\",\n    \"0xa41fb1f327ef91dcb7ac0787918376584890dd9a9675c297c45796e32d6e5985b12f9b80be47fc3a8596c245f419d395\",\n    \"0x90dafa3592bdbb3465c92e2a54c2531822ba0459d45d3e7a7092fa6b823f55af28357cb51896d4ec2d66029c82f08e26\",\n    \"0xa0a9adc872ebc396557f484f1dd21954d4f4a21c4aa5eec543f5fa386fe590839735c01f236574f7ff95407cd12de103\",\n    \"0xb8c5c940d58be7538acf8672852b5da3af34f82405ef2ce8e4c923f1362f97fc50921568d0fd2fe846edfb0823e62979\",\n    \"0x85aaf06a8b2d0dac89dafd00c28533f35dbd074978c2aaa5bef75db44a7b12aeb222e724f395513b9a535809a275e30b\",\n    \"0x81f3cbe82fbc7028c26a6c1808c604c63ba023a30c9f78a4c581340008dbda5ec07497ee849a2183fcd9124f7936af32\",\n    \"0xa11ac738de75fd60f15a34209d3825d5e23385796a4c7fc5931822f3f380af977dd0f7b59fbd58eed7777a071e21b680\",\n    \"0x85a279c493de03db6fa6c3e3c1b1b29adc9a8c4effc12400ae1128da8421954fa8b75ad19e5388fe4543b76fb0812813\",\n    \"0x83a217b395d59ab20db6c4adb1e9713fc9267f5f31a6c936042fe051ce8b541f579442f3dcf0fa16b9e6de9fd3518191\",\n    \"0x83a0b86e7d4ed8f9ccdc6dfc8ff1484509a6378fa6f09ed908e6ab9d1073f03011dc497e14304e4e3d181b57de06a5ab\",\n    \"0xa63ad69c9d25704ce1cc8e74f67818e5ed985f8f851afa8412248b2df5f833f83b95b27180e9e7273833ed0d07113d3b\",\n    \"0x99b1bc2021e63b561fe44ddd0af81fcc8627a91bfeecbbc989b642bc859abc0c8d636399701aad7bbaf6a385d5f27d61\",\n    \"0xb53434adb66f4a807a6ad917c6e856321753e559b1add70824e5c1e88191bf6993fccb9b8b911fc0f473fb11743acacd\",\n    \"0x97ed3b9e6fb99bf5f945d4a41f198161294866aa23f2327818cdd55cb5dc4c1a8eff29dd8b8d04902d6cd43a71835c82\",\n    \"0xb1e808260e368a18d9d10bdea5d60223ba1713b948c782285a27a99ae50cc5fc2c53d407de07155ecc16fb8a36d744a0\",\n    \"0xa3eb4665f18f71833fec43802730e56b3ee5a357ea30a888ad482725b169d6f1f6ade6e208ee081b2e2633079b82ba7d\",\n    \"0xab8beb2c8353fc9f571c18fdd02bdb977fc883313469e1277b0372fbbb33b80dcff354ca41de436d98d2ed710faa467e\",\n    \"0xaa9071cfa971e4a335a91ad634c98f2be51544cb21f040f2471d01bb97e1df2277ae1646e1ea8f55b7ba9f5c8c599b39\",\n    \"0x80b7dbfdcaf40f0678012acc634eba44ea51181475180d9deb2050dc4f2de395289edd0223018c81057ec79b04b04c49\",\n    \"0x89623d7f6cb17aa877af14de842c2d4ab7fd576d61ddd7518b5878620a01ded40b6010de0da3cdf31d837eecf30e9847\",\n    \"0xa773bb024ae74dd24761f266d4fb27d6fd366a8634febe8235376b1ae9065c2fe12c769f1d0407867dfbe9f5272c352f\",\n    \"0x8455a561c3aaa6ba64c881a5e13921c592b3a02e968f4fb24a2243c36202795d0366d9cc1a24e916f84d6e158b7aeac7\",\n    \"0x81d8bfc4b283cf702a40b87a2b96b275bdbf0def17e67d04842598610b67ea08c804d400c3e69fa09ea001eaf345b276\",\n    \"0xb8f8f82cb11fea1c99467013d7e167ff03deb0c65a677fab76ded58826d1ba29aa7cf9fcd7763615735ea3ad38e28719\",\n    \"0x89a6a04baf9cccc1db55179e1650b1a195dd91fb0aebc197a25143f0f393524d2589975e3fbfc2547126f0bced7fd6f2\",\n    \"0xb81b2162df045390f04df07cbd0962e6b6ca94275a63edded58001a2f28b2ae2af2c7a6cba4ecd753869684e77e7e799\",\n    \"0xa3757f722776e50de45c62d9c4a2ee0f5655a512344c4cbec542d8045332806568dd626a719ef21a4eb06792ca70f204\",\n    \"0x8c5590df96ec22179a4e8786de41beb44f987a1dcc508eb341eecbc0b39236fdfad47f108f852e87179ccf4e10091e59\",\n    \"0x87502f026ed4e10167419130b88c3737635c5b9074c364e1dd247cef5ef0fc064b4ae99b187e33301e438bbd2fe7d032\",\n    \"0xaf925a2165e980ced620ff12289129fe17670a90ae0f4db9d4b39bd887ccb1f5d2514ac9ecf910f6390a8fc66bd5be17\",\n    \"0x857fca899828cf5c65d26e3e8a6e658542782fc72762b3b9c73514919f83259e0f849a9d4838b40dc905fe43024d0d23\",\n    \"0x87ffebdbfb69a9e1007ebac4ffcb4090ff13705967b73937063719aa97908986effcb7262fdadc1ae0f95c3690e3245d\",\n    \"0xa9ff6c347ac6f4c6ab993b748802e96982eaf489dc69032269568412fc9a79e7c2850dfc991b28211b3522ee4454344b\",\n    \"0xa65b3159df4ec48bebb67cb3663cd744027ad98d970d620e05bf6c48f230fa45bf17527fe726fdf705419bb7a1bb913e\",\n    \"0x84b97b1e6408b6791831997b03cd91f027e7660fd492a93d95daafe61f02427371c0e237c75706412f442991dfdff989\",\n    \"0xab761c26527439b209af0ae6afccd9340bbed5fbe098734c3145b76c5d2cd7115d9227b2eb523882b7317fbb09180498\",\n    \"0xa0479a8da06d7a69c0b0fee60df4e691c19c551f5e7da286dab430bfbcabf31726508e20d26ea48c53365a7f00a3ad34\",\n    \"0xa732dfc9baa0f4f40b5756d2e8d8937742999623477458e0bc81431a7b633eefc6f53b3b7939fe0a020018549c954054\",\n    \"0x901502436a1169ba51dc479a5abe7c8d84e0943b16bc3c6a627b49b92cd46263c0005bc324c67509edd693f28e612af1\",\n    \"0xb627aee83474e7f84d1bab9b7f6b605e33b26297ac6bbf52d110d38ba10749032bd551641e73a383a303882367af429b\",\n    \"0x95108866745760baef4a46ef56f82da6de7e81c58b10126ebd2ba2cd13d339f91303bf2fb4dd104a6956aa3b13739503\",\n    \"0x899ed2ade37236cec90056f3569bc50f984f2247792defafcceb49ad0ca5f6f8a2f06573705300e07f0de0c759289ff5\",\n    \"0xa9f5eee196d608efe4bcef9bf71c646d27feb615e21252cf839a44a49fd89da8d26a758419e0085a05b1d59600e2dc42\",\n    \"0xb36c6f68fed6e6c85f1f4a162485f24817f2843ec5cbee45a1ebfa367d44892e464949c6669f7972dc7167af08d55d25\",\n    \"0xaaaede243a9a1b6162afbc8f571a52671a5a4519b4062e3f26777664e245ba873ed13b0492c5dbf0258c788c397a0e9e\",\n    \"0x972b4fb39c31cbe127bf9a32a5cc10d621ebdd9411df5e5da3d457f03b2ab2cd1f6372d8284a4a9400f0b06ecdbfd38e\",\n    \"0x8f6ca1e110e959a4b1d9a5ce5f212893cec21db40d64d5ac4d524f352d72198f923416a850bf845bc5a22a79c0ea2619\",\n    \"0xa0f3c93b22134f66f04b2553a53b738644d1665ceb196b8494b315a4c28236fb492017e4a0de4224827c78e42f9908b7\",\n    \"0x807fb5ee74f6c8735b0b5ca07e28506214fe4047dbeb00045d7c24f7849e98706aea79771241224939cb749cf1366c7d\",\n    \"0x915eb1ff034224c0b645442cdb7d669303fdc00ca464f91aaf0b6fde0b220a3a74ff0cb043c26c9f3a5667b3fdaa9420\",\n    \"0x8fda6cef56ed33fefffa9e6ac8e6f76b1af379f89761945c63dd448801f7bb8ca970504a7105fac2f74f652ccff32327\",\n    \"0x87380cffdcffb1d0820fa36b63cc081e72187f86d487315177d4d04da4533eb19a0e2ff6115ceab528887819c44a5164\",\n    \"0x8cd89e03411a18e7f16f968b89fb500c36d47d229f6487b99e62403a980058db5925ce249206743333538adfad168330\",\n    \"0x974451b1df33522ce7056de9f03e10c70bf302c44b0741a59df3d6877d53d61a7394dcee1dd46e013d7cb9d73419c092\",\n    \"0x98c35ddf645940260c490f384a49496a7352bb8e3f686feed815b1d38f59ded17b1ad6e84a209e773ed08f7b8ff1e4c2\",\n    \"0x963f386cf944bb9b2ddebb97171b64253ea0a2894ac40049bdd86cda392292315f3a3d490ca5d9628c890cfb669f0acb\",\n    \"0x8d507712152babd6d142ee682638da8495a6f3838136088df9424ef50d5ec28d815a198c9a4963610b22e49b4cdf95e9\",\n    \"0x83d4bc6b0be87c8a4f1e9c53f257719de0c73d85b490a41f7420e777311640937320557ff2f1d9bafd1daaa54f932356\",\n    \"0x82f5381c965b7a0718441131c4d13999f4cdce637698989a17ed97c8ea2e5bdb5d07719c5f7be8688edb081b23ede0f4\",\n    \"0xa6ebecab0b72a49dfd01d69fa37a7f74d34fb1d4fef0aa10e3d6fceb9eccd671225c230af89f6eb514250e41a5f91f52\",\n    \"0x846d185bdad6e11e604df7f753b7a08a28b643674221f0e750ebdb6b86ec584a29c869e131bca868972a507e61403f6a\",\n    \"0x85a98332292acb744bd1c0fd6fdcf1f889a78a2c9624d79413ffa194cc8dfa7821a4b60cde8081d4b5f71f51168dd67f\",\n    \"0x8f7d97c3b4597880d73200d074eb813d95432306e82dafc70b580b8e08cb8098b70f2d07b4b3ac6a4d77e92d57035031\",\n    \"0x8185439c8751e595825d7053518cbe121f191846a38d4dbcb558c3f9d7a3104f3153401adaaaf27843bbe2edb504bfe3\",\n    \"0xb3c00d8ece1518fca6b1215a139b0a0e26d9cba1b3a424f7ee59f30ce800a5db967279ed60958dd1f3ee69cf4dd1b204\",\n    \"0xa2e6cb6978e883f9719c3c0d44cfe8de0cc6f644b98f98858433bea8bbe7b612c8aca5952fccce4f195f9d54f9722dc2\",\n    \"0x99663087e3d5000abbec0fbda4e7342ec38846cc6a1505191fb3f1a337cb369455b7f8531a6eb8b0f7b2c4baf83cbe2b\",\n    \"0xab0836c6377a4dbc7ca6a4d6cf021d4cd60013877314dd05f351706b128d4af6337711ed3443cb6ca976f40d74070a9a\",\n    \"0x87abfd5126152fd3bac3c56230579b489436755ea89e0566aa349490b36a5d7b85028e9fb0710907042bcde6a6f5d7e3\",\n    \"0x974ba1033f75f60e0cf7c718a57ae1da3721cf9d0fb925714c46f027632bdd84cd9e6de4cf4d00bc55465b1c5ebb7384\",\n    \"0xa607b49d73689ac64f25cec71221d30d53e781e1100d19a2114a21da6507a60166166369d860bd314acb226596525670\",\n    \"0xa7c2b0b915d7beba94954f2aa7dd08ec075813661e2a3ecca5d28a0733e59583247fed9528eb28aba55b972cdbaf06eb\",\n    \"0xb8b3123e44128cc8efbe3270f2f94e50ca214a4294c71c3b851f8cbb70cb67fe9536cf07d04bf7fe380e5e3a29dd3c15\",\n    \"0xa59a07e343b62ad6445a0859a32b58c21a593f9ddbfe52049650f59628c93715aa1f4e1f45b109321756d0eeec8a5429\",\n    \"0x94f51f8a4ed18a6030d0aaa8899056744bd0e9dc9ac68f62b00355cddab11da5da16798db75f0bfbce0e5bdfe750c0b6\",\n    \"0x97460a97ca1e1fa5ce243b81425edc0ec19b7448e93f0b55bc9785eedeeafe194a3c8b33a61a5c72990edf375f122777\",\n    \"0x8fa859a089bc17d698a7ee381f37ce9beadf4e5b44fce5f6f29762bc04f96faff5d58c48c73631290325f05e9a1ecf49\",\n    \"0xabdf38f3b20fc95eff31de5aa9ef1031abfa48f1305ee57e4d507594570401503476d3bcc493838fc24d6967a3082c7f\",\n    \"0xb8914bfb82815abb86da35c64d39ab838581bc0bf08967192697d9663877825f2b9d6fbdcf9b410463482b3731361aef\",\n    \"0xa8187f9d22b193a5f578999954d6ec9aa9b32338ccadb8a3e1ce5bad5ea361d69016e1cdfac44e9d6c54e49dd88561b9\",\n    \"0xaac262cb7cba7fd62c14daa7b39677cabc1ef0947dd06dd89cac8570006a200f90d5f0353e84f5ff03179e3bebe14231\",\n    \"0xa630ef5ece9733b8c46c0a2df14a0f37647a85e69c63148e79ffdcc145707053f9f9d305c3f1cf3c7915cb46d33abd07\",\n    \"0xb102c237cb2e254588b6d53350dfda6901bd99493a3fbddb4121d45e0b475cf2663a40d7b9a75325eda83e4ba1e68cb3\",\n    \"0x86a930dd1ddcc16d1dfa00aa292cb6c2607d42c367e470aa920964b7c17ab6232a7108d1c2c11fc40fb7496547d0bbf8\",\n    \"0xa832fdc4500683e72a96cce61e62ac9ee812c37fe03527ad4cf893915ca1962cee80e72d4f82b20c8fc0b764376635a1\",\n    \"0x88ad985f448dabb04f8808efd90f273f11f5e6d0468b5489a1a6a3d77de342992a73eb842d419034968d733f101ff683\",\n    \"0x98a8538145f0d86f7fbf9a81c9140f6095c5bdd8960b1c6f3a1716428cd9cca1bf8322e6d0af24e6169abcf7df2b0ff6\",\n    \"0x9048c6eba5e062519011e177e955a200b2c00b3a0b8615bdecdebc217559d41058d3315f6d05617be531ef0f6aef0e51\",\n    \"0x833bf225ab6fc68cdcacf1ec1b50f9d05f5410e6cdcd8d56a3081dc2be8a8d07b81534d1ec93a25c2e270313dfb99e3b\",\n    \"0xa84bcd24c3da5e537e64a811b93c91bfc84d7729b9ead7f79078989a6eb76717d620c1fad17466a0519208651e92f5ff\",\n    \"0xb7cdd0a3fbd79aed93e1b5a44ca44a94e7af5ed911e4492f332e3a5ed146c7286bde01b52276a2fcc02780d2109874dd\",\n    \"0x8a19a09854e627cb95750d83c20c67442b66b35896a476358f993ba9ac114d32c59c1b3d0b8787ee3224cf3888b56c64\",\n    \"0xa9abd5afb8659ee52ada8fa5d57e7dd355f0a7350276f6160bec5fbf70d5f99234dd179eb221c913e22a49ec6d267846\",\n    \"0x8c13c4274c0d30d184e73eaf812200094bbbd57293780bdadbceb262e34dee5b453991e7f37c7333a654fc71c69d6445\",\n    \"0xa4320d73296ff8176ce0127ca1921c450e2a9c06eff936681ebaffb5a0b05b17fded24e548454de89aca2dcf6d7a9de4\",\n    \"0xb2b8b3e15c1f645f07783e5628aba614e60157889db41d8161d977606788842b67f83f361eae91815dc0abd84e09abd5\",\n    \"0xad26c3aa35ddfddc15719b8bb6c264aaec7065e88ac29ba820eb61f220fef451609a7bb037f3722d022e6c86e4f1dc88\",\n    \"0xb8615bf43e13ae5d7b8dd903ce37190800cd490f441c09b22aa29d7a29ed2c0417b7a08ead417868f1de2589deaadd80\",\n    \"0x8d3425e1482cd1e76750a76239d33c06b3554c3c3c87c15cb7ab58b1cee86a4c5c4178b44e23f36928365a1b484bde02\",\n    \"0x806893a62e38c941a7dd6f249c83af16596f69877cc737d8f73f6b8cd93cbc01177a7a276b2b8c6b0e5f2ad864db5994\",\n    \"0x86618f17fa4b0d65496b661bbb5ba3bc3a87129d30a4b7d4f515b904f4206ca5253a41f49fd52095861e5e065ec54f21\",\n    \"0x9551915da1304051e55717f4c31db761dcdcf3a1366c89a4af800a9e99aca93a357bf928307f098e62b44a02cb689a46\",\n    \"0x8f79c4ec0ec1146cb2a523b52fe33def90d7b5652a0cb9c2d1c8808a32293e00aec6969f5b1538e3a94cd1efa3937f86\",\n    \"0xa0c03e329a707300081780f1e310671315b4c6a4cedcb29697aedfabb07a9d5df83f27b20e9c44cf6b16e39d9ded5b98\",\n    \"0x86a7cfa7c8e7ce2c01dd0baec2139e97e8e090ad4e7b5f51518f83d564765003c65968f85481bbb97cb18f005ccc7d9f\",\n    \"0xa33811770c6dfda3f7f74e6ad0107a187fe622d61b444bbd84fd7ef6e03302e693b093df76f6ab39bb4e02afd84a575a\",\n    \"0x85480f5c10d4162a8e6702b5e04f801874d572a62a130be94b0c02b58c3c59bdcd48cd05f0a1c2839f88f06b6e3cd337\",\n    \"0x8e181011564b17f7d787fe0e7f3c87f6b62da9083c54c74fd6c357a1f464c123c1d3d8ade3cf72475000b464b14e2be3\",\n    \"0x8ee178937294b8c991337e0621ab37e9ffa4ca2bdb3284065c5e9c08aad6785d50cf156270ff9daf9a9127289710f55b\",\n    \"0x8bd1e8e2d37379d4b172f1aec96f2e41a6e1393158d7a3dbd9a95c8dd4f8e0b05336a42efc11a732e5f22b47fc5c271d\",\n    \"0x8f3da353cd487c13136a85677de8cedf306faae0edec733cf4f0046f82fa4639db4745b0095ff33a9766aba50de0cbcf\",\n    \"0x8d187c1e97638df0e4792b78e8c23967dac43d98ea268ca4aabea4e0fa06cb93183fd92d4c9df74118d7cc27bf54415e\",\n    \"0xa4c992f08c2f8bac0b74b3702fb0c75c9838d2ce90b28812019553d47613c14d8ce514d15443159d700b218c5a312c49\",\n    \"0xa6fd1874034a34c3ea962a316c018d9493d2b3719bb0ec4edbc7c56b240802b2228ab49bee6f04c8a3e9f6f24a48c1c2\",\n    \"0xb2efed8e799f8a15999020900dc2c58ece5a3641c90811b86a5198e593d7318b9d53b167818ccdfbe7df2414c9c34011\",\n    \"0x995ff7de6181ddf95e3ead746089c6148da3508e4e7a2323c81785718b754d356789b902e7e78e2edc6b0cbd4ff22c78\",\n    \"0x944073d24750a9068cbd020b834afc72d2dde87efac04482b3287b40678ad07588519a4176b10f2172a2c463d063a5cd\",\n    \"0x99db4b1bb76475a6fd75289986ef40367960279524378cc917525fb6ba02a145a218c1e9caeb99332332ab486a125ac0\",\n    \"0x89fce4ecd420f8e477af4353b16faabb39e063f3f3c98fde2858b1f2d1ef6eed46f0975a7c08f233b97899bf60ccd60a\",\n    \"0x8c09a4f07a02b80654798bc63aada39fd638d3e3c4236ccd8a5ca280350c31e4a89e5f4c9aafb34116e71da18c1226b8\",\n    \"0x85325cfa7ded346cc51a2894257eab56e7488dbff504f10f99f4cd2b630d913003761a50f175ed167e8073f1b6b63fb0\",\n    \"0xb678b4fbec09a8cc794dcbca185f133578f29e354e99c05f6d07ac323be20aecb11f781d12898168e86f2e0f09aca15e\",\n    \"0xa249cfcbca4d9ba0a13b5f6aac72bf9b899adf582f9746bb2ad043742b28915607467eb794fca3704278f9136f7642be\",\n    \"0x9438e036c836a990c5e17af3d78367a75b23c37f807228362b4d13e3ddcb9e431348a7b552d09d11a2e9680704a4514f\",\n    \"0x925ab70450af28c21a488bfb5d38ac994f784cf249d7fd9ad251bb7fd897a23e23d2528308c03415074d43330dc37ef4\",\n    \"0xa290563904d5a8c0058fc8330120365bdd2ba1fdbaef7a14bc65d4961bb4217acfaed11ab82669e359531f8bf589b8db\",\n    \"0xa7e07a7801b871fc9b981a71e195a3b4ba6b6313bc132b04796a125157e78fe5c11a3a46cf731a255ac2d78a4ae78cd0\",\n    \"0xb26cd2501ee72718b0eebab6fb24d955a71f363f36e0f6dff0ab1d2d7836dab88474c0cef43a2cc32701fca7e82f7df3\",\n    \"0xa1dc3b6c968f3de00f11275092290afab65b2200afbcfa8ddc70e751fa19dbbc300445d6d479a81bda3880729007e496\",\n    \"0xa9bc213e28b630889476a095947d323b9ac6461dea726f2dc9084473ae8e196d66fb792a21905ad4ec52a6d757863e7d\",\n    \"0xb25d178df8c2df8051e7c888e9fa677fde5922e602a95e966db9e4a3d6b23ce043d7dc48a5b375c6b7c78e966893e8c3\",\n    \"0xa1c8d88d72303692eaa7adf68ea41de4febec40cc14ae551bb4012afd786d7b6444a3196b5d9d5040655a3366d96b7cd\",\n    \"0xb22bd44f9235a47118a9bbe2ba5a2ba9ec62476061be2e8e57806c1a17a02f9a51403e849e2e589520b759abd0117683\",\n    \"0xb8add766050c0d69fe81d8d9ea73e1ed05f0135d093ff01debd7247e42dbb86ad950aceb3b50b9af6cdc14ab443b238f\",\n    \"0xaf2cf95f30ef478f018cf81d70d47d742120b09193d8bb77f0d41a5d2e1a80bfb467793d9e2471b4e0ad0cb2c3b42271\",\n    \"0x8af5ef2107ad284e246bb56e20fef2a255954f72de791cbdfd3be09f825298d8466064f3c98a50496c7277af32b5c0bc\",\n    \"0x85dc19558572844c2849e729395a0c125096476388bd1b14fa7f54a7c38008fc93e578da3aac6a52ff1504d6ca82db05\",\n    \"0xae8c9b43c49572e2e166d704caf5b4b621a3b47827bb2a3bcd71cdc599bba90396fd9a405261b13e831bb5d44c0827d7\",\n    \"0xa7ba7efede25f02e88f6f4cbf70643e76784a03d97e0fbd5d9437c2485283ad7ca3abb638a5f826cd9f6193e5dec0b6c\",\n    \"0x94a9d122f2f06ef709fd8016fd4b712d88052245a65a301f5f177ce22992f74ad05552b1f1af4e70d1eac62cef309752\",\n    \"0x82d999b3e7cf563833b8bc028ff63a6b26eb357dfdb3fd5f10e33a1f80a9b2cfa7814d871b32a7ebfbaa09e753e37c02\",\n    \"0xaec6edcde234df502a3268dd2c26f4a36a2e0db730afa83173f9c78fcb2b2f75510a02b80194327b792811caefda2725\",\n    \"0x94c0bfa66c9f91d462e9194144fdd12d96f9bbe745737e73bab8130607ee6ea9d740e2cfcbbd00a195746edb6369ee61\",\n    \"0xab7573dab8c9d46d339e3f491cb2826cabe8b49f85f1ede78d845fc3995537d1b4ab85140b7d0238d9c24daf0e5e2a7e\",\n    \"0x87e8b16832843251fe952dadfd01d41890ed4bb4b8fa0254550d92c8cced44368225eca83a6c3ad47a7f81ff8a80c984\",\n    \"0x9189d2d9a7c64791b19c0773ad4f0564ce6bea94aa275a917f78ad987f150fdb3e5e26e7fef9982ac184897ecc04683f\",\n    \"0xb3661bf19e2da41415396ae4dd051a9272e8a2580b06f1a1118f57b901fa237616a9f8075af1129af4eabfefedbe2f1c\",\n    \"0xaf43c86661fb15daf5d910a4e06837225e100fb5680bd3e4b10f79a2144c6ec48b1f8d6e6b98e067d36609a5d038889a\",\n    \"0x82ac0c7acaa83ddc86c5b4249aae12f28155989c7c6b91e5137a4ce05113c6cbc16f6c44948b0efd8665362d3162f16a\",\n    \"0x8f268d1195ab465beeeb112cd7ffd5d5548559a8bc01261106d3555533fc1971081b25558d884d552df0db1cddda89d8\",\n    \"0x8ef7caa5521f3e037586ce8ac872a4182ee20c7921c0065ed9986c047e3dda08294da1165f385d008b40d500f07d895f\",\n    \"0x8c2f98f6880550573fad46075d3eba26634b5b025ce25a0b4d6e0193352c8a1f0661064027a70fe8190b522405f9f4e3\",\n    \"0xb7653f353564feb164f0f89ec7949da475b8dad4a4d396d252fc2a884f6932d027b7eb2dc4d280702c74569319ed701a\",\n    \"0xa026904f4066333befd9b87a8fad791d014096af60cdd668ef919c24dbe295ff31f7a790e1e721ba40cf5105abca67f4\",\n    \"0x988f982004ada07a22dd345f2412a228d7a96b9cae2c487de42e392afe1e35c2655f829ce07a14629148ce7079a1f142\",\n    \"0x9616add009067ed135295fb74d5b223b006b312bf14663e547a0d306694ff3a8a7bb9cfc466986707192a26c0bce599f\",\n    \"0xad4c425de9855f6968a17ee9ae5b15e0a5b596411388cf976df62ecc6c847a6e2ddb2cea792a5f6e9113c2445dba3e5c\",\n    \"0xb698ac9d86afa3dc69ff8375061f88e3b0cff92ff6dfe747cebaf142e813c011851e7a2830c10993b715e7fd594604a9\",\n    \"0xa386fa189847bb3b798efca917461e38ead61a08b101948def0f82cd258b945ed4d45b53774b400af500670149e601b7\",\n    \"0x905c95abda2c68a6559d8a39b6db081c68cef1e1b4be63498004e1b2f408409be9350b5b5d86a30fd443e2b3e445640a\",\n    \"0x9116dade969e7ce8954afcdd43e5cab64dc15f6c1b8da9d2d69de3f02ba79e6c4f6c7f54d6bf586d30256ae405cd1e41\",\n    \"0xa3084d173eacd08c9b5084a196719b57e47a0179826fda73466758235d7ecdb87cbcf097bd6b510517d163a85a7c7edd\",\n    \"0x85bb00415ad3c9be99ff9ba83672cc59fdd24356b661ab93713a3c8eab34e125d8867f628a3c3891b8dc056e69cd0e83\",\n    \"0x8d58541f9f39ed2ee4478acce5d58d124031338ec11b0d55551f00a5a9a6351faa903a5d7c132dc5e4bb026e9cbd18e4\",\n    \"0xa622adf72dc250e54f672e14e128c700166168dbe0474cecb340da175346e89917c400677b1bc1c11fcc4cc26591d9db\",\n    \"0xb3f865014754b688ca8372e8448114fff87bf3ca99856ab9168894d0c4679782c1ced703f5b74e851b370630f5e6ee86\",\n    \"0xa7e490b2c40c2446fcd91861c020da9742c326a81180e38110558bb5d9f2341f1c1885e79b364e6419023d1cbdc47380\",\n    \"0xb3748d472b1062e54572badbb8e87ac36534407f74932e7fc5b8392d008e8e89758f1671d1e4d30ab0fa40551b13bb5e\",\n    \"0x89898a5c5ec4313aabc607b0049fd1ebad0e0c074920cf503c9275b564d91916c2c446d3096491c950b7af3ac5e4b0ed\",\n    \"0x8eb8c83fef2c9dd30ea44e286e9599ec5c20aba983f702e5438afe2e5b921884327ad8d1566c72395587efac79ca7d56\",\n    \"0xb92479599e806516ce21fb0bd422a1d1d925335ebe2b4a0a7e044dd275f30985a72b97292477053ac5f00e081430da80\",\n    \"0xa34ae450a324fe8a3c25a4d653a654f9580ed56bbea213b8096987bbad0f5701d809a17076435e18017fea4d69f414bc\",\n    \"0x81381afe6433d62faf62ea488f39675e0091835892ecc238e02acf1662669c6d3962a71a3db652f6fe3bc5f42a0e5dc5\",\n    \"0xa430d475bf8580c59111103316fe1aa79c523ea12f1d47a976bbfae76894717c20220e31cf259f08e84a693da6688d70\",\n    \"0xb842814c359754ece614deb7d184d679d05d16f18a14b288a401cef5dad2cf0d5ee90bad487b80923fc5573779d4e4e8\",\n    \"0x971d9a2627ff2a6d0dcf2af3d895dfbafca28b1c09610c466e4e2bff2746f8369de7f40d65b70aed135fe1d72564aa88\",\n    \"0x8f4ce1c59e22b1ce7a0664caaa7e53735b154cfba8d2c5cc4159f2385843de82ab58ed901be876c6f7fce69cb4130950\",\n    \"0x86cc9dc321b6264297987000d344fa297ef45bcc2a4df04e458fe2d907ad304c0ea2318e32c3179af639a9a56f3263cf\",\n    \"0x8229e0876dfe8f665c3fb19b250bd89d40f039bbf1b331468b403655be7be2e104c2fd07b9983580c742d5462ca39a43\",\n    \"0x99299d73066e8eb128f698e56a9f8506dfe4bd014931e86b6b487d6195d2198c6c5bf15cccb40ccf1f8ddb57e9da44a2\",\n    \"0xa3a3be37ac554c574b393b2f33d0a32a116c1a7cfeaf88c54299a4da2267149a5ecca71f94e6c0ef6e2f472b802f5189\",\n    \"0xa91700d1a00387502cdba98c90f75fbc4066fefe7cc221c8f0e660994c936badd7d2695893fde2260c8c11d5bdcdd951\",\n    \"0x8e03cae725b7f9562c5c5ab6361644b976a68bada3d7ca508abca8dfc80a469975689af1fba1abcf21bc2a190dab397d\",\n    \"0xb01461ad23b2a8fa8a6d241e1675855d23bc977dbf4714add8c4b4b7469ccf2375cec20e80cedfe49361d1a30414ac5b\",\n    \"0xa2673bf9bc621e3892c3d7dd4f1a9497f369add8cbaa3472409f4f86bd21ac67cfac357604828adfee6ada1835365029\",\n    \"0xa042dff4bf0dfc33c178ba1b335e798e6308915128de91b12e5dbbab7c4ac8d60a01f6aea028c3a6d87b9b01e4e74c01\",\n    \"0x86339e8a75293e4b3ae66b5630d375736b6e6b6b05c5cda5e73fbf7b2f2bd34c18a1d6cefede08625ce3046e77905cb8\",\n    \"0xaf2ebe1b7d073d03e3d98bc61af83bf26f7a8c130fd607aa92b75db22d14d016481b8aa231e2c9757695f55b7224a27f\",\n    \"0xa00ee882c9685e978041fd74a2c465f06e2a42ffd3db659053519925be5b454d6f401e3c12c746e49d910e4c5c9c5e8c\",\n    \"0x978a781c0e4e264e0dad57e438f1097d447d891a1e2aa0d5928f79a9d5c3faae6f258bc94fdc530b7b2fa6a9932bb193\",\n    \"0xaa4b7ce2e0c2c9e9655bf21e3e5651c8503bce27483017b0bf476be743ba06db10228b3a4c721219c0779747f11ca282\",\n    \"0xb003d1c459dacbcf1a715551311e45d7dbca83a185a65748ac74d1800bbeaba37765d9f5a1a221805c571910b34ebca8\",\n    \"0x95b6e531b38648049f0d19de09b881baa1f7ea3b2130816b006ad5703901a05da57467d1a3d9d2e7c73fb3f2e409363c\",\n    \"0xa6cf9c06593432d8eba23a4f131bb7f72b9bd51ab6b4b772a749fe03ed72b5ced835a349c6d9920dba2a39669cb7c684\",\n    \"0xaa3d59f6e2e96fbb66195bc58c8704e139fa76cd15e4d61035470bd6e305db9f98bcbf61ac1b95e95b69ba330454c1b3\",\n    \"0xb57f97959c208361de6d7e86dff2b873068adb0f158066e646f42ae90e650079798f165b5cd713141cd3a2a90a961d9a\",\n    \"0xa76ee8ed9052f6a7a8c69774bb2597be182942f08115baba03bf8faaeaee526feba86120039fe8ca7b9354c3b6e0a8e6\",\n    \"0x95689d78c867724823f564627d22d25010f278674c6d2d0cdb10329169a47580818995d1d727ce46c38a1e47943ebb89\",\n    \"0xab676d2256c6288a88e044b3d9ffd43eb9d5aaee00e8fc60ac921395fb835044c71a26ca948e557fed770f52d711e057\",\n    \"0x96351c72785c32e5d004b6f4a1259fb8153d631f0c93fed172f18e8ba438fbc5585c1618deeabd0d6d0b82173c2e6170\",\n    \"0x93dd8d3db576418e22536eba45ab7f56967c6c97c64260d6cddf38fb19c88f2ec5cd0e0156f50e70855eee8a2b879ffd\",\n    \"0xad6ff16f40f6de3d7a737f8e6cebd8416920c4ff89dbdcd75eabab414af9a6087f83ceb9aff7680aa86bff98bd09c8cc\",\n    \"0x84de53b11671abc9c38710e19540c5c403817562aeb22a88404cdaff792c1180f717dbdfe8f54940c062c4d032897429\",\n    \"0x872231b9efa1cdd447b312099a5c164c560440a9441d904e70f5abfc3b2a0d16be9a01aca5e0a2599a61e19407587e3d\",\n    \"0x88f44ac27094a2aa14e9dc40b099ee6d68f97385950f303969d889ee93d4635e34dff9239103bdf66a4b7cbba3e7eb7a\",\n    \"0xa59afebadf0260e832f6f44468443562f53fbaf7bcb5e46e1462d3f328ac437ce56edbca617659ac9883f9e13261fad7\",\n    \"0xb1990e42743a88de4deeacfd55fafeab3bc380cb95de43ed623d021a4f2353530bcab9594389c1844b1c5ea6634c4555\",\n    \"0x85051e841149a10e83f56764e042182208591396d0ce78c762c4a413e6836906df67f38c69793e158d64fef111407ba3\",\n    \"0x9778172bbd9b1f2ec6bbdd61829d7b39a7df494a818e31c654bf7f6a30139899c4822c1bf418dd4f923243067759ce63\",\n    \"0x9355005b4878c87804fc966e7d24f3e4b02bed35b4a77369d01f25a3dcbff7621b08306b1ac85b76fe7b4a3eb5f839b1\",\n    \"0x8f9dc6a54fac052e236f8f0e1f571ac4b5308a43acbe4cc8183bce26262ddaf7994e41cf3034a4cbeca2c505a151e3b1\",\n    \"0x8cc59c17307111723fe313046a09e0e32ea0cce62c13814ab7c6408c142d6a0311d801be4af53fc9240523f12045f9ef\",\n    \"0x8e6057975ed40a1932e47dd3ac778f72ee2a868d8540271301b1aa6858de1a5450f596466494a3e0488be4fbeb41c840\",\n    \"0x812145efbd6559ae13325d56a15940ca4253b17e72a9728986b563bb5acc13ec86453796506ac1a8f12bd6f9e4a288c3\",\n    \"0x911da0a6d6489eb3dab2ec4a16e36127e8a291ae68a6c2c9de33e97f3a9b1f00da57a94e270a0de79ecc5ecb45d19e83\",\n    \"0xb72ea85973f4b2a7e6e71962b0502024e979a73c18a9111130e158541fa47bbaaf53940c8f846913a517dc69982ba9e1\",\n    \"0xa7a56ad1dbdc55f177a7ad1d0af78447dc2673291e34e8ab74b26e2e2e7d8c5fe5dc89e7ef60f04a9508847b5b3a8188\",\n    \"0xb52503f6e5411db5d1e70f5fb72ccd6463fa0f197b3e51ca79c7b5a8ab2e894f0030476ada72534fa4eb4e06c3880f90\",\n    \"0xb51c7957a3d18c4e38f6358f2237b3904618d58b1de5dec53387d25a63772e675a5b714ad35a38185409931157d4b529\",\n    \"0xb86b4266e719d29c043d7ec091547aa6f65bbf2d8d831d1515957c5c06513b72aa82113e9645ad38a7bc3f5383504fa6\",\n    \"0xb95b547357e6601667b0f5f61f261800a44c2879cf94e879def6a105b1ad2bbf1795c3b98a90d588388e81789bd02681\",\n    \"0xa58fd4c5ae4673fa350da6777e13313d5d37ed1dafeeb8f4f171549765b84c895875d9d3ae6a9741f3d51006ef81d962\",\n    \"0x9398dc348d078a604aadc154e6eef2c0be1a93bb93ba7fe8976edc2840a3a318941338cc4d5f743310e539d9b46613d2\",\n    \"0x902c9f0095014c4a2f0dccaaab543debba6f4cc82c345a10aaf4e72511725dbed7a34cd393a5f4e48a3e5142b7be84ed\",\n    \"0xa7c0447849bb44d04a0393a680f6cd390093484a79a147dd238f5d878030d1c26646d88211108e59fe08b58ad20c6fbd\",\n    \"0x80db045535d6e67a422519f5c89699e37098449d249698a7cc173a26ccd06f60238ae6cc7242eb780a340705c906790c\",\n    \"0x8e52b451a299f30124505de2e74d5341e1b5597bdd13301cc39b05536c96e4380e7f1b5c7ef076f5b3005a868657f17c\",\n    \"0x824499e89701036037571761e977654d2760b8ce21f184f2879fda55d3cda1e7a95306b8abacf1caa79d3cc075b9d27f\",\n    \"0x9049b956b77f8453d2070607610b79db795588c0cec12943a0f5fe76f358dea81e4f57a4692112afda0e2c05c142b26f\",\n    \"0x81911647d818a4b5f4990bfd4bc13bf7be7b0059afcf1b6839333e8569cdb0172fd2945410d88879349f677abaed5eb3\",\n    \"0xad4048f19b8194ed45b6317d9492b71a89a66928353072659f5ce6c816d8f21e69b9d1817d793effe49ca1874daa1096\",\n    \"0x8d22f7b2ddb31458661abd34b65819a374a1f68c01fc6c9887edeba8b80c65bceadb8f57a3eb686374004b836261ef67\",\n    \"0x92637280c259bc6842884db3d6e32602a62252811ae9b019b3c1df664e8809ffe86db88cfdeb8af9f46435c9ee790267\",\n    \"0xa2f416379e52e3f5edc21641ea73dc76c99f7e29ea75b487e18bd233856f4c0183429f378d2bfc6cd736d29d6cadfa49\",\n    \"0x882cb6b76dbdc188615dcf1a8439eba05ffca637dd25197508156e03c930b17b9fed2938506fdd7b77567cb488f96222\",\n    \"0xb68b621bb198a763fb0634eddb93ed4b5156e59b96c88ca2246fd1aea3e6b77ed651e112ac41b30cd361fadc011d385e\",\n    \"0xa3cb22f6b675a29b2d1f827cacd30df14d463c93c3502ef965166f20d046af7f9ab7b2586a9c64f4eae4fad2d808a164\",\n    \"0x8302d9ce4403f48ca217079762ce42cee8bc30168686bb8d3a945fbd5acd53b39f028dce757b825eb63af2d5ae41169d\",\n    \"0xb2eef1fbd1a176f1f4cd10f2988c7329abe4eb16c7405099fb92baa724ab397bc98734ef7d4b24c0f53dd90f57520d04\",\n    \"0xa1bbef0bd684a3f0364a66bde9b29326bac7aa3dde4caed67f14fb84fed3de45c55e406702f1495a3e2864d4ee975030\",\n    \"0x976acdb0efb73e3a3b65633197692dedc2adaed674291ae3df76b827fc866d214e9cac9ca46baefc4405ff13f953d936\",\n    \"0xb9fbf71cc7b6690f601f0b1c74a19b7d14254183a2daaafec7dc3830cba5ae173d854bbfebeca985d1d908abe5ef0cda\",\n    \"0x90591d7b483598c94e38969c4dbb92710a1a894bcf147807f1bcbd8aa3ac210b9f2be65519aa829f8e1ccdc83ad9b8cf\",\n    \"0xa30568577c91866b9c40f0719d46b7b3b2e0b4a95e56196ac80898a2d89cc67880e1229933f2cd28ee3286f8d03414d7\",\n    \"0x97589a88c3850556b359ec5e891f0937f922a751ac7c95949d3bbc7058c172c387611c0f4cb06351ef02e5178b3dd9e4\",\n    \"0x98e7bbe27a1711f4545df742f17e3233fbcc63659d7419e1ca633f104cb02a32c84f2fac23ca2b84145c2672f68077ab\",\n    \"0xa7ddb91636e4506d8b7e92aa9f4720491bb71a72dadc47c7f4410e15f93e43d07d2b371951a0e6a18d1bd087aa96a5c4\",\n    \"0xa7c006692227a06db40bceac3d5b1daae60b5692dd9b54772bedb5fea0bcc91cbcdb530cac31900ffc70c5b3ffadc969\",\n    \"0x8d3ec6032778420dfa8be52066ba0e623467df33e4e1901dbadd586c5d750f4ccde499b5197e26b9ea43931214060f69\",\n    \"0x8d9a8410518ea64f89df319bfd1fc97a0971cdb9ad9b11d1f8fe834042ea7f8dce4db56eeaf179ff8dda93b6db93e5ce\",\n    \"0xa3c533e9b3aa04df20b9ff635cb1154ce303e045278fcf3f10f609064a5445552a1f93989c52ce852fd0bbd6e2b6c22e\",\n    \"0x81934f3a7f8c1ae60ec6e4f212986bcc316118c760a74155d06ce0a8c00a9b9669ec4e143ca214e1b995e41271774fd9\",\n    \"0xab8e2d01a71192093ef8fafa7485e795567cc9db95a93fb7cc4cf63a391ef89af5e2bfad4b827fffe02b89271300407f\",\n    \"0x83064a1eaa937a84e392226f1a60b7cfad4efaa802f66de5df7498962f7b2649924f63cd9962d47906380b97b9fe80e1\",\n    \"0xb4f5e64a15c6672e4b55417ee5dc292dcf93d7ea99965a888b1cc4f5474a11e5b6520eacbcf066840b343f4ceeb6bf33\",\n    \"0xa63d278b842456ef15c278b37a6ea0f27c7b3ffffefca77c7a66d2ea06c33c4631eb242bbb064d730e70a8262a7b848a\",\n    \"0x83a41a83dbcdf0d22dc049de082296204e848c453c5ab1ba75aa4067984e053acf6f8b6909a2e1f0009ed051a828a73b\",\n    \"0x819485b036b7958508f15f3c19436da069cbe635b0318ebe8c014cf1ef9ab2df038c81161b7027475bcfa6fff8dd9faf\",\n    \"0xaa40e38172806e1e045e167f3d1677ef12d5dcdc89b43639a170f68054bd196c4fae34c675c1644d198907a03f76ba57\",\n    \"0x969bae484883a9ed1fbed53b26b3d4ee4b0e39a6c93ece5b3a49daa01444a1c25727dabe62518546f36b047b311b177c\",\n    \"0x80a9e73a65da99664988b238096a090d313a0ee8e4235bc102fa79bb337b51bb08c4507814eb5baec22103ec512eaab0\",\n    \"0x86604379aec5bddda6cbe3ef99c0ac3a3c285b0b1a15b50451c7242cd42ae6b6c8acb717dcca7917838432df93a28502\",\n    \"0xa23407ee02a495bed06aa7e15f94cfb05c83e6d6fba64456a9bbabfa76b2b68c5c47de00ba169e710681f6a29bb41a22\",\n    \"0x98cff5ecc73b366c6a01b34ac9066cb34f7eeaf4f38a5429bad2d07e84a237047e2a065c7e8a0a6581017dadb4695deb\",\n    \"0x8de9f68a938f441f3b7ab84bb1f473c5f9e5c9e139e42b7ccee1d254bd57d0e99c2ccda0f3198f1fc5737f6023dd204e\",\n    \"0xb0ce48d815c2768fb472a315cad86aa033d0e9ca506f146656e2941829e0acb735590b4fbc713c2d18d3676db0a954ac\",\n    \"0x82f485cdefd5642a6af58ac6817991c49fac9c10ace60f90b27f1788cc026c2fe8afc83cf499b3444118f9f0103598a8\",\n    \"0x82c24550ed512a0d53fc56f64cc36b553823ae8766d75d772dacf038c460f16f108f87a39ceef7c66389790f799dbab3\",\n    \"0x859ffcf1fe9166388316149b9acc35694c0ea534d43f09dae9b86f4aa00a23b27144dda6a352e74b9516e8c8d6fc809c\",\n    \"0xb8f7f353eec45da77fb27742405e5ad08d95ec0f5b6842025be9def3d9892f85eb5dd0921b41e6eff373618dba215bca\",\n    \"0x8ccca4436f9017e426229290f5cd05eac3f16571a4713141a7461acfe8ae99cd5a95bf5b6df129148693c533966145da\",\n    \"0xa2c67ecc19c0178b2994846fea4c34c327a5d786ac4b09d1d13549d5be5996d8a89021d63d65cb814923388f47cc3a03\",\n    \"0xaa0ff87d676b418ec08f5cbf577ac7e744d1d0e9ebd14615b550eb86931eafd2a36d4732cc5d6fab1713fd7ab2f6f7c0\",\n    \"0x8aef4730bb65e44efd6bb9441c0ae897363a2f3054867590a2c2ecf4f0224e578c7a67f10b40f8453d9f492ac15a9b2d\",\n    \"0x86a187e13d8fba5addcfdd5b0410cedd352016c930f913addd769ee09faa6be5ca3e4b1bdb417a965c643a99bd92be42\",\n    \"0xa0a4e9632a7a094b14b29b78cd9c894218cdf6783e61671e0203865dc2a835350f465fbaf86168f28af7c478ca17bc89\",\n    \"0xa8c7b02d8deff2cd657d8447689a9c5e2cd74ef57c1314ac4d69084ac24a7471954d9ff43fe0907d875dcb65fd0d3ce5\",\n    \"0x97ded38760aa7be6b6960b5b50e83b618fe413cbf2bcc1da64c05140bcc32f5e0e709cd05bf8007949953fac5716bad9\",\n    \"0xb0d293835a24d64c2ae48ce26e550b71a8c94a0883103757fb6b07e30747f1a871707d23389ba2b2065fa6bafe220095\",\n    \"0x8f9e291bf849feaa575592e28e3c8d4b7283f733d41827262367ea1c40f298c7bcc16505255a906b62bf15d9f1ba85fb\",\n    \"0x998f4e2d12708b4fd85a61597ca2eddd750f73c9e0c9b3cf0825d8f8e01f1628fd19797dcaed3b16dc50331fc6b8b821\",\n    \"0xb30d1f8c115d0e63bf48f595dd10908416774c78b3bbb3194192995154d80ea042d2e94d858de5f8aa0261b093c401fd\",\n    \"0xb5d9c75bb41f964cbff3f00e96d9f1480c91df8913f139f0d385d27a19f57a820f838eb728e46823cbff00e21c660996\",\n    \"0xa6edec90b5d25350e2f5f0518777634f9e661ec9d30674cf5b156c4801746d62517751d90074830ac0f4b09911c262f1\",\n    \"0x82f98da1264b6b75b8fbeb6a4d96d6a05b25c24db0d57ba3a38efe3a82d0d4e331b9fc4237d6494ccfe4727206457519\",\n    \"0xb89511843453cf4ecd24669572d6371b1e529c8e284300c43e0d5bb6b3aaf35aeb634b3cb5c0a2868f0d5e959c1d0772\",\n    \"0xa82bf065676583e5c1d3b81987aaae5542f522ba39538263a944bb33ea5b514c649344a96c0205a3b197a3f930fcda6c\",\n    \"0xa37b47ea527b7e06c460776aa662d9a49ff4149d3993f1a974b0dd165f7171770d189b0e2ea54fd5fccb6a14b116e68a\",\n    \"0xa1017677f97dda818274d47556d09d0e4ccacb23a252f82a6cfe78c630ad46fb9806307445a59fb61262182de3a2b29c\",\n    \"0xb01e9fcac239ba270e6877b79273ddd768bf8a51d2ed8a051b1c11e18eff3de5920e2fcbfbd26f06d381eddd3b1f1e1b\",\n    \"0x82fcd53d803b1c8e4ed76adc339b7f3a5962d37042b9683aabac7513ac68775d4a566a9460183926a6a95dbe7d551a1f\",\n    \"0xa763e78995d55cd21cdb7ef75d9642d6e1c72453945e346ab6690c20a4e1eeec61bb848ef830ae4b56182535e3c71d8f\",\n    \"0xb769f4db602251d4b0a1186782799bdcef66de33c110999a5775c50b349666ffd83d4c89714c4e376f2efe021a5cfdb2\",\n    \"0xa59cbd1b785efcfa6e83fc3b1d8cf638820bc0c119726b5368f3fba9dce8e3414204fb1f1a88f6c1ff52e87961252f97\",\n    \"0x95c8c458fd01aa23ecf120481a9c6332ebec2e8bb70a308d0576926a858457021c277958cf79017ddd86a56cacc2d7db\",\n    \"0x82eb41390800287ae56e77f2e87709de5b871c8bdb67c10a80fc65f3acb9f7c29e8fa43047436e8933f27449ea61d94d\",\n    \"0xb3ec25e3545eb83aed2a1f3558d1a31c7edde4be145ecc13b33802654b77dc049b4f0065069dd9047b051e52ab11dcdd\",\n    \"0xb78a0c715738f56f0dc459ab99e252e3b579b208142836b3c416b704ca1de640ca082f29ebbcee648c8c127df06f6b1e\",\n    \"0xa4083149432eaaf9520188ebf4607d09cf664acd1f471d4fb654476e77a9eaae2251424ffda78d09b6cb880df35c1219\",\n    \"0x8c52857d68d6e9672df3db2df2dbf46b516a21a0e8a18eec09a6ae13c1ef8f369d03233320dd1c2c0bbe00abfc1ea18b\",\n    \"0x8c856089488803066bff3f8d8e09afb9baf20cecc33c8823c1c0836c3d45498c3de37e87c016b705207f60d2b00f8609\",\n    \"0x831a3df39be959047b2aead06b4dcd3012d7b29417f642b83c9e8ce8de24a3dbbd29c6fdf55e2db3f7ea04636c94e403\",\n    \"0xaed84d009f66544addabe404bf6d65af7779ce140dc561ff0c86a4078557b96b2053b7b8a43432ffb18cd814f143b9da\",\n    \"0x93282e4d72b0aa85212a77b336007d8ba071eea17492da19860f1ad16c1ea8867ccc27ef5c37c74b052465cc11ea4f52\",\n    \"0xa7b78b8c8d057194e8d68767f1488363f77c77bddd56c3da2bc70b6354c7aa76247c86d51f7371aa38a4aa7f7e3c0bb7\",\n    \"0xb1c77283d01dcd1bde649b5b044eac26befc98ff57cbee379fb5b8e420134a88f2fc7f0bf04d15e1fbd45d29e7590fe6\",\n    \"0xa4aa8de70330a73b2c6458f20a1067eed4b3474829b36970a8df125d53bbdda4f4a2c60063b7cccb0c80fc155527652f\",\n    \"0x948a6c79ba1b8ad7e0bed2fae2f0481c4e41b4d9bbdd9b58164e28e9065700e83f210c8d5351d0212e0b0b68b345b3a5\",\n    \"0x86a48c31dcbbf7b082c92d28e1f613a2378a910677d7db3a349dc089e4a1e24b12eee8e8206777a3a8c64748840b7387\",\n    \"0x976adb1af21e0fc34148917cf43d933d7bfd3fd12ed6c37039dcd5a4520e3c6cf5868539ba5bf082326430deb8a4458d\",\n    \"0xb93e1a4476f2c51864bb4037e7145f0635eb2827ab91732b98d49b6c07f6ac443111aa1f1da76d1888665cb897c3834e\",\n    \"0x8afd46fb23bf869999fa19784b18a432a1f252d09506b8dbb756af900518d3f5f244989b3d7c823d9029218c655d3dc6\",\n    \"0x83f1e59e3abeed18cdc632921672673f1cb6e330326e11c4e600e13e0d5bc11bdc970ae12952e15103a706fe720bf4d6\",\n    \"0x90ce4cc660714b0b673d48010641c09c00fc92a2c596208f65c46073d7f349dd8e6e077ba7dcef9403084971c3295b76\",\n    \"0x8b09b0f431a7c796561ecf1549b85048564de428dac0474522e9558b6065fede231886bc108539c104ce88ebd9b5d1b0\",\n    \"0x85d6e742e2fb16a7b0ba0df64bc2c0dbff9549be691f46a6669bca05e89c884af16822b85faefefb604ec48c8705a309\",\n    \"0xa87989ee231e468a712c66513746fcf03c14f103aadca0eac28e9732487deb56d7532e407953ab87a4bf8961588ef7b0\",\n    \"0xb00da10efe1c29ee03c9d37d5918e391ae30e48304e294696b81b434f65cf8c8b95b9d1758c64c25e534d045ba28696f\",\n    \"0x91c0e1fb49afe46c7056400baa06dbb5f6e479db78ee37e2d76c1f4e88994357e257b83b78624c4ef6091a6c0eb8254d\",\n    \"0x883fb797c498297ccbf9411a3e727c3614af4eccde41619b773dc7f3259950835ee79453debf178e11dec4d3ada687a0\",\n    \"0xa14703347e44eb5059070b2759297fcfcfc60e6893c0373eea069388eba3950aa06f1c57cd2c30984a2d6f9e9c92c79e\",\n    \"0xafebc7585b304ceba9a769634adff35940e89cd32682c78002822aab25eec3edc29342b7f5a42a56a1fec67821172ad5\",\n    \"0xaea3ff3822d09dba1425084ca95fd359718d856f6c133c5fabe2b2eed8303b6e0ba0d8698b48b93136a673baac174fd9\",\n    \"0xaf2456a09aa777d9e67aa6c7c49a1845ea5cdda2e39f4c935c34a5f8280d69d4eec570446998cbbe31ede69a91e90b06\",\n    \"0x82cada19fed16b891ef3442bafd49e1f07c00c2f57b2492dd4ee36af2bd6fd877d6cb41188a4d6ce9ec8d48e8133d697\",\n    \"0x82a21034c832287f616619a37c122cee265cc34ae75e881fcaea4ea7f689f3c2bc8150bbf7dbcfd123522bfb7f7b1d68\",\n    \"0x86877217105f5d0ec3eeff0289fc2a70d505c9fdf7862e8159553ef60908fb1a27bdaf899381356a4ef4649072a9796c\",\n    \"0x82b196e49c6e861089a427c0b4671d464e9d15555ffb90954cd0d630d7ae02eb3d98ceb529d00719c2526cd96481355a\",\n    \"0xa29b41d0d43d26ce76d4358e0db2b77df11f56e389f3b084d8af70a636218bd3ac86b36a9fe46ec9058c26a490f887f7\",\n    \"0xa4311c4c20c4d7dd943765099c50f2fd423e203ccfe98ff00087d205467a7873762510cac5fdce7a308913ed07991ed7\",\n    \"0xb1f040fc5cc51550cb2c25cf1fd418ecdd961635a11f365515f0cb4ffb31da71f48128c233e9cc7c0cf3978d757ec84e\",\n    \"0xa9ebae46f86d3bd543c5f207ed0d1aed94b8375dc991161d7a271f01592912072e083e2daf30c146430894e37325a1b9\",\n    \"0x826418c8e17ad902b5fe88736323a47e0ca7a44bce4cbe27846ec8fe81de1e8942455dda6d30e192cdcc73e11df31256\",\n    \"0x85199db563427c5edcbac21f3d39fec2357be91fb571982ddcdc4646b446ad5ced84410de008cb47b3477ee0d532daf8\",\n    \"0xb7eed9cd400b2ca12bf1d9ae008214b8561fb09c8ad9ff959e626ffde00fee5ff2f5b6612e231f2a1a9b1646fcc575e3\",\n    \"0x8b40bf12501dcbac78f5a314941326bfcddf7907c83d8d887d0bb149207f85d80cd4dfbd7935439ea7b14ea39a3fded7\",\n    \"0x83e3041af302485399ba6cd5120e17af61043977083887e8d26b15feec4a6b11171ac5c06e6ad0971d4b58a81ff12af3\",\n    \"0x8f5b9a0eecc589dbf8c35a65d5e996a659277ef6ea509739c0cb7b3e2da9895e8c8012de662e5b23c5fa85d4a8f48904\",\n    \"0x835d71ed5e919d89d8e6455f234f3ff215462c4e3720c371ac8c75e83b19dfe3ae15a81547e4dc1138e5f5997f413cc9\",\n    \"0x8b7d2e4614716b1db18e9370176ea483e6abe8acdcc3dcdf5fb1f4d22ca55d652feebdccc171c6de38398d9f7bfdec7a\",\n    \"0x93eace72036fe57d019676a02acf3d224cf376f166658c1bf705db4f24295881d477d6fdd7916efcfceff8c7a063deda\",\n    \"0xb1ac460b3d516879a84bc886c54f020a9d799e7c49af3e4d7de5bf0d2793c852254c5d8fe5616147e6659512e5ccb012\",\n    \"0xacd0947a35cb167a48bcd9667620464b54ac0e78f9316b4aa92dcaab5422d7a732087e52e1c827faa847c6b2fe6e7766\",\n    \"0x94ac33d21c3d12ff762d32557860e911cd94d666609ddcc42161b9c16f28d24a526e8b10bb03137257a92cec25ae637d\",\n    \"0x832e02058b6b994eadd8702921486241f9a19e68ed1406dad545e000a491ae510f525ccf9d10a4bba91c68f2c53a0f58\",\n    \"0x9471035d14f78ff8f463b9901dd476b587bb07225c351161915c2e9c6114c3c78a501379ab6fb4eb03194c457cbd22bf\",\n    \"0xab64593e034c6241d357fcbc32d8ea5593445a5e7c24cac81ad12bd2ef01843d477a36dc1ba21dbe63b440750d72096a\",\n    \"0x9850f3b30045e927ad3ec4123a32ed2eb4c911f572b6abb79121873f91016f0d80268de8b12e2093a4904f6e6cab7642\",\n    \"0x987212c36b4722fe2e54fa30c52b1e54474439f9f35ca6ad33c5130cd305b8b54b532dd80ffd2c274105f20ce6d79f6e\",\n    \"0x8b4d0c6abcb239b5ed47bef63bc17efe558a27462c8208fa652b056e9eae9665787cd1aee34fbb55beb045c8bfdb882b\",\n    \"0xa9f3483c6fee2fe41312d89dd4355d5b2193ac413258993805c5cbbf0a59221f879386d3e7a28e73014f10e65dd503d9\",\n    \"0xa2225da3119b9b7c83d514b9f3aeb9a6d9e32d9cbf9309cbb971fd53c4b2c001d10d880a8ad8a7c281b21d85ceca0b7c\",\n    \"0xa050be52e54e676c151f7a54453bbb707232f849beab4f3bf504b4d620f59ed214409d7c2bd3000f3ff13184ccda1c35\",\n    \"0xadbccf681e15b3edb6455a68d292b0a1d0f5a4cb135613f5e6db9943f02181341d5755875db6ee474e19ace1c0634a28\",\n    \"0x8b6eff675632a6fad0111ec72aacc61c7387380eb87933fd1d098856387d418bd38e77d897e65d6fe35951d0627c550b\",\n    \"0xaabe2328ddf90989b15e409b91ef055cb02757d34987849ae6d60bef2c902bf8251ed21ab30acf39e500d1d511e90845\",\n    \"0x92ba4eb1f796bc3d8b03515f65c045b66e2734c2da3fc507fdd9d6b5d1e19ab3893726816a32141db7a31099ca817d96\",\n    \"0x8a98b3cf353138a1810beb60e946183803ef1d39ac4ea92f5a1e03060d35a4774a6e52b14ead54f6794d5f4022b8685c\",\n    \"0x909f8a5c13ec4a59b649ed3bee9f5d13b21d7f3e2636fd2bb3413c0646573fdf9243d63083356f12f5147545339fcd55\",\n    \"0x9359d914d1267633141328ed0790d81c695fea3ddd2d406c0df3d81d0c64931cf316fe4d92f4353c99ff63e2aefc4e34\",\n    \"0xb88302031681b54415fe8fbfa161c032ea345c6af63d2fb8ad97615103fd4d4281c5a9cae5b0794c4657b97571a81d3b\",\n    \"0x992c80192a519038082446b1fb947323005b275e25f2c14c33cc7269e0ec038581cc43705894f94bad62ae33a8b7f965\",\n    \"0xa78253e3e3eece124bef84a0a8807ce76573509f6861d0b6f70d0aa35a30a123a9da5e01e84969708c40b0669eb70aa6\",\n    \"0x8d5724de45270ca91c94792e8584e676547d7ac1ac816a6bb9982ee854eb5df071d20545cdfd3771cd40f90e5ba04c8e\",\n    \"0x825a6f586726c68d45f00ad0f5a4436523317939a47713f78fd4fe81cd74236fdac1b04ecd97c2d0267d6f4981d7beb1\"\n  ],\n  \"g2_monomial\": [\n    \"0x93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8\",\n    \"0xb5bfd7dd8cdeb128843bc287230af38926187075cbfbefa81009a2ce615ac53d2914e5870cb452d2afaaab24f3499f72185cbfee53492714734429b7b38608e23926c911cceceac9a36851477ba4c60b087041de621000edc98edada20c1def2\",\n    \"0xb5337ba0ce5d37224290916e268e2060e5c14f3f9fc9e1ec3af5a958e7a0303122500ce18f1a4640bf66525bd10e763501fe986d86649d8d45143c08c3209db3411802c226e9fe9a55716ac4a0c14f9dcef9e70b2bb309553880dc5025eab3cc\",\n    \"0xb3c1dcdc1f62046c786f0b82242ef283e7ed8f5626f72542aa2c7a40f14d9094dd1ebdbd7457ffdcdac45fd7da7e16c51200b06d791e5e43e257e45efdf0bd5b06cd2333beca2a3a84354eb48662d83aef5ecf4e67658c851c10b13d8d87c874\",\n    \"0x954d91c7688983382609fca9e211e461f488a5971fd4e40d7e2892037268eacdfd495cfa0a7ed6eb0eb11ac3ae6f651716757e7526abe1e06c64649d80996fd3105c20c4c94bc2b22d97045356fe9d791f21ea6428ac48db6f9e68e30d875280\",\n    \"0x88a6b6bb26c51cf9812260795523973bb90ce80f6820b6c9048ab366f0fb96e48437a7f7cb62aedf64b11eb4dfefebb0147608793133d32003cb1f2dc47b13b5ff45f1bb1b2408ea45770a08dbfaec60961acb8119c47b139a13b8641e2c9487\",\n    \"0x85cd7be9728bd925d12f47fb04b32d9fad7cab88788b559f053e69ca18e463113ecc8bbb6dbfb024835f901b3a957d3108d6770fb26d4c8be0a9a619f6e3a4bf15cbfd48e61593490885f6cee30e4300c5f9cf5e1c08e60a2d5b023ee94fcad0\",\n    \"0x80477dba360f04399821a48ca388c0fa81102dd15687fea792ee8c1114e00d1bc4839ad37ac58900a118d863723acfbe08126ea883be87f50e4eabe3b5e72f5d9e041db8d9b186409fd4df4a7dde38c0e0a3b1ae29b098e5697e7f110b6b27e4\",\n    \"0xb7a6aec08715a9f8672a2b8c367e407be37e59514ac19dd4f0942a68007bba3923df22da48702c63c0d6b3efd3c2d04e0fe042d8b5a54d562f9f33afc4865dcbcc16e99029e25925580e87920c399e710d438ac1ce3a6dc9b0d76c064a01f6f7\",\n    \"0xac1b001edcea02c8258aeffbf9203114c1c874ad88dae1184fadd7d94cd09053649efd0ca413400e6e9b5fa4eac33261000af88b6bd0d2abf877a4f0355d2fb4d6007adb181695201c5432e50b850b51b3969f893bddf82126c5a71b042b7686\",\n    \"0x90043fda4de53fb364fab2c04be5296c215599105ecff0c12e4917c549257125775c29f2507124d15f56e30447f367db0596c33237242c02d83dfd058735f1e3c1ff99069af55773b6d51d32a68bf75763f59ec4ee7267932ae426522b8aaab6\",\n    \"0xa8660ce853e9dc08271bf882e29cd53397d63b739584dda5263da4c7cc1878d0cf6f3e403557885f557e184700575fee016ee8542dec22c97befe1d10f414d22e84560741cdb3e74c30dda9b42eeaaf53e27822de2ee06e24e912bf764a9a533\",\n    \"0x8fe3921a96d0d065e8aa8fce9aa42c8e1461ca0470688c137be89396dd05103606dab6cdd2a4591efd6addf72026c12e065da7be276dee27a7e30afa2bd81c18f1516e7f068f324d0bad9570b95f6bd02c727cd2343e26db0887c3e4e26dceda\",\n    \"0x8ae1ad97dcb9c192c9a3933541b40447d1dc4eebf380151440bbaae1e120cc5cdf1bcea55180b128d8e180e3af623815191d063cc0d7a47d55fb7687b9d87040bf7bc1a7546b07c61db5ccf1841372d7c2fe4a5431ffff829f3c2eb590b0b710\",\n    \"0x8c2fa96870a88150f7876c931e2d3cc2adeaaaf5c73ef5fa1cf9dfa0991ae4819f9321af7e916e5057d87338e630a2f21242c29d76963cf26035b548d2a63d8ad7bd6efefa01c1df502cbdfdfe0334fb21ceb9f686887440f713bf17a89b8081\",\n    \"0xb9aa98e2f02bb616e22ee5dd74c7d1049321ac9214d093a738159850a1dbcc7138cb8d26ce09d8296368fd5b291d74fa17ac7cc1b80840fdd4ee35e111501e3fa8485b508baecda7c1ab7bd703872b7d64a2a40b3210b6a70e8a6ffe0e5127e3\",\n    \"0x9292db67f8771cdc86854a3f614a73805bf3012b48f1541e704ea4015d2b6b9c9aaed36419769c87c49f9e3165f03edb159c23b3a49c4390951f78e1d9b0ad997129b17cdb57ea1a6638794c0cca7d239f229e589c5ae4f9fe6979f7f8cba1d7\",\n    \"0x91cd9e86550f230d128664f7312591fee6a84c34f5fc7aed557bcf986a409a6de722c4330453a305f06911d2728626e611acfdf81284f77f60a3a1595053a9479964fd713117e27c0222cc679674b03bc8001501aaf9b506196c56de29429b46\",\n    \"0xa9516b73f605cc31b89c68b7675dc451e6364595243d235339437f556cf22d745d4250c1376182273be2d99e02c10eee047410a43eff634d051aeb784e76cb3605d8e079b9eb6ad1957dfdf77e1cd32ce4a573c9dfcc207ca65af6eb187f6c3d\",\n    \"0xa9667271f7d191935cc8ad59ef3ec50229945faea85bfdfb0d582090f524436b348aaa0183b16a6231c00332fdac2826125b8c857a2ed9ec66821cfe02b3a2279be2412441bc2e369b255eb98614e4be8490799c4df22f18d47d24ec70bba5f7\",\n    \"0xa4371144d2aa44d70d3cb9789096d3aa411149a6f800cb46f506461ee8363c8724667974252f28aea61b6030c05930ac039c1ee64bb4bd56532a685cae182bf2ab935eee34718cffcb46cae214c77aaca11dbb1320faf23c47247db1da04d8dc\",\n    \"0x89a7eb441892260b7e81168c386899cd84ffc4a2c5cad2eae0d1ab9e8b5524662e6f660fe3f8bfe4c92f60b060811bc605b14c5631d16709266886d7885a5eb5930097127ec6fb2ebbaf2df65909cf48f253b3d5e22ae48d3e9a2fd2b01f447e\",\n    \"0x9648c42ca97665b5eccb49580d8532df05eb5a68db07f391a2340769b55119eaf4c52fe4f650c09250fa78a76c3a1e271799b8333cc2628e3d4b4a6a3e03da1f771ecf6516dd63236574a7864ff07e319a6f11f153406280d63af9e2b5713283\",\n    \"0x9663bf6dd446ea7a90658ee458578d4196dc0b175ef7fcfa75f44d41670850774c2e46c5a6be132a2c072a3c0180a24f0305d1acac49d2d79878e5cda80c57feda3d01a6af12e78b5874e2a4b3717f11c97503b41a4474e2e95b179113726199\",\n    \"0xb212aeb4814e0915b432711b317923ed2b09e076aaf558c3ae8ef83f9e15a83f9ea3f47805b2750ab9e8106cb4dc6ad003522c84b03dc02829978a097899c773f6fb31f7fe6b8f2d836d96580f216fec20158f1590c3e0d7850622e15194db05\",\n    \"0x925f005059bf07e9ceccbe66c711b048e236ade775720d0fe479aebe6e23e8af281225ad18e62458dc1b03b42ad4ca290d4aa176260604a7aad0d9791337006fbdebe23746f8060d42876f45e4c83c3643931392fde1cd13ff8bddf8111ef974\",\n    \"0x9553edb22b4330c568e156a59ef03b26f5c326424f830fe3e8c0b602f08c124730ffc40bc745bec1a22417adb22a1a960243a10565c2be3066bfdb841d1cd14c624cd06e0008f4beb83f972ce6182a303bee3fcbcabc6cfe48ec5ae4b7941bfc\",\n    \"0x935f5a404f0a78bdcce709899eda0631169b366a669e9b58eacbbd86d7b5016d044b8dfc59ce7ed8de743ae16c2343b50e2f925e88ba6319e33c3fc76b314043abad7813677b4615c8a97eb83cc79de4fedf6ccbcfa4d4cbf759a5a84e4d9742\",\n    \"0xa5b014ab936eb4be113204490e8b61cd38d71da0dec7215125bcd131bf3ab22d0a32ce645bca93e7b3637cf0c2db3d6601a0ddd330dc46f9fae82abe864ffc12d656c88eb50c20782e5bb6f75d18760666f43943abb644b881639083e122f557\",\n    \"0x935b7298ae52862fa22bf03bfc1795b34c70b181679ae27de08a9f5b4b884f824ef1b276b7600efa0d2f1d79e4a470d51692fd565c5cf8343dd80e5d3336968fc21c09ba9348590f6206d4424eb229e767547daefa98bc3aa9f421158dee3f2a\",\n    \"0x9830f92446e708a8f6b091cc3c38b653505414f8b6507504010a96ffda3bcf763d5331eb749301e2a1437f00e2415efb01b799ad4c03f4b02de077569626255ac1165f96ea408915d4cf7955047620da573e5c439671d1fa5c833fb11de7afe6\",\n    \"0x840dcc44f673fff3e387af2bb41e89640f2a70bcd2b92544876daa92143f67c7512faf5f90a04b7191de01f3e2b1bde00622a20dc62ca23bbbfaa6ad220613deff43908382642d4d6a86999f662efd64b1df448b68c847cfa87630a3ffd2ec76\",\n    \"0x92950c895ed54f7f876b2fda17ecc9c41b7accfbdd42c210cc5b475e0737a7279f558148531b5c916e310604a1de25a80940c94fe5389ae5d6a5e9c371be67bceea1877f5401725a6595bcf77ece60905151b6dfcb68b75ed2e708c73632f4fd\",\n    \"0x8010246bf8e94c25fd029b346b5fbadb404ef6f44a58fd9dd75acf62433d8cc6db66974f139a76e0c26dddc1f329a88214dbb63276516cf325c7869e855d07e0852d622c332ac55609ba1ec9258c45746a2aeb1af0800141ee011da80af175d4\",\n    \"0xb0f1bad257ebd187bdc3f37b23f33c6a5d6a8e1f2de586080d6ada19087b0e2bf23b79c1b6da1ee82271323f5bdf3e1b018586b54a5b92ab6a1a16bb3315190a3584a05e6c37d5ca1e05d702b9869e27f513472bcdd00f4d0502a107773097da\",\n    \"0x9636d24f1ede773ce919f309448dd7ce023f424afd6b4b69cb98c2a988d849a283646dc3e469879daa1b1edae91ae41f009887518e7eb5578f88469321117303cd3ac2d7aee4d9cb5f82ab9ae3458e796dfe7c24284b05815acfcaa270ff22e2\",\n    \"0xb373feb5d7012fd60578d7d00834c5c81df2a23d42794fed91aa9535a4771fde0341c4da882261785e0caca40bf83405143085e7f17e55b64f6c5c809680c20b050409bf3702c574769127c854d27388b144b05624a0e24a1cbcc4d08467005b\",\n    \"0xb15680648949ce69f82526e9b67d9b55ce5c537dc6ab7f3089091a9a19a6b90df7656794f6edc87fb387d21573ffc847062623685931c2790a508cbc8c6b231dd2c34f4d37d4706237b1407673605a604bcf6a50cc0b1a2db20485e22b02c17e\",\n    \"0x8817e46672d40c8f748081567b038a3165f87994788ec77ee8daea8587f5540df3422f9e120e94339be67f186f50952504cb44f61e30a5241f1827e501b2de53c4c64473bcc79ab887dd277f282fbfe47997a930dd140ac08b03efac88d81075\",\n    \"0xa6e4ef6c1d1098f95aae119905f87eb49b909d17f9c41bcfe51127aa25fee20782ea884a7fdf7d5e9c245b5a5b32230b07e0dbf7c6743bf52ee20e2acc0b269422bd6cf3c07115df4aa85b11b2c16630a07c974492d9cdd0ec325a3fabd95044\",\n    \"0x8634aa7c3d00e7f17150009698ce440d8e1b0f13042b624a722ace68ead870c3d2212fbee549a2c190e384d7d6ac37ce14ab962c299ea1218ef1b1489c98906c91323b94c587f1d205a6edd5e9d05b42d591c26494a6f6a029a2aadb5f8b6f67\",\n    \"0x821a58092900bdb73decf48e13e7a5012a3f88b06288a97b855ef51306406e7d867d613d9ec738ebacfa6db344b677d21509d93f3b55c2ebf3a2f2a6356f875150554c6fff52e62e3e46f7859be971bf7dd9d5b3e1d799749c8a97c2e04325df\",\n    \"0x8dba356577a3a388f782e90edb1a7f3619759f4de314ad5d95c7cc6e197211446819c4955f99c5fc67f79450d2934e3c09adefc91b724887e005c5190362245eec48ce117d0a94d6fa6db12eda4ba8dde608fbbd0051f54dcf3bb057adfb2493\",\n    \"0xa32a690dc95c23ed9fb46443d9b7d4c2e27053a7fcc216d2b0020a8cf279729c46114d2cda5772fd60a97016a07d6c5a0a7eb085a18307d34194596f5b541cdf01b2ceb31d62d6b55515acfd2b9eec92b27d082fbc4dc59fc63b551eccdb8468\",\n    \"0xa040f7f4be67eaf0a1d658a3175d65df21a7dbde99bfa893469b9b43b9d150fc2e333148b1cb88cfd0447d88fa1a501d126987e9fdccb2852ecf1ba907c2ca3d6f97b055e354a9789854a64ecc8c2e928382cf09dda9abde42bbdf92280cdd96\",\n    \"0x864baff97fa60164f91f334e0c9be00a152a416556b462f96d7c43b59fe1ebaff42f0471d0bf264976f8aa6431176eb905bd875024cf4f76c13a70bede51dc3e47e10b9d5652d30d2663b3af3f08d5d11b9709a0321aba371d2ef13174dcfcaf\",\n    \"0x95a46f32c994133ecc22db49bad2c36a281d6b574c83cfee6680b8c8100466ca034b815cfaedfbf54f4e75188e661df901abd089524e1e0eb0bf48d48caa9dd97482d2e8c1253e7e8ac250a32fd066d5b5cb08a8641bdd64ecfa48289dca83a3\",\n    \"0xa2cce2be4d12144138cb91066e0cd0542c80b478bf467867ebef9ddaf3bd64e918294043500bf5a9f45ee089a8d6ace917108d9ce9e4f41e7e860cbce19ac52e791db3b6dde1c4b0367377b581f999f340e1d6814d724edc94cb07f9c4730774\",\n    \"0xb145f203eee1ac0a1a1731113ffa7a8b0b694ef2312dabc4d431660f5e0645ef5838e3e624cfe1228cfa248d48b5760501f93e6ab13d3159fc241427116c4b90359599a4cb0a86d0bb9190aa7fabff482c812db966fd2ce0a1b48cb8ac8b3bca\",\n    \"0xadabe5d215c608696e03861cbd5f7401869c756b3a5aadc55f41745ad9478145d44393fec8bb6dfc4ad9236dc62b9ada0f7ca57fe2bae1b71565dbf9536d33a68b8e2090b233422313cc96afc7f1f7e0907dc7787806671541d6de8ce47c4cd0\",\n    \"0xae7845fa6b06db53201c1080e01e629781817f421f28956589c6df3091ec33754f8a4bd4647a6bb1c141ac22731e3c1014865d13f3ed538dcb0f7b7576435133d9d03be655f8fbb4c9f7d83e06d1210aedd45128c2b0c9bab45a9ddde1c862a5\",\n    \"0x9159eaa826a24adfa7adf6e8d2832120ebb6eccbeb3d0459ffdc338548813a2d239d22b26451fda98cc0c204d8e1ac69150b5498e0be3045300e789bcb4e210d5cd431da4bdd915a21f407ea296c20c96608ded0b70d07188e96e6c1a7b9b86b\",\n    \"0xa9fc6281e2d54b46458ef564ffaed6944bff71e389d0acc11fa35d3fcd8e10c1066e0dde5b9b6516f691bb478e81c6b20865281104dcb640e29dc116daae2e884f1fe6730d639dbe0e19a532be4fb337bf52ae8408446deb393d224eee7cfa50\",\n    \"0x84291a42f991bfb36358eedead3699d9176a38f6f63757742fdbb7f631f2c70178b1aedef4912fed7b6cf27e88ddc7eb0e2a6aa4b999f3eb4b662b93f386c8d78e9ac9929e21f4c5e63b12991fcde93aa64a735b75b535e730ff8dd2abb16e04\",\n    \"0xa1b7fcacae181495d91765dfddf26581e8e39421579c9cbd0dd27a40ea4c54af3444a36bf85a11dda2114246eaddbdd619397424bb1eb41b5a15004b902a590ede5742cd850cf312555be24d2df8becf48f5afba5a8cd087cb7be0a521728386\",\n    \"0x92feaaf540dbd84719a4889a87cdd125b7e995a6782911931fef26da9afcfbe6f86aaf5328fe1f77631491ce6239c5470f44c7791506c6ef1626803a5794e76d2be0af92f7052c29ac6264b7b9b51f267ad820afc6f881460521428496c6a5f1\",\n    \"0xa525c925bfae1b89320a5054acc1fa11820f73d0cf28d273092b305467b2831fab53b6daf75fb926f332782d50e2522a19edcd85be5eb72f1497193c952d8cd0bcc5d43b39363b206eae4cb1e61668bde28a3fb2fc1e0d3d113f6dfadb799717\",\n    \"0x98752bb6f5a44213f40eda6aa4ff124057c1b13b6529ab42fe575b9afa66e59b9c0ed563fb20dff62130c436c3e905ee17dd8433ba02c445b1d67182ab6504a90bbe12c26a754bbf734665c622f76c62fe2e11dd43ce04fd2b91a8463679058b\",\n    \"0xa9aa9a84729f7c44219ff9e00e651e50ddea3735ef2a73fdf8ed8cd271961d8ed7af5cd724b713a89a097a3fe65a3c0202f69458a8b4c157c62a85668b12fc0d3957774bc9b35f86c184dd03bfefd5c325da717d74192cc9751c2073fe9d170e\",\n    \"0xb221c1fd335a4362eff504cd95145f122bf93ea02ae162a3fb39c75583fc13a932d26050e164da97cff3e91f9a7f6ff80302c19dd1916f24acf6b93b62f36e9665a8785413b0c7d930c7f1668549910f849bca319b00e59dd01e5dec8d2edacc\",\n    \"0xa71e2b1e0b16d754b848f05eda90f67bedab37709550171551050c94efba0bfc282f72aeaaa1f0330041461f5e6aa4d11537237e955e1609a469d38ed17f5c2a35a1752f546db89bfeff9eab78ec944266f1cb94c1db3334ab48df716ce408ef\",\n    \"0xb990ae72768779ba0b2e66df4dd29b3dbd00f901c23b2b4a53419226ef9232acedeb498b0d0687c463e3f1eead58b20b09efcefa566fbfdfe1c6e48d32367936142d0a734143e5e63cdf86be7457723535b787a9cfcfa32fe1d61ad5a2617220\",\n    \"0x8d27e7fbff77d5b9b9bbc864d5231fecf817238a6433db668d5a62a2c1ee1e5694fdd90c3293c06cc0cb15f7cbeab44d0d42be632cb9ff41fc3f6628b4b62897797d7b56126d65b694dcf3e298e3561ac8813fbd7296593ced33850426df42db\",\n    \"0xa92039a08b5502d5b211a7744099c9f93fa8c90cedcb1d05e92f01886219dd464eb5fb0337496ad96ed09c987da4e5f019035c5b01cc09b2a18b8a8dd419bc5895388a07e26958f6bd26751929c25f89b8eb4a299d822e2d26fec9ef350e0d3c\",\n    \"0x92dcc5a1c8c3e1b28b1524e3dd6dbecd63017c9201da9dbe077f1b82adc08c50169f56fc7b5a3b28ec6b89254de3e2fd12838a761053437883c3e01ba616670cea843754548ef84bcc397de2369adcca2ab54cd73c55dc68d87aec3fc2fe4f10\"\n  ]\n}"
  },
  {
    "path": "testing/files/spec.toml",
    "content": "# Devnet Chain Spec Configuration\n\n# Gwei value constants\nmax-effective-balance = 4_000_000_000_000\neffective-balance-increment = 1_000_000_000\n\n# Hysteresis parameters\nhysteresis-quotient = 4\nhysteresis-downward-multiplier = 1\nhysteresis-upward-multiplier = 5\n\n# Time parameters\nslots-per-epoch = 32\nslots-per-historical-root = 8\nmin-epochs-to-inactivity-penalty = 4\n\n# Signature domains\ndomain-type-beacon-proposer = \"0x00000000\"\ndomain-type-beacon-attester = \"0x01000000\"\ndomain-type-randao = \"0x02000000\"\ndomain-type-deposit = \"0x03000000\"\ndomain-type-voluntary-exit = \"0x04000000\"\ndomain-type-selection-proof = \"0x05000000\"\ndomain-type-aggregate-and-proof = \"0x06000000\"\ndomain-type-application-mask = \"0x00000001\"\n\n# Eth1-related values\ndeposit-contract-address = \"0x4242424242424242424242424242424242424242\"\nmax-deposits-per-block = 16\ndeposit-eth1-chain-id = 80087\neth1-follow-distance = 1\ntarget-seconds-per-eth1-block = 2\n\n# Fork-related values\ngenesis-time = 0\ndeneb-one-fork-time = 0\nelectra-fork-time = 0\nelectra-one-fork-time = 0\nfulu-fork-time = 0\n\n# State list lengths\nepochs-per-historical-vector = 8\nepochs-per-slashings-vector = 8\nhistorical-roots-limit = 8\nvalidator-registry-limit = 1_099_511_627_776\n\n# Capella values\nmax-withdrawals-per-payload = 16\nmax-validators-per-withdrawals-sweep = 31\n\n# Deneb values\nmin-epochs-for-blobs-sidecars-request = 4096\nmax-blob-commitments-per-block = 4096\nmax-blobs-per-block = 6\nfield-elements-per-blob = 4096\nbytes-per-blob = 131072\n\n# Berachain genesis values\nvalidator-set-cap = 69\nevm-inflation-address = \"0x6942069420694206942069420694206942069420\"\nevm-inflation-per-block = 10_000_000_000\n\n# Deneb1 value changes\nevm-inflation-address-deneb-one = \"0x4206942069420694206942069420694206942069\"\nevm-inflation-per-block-deneb-one = 11_000_000_000\n\n# Electra values\nmin-activation-balance = 32_000_000_000\nmin-validator-withdrawability-delay = 32\n\n# Fulu values (BRIP-0008 hysteresis + PoL vNext)\nhysteresis-quotient-fulu = 100\nhysteresis-upward-multiplier-fulu = 10\nevm-inflation-address-fulu = \"0x4206942069420694206942069420694206942069\"\nevm-inflation-per-block-fulu = 12_000_000_000\n\n[block-delay-configuration]\nmax-block-delay = 300_000_000_000\ntarget-block-time = 2_000_000_000\nconst-block-delay = 500_000_000\nconsensus-update-height = 1\nconsensus-enable-height = 2\n"
  },
  {
    "path": "testing/files/test_data.json",
    "content": "{\n  \"input\": {\n    \"blob\": \"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n    \"commitment\": \"0x93efc82d2017e9c57834a1246463e64774e56183bb247c8fc9dd98c56817e878d97b05f5c8d900acf1fbbbca6f146556\",\n    \"proof\": \"0x9720099d507280aba6a9c9e8c31187336d10dc6a4b04646d1aa42c8d38f891de36f939313cb99e9e7953606555db269a\"\n  }\n}"
  },
  {
    "path": "testing/files/test_data_batch.json",
    "content": "{\n  \"input\": {\n    \"blobs\": [\n      \"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n      \"0x0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002\",\n      \"0x1824b159acc5056f998c4fefecbc4ff55884b7fa0003480200000001fffffffe304962b3598a0adf33189fdfd9789feab1096ff40006900400000003fffffffc6092c566b31415be66313fbfb2f13fd56212dfe8000d200800000007fffffff84d37e37a3c8aae349928a7775c40a7a570681bcd001be41100000010ffffffef26821fa14f77df20ff1776e6aedf77458d12939700396c2300000022ffffffdd4d043f429eefbe41fe2eedcd5dbeee8b1a25272e0072d84600000045ffffffba261ad7321441ff3bc9240392b1dc0510e08caa5900e7548d0000008cffffff734c35ae642883fe779248072563b80a21c11954b201cea91a00000119fffffee6247db575276a7fa6f1563642bdce3c3e2e750561039ef63500000234fffffdcb48fb6aea4ed4ff4de2ac6c857b9c787c5cea0ac2073dec6a00000469fffffb961e092e81740c8153921f0102ed9718f3661671810e7d7cd5000008d4fffff72b3c125d02e81902a7243e0205db2e31e6cc2ce3021cfaf9aa000011a9ffffee56043712b2a694880615422c03acba8bc8449c220139f7975500002354ffffdcab086e25654d29100c2a845807597517908938440273ef2eaa000046a9ffffb95610dc4aca9a5220185508b00eb2ea2f2112708804e7de5d5400008d53ffff72ac21b8959534a44030aa11601d65d45e4224e11009cfbcbaa800011aa7fffee55843712b2a694880615422c03acba8bc8449c220139f7975500002354ffffdcab012f4af01a8f3837a750ba86d8dafa1033fc69c243ef48ea100046aa0fffb955f25e95e0351e706f4ea1750db1b5f42067f8d38487de91d420008d541fff72abe4bd2bc06a3ce0de9d42ea1b636be840cff1a7090fbd23a840011aa83ffee557c23b7d0ba1dfe9e8b75236b6463db3014aa773d1ef7a6190900235508ffdcaaf7476fa1743bfd3d16ea46d6c8c7b6602954ee7a3def4c32120046aa11ffb955ee1af19b954e5cfce5a153d58985cae84d561f5078de9a0825008d5424ff72abdb35e3372a9cb9f9cb42a7ab130b95d09aac3ea0f1bd34104a011aa849fee557b66bc66e553973f396854f5626172ba135587d41e37a68209402355093fdcaaf6c639f3557494a69e4d764d44424b56a655d3cdfc3f4d1e529046aa128fb955ed75350c35b68f756817b8fd0803fc8fcc566bc1b84e9a56e5308d54252f72abdad32b3df63a8512fbac3e5c8f875f0218579ba9306d34c80a711aa84a6ee557b596567bec750a25f7587cb91f0ebe0430af375260da699014e2355094ddcaaf6b256e1d63b77a741a2dc5d4bd9ce1eae10932ca8184d33a69d46aa129cb955ed6339d60523c5b105fd8580bfab929b841bd29bac2d9a68f13b8d54253a72abdac573ac0a478b620bfb0b017f5725370837a537585b34d1e2771aa84a74e557b58a736a6d3bed269aade2c926a640cc3869f6b10cb369a568ef355094eacaaf6b1372e73324b0afb8139258754477f698ce99a47563d34c75df6aa129d6955ed62571e0bef637c1f2def1771280e64b5997df8b46c4a69a8fbfd54253ae2abdac496fd3d69945e66875afb44cf9c2f4db2a6b58e9864d36c380aa84a75d557b58916bba05df622f53a32c2ec1eb7c47de4f82f42f099a6f2b0255094ebbaaf6b1216386646b9ac129fe2523abceeeede499b22aba1034dffa05aa129d7855ed6241531f21840be4d6b4170d7f95d439f12e1097d01d69c1980c54253af1abdac48132509bb4ee2c301ffae127239ed20a56cd71fc37d384d419a84a75e457b5890164a13769dc58603ff5c24e473da414ad9ae3f86fa709a8335094ebc8af6b12025554c7808f134337b84ac48671a65155e20a4cdc4e14f467a129d7925ed6240336bbe7adf48909273d5bb104d9aacaa67056f5b59c2b8cd04253af25bdac48056d77cf5be912124e7ab76209b355954ce0adeb6b385719a084a75e4b7b58900a6701f764a886a754c234ec0b5d0952946d9e32d370afd742094ebc97f6b120135a164776276fd1615130000eb070cd23877ec1a3e1615285129d7930ed624025403ee7992542257a6f262815573fc241bb3fdf44c2c4490b253af262dac480490c9027df20e6cdacab127822a4ddac7e22c21a86858a36174a75e4c6b589009119204fbe41cd9b595624f04549bb58fc4584350d0b146c2e94ebc98d6b12012232409f7c839b36b2ac49e08a9376b1f88b086a1a1628d85d29d7931ad624024464813ef907366d655893c11526ed63f11610d4342c51b0ba53af2635ac4804885514d69ee4cf5d827dedaa224438efdcd864046558a50575a75e4c6c5890090f363c05eaa0013dbcc8a17c3c7ed007b45d0a64c7b14baeec4ebc98d9b120121d6c780bd540027b799142f878fda00f68ba14c98f62975dd89d7931b36240243a65027057566779aaef4c18e9f19e46cc206bef1bc5305fb23af26367c48048735617395b8331760dab5e59cbd99ab592ed1a3a348a62636575e4c6d0890090e53840cb63dcc56ed32382db8fa99393208676d06614c66acbebc98da2120121c9708196c7b98adda64705b71f532726410ceda0cc298cd597d7931b44240243926d15863c49783e045ad196369cac747cc61d9d95531b4f30af26368948048723663d65256952fec0826954652fb710f4387d9727a63842625e4c6d1390090e45588d22f7a9088038d198d0c255cc49e31d3d8a4c4c7228c5bc98da2820121c893d2c9e9c287383296ff7c97ca1f6bbc0e6bd709598e5f58c7931b45140243911066b95e52749890aacb5baf13a4b9f7c79bd3d2831cd8f19f26368a3804872210cd72bca4e931215596b75e274973ef8f37a7a50639b1e33e4c6d1470090e44219ae57949d26242ab2d6ebc4e92e7df1e6f4f4a0c7363c67c98da28e0121c884335caf293a4c485565add789d25cfbe3cde9e9418e6c78cf931b451c0243910866b95e52749890aacb5baf13a4b9f7c79bd3d2831cd8f19f26368a380487221059851551bf93a40d637d861f3fd21789e3ea010339b3873f4c6d1471090e441f3f1c83505589cad293c134367602570e74165e037368b27f98da28e3121c883d0a4b5f4d8176185cf4489064e262d617946f1803e6d3090031b451c7243910791496be9b02ec30b9e89120c9c4c5ac2f28de3007cda612006368a38e487220f2292d7d3605d86173d1224193898b585e51bc600f9b4c2400c6d1471c90e441e4525afa6c0bb0c2e7a24483271316b0bca378c01f369848018da28e3921c883c830c84d84edc40887114f2e461c8b8973f333dc3b6d3234041b451c734391078f61909b09db88110e229e5c8c391712e7e667b876da646808368a38e687220f1e4f338ec08d72a4d41202e110688c4dca7911cceab4ca74116d1471ce0e441e3b2a79762df147cc5ff0cbea18c776c38f9e65f5d269968c23da28e39d1c883c7554f2ec5be28f98bfe197d4318eed871f3ccbeba4d32d1847b451c73a391078ea35f831649b81b4378ff5d05b1439363925da3346a65bd49068a38e757220f1d36bf062c93703686f1feba0b628726c724bb4668d4cb7a920d1471ceae441e3a663f31e3f446953960c9d6964474300df43ab29179970f642a28e39d6c883c74b53f8952b5f3529e3e600fac084e429b93398ae2c32e39086451c73ae91078e953403830394ccd67f98c81d7900267b6d1373b85565c8c50d8a38e75e220f1d29680706072999acff31903af2004cf6da26e770aacb918a1b1471cebc441e3a525c2064bb2995dcb62fe69ddbf6f815aefa113d529724b83728e39d79883c74a344532223298e3c242c9363afe44e5358a064d6a22e4b146f51c73af41078e94514b89cf3297efb0025ecef57befaceabed0c09415c97ccdfa38e75e920f1d289297139e652fdf6004bd9deaf7df59d57da181282b92f99bf471cebd241e3a51252e273cca5fbec0097b3bd5efbeb3aafb4302505725f337e8e39d7a483c74a2431d74046225a5ab8fc2da2b5ee349d5a14a2a607e4c00afe1c73af4a078e944763ae808c44b4b571f85b456bdc693ab429454c0fc98015fc38e75e940f1d288e536f59c55fcbed9bbd7cb2cfaf309d62feccf41c9301cff971cebd291e3a511b32f10c3795fa5def47bf8d9754bf62c0a9dc4436260543f3e39d7a533c74a23565e2186f2bf4bbde8f7f1b2ea97ec58153b8886c4c0a87e7c73af4a678e9446a57d6898b2e4bfa74ebc45e55495bb2fd53b36cd59816b3d08e75e94df1d288d33bbf6bc332fa77a1a44ee4a289158df553a935a8302f0ba21cebd29ce3a511a5039130333c5771fb1563f13d088943e55394c74d605fbb4539d7a53ac74a23490722606678aee3f62ac7e27a111287caa7298e9ac0bf768a73af4a758e9446920e44c0ccf15dc7ec558fc4f422250f954e531d35817eed14e75e94eb1d288d241c898199e2bb8fd8ab1f89e8444a1f2a9ca63a6b02fdda29cebd29d63a511a4839130333c5771fb1563f13d088943e55394c74d605fbb4539d7a53ac74a23490722606678aee3f62ac7e27a111287caa7298e9ac0bf768a73af4a758e9446920705e657bec3f017d25c2773a18af214f91742f5517f0754f75e94eb2d288d23f6ccf23a4aee085b2184b166c27bc6a99cf2abaa72fe28e9febd29d66a511a47d65b09ff634238e1bfd5c54d045d6fd2e4a97d14b5fc6c140d7a53ace4a2348f9577398993ea99eefc77ed198820c22574171fe93bf8f2682af4a759d944691f13af989df53b5c0975bc3cb28fa766ca92f2659247f1ff1065e94eb3c288d23e102056c6b7dce03e6844dbe49eb4b014d0a8f0e45fe41860dbd29d679511a47c1040ad8d6fb9c07cd089b7c93d696029a151e1c8bfc830c1b7a53acf2a2348f820815b1adf7380f9a1136f927ad2c05342a3c3917f9061836f4a759e544691f04102b635bee701f34226df24f5a580a685478722ff20c306de94eb3ca88d23e082056c6b7dce03e6844dbe49eb4b014d0a8f0e45fe41860dbd29d679511a47c1040ad8d6fb9c07cd089b7c93d696029a151e1c8bfc830c1b7a53acf2a2348f8200d6d738c49e37c58e035ba72c91e7b3d5005ed7c906327704a759e554691f03f1adae71893c6f8b1c06b74e5923cf67aa00bdaf920c64ee094eb3caa8d23e07e35b5ce31278df16380d6e9cb2479ecf54017b5f2418c9dc129d679551a47c0fc6b6b9c624f1be2c701add39648f3d9ea802f6be483193b8253acf2aa348f81f862e99171749a4845d021cf248845dbcfaca133c606341b05a759e555691f03ef51e57b8fbf9713436d09c64106e9df9a0584c3890c69da0c4eb3caabd23e07dd2fdd4fcc5590a93ea6d9b47a0431e72eb74be30f18d558199d679558a47c0fb95fba9f98ab21527d4db368f40863ce5d6e97c61e31aab0333acf2ab148f81f724b8797de2ca527b2682cf9e00725c4b58971e83963570467759e556391f03ee3232188692facd21c9d201bb804a9b165bf262c6fc6afaccfeb3caac823e07dc5464310d25f59a4393a403770095362cb7e4c58df8d5f599fd679559047c0fb8a18987a519515cb2a414696d80904ed91a8db0dbc1ac05740acf2ab218f81f7133130f4a32a2b9654828d2db01209db2351b61b783580ae8159e556431f03ee266261e94654572ca9051a5b602413b646a36c36f06b015d02b3caac863e07dc4c50d62b397f10dc09d6fadeb83e859487f31ac9ddd6045e066795590d7c0fb8972dbeaf1fd4843acb7abbe5687369510a9277efb8ac0a600dcf2ab21bf81f712d5b7d5e3fa9087596f577cad0e6d2a21524efdf715814c01b9e556437f03ee25a430d152c28736de5b7b5bd99c4036c24f6221adfb02b24383caac870e07dc4b3122c830527495e833c31a32b7e650044988691bc6057ec71795590e2c0fb89652459060a4e92bd0678634656fcca0089310d2378c0afd8e2f2ab21c581f712ca48b20c149d257a0cf0c68cadf9940112621a46f1815fb1c5e556438b03ee25941d7670d610ad76d1ae534153e9862a1f7076e9e002c1078ccaac871707dc4b273aece1ac215aeda35ca682a7d30c543ee0edd3c005820f1995590e2e0fb8964e01ec1c0519185dfe86132d479c76d0786e1e037d0b05c2342ab21c5d1f712c9b03d8380a3230bbfd0c265a8f38eda0f0dc3c06fa160b8468556438ba3ee2593607b07014646177fa184cb51e71db41e1b8780df42c1708d0aac871747dc4b26c0f60e028c8c2eff430996a3ce3b683c370f01be8582e11a15590e2e8fb8964d81ec1c0519185dfe86132d479c76d0786e1e037d0b05c2342ab21c5d1f712c9b03d8380a3230bbfd0c265a8f38eda0f0dc3c06fa160b8468556438ba3ee259360071959f31c7a0259519179df1412461633c33b3fc172310bac871748dc4b26bf0e32b3e638f404b2a322f3be28248c2c6786767f82e46217590e2e91b8964d7e1c6567cc71e809654645e77c50491858cf0cecff05c8c42eb21c5d23712c9afc38cacf98e3d012ca8c8bcef8a09230b19e19d9fe0b91885d6438ba46e25935f871959f31c7a0259519179df1412461633c33b3fc172310bac871748dc4b26bf06f3d971065a2cde1fef563da78a6eac124a9c3f52e47c57690e2e91c8964d7df6a8d86cda1a81e7bcab0eface7abfd7cf595e3e75c912eee21c5d23a12c9afbd612d664819b2bfaf62280751c5b622f4976e23cbb92401dd438ba47525935f794e6d253d09c802169116369b81ca6de3db1ea3947249a7bb871748eb4b26bef128eca326e9f286e4eef2952ef9f303c2627fa325e494f3780e2e91d7964d7de151d9464dd3e50dc9dde52a5df3e60784c4ff464bc929e6f01c5d23af2c9afbc22fc4e5487e2c9e4b88907cb3de2a37043640e894925571e138ba475f5935f7835f89ca90fc593c971120f967bc546e086c81d12924aae3c271748ebeb26bef064b25edcecf14fbe5ef081ac76f07040b8545fe4f49576b85e2e91d7e64d7de0b225e344a748c7a83aad65d86d46c3011b6ce589b92b07b0cc5d23afdc9afbc1544bc6894e918f50755acbb0da8d860236d9cb1372560f6198ba475fb935f782a158b29d6a8946cc6781f9e13480ee841877bbe6b4ac390341748ebf826bef0532b1653ad5128d98cf03f3c26901dd0830ef77cd6958720682e91d7f04d7de0a6562ca75aa251b319e07e784d203ba1061deef9ad2b0e40d05d23afe09afbc14c386ba7621b05e8eb8dc3189236d56a06e8204f57561e25a1ba475fc235f7829770d74ec4360bd1d71b8631246daad40dd0409eaeac3c4b43748ebf846bef052e6dc0f635427a266603d28a40d1b3d0164cc3995a587a3a87e91d7f09d7de0a5b679445175b56cf83d46b3c7999c5c82745c98eb1b0f61910d23afe14afbc14b55b3ae2db8d1021bf759ca0eb29e9b84937d5796061edd622a475fc2a5f78296942881e63f082c636b7ff69ce4a31988d1bed4ebdc3dd504648ebf855bef052d111229574b7680f253cc4fb948ac15914e41cf97887bc448d91d7f0ac7de0a5a122452ae96ed01e4a7989f7291582b229c839f2f10f78891b23afe158fbc14b42448a55d2dda03c94f313ee522b0564539073e5e21ef11236475fc2b1f78296841527045291a2fbe1b2ee049c4c68f0a1cd2a27c13de3c86d8ebf8564ef052d072a4e08a52345f7c365dc093898d1e1439a544f827bc790db1d7f0ac9de0a5a0e549c114a468bef86cbb8127131a3c28734a89f04f78f21b63afe1593bc14b41c354a7b41637a61c564364cda59a5ad0915939a06ef1fe76d75fc2b28782968376a94f682c6f4c38ac86c99b4b34b5a122b27340dde3fcedaebf85650f052d06e613c45b2644c09cd5d9f5b615cf4dc1f0290c418bc8141b6d7f0aca2e0a5a0db4e8ae4119efa96528804debab047e038b163e42e7904276eafe15946c14b41b5292820d01457af5cdccfe56d56ede86c0f0a2459f209f2de5fc2b28e82968369525041a028af5eb9b99fcadaaddbd0d81e1448b3e413e5bcbf85651d052d06d230b2dbed27c1402b4005bdad5215c9aae86aed64c8296f7a7f0aca3b0a5a0da36165b7da4f828056800b7b5aa42b9355d0d5dac99052def4fe15947614b41b464eddc86175678364ccdd1ead3eb54ea64dee119020a761eafc2b28ed2968368b29cde96fc13189816680655273c8c547481e7f1d415067d6f85651db52d06d15539bd2df82631302cd00caa4e7918a8e903cfe3a82a0cfadf0aca3b6a5a0da2a3349fe6bdb28a8bd66c7bd41c5813d17ccbc58720543435ce159476e4b41b4536693fcd7b651517acd8f7a838b027a2f9978b0e40a8686b9c2b28edc968368a6593a525c430525ad67e51cff0c631c59df33bdc5150eb17485651dba2d06d14b3e86fd655c6cce129c9061f60f2460ae6aa9d7872a1f06ea0aca3b755a0da295092053778f3c1edd05e6ebe414a6e95781960b0b543fb1d5159476ebb41b45291240a6ef1e783dba0bcdd7c8294dd2af032c1616a87f63aa2b28edd768368a5224814dde3cf07b74179baf90529ba55e06582c2d50fec7545651dbaed06d14a449029bbc79e0f6e82f375f20a5374abc0cb0585aa1fd8ea8aca3b75da0da29481e179025ca2470882b34e63940ccbd72c5a30cb243fcc15259476ebc41b4528f3c2f204b9448e1105669cc7281997ae58b46196487f982a4b28edd788368a51e04709943fef444d87999c0dcf9911dc5c2ce8ec60ff4a94a651dbaf206d14a3b08e13287fde889b0f33381b9f3223b8b859d1d8c1fe95294ca3b75e40da2947611c2650ffbd11361e6670373e64477170b3a3b183fd2a5299476ebc81b4528ec2384ca1ff7a226c3ccce06e7cc88ee2e167476307fa54a5328edd790368a51d84709943fef444d87999c0dcf9911dc5c2ce8ec60ff4a94a651dbaf206d14a3b01a25812cb4eb1dc6fffe43972881e0b3061434befe96cd4da3b75e41da29475f344b025969d63b8dfffc872e5103c1660c28697dfd2d9a9b476ebc83b4528ebe689604b2d3ac771bfff90e5ca20782cc1850d2fbfa5b35368edd790768a51d7c5d3e62127dbb70efccb844b13a6d2d92dce401f4f4b80e6e1dbaf20fd14a3af7468f1cd1d1d964976636b15a6b388320660a5fe6e971c0dd3b75e420a29475ed193092507a154be699338aaccccf2e3b78571bcad2e525bb76ebc8424528ebd9326124a0f42a97cd32671559999e5c76f0ae3795a5ca4b76edd790848a51d7b264c24941e8552f9a64ce2ab3333cb8ede15c6f2b4b9496eddbaf210914a3af645596eb30a70ce1ec96627d5e5cd799d66efb3a53972ad1dcb75e421329475ec737402f0e247c4690f98b22b4b00d5ba78a38d0a42e5747ba6ebc8427528ebd8d6e805e1c48f88d21f3164569601ab74f1471a1485cae8f74dd79084ea51d7b1a691314e568539cfbb2f2b2cab6939698d5259e8db95ec2eabaf2109e4a3af6335e388277a709bcaf32ab8d8d6385552c568d991872bf29d675e4213d9475ec6548835d9c2475fc16321d4312bd68d253595d8e2de57ff7adebc8427c28ebd8c91d1913e51f4e7ae43100ae1d712fcca15efd7858cb01935cd79084f951d7b1913a3227ca3e9cf5c862015c3ae25f9942bdfaf0b1960326b9af2109f2a3af63220076a841539c6e4890c8e06dbb1d5a8028383d602c07f1745e4213e6475ec64300ed5082a738dc912191c0db763ab50050707ac0580fe2e8bc8427cc8ebd8c8601daa1054e71b922432381b6ec756a00a0e0f580b01fc5d179084f991d7b190c03b5420a9ce372448647036dd8ead40141c1eb01603f8ba2f2109f323af63218076a841539c6e4890c8e06dbb1d5a8028383d602c07f1745e4213e6475ec64300ed5082a738dc912191c0db763ab50050707ac0580fe2e8bc8427cc8ebd8c8601daa1054e71b922432381b6ec756a00a0e0f580b01fc5d179084f991d7b190c03b5420a9ce372448647036dd8ead40141c1eb01603f8ba2f2109f323af63218002ba9a0072d0cb4895a695b313b8a822e47fbc2907f3185f4213e6485ec642ff05753400e5a196912b4d2b6627715045c8ff78520fe630be8427cc90bd8c85fe0aea6801cb432d22569a56cc4ee2a08b91fef0a41fcc617d084f99217b190bfc15d4d00396865a44ad34ad989dc5411723fde1483f98c2fa109f3242f63217f82ba9a0072d0cb4895a695b313b8a822e47fbc2907f3185f4213e6485ec642ff05753400e5a196912b4d2b6627715045c8ff78520fe630be8427cc90bd8c85fe03ab8d8c98a9554dd366b94bce48830b3cc31663efcc7bbd184f99218b190bfbf01840a3feb8d2c72399d5171bf6e896244a5287af9911ba409f3243263217f7d0308147fd71a58e4733aa2e37edd12c4894a50f5f322374813e64864c642fefa061028ffae34b1c8e67545c6fdba25891294a1ebe6446e9027cc90c98c85fdf40c2051ff5c696391ccea8b8dfb744b12252943d7cc88dd204f992193190bfbe81840a3feb8d2c72399d5171bf6e896244a5287af9911ba409f3243263217f7d0308147fd71a58e4733aa2e37edd12c4894a50f5f322374813e64864c642fefa061028ffae34b1c8e67545c6fdba25891294a1ebe6446e9027cc90c98c85fdf404e1778a29cf8bbd49b6ee0d7ada2d91cfed69979c88f7605f992193290bfbe7f284149f21053fa6103a3e9a751a3da34a9ef8ef09120900cf3243266217f7cfd508293e420a7f4c20747d34ea347b46953df1de122412019e64864cc42fef9fa2d17807517b26c3bdb55ce953ced90cd540097bf4483e434cc90c99985fdf3f35a2f00ea2f64d877b6ab9d2a79db219aa8012f7e8907c869992193330bfbe7e640705a81352c33a73a1d624cea146b2ffc44bafa121134d43243266717f7cfcb0cf30daf40baea064100ec91ca86fe5aa4cbd1f124240da964864ccf2fef9f9519e61b5e8175d40c8201d923950dfcb54997a3e248481b52c90c999e5fdf3f2a33cc36bd02eba8190403b2472a1bf96a932f47c4909036a59219333cbfbe7e5467986d7a05d750320807648e5437f2d5265e8f8921206d4b243266797f7cfca85b4333a0e211231bdcd4f1149ece0da4f8ff7b0f42427e974864ccf3fef9f94f4298bfee9a84c8ef86700a2133fa43449e41521b8486a12f90c999e8fdf3f29d1143d88a0b6c1496d9a63c3a5e52ae83e8c50034090ee660219333d2fbe7e5392287b11416d8292db34c7874bca55d07d18a0068121dccc0432667a5f7cfca72450f62282db0525b6698f0e9794aba0fa31400d0243b9980864ccf4bef9f94e416311cfd31c3276e99f809cae8f39c19f26a5d9d4878d7020c999e98df3f29c72c6239fa63864edd33f01395d1e73833e4d4bb3a90f1ae0419333d31be7e538e58c473f4c70c9dba67e0272ba3ce7067c9a9767521e35c0832667a637cfca71c3d9b4096647bbe2c9c86764f3dfb08ca3f9548e743c85c1164ccf4c7f9f94e370748d9d99f59ff1105d314967254398f2b6cedcb87925c23c999e990f3f29c6d0e91b3b33eb3fe220ba6292ce4a8731e56d9db970f24b8479333d321e7e538da1d2367667d67fc44174c5259c950e63cadb3b72e1e49708f2667a643cfca71b43a46ceccfacff8882e98a4b392a1cc795b676e5c3c92e11e4ccf4c879f94e368009ff646cc0273c829f7715f1ba1c0ed631138b57927663d999e99103f29c6cf013fec8d9804e79053eee2be374381dac622716af24ecc7b333d32207e538d9e027fd91b3009cf20a7ddc57c6e8703b58c44e2d5e49d98f6667a6440fca71b3c04ffb23660139e414fbb8af8dd0e076b1889c5abc93b31ecccf4c881f94e367809ff646cc0273c829f7715f1ba1c0ed631138b57927663d999e99103f29c6cf013fec8d9804e79053eee2be374381dac622716af24ecc7b333d32207e538d9e027fd91b3009cf20a7ddc57c6e8703b58c44e2d5e49d98f6667a6440fca71b3c04ffb23660139e414fbb8af8dd0e076b1889c5abc93b31ecccf4c881f94e367802c089f78d8d64ae1c4378713981f155dbd7b11762767e19a9e99104029c6ceff58113ef1b1ac95c3886f0e27303e2abb7af622ec4ecfc3353d322080538d9dfe3c34d69039bbae3edda4444656da7d71a22ea1d59da12a6b7a644101a71b3bfb047c05cd49d9df35880eb084a41322ddf09f9fa83b43f8d7f4c882044e3677f508f80b9a93b3be6b101d6109482645bbe13f3f507687f1afe99104089c6cefea11f0173527677cd6203ac212904c8b77c27e7ea0ed0fe35fd322081138d9dfd423e02e6a4ecef9ac40758425209916ef84fcfd41da1fc6bfa644102271b3bfa847c05cd49d9df35880eb084a41322ddf09f9fa83b43f8d7f4c882044e3677f501b931256119e6968ce9c388c78c283b8c03651046880beff9910408ac6cefe9f372624ac233cd2d19d387118f1850771806ca208d1017dff322081158d9dfd3e6e4c49584679a5a33a70e231e30a0ee300d94411a202fbfe6441022b1b3bfa7c68aaeb5d6355cdfe41a7ec5bbc7245c0adf4e42044079bfdc88204573677f4f75d682f679d0e1eb4501600af6f42b37c082c243d8810dbfc910408af6cefe9ed46e2b77c107ec0206cf22956d4e38ef2bc9aa47810235bfa2208115fd9dfd3d919d7c7a4f76002f8a6aa7aa5a02545e02577a4ed20485bf5441022c0b3bfa7b133af8f49eec005f14d54f54b404a8bc04aef49da4090b7ea88204581677f4f62675f1e93dd800be29aa9ea968095178095de93b481216fd510408b02cefe9ec45ad095d491629a7d0219fd24f78856fbd7ff8366024483ab208116069dfd3d8741b38455f927b7b1d0fa2241e56ed5f25c4162c9048aab5741022c0e3bfa7b0d0f796158c8b1f21b6eba6c7bc13bd3df64c5218f0916faaf8204581d77f4f6191ef2c2b19163e436dd74d8f78277a7bec98a431e122df55f0408b03aefe9ec323de5856322c7c86dbae9b1ef04ef4f7d9314863c245beabe08116075dfd3d86407dd63731bf2139342998bd6003cc6f5d26b687548b9797d1022c0ecbfa7b0c70fbac6e637e42726853317ac00798deba4d6d0ea9172f2fa204581d97f4f618e1f758dcc6fc84e4d0a662f5800f31bd749ada1d522e5e5f4408b03b2fe9ec31c3eeb1b98df909c9a14cc5eb001e637ae935b43aa45cbcbe881160765fd3d863809e88fde9583bbebf65ee557fa2a9757d2f8e3518b993bd2022c0eccfa7b0c6f13d11fbd2b0777d7ecbdcaaff4552eafa5f1c6a3173277a404581d99f4f618de27a23f7a560eefafd97b955fe8aa5d5f4be38d462e64ef4808b03b33e9ec31bc4f447ef4ac1ddf5fb2f72abfd154babe97c71a8c5cc9de9011607667d3d863782a9b56962e9e417732b47d7799079d77dbd09115b995612122c0ecd0a7b0c6ef5536ad2c5d3c82ee6568faef320f3aefb7a1222b732ac2424581d9a14f618dde367fb30590db889497981dd65a7c9dda1b84a053e65728858b03b3439ec31bbb6cff660b21b711292f303bacb4f93bb4370940a7ccae510b160766873d863776661124c319d0a50a2b269f5160509f631a54dd4c995e46172c0ecd0f7b0c6eeb5834a2330a03cccc2313669ab6ff66c0e0ec169632be302f581d9a1ff618ddd53c7b9d12ea6a1c5012ecf52d645cf57c6e1a8929657e045fb03b3440ec31bba9050992d2ab36bb57f2a01252bf1812f388776e4fcafdacc060766882d86377510a1325a5566d76afe54024a57e3025e710eedc9f95fb5980c0ecd105b0c6eea214264b4aacdaed5fca80494afc604bce21ddb93f2bf6b30181d9a20b618ddd44284c969559b5dabf95009295f8c0979c43bb727e57ed660303b34416c31bba8850992d2ab36bb57f2a01252bf1812f388776e4fcafdacc060766882d863775102d44b3023d39edb620c8724fd960866bbb3025f65fb73c0d0ecd105c0c6eea1f5a8966047a73db6c4190e49fb2c10cd776604becbf6e781a1d9a20b818ddd43e412524b5cb4a39904fe7f1375be041a99902f3d67ede94353b34417131bba87b0e5ca2186cf6f5d86c960a66ae1eab4dde4843a9fdbecc6b766882e3637750f51cb94430d9edebb0d92c14cd5c3d569bbc908753fb7d98d6ecd105c6c6eea1ea39728861b3dbd761b258299ab87aad3779210ea7f6fb31add9a20b8d8ddd43d472e510c367b7aec364b0533570f55a6ef2421d4fedf6635bb344171b1bba87a871dc7a33a5d1e03e9626ce62d848dcd890c6969cdbee6ab866882e3737750f4f6fcb4d1422064334f913c4bda6efe1abcdcf8936b7de7971cd105c6f6eea1e9d6ba8f2d51a6f0921beedb173443deb5247e16e6a6fbe96e49a20b8dfddd43d3963643e570b4094fb4aa18ade7ed9fe9f3c0538d1df7ed1ca344171c0bba87a7152dad55aece3acae62093db4f4122539244ccda0beff47956882e3827750f4e131c80362b029dc1490d8a361de82726cf4dbf73e7e00332bd105c705eea1e9c1639006c56053b82921b146c3bd04e4d9e9b7ee7cfc006657a20b8e0bdd43d382533266379709f30a1028b57f7067f1ae7fb238f6f80270b044171c18ba87a7033277251c047668cbed1792f6d72e0b57aba6cdeaf0068561882e3832750f4e0564ee4a3808ecd197da2f25edae5c16af574d9bd5e00d0ac3105c7064ea1e9c0a55eeed1ce83c25e7812473d3531655595add93a8c01bb98720b8e0cad43d381337f032e6a6dace86cf0f0f9e9c8ad2ad61fd834e8039170f4171c196a87a70256fe065cd4db59d0d9e1e1f3d3915a55ac3fb069d00722e1e82e3832d50f4e04a6bd3244771cdbcd309026672688972b03438693700e6003e05c7065ba1e9c09363b8a13bb9fdfc5ddecaf4dcc7710d5b14b32e6b01cda47d0b8e0cb843d3812553839b244a5e7b738a5c11b1854042b0d5a8b8d3039cecfb171c197187a7024933198ef56b1f799ee17e4b5b00dead5c5793cda3073b7df72e3832e40f4e049166331dead63ef33dc2fc96b601bd5ab8af279b460e76fbee5c7065c81e9c09225878948282e0693352bf5563f9d8dd6c0a9192891cef9bddb8e0cb913d3812433d0381b1dc23551e7244d2bfea0fe2d2c165810f39e0dbbc71c197237a70248506195c108ea92cf4b14fcd77ca7deda02f0d5e1b73c35b79e3832e47f4e049090c32b8211d5259e9629f9aef94fbdb405e1abc36e786b6f3c7065c8fe9c09212186570423aa4b3d2c53f35df29f7b680bc35786dcf0d6de78e0cb91fd381242430cae084754967a58a7e6bbe53ef6d01786af0db9e1adbcf1c19723fa70248486195c108ea92cf4b14fcd77ca7deda02f0d5e1b73c35b79e3832e47f4e0490904f3ddabeab88214df6bfd6f1461bdc008dee1f6b786d133d7065c8ff9c09211f2a8e0e2a2d72c553ba45d5da8295dffbc81e9ad3f0dbca7be0cb92003812423d551c1c545ae58aa7748babb5052bbff7903d35a7e1b794f7c19724007024847a364a91558c2d9806b5dd7f6200b5a7e9ccbcc74cc370cdf0832e4801e04908f36c9522ab185b300d6bbafec4016b4fd399798e9986e19be1065c9003c09211e6653c9e030718e2d2a43c257ff934c7a1df3579300dc4dbc30cb92008812423cb568b94b2e494485d153e72f7e8c7b73e6aad4e5d1b8b5b871972401202484795392982129f8b1371f7430de7c7ed9677819cf8b737185b0f32e4802504908f29725304253f1626e3ee861bcf8fdb2cef0339f16e6e30b61e65c9004a09211e5270b860f7548ed07fa9d25f97161481d8b2b63ed9dc63103dcb92009512423ca36d831a9b7f8023b7206ae72622872bac11aed9b0b8c7c47c9724012b2484794567188de3d562ca260d9bf6443b6c7f52cfa00f5e71912cfa2e4802574908f2895a43747481281703e7fe14806d3726a04b827ab9e323fdf55c9004af9211e51140994195d8b2b0bf9cc250f8d0cc753b43475170c6499febb92009602423ca210d44dbd887c7e437064ac9e997f7127132d0fede8c94e3d8724012c1484794411a89b7b10f8fc86e0c9593d32fee24e265a1fdbd1929c7b0e4802582908f288235136f621f1f90dc192b27a65fdc49c4cb43fb7a32538f61c9004b05211e51046a26dec43e3f21b832564f4cbfb893899687f6f464a71ec39200960a423ca2086060163552e0c6283172c69175cf4f0dd95249e5c94fe18824012c158479440f4cd285177c240f082fabb51ae1fcc6165ee6efc892a167114802582c08f2881d25b762dbceaaa0c82c1d922dba57b4276a103b8e254472239004b05911e510394b6ec5b79d554190583b245b74af684ed420771c4a88e447200960b223ca207222efe41c110d05d87d3c70aedfbcf89854834a3595136c8f4012c165479440e345dfc838221a0bb0fa78e15dbf79f130a906946b2a26d91e802582ca8f2881c617d1e91d1a969a19c1b7eab375520a5bfe4f84d3544f563e004b05961e51038b2fa3d23a352d3433836fd566eaa414b7fc9f09a6a89eac7c00960b2c3ca207165f47a4746a5a686706dfaacdd548296ff93e134d513d58f8012c165879440e2c4aa1a195ab175385da857d93a0ee7ada9ebe8297a27c55f102582cb1f2881c5721559bd82c9129c381d1231f383b1dafe9bf612c44fa4fe304b05964e51038ad42ab37b05922538703a2463e70763b5fd37ec25889f49fc60960b2c9ca20715a1168c80d88a729c5d40ab474d74a9eba533fe0ae13eae38d12c165949440e2b322d1901b114e538ba81568e9ae953d74a67fc15c27d5c71a2582cb292881c56645a32036229ca717502ad1d35d2a7ae94cff82b84fab8e344b05965251038acc175899191b9bd0e66d1bcb9eb0b31dcd4641616d9f58c069960b2ca5a20715972eb132323737a1ccda37973d61663b9a8c82c2db3eb180d32c16594b440e2b2e5d6264646e6f4399b46f2e7ac2cc7735190585b67d6301a6582cb296881c565c46d72175b34109eb35a484ed7bf71664de4d6769fac7a74db059652e1038acb719c09b983ce4968e380f31d2ee4c54c468dd2ad0f590f29c60b2ca5d2071596d3381373079c92d1c701e63a5dc98a988d1ba55a1eb21e538c16594ba40e2b2da67026e60f3925a38e03cc74bb9315311a374ab43d643ca7182cb297481c565b45a17356ebd8737298d3fb68f68c0ce1df32bb284ac8938e4059652ea038acb674040c38a5170f10ae7459516c7dfc4369299c106591415c90b2ca5d5071596cd0c93dfc1794464cd9b515225861db067d175de09b229cf9316594bab0e2b2d991927bf82f288c99b36a2a44b0c3b60cfa2ebbc1364539f262cb297561c565b32324f7f05e51193366d4548961876c19f45d77826c8a73e4c59652eac38acb664649efe0bca23266cda8a912c30ed833e8baef04d914e7c98b2ca5d5871596cc8555054c46aa8cf9181db4a5058392e77c3a03c98229e9d326594bab1e2b2d98f36b30235abb421dad07cbc98a6d084ea3382d52d453ede65cb297564c565b31d6d66046b576843b5a0f979314da109d46705aa5a8a7dbccb9652eac98acb663a66de618385330a230eb91a5a91a03ba37a4db0b214fd1d982ca5d5941596cc7359cf1bb3e0c896fdea385cad199e9f41a0ddbd6129fbdf31594bab292b2d98e53fb0901497f3b0b3a136e152299b667dedfdd6bf53f96263b2975653565b31c90b7378d60649e41f0f33ea9c4994f4f6883e097ba7f468c8652eaca7acb6639116e6f1ac0c93c83e1e67d5389329e9ed107c12f74fe8d190ca5d594f596cc7222dcde3581927907c3ccfaa712653d3da20f825ee9fd1a32194bab29eb2d98e445b9bc6b0324f20f8799f54e24ca7a7b441f04bdd3fa346432975653d65b31c884349e60d3b00c4a8c004d1bc8fad77633022f3b77f48308752eaca7bcb66390f12a624c74c640c094ccfcb7115b916c10c88436bfe92050fa5d594f896cc721d254c498e98c81812999f96e22b722d82191086d7fd240a1f4bab29f12d98e43a4a98931d31903025333f2dc456e45b0432210daffa48143e975653e25b31c87421437ee73982e30233448380a426de031084775cf491cc7e2eaca7c5b66390e74286fdce7305c60466890701484dbc062108eeb9e92398fc5d594f8b6cc721ce11205449bc6e0ec099d835fa86f9a006ee543970d248d5f9bab29f17d98e439b2240a89378dc1d8133b06bf50df3400ddca872e1a491abf375653e2fb31c873644815126f1b83b026760d7ea1be6801bb950e5c3492357e6eaca7c5f66390e6c1514fafab9d2f8bc9b87d7cc2e2b28321ee42783924853ced594f8bfcc721cd72a29f5f573a5f179370faf985c5650643dc84f072490a79dab29f17f98e439ae5453ebeae74be2f26e1f5f30b8aca0c87b909e0e49214f3b5653e2ff31c8735c34ba3082a4fa489ca904e65967b7698ba363981992444277aca7c5ff6390e6b76974610549f491395209ccb2cf6ed31746c73033248884ef594f8bfec721cd6e5efb1ab76a4ba52a70d9c15d953bce2939d0bc634912addfb29f17fe8e439adb4a088e1baaf9cd0cae79aab320d5c44d1fe3d4c39226ffc0653e2ffe1c8735b5202374e42c561cd129b97d5e3809b094ec0a0584244fa381ca7c5ffd390e6b694046e9c858ac39a25372fabc70136129d8140b08489f470394f8bffa721cd6d20ca02c3d87baf5fc73ac1d70d684ea4e5c6a720d9140320829f17ff5e439ada31940587b0f75ebf8e7583ae1ad09d49cb8d4e41b2280641053e2ffebc8735b463280b0f61eebd7f1ceb075c35a13a93971a9c8364500c820a7c5ffd790e6b68c650161ec3dd7afe39d60eb86b4275272e353906c8a0190414f8bffaf21cd6d1856151c855211e27f0787ff055eaccce072e97cd61404c4839f17ff5f439ada2f383c91b77a8647b5dbd62602b3b7c1bb921555a9280b2d083e2ffebf8735b45d7079236ef50c8f6bb7ac4c05676f8377242aab5250165a107c5ffd7f0e6b68ba6d049f8ac07ba18f3c1ec002c53d2ee8f497b2a1a02e5821f8bffaff1cd6d173661b97c25759c5d64503a7fd80d885cc9571c140405e5444f17ff5ff39ada2e55849883185160e6456cd77f2f80f3393d725de7d80be4c8ae2ffebff735b45c93ca5690fe08e9f807a6117dde67c8f225a8e18f8017e3d16c5ffd7ffe6b68b91055d2acc977fc1b8c18857b3c357463f615e8ded02fe1e2e8bffb000cd6d17210aba55992eff83718310af6786ae8c7ec2bd1bda05fc3c5d17ff60019ada2e421574ab325dff06e306215ecf0d5d18fd857a37b40bf878ba2ffec00335b45c842ae95664bbfe0dc60c42bd9e1aba31fb0af46f6817f0f1745ffd80066b68b90855d2acc977fc1b8c18857b3c357463f615e8ded02fe1e2e8bffb000cd6d1721037b7b23fc65ab9cffdd11e706146efe6d814199d5fc569d27ff6001aada2e41f6f6f647f8cb5739ffba23ce0c28ddfcdb028333abf8ad3a4ffec00355b45c83e6af121abefcd69f7c40aa1b97b79e7960c92c2727f174b4affd8006bb68b907b61f49c04b5fd56a754db6b6aed51f726c567e0e1fe303a96ffb000d86d1720f54ffb90b6425d3006767cfecdd102164837121dc0fc62192eff6001b1da2e41e92c097a195b1ce2c4b9c025939862548b1a66977ef8c5d65efec00364b45c83d15812f432b639c58973804b2730c4a91634cd2efdf18bacbdfd8006c968b907a23c38411242d60dcab3c6be4657e77a2715dcb9f8e318fd7cfb000d93d1720f430482dad15c0e9e4d3453a484a62d1c48d7fbcfeec6339efaf6001b28a2e41e850905b5a2b81d3c9a68a749094c5a3891aff79fdd8c673df5ec00365145c83d0a120b6b45703a7934d14e921298b471235fef3fbb18ce7bebd8006ca28b907a142416d68ae074f269a29d24253168e246bfde7f76319cf7d7b000d9451720f428482dad15c0e9e4d3453a484a62d1c48d7fbcfeec6339efaf6001b28a2e41e8501c6db2d858364c5e573ab88cbc01b115abbc59d5c675835fc00365155c83d09f38db65b0b06c98bcae7571197803622b5778b3ab8ceb06bf8006ca2ab907a13e71b6cb6160d931795ceae232f006c456aef1675719d60d7f000d9455720f427c6f7fef6f9814e5aa869bec5dd66bb0a80a252aab33adbeff001b28abe41e84f76b12378c068c4e0cd9fe00b3a335894ac08cb153675d21ff00365158c83d09ed6236c7c4e37b1ed180c2295f3cc93a902d5bbea3cebbe7ff006ca2b2907a13d9507fe8369d58c05ace4a7ab66ff09d1b06f9d9449d7973ff00d9456620f427b12d12291a1114036d695b1d64d63f6230ba360e863af48bff01b28acd41e84f615a245234222806dad2b63ac9ac7ec461746c1d0c75e917fe0365159a83d09ec2405afd151ab2906d72329d8b4f5bb0bd951a9615ebd3d3fd06ca2b3607a13d830cc852d70bc7a392b12b630e95158975d6778828d7a94bfb0d94566d0f427b051990a5ae178f47256256c61d2a2b12ebacef1051af5297f61b28acda1e84f60a33214b5c2f1e8e4ac4ad8c3a545625d759de20a35ea52fec365159b43d09ec14664296b85e3d1c95895b1874a8ac4baeb3bc4146bd4a5fd86ca2b3687a13d8285897861d92dcbbe2df7c58e147b6bf5813bade8a7a9663b1d94566d1f427b04f3d4164e7fc1bfa7d8bbed9ba85cba6aad3b81911f52e6b64b28acda4e84f609d0695227cce9a77b2e443db6d01f5755053b28e20ea5e7aca65159b4ad09ec1390d2a44f99d34ef65c887b6da03eaeaa0a7651c41d4bcf594ca2b3695a13d82721a5489f33a69decb910f6db407d5d5414eca3883a979eb2994566d2b427b04e434a913e674d3bd97221edb680fabaa829d94710752f3d65328acda5684f609c8695227cce9a77b2e443db6d01f5755053b28e20ea5e7aca65159b4ad09ec13905eb6a846a9b1791455419598350cd2052294201a4bd0fd4da2b3695b13d8271f497fa93a29c574e0774953286077cc04f16a9c3197a39e9c4566d2b727b04e3d1f11ab2129ed6c78bb58ce48b74dc0048f1794602f48e1398acda56f4f609c793e23564253dad8f176b19c916e9b80091e2f28c05e91c273159b4ade9ec138f2085905317e18349aba29611ad395280ce8a0ad7dbd2528e72b3695be3d8271e310b20a62fc3069357452c235a72a5019d1415afb7a4a51ce566d2b7c7b04e3c6216414c5f860d26ae8a5846b4e54a033a282b5f6f494a39cacda56f8f609c78c42c8298bf0c1a4d5d14b08d69ca9406745056bede929473959b4adf1ec138f1811a2abc4b7e5cc636f5c39a52fb0a8c9364d33d8d2543273b3695be4d8271e2f234557896fcb98c6deb8734a5f6151926c9a67b1a4a864e766d2b7c9b04e3c5e468aaf12df97318dbd70e694bec2a324d934cf634950c9cecda56f93609c78bc1927b6d29590e5d347a7f52173e36e445eabfac392a3379e9b4adf27c138f177324f6da52b21cba68f4fea42e7c6dc88bd57f58725466f3d3695be4f8271e2ee649edb4a5643974d1e9fd485cf8db9117aafeb0e4a8cde7a6d2b7c9f04e3c5dc55500f4182e9b1520a05d10395799a1da1a23219951b60f5da56f93f09c78bb736b2772fdc35e55be0d1c9ff21515c35ef86c0302a3865ecb4adf27f138f176d6d64ee5fb86bcab7c1a393fe42a2b86bdf0d80605470cbd9695be4fe271e2eda66dc356c473a1827500d4ff47ba398d26a5d5cbda8e33bb3d2b7c9fd4e3c5db359cac38564d6b3066ce0c7e0eda5599f80fd157851c81b68a56f93fb9c78bb653fa7dfb7a00fe8c4a687b7b9d1a8db39ae3c86eda391dad24adf27f838f176c90b62181c1682544119d5976b99afde6e08bb69d8472559a595be4ff171e2ed9116c430382d04a88233ab2ed7335fbcdc1176d3b08e4ab34b2b7c9fe2e3c5db222d8860705a09510467565dae66bf79b822eda7611c95669656f93fc5c78bb6445b10c0e0b412a208ceacbb5ccd7ef37045db4ec2392acd2cadf27f8b8f176c884233da6e3e87c6c96a1f9eb1915c0edb37f8f98172573e5a5be4ff181e2ed90f107a0d895372104aa105655b191645b11c344effe4b020b5b7c9fe313c5db21d20f41b12a6e42095420acab6322c8b6238689dffc960416b6f93fc6278bb643a41e836254dc8412a8415956c645916c470d13bff92c082d6df27f8c4f176c8740fe2c4f771f3050cd4f152d0bf1055838de4d3fc2582a9aebe4ff18ae2ed90e71fc589eee3e60a19a9e2a5a17e20ab071bc9a7f84b05535d7c9fe315c5db21ce3f8b13ddc7cc143353c54b42fc41560e37934ff0960aa6baf93fc62b8bb6439c0b28806865faab1e7450be7deee0d4171b68fbde2c16f176f27f8c58176c8737165100d0cbf5563ce8a17cfbddc1a82e36d1f7bc582de2ede4ff18b02ed90e6e2ca201a197eaac79d142f9f7bb83505c6da3ef78b05bc5dbc9fe31605db21cdc594403432fd558f3a285f3ef7706a0b8db47def160b78bb793fc62c0bb6439b83e9a5f33360d349f11d20fd6e46b696c62d219dfc170bb7027f8c58276c8736f09471713427cebf5f06a47a5bf34fad371e68fbc82e31ae14ff18b05ed90e6dd128e2e2684f9d7ebe0d48f4b7e69f5a6e3cd1f7905c635c29fe3160bdb21cdba251c5c4d09f3afd7c1a91e96fcd3eb4dc79a3ef20b8c6b853fc62c17b6439b744a38b89a13e75faf83523d2df9a7d69b8f347de41718d70a7f8c582f6c8736e82083c9e0fe314216d36aa253e9add531caab57c52e335215ff18b05fd90e6dcf410793c1fc62842da6d544a7d35baa639556af8a5c66a42bfe3160bfb21cdb9e0e218030cf278b131a70b1479d157cc1d6efbb11b8ceec58fc62c1806439b73b1c4300619e4f162634e1628f3a2af983addf7623719dd8b1f8c58300c8736e76388600c33c9e2c4c69c2c51e7455f3075bbeec46e33bb163f18b060190e6dcec710c0186793c5898d3858a3ce8abe60eb77dd88dc67762c7e3160c0321cdb9d86e2a5bb9c8db33e973d13c71c7b5f4181b3e0d188cf06990c62c1807439b73af686710206818ea8ab468a0db85ca102ae2be762e19e277228c58300f8736e75d5ce078eda69457cd359769af01f2485071bf485933c6924618b060200e6dceb945d34a88238b325237f4fb55fa42b89b8fc0ecaf678ec88d3160c0411cdb9d7117b8edbd1d78e75c3cb01ea3eae39931cbc4355bcf1f351b62c1808339b73ae12f71db7a3af1ceb879603d47d5c7326397886ab79e3e6a36c5830106736e75c25ee3b6f475e39d70f2c07a8fab8e64c72f10d56f3c7cd46d8b06020ce6dceb8449d9c695c229bd99b2471d174d7af1890a6406db78fb4cdc160c041acdb9d7071fc5e5d85ab5fdeb3154622691540b0cc10a69b3f1f83db92c1808369b73ae0d3f8bcbb0b56bfbd662a8c44d22a816198214d367e3f07b725830106d36e75c1a0b29f00e413a7a649217b0923bae542db06c02ccc7e29ae5b06020db6dceb8331653e01c8274f4c9242f6124775ca85b60d805998fc535cb60c041b6db9d70662ca7c03904e9e992485ec248eeb950b6c1b00b331f8a6b96c180836db73ae0cc594f807209d3d32490bd8491dd72a16d836016663f14d72d830106db6e75c1983eb15990ea0a2900ee41311bb1436ad5b30288c97e2b525c06020db7dceb832f09750bceaa76d4b9a9488a2f58e4fda612476d8ffc5848b90c041b70b9d7065d12ea179d54eda9735291145eb1c9fb4c248edb1ff8b09172180836e173ae0cba25d42f3aa9db52e6a52228bd6393f698491db63ff16122e430106dc2e75c19744ba85e7553b6a5cd4a44517ac727ed30923b6c7fe2c245c86020db85ceb832e8236315977dcfce52614ecaed84ae025bd0b934fcc5862f91c041b70c9d7065cf46c62b2efb9f9ca4c29d95db095c04b7a17269f98b0c5f2380836e193ae0cb9e199eaf0acda1bc01520153ae09163169ef272ff0161a62480106dc3375c1973b333d5e159b437802a402a75c122c62d3de4e5fe02c34c490020db866eb832e76667abc2b3686f00548054eb82458c5a7bc9cbfc058698920041b70cdd7065cec5907d103437062c25cd0c5683f0fb34a257bdb7db0d4b6410836e19cae0cb9d73e21fab35d43483c8667b2c8747d8e8ef73a12f861ab1083106dc33a5c1973ad08564e1390e91330d9958d88df5945189ab681edc357c50720db8675b832e75910ac9c2721d22661b32b1b11beb28a31356d03db86af8a0e41b70ceb7065ceb22159384e43a44cc3665636237d6514626ada07b70d5f141c836e19d6e0cb9d6442b2709c87489986ccac6c46faca28c4d5b40f6e1abe283906dc33adc1973ac8117739e5e4f3b5c5661f0085ebf2798457aa7ad9357df4730db8675c832e758f22ee73cbc9e76b8acc3e010bd7e4f308af54f5b26afbe8e61b70ceb9065ceb1e45dce79793ced715987c0217afc9e6115ea9eb64d5f7d1cc36e19d720cb9d63c17cc27dbfe0030e2fdbe2c2755f1f41d699632c6abf147996dc33ae51973ac772f984fb7fc0061c5fb7c584eabe3e83ad32c658d57e28f32db8675ca32e758ee5f309f6ff800c38bf6f8b09d57c7d075a658cb1aafc51e65b70ceb9465ceb1dc4a73978cc66409cfbab78932a5edc8e5f8f3f2325f8be0cc6e19d729cb9d63b720f987c6632a965742353a5d4239b9c69e2a4061bf196599dc33ae54973ac76d41f30f8cc6552cae846a74ba8473738d3c5480c37e32cb33b8675ca92e758eda0ff877c6630cdc14d59b116cff450f1524eb5d83fc673a6870ceb9535ceb1db31ff0ef8cc619b829ab3622d9fe8a1e2a49d6bb07f8ce74d0e19d72a6b9d63b663fe1df198c337053566c45b3fd143c5493ad760ff19ce9a1c33ae54d73ac76cc0bd616dfeec9635e799eb35ff086a0a3d39d481ce33b77448675ca9be758ed9717ac2dbfdd92c6bcf33d66bfe10d4147a73a9039c676ee890ceb9537ceb1db2e2f585b7fbb258d79e67acd7fc21a828f4e7520738ceddd1219d72a6f9d63b65c5eb0b6ff764b1af3ccf59aff8435051e9cea40e719dbba2433ae54df3ac76cb84973c6abc2f8b89f66b15df6fec83237e616ddcb33b91849675ca9bf758ed96f1ef9e6045c53f3f69a28e3e5f3ee8c6a787017936773d493ceb9537feb1db2dd3df3cc08b8a7e7ed3451c7cbe7dd18d4f0e02f26cee7a9279d72a6ffd63b65ba07f9f0be47b252923569b78fc61859a48e02ba4a9dd0f6503ae54e00ac76cb730ff3e17c8f64a5246ad36f1f8c30b3491c0574953ba1eca075ca9c0158ed96e61fe7c2f91ec94a48d5a6de3f18616692380ae92a7743d940eb953802b1db2dcc3fcf85f23d929491ab4dbc7e30c2cd247015d254ee87b281d72a700563b65b980bb164915187abdb2361a0f457e3c2438c6e00a6dd110904ae54e00bc76cb72f1762c922a30f57b646c341e8afc7848718dc014dba2212095ca9c0178ed96e5e2ec59245461eaf6c8d8683d15f8f090e31b8029b74442412b953802f1db2dcbc5d8b248a8c3d5ed91b0d07a2bf1e121c63700536e888482572a7005e3b65b9784728a1c1eedd406a02e0373d749a4c337322666ad112344be54e00bd76cb72ef1a639c30b41d038bd2869672df92c061928728d2a2260c98ca9c017bed96e5dd34c73861683a0717a50d2ce5bf2580c3250e51a5444c1931953802f7db2dcbba698e70c2d0740e2f4a1a59cb7e4b01864a1ca34a889832632a7005efb65b97745f2f3a32774a9f1660fadb8ef2f42b07407ba292113208c754e00be06cb72ee74a70cd11c4f7c0e48ebbdf15dc467e092d39a1212265b58fa9c017c1d96e5dcd20f3f2d060520480ea3de623aeeb240d06b59e3f44cd0f2053802f84b2dcbb9941e7e5a0c0a40901d47bcc475dd6481a0d6b3c7e899a1e40a7005f0965b977320fe223ee57aa94bb75bdc086b20ab82ec718d4fa1335e0824e00be13cb72ee631fc447dcaf552976eb7b810d6415705d8e31a9f4266bc1049c017c2796e5dcc63f888fb95eaa52edd6f7021ac82ae0bb1c6353e84cd782093802f84f2dcbb98c0b23781f93b728937ab42c2d86b3e970e50903cd99b0a8137005f09f5b9773171646f03f276e5126f568585b0d67d2e1ca12079b33615026e00be13eb72ee62e2c8de07e4edca24dead0b0b61acfa5c394240f3666c2a04dc017c27d6e5dcc5c591bc0fc9db9449bd5a1616c359f4b8728481e6ccd85409b802f84fadcbb98b83e49daa611d50bef7808ead0619cbf08fcd298d69b0c2538005f09f6b977316f08a60df8fa0c9a96bcd7fd98b997a60ca5e78daa3619ee7100be13ee72ee62dd114c1bf1f419352d79affb31732f4c194bcf1b546c33dce2017c27dce5dcc5ba229837e3e8326a5af35ff662e65e9832979e36a8d867b9c402f84fb9cbb98b7445306fc7d064d4b5e6bfecc5ccbd30652f3c6d51b0cf738805f09f73977316e81673383c772c2c239a4601838fd888c50abb36a061a08b110be13ee82ee62dcf2ce67078ee585847348c03071fb1118a15766d40c341162217c27dd05dcc5b9e59cce0f1dcb0b08e6918060e3f6223142aecda8186822c442f84fba0bb98b73c3fac1a908fc3e3d49ef6341475226e23021c11000d05fc895f09f74277316e770b6a8dcdf5ea4a610ab29020e0a30440b07a7dfd1a0d9d13be13ee85ee62dced16d51b9bebd494c215652041c146088160f4fbfa341b3a277c27dd0bdcc5b9da2daa3737d7a929842aca4083828c1102c1e9f7f46836744ef84fba17b98b73b45b546e6faf525308559481070518220583d3efe8d06ce89df09f742f7316e76842bb358c350728c877ef2a06008e6c05b3ea3bcea0db753ce13ee85fe62dcecf1188c3c54070d448bca47c03f77b00061416d39a41b88e7ac27dd0c0cc5b9d9d2311878a80e1a8917948f807eef6000c282da73483711cf584fba18198b73b3a46230f1501c35122f291f00fddec0018505b4e6906e239eb09f74303316e7674185876d6d9e924fdb1ea0817b236282b4cf8f8cf0dc617d713ee860762dcece730b0edadb3d249fb63d4102f646c505699f1f19e1b8c2fae27dd0c0ec5b9d9ce6161db5b67a493f6c7a8205ec8d8a0ad33e3e33c37185f5c4fba181d8b73b39c4ed60f63a5abaaa55c1668b5880f6955140a22756e3262b99f74303c16e7673729be777421b9d80284f2f963067cfaa4d456a0e7dc6669743ee860792dcece6d537ceee84373b00509e5f2c60cf9f549a8ad41cfb8ccd2e87dd0c0f25b9d9cda330c367d5d49e2c1e0920d841052128dfd9cdf9c719b49d1fba181e5b73b39b366186cfaba93c583c1241b0820a4251bfb39bf38e33693a3f74303cb6e767366584332a24b8a0dbf4f0e5e0837a67232a2b5da6ec66ecb48ee860797dcece6cb3c98bdf16d769e366ae2e40865ab0c5ff1ae10da8cdf3a92dd0c0f30b9d9cd950543d48fb14fbf24a28bf008c1b440ba8f9e7db219c01926ba181e6273b39b290a87a91f629f7e494517e011836881751f3cfb643380324d74303cc4e7673652150f523ec53efc928a2fc02306d102ea3e79f6c86700649ae8607989cece6ca42a1ea47d8a7df925145f80460da205d47cf3ed90ce00c935d0c0f3139d9cd948543d48fb14fbf24a28bf008c1b440ba8f9e7db219c01926ba181e6273b39b290348ceaa3005a674c1e4429102ce63f4ca01212403804c8d84303cc4f7673651f6919d54600b4ce983c88522059cc7e9940242480700991b08607989eece6ca3e5e460338d7cc1fe845d6cc38a9f7252d2c8aa4fde014c7620c0f313ed9cd947b489e5f1e85fac2885873c0694a4c72550557a5f8c02b32c5181e627eb39b28f51d4f16e9e25807c87dada8ca8af70ca4b6f1a7ee8058098b303cc4fe673651e93a9e2dd3c4b00f90fb5b519515ee19496de34fdd00b01316607989fcce6ca3d2014eb4545fc2a1d9c37ccb22223a5a8d8808fbb70161ca2dc0f313fa9cd947a3029d68a8bf8543b386f996444474b51b1011f76e02c3945b81e627f539b28f46053ad1517f0a87670df32c8888e96a362023eedc058728b703cc4fea73651e8c0a75a2a2fe150ece1be6591111d2d46c4047ddb80b0e516e07989fd4e6ca3d1814eb4545fc2a1d9c37ccb22223a5a8d8808fbb70161ca2dc0f313fa9cd947a3029d68a8bf8543b386f996444474b51b1011f76e02c3945b81e627f539b28f46053ad1517f0a87670df32c8888e96a362023eedc058728b703cc4fea73651e8c0336c82dcb7b36f998b2bb909138b6ebeb0c0377db0e6bae17989fd4f6ca3d17f66d905b96f66df33165772122716dd7d61806efb61cd75c2f313fa9ed947a2fe59c4641fb530411df9750c1c448be2f56f4339f3c39c8f86e627f53eb28f45fb3f9b20ec40c304f3bfb040307f75ede58ac8cfe4873ac30ecc4fea7e651e8bf50b489a8557e88c9f4c26a858f54a03c5c1d3fbc60e772a1e989fd4fdca3d17e91691350aafd1193e984d50b1ea94078b83a7f78c1cee543d313fa9fb947a2fd22d226a155fa2327d309aa163d5280f17074fef1839dca87a627f53f728f45fa45a44d42abf4464fa613542c7aa501e2e0e9fde3073b950f4c4fea7ee51e8bf48409c010254eb4cac8f30ad874afe6456c982185de77445ea89fd4fdda3d17e8f0d4a5ab180391c10eb2783068c5af0a83f468cb8ceea2fd613fa9fbc47a2fd1d1a94b56300723821d64f060d18b5e1507e8d19719dd45fac27f53f788f45fa3a35296ac600e47043ac9e0c1a316bc2a0fd1a32e33ba8bf584fea7ef11e8bf4746a52d58c01c8e087593c183462d78541fa3465c677517eb09fd4fde23d17e8e860b803c4d9f443c67f3e5860bc0d327ea0ab2789eea4a1623fa9fbc57a2fd1cf4d8260368a4b0a44cb42d8b96e788cf7ed98ab10dd4ae6c57f53f78bf45fa39d27171919eaf89741634bd96ad34f41ea8773b21eba97718bfea7ef18e8bf47394e2e3233d5f12e82c697b2d5a69e83d50ee7643d752ee317fd4fde31d17e8e72286ebd148244dfbd59f58da3439b2fa4ca112477ea5f6a30fa9fbc64a2fd1ce350dd7a290489bf7ab3eb1b4687365f49942248efd4bed461f53f78c945fa39c62dcd4cfedf7601ad349c5e8504cae68dd486eddca97f4cc4ea7ef1938bf4738b5b9a99fdbeec035a6938bd0a0995cd1ba90ddbb952fe9989d4fde32717e8e71643478ca8543a896c9f37a20c0989c231fe5e136fa5fed714a9fbc64f2fd1ce2b12a171fd7ed795910b356c100971ac5ea8fe82dc4bff522a53f78c9f5fa39c552542e3fafdaf2b22166ad82012e358bd51fd05b897fea454a7ef193ebf4738aa4a85c7f5fb5e56442cd5b04025c6b17aa3fa0b712ffd48a94fde327d7e8e7154211de898cd1f2f402671887841eb8aeff43672df5ffc35539fbc64fbfd1ce2a7423bd1319a3e5e804ce310f083d715dfe86ce5bebff86aa73f78c9f7fa39c54e1089fb100adf3fb8668c49d8fe0c53ba7d1c277a7ff2794f7ef193f0f4738a9b2113f62015be7f70cd1893b1fc18a774fa384ef4ffe4f29efde327e1e8e715364227ec402b7cfee19a312763f8314ee9f4709de9ffc9e53dfbc64fc3d1ce2a6c1062312d2d5c807b012876bfe6c0c5ce952397d0ff956e7cf78c9f88a39c54d720c4625a5ab900f60250ed7fcd818b9d2a472fa1ff2adcf9ef193f114738a9ae4188c4b4b57201ec04a1daff9b03173a548e5f43fe55b9f3de327e228e71535c0f23e2164146868fd609ddf72c64566f555f1a84fcad17e8bc64fc461ce2a6b71e47c42c828d0d1fac13bbee58c8acdeaabe3509f95a2fd178c9f88c39c54d6e3c8f8859051a1a3f582777dcb19159bd557c6a13f2b45fa2f193f118738a9adc0531695ee096b7367d1517b15980db75573b3024e56a6346e327e231e71535b70a62d2bdc12d6e6cfa2a2f62b301b6eaae766049cad4c68dc64fc463ce2a6b6e14c5a57b825adcd9f4545ec566036dd55cecc09395a98d1b8c9f88c79c54d6dc298b4af704b5b9b3e8a8bd8acc06dbaab9d981272b531a37193f118f38a9adb8531695ee096b7367d1517b15980db75573b3024e56a6346e327e231e71535b70323f8488e93969876f691e23267996a593a86099ad4e0cdd64fc463de2a6b6df647f0911d272d30eded23c464cf32d4b2750c1335a9c19bac9f88c7bc54d6dbe55106ad07b4828d58a6aa08490448290fae3de63b539d77693f118f88a9adb7b36332e4dccf2d462e19b690116e72d1ca20a18c46a7552ee27e231f21535b6f56c665c9b99e5a8c5c336d2022dce5a3944143188d4eaa5dc4fc463e42a6b6dea64df11e40a2dd4435333cbfc51fadc6d346abf0ea9d6efb99f88c7c954d6dbd355d07c74eabe2b3e732dbff09a53e0d51517da1a53af83743f118f93a9adb7a537b35196abded934b321a7d92b05e9a4d6721031a760aae97e231f28535b6f496f66a32d57bdb26966434fb2560bd349ace420634ec155d2fc463e50a6b6de926adf9f0785dde78a994cc75ca275ce8e060a9cc39d844fa6f88c7ca24d6dbd2361d196bbe21e51ccff5fb6b13b49c516b85795843b0a434ef118f9459adb7a454fb586249a9f2651cb85955a6cf1b2281cf1870576162a9ee231f28c35b6f4892b7d64f60ba0cf5b63d152acd0418c4ae6256a07ec2df93ec463e5196b6de91156fac9ec17419eb6c7a2a559a0831895cc4ad40fd85bf27d88c7ca32d6dbd2223a07ec8504e5c0255c0b72ab3764592644d8041cb0b988fc118f9466adb7a443002231b6e02e030284dd0d4e6526da4735f264366174b5f9231f28ce5b6f48850044636dc05c060509ba1a9cca4db48e6be4c86cc2e96bf2463e519cb6de910a0088c6db80b80c0a13743539949b691cd7c990d985d2d7e48c7ca3396dbd221401118db70170181426e86a732936d239af9321b30ba5afc918f94672db7a442802231b6e02e030284dd0d4e6526da4735f264366174b5f9231f28ce5b6f48850044636dc05c060509ba1a9cca4db48e6be4c86cc2e96bf2463e519cb6de910a0088c6db80b80c0a13743539949b691cd7c990d985d2d7e48c7ca3396dbd221401118db70170181426e86a732936d239af9321b30ba5afc918f94672db7a442802231b6e02e030284dd0d4e6526da4735f264366174b5f9231f28ce5b6f48850044636dc05c060509ba1a9cca4db48e6be4c86cc2e96bf2463e519cb6de910a0014d9342d8e6e8ccb40fb618c91c744d275d33582d2d9888d7ca3396ebd2213ff29b2685b1cdd199681f6c319238e89a4eba66b05a5b3111af94672dd7a4427fe5364d0b639ba332d03ed8632471d1349d74cd60b4b662235f28ce5baf4884ffc32dbfa1949d6e911d4a1345c84984e8e5adc081396cde86ce519cb76e9109ff765b7f43293add223a94268b909309d1cb5b810272d9bd0d9ca3396edd2213fee57824111fdbe26ff1f4af96a08bf623417b27c4b5b3945b494672ddca4427fdb3b16dad0d1ded0b60b5c1acc07dcec62dba75493b6742f6a28ce5bba4884ffb502400e4e7a202423e37e5d90061800c0639105246cea02d5519cb7759109ff6904801c9cf4404847c6fcbb200c300180c7220a48d9d405aaa3396eeb2213fed209003939e880908f8df97640186003018e441491b3a80b554672ddd64427fda412007273d101211f1bf2ec8030c006031c882923675016aa8ce5bbac884ffb482400e4e7a202423e37e5d90061800c0639105246cea02d5519cb7759109ff6904801c9cf4404847c6fcbb200c300180c7220a48d9d405aaa3396eeb2213fed201c15ec4b5e6b8bb0ac5d8bf97c5e58139083a5183a825955672ddd65427fda3f382bd896bcd7176158bb17f2f8bcb02721074a307504b2aace5bbaca84ffb47e7057b12d79ae2ec2b1762fe5f179604e420e9460ea0965559cb7759509ff68fc6cc1bb07c9bee03d2fb287c3d950e897305f84bed4146eac396eeb2b13fed1f76595cebc69e043322c2b377fa8fff9290d01657aa82a815972ddd65727fda3ed573df625aa23091c251c96f7485e1a4cc64526f25056a6b3e5bbacaf4ffb47d93a8e44f82aa894f016ff55e6871a5c9438cca9e1a0aef168cb77595f9ff68fb1012ee29d2bb3ac97fac4d3c50492e1231ddbafc0415f86d296eeb2c03fed1f61025dc53a5767592ff589a78a0925c2463bb75f8082bf0da52ddd65807fda3ec204bb8a74aeceb25feb134f14124b848c776ebf01057e1b4a5bbacb00ffb47d84097714e95d9d64bfd6269e2824970918eedd7e020afc3694b7759601ff68fb0812ee29d2bb3ac97fac4d3c50492e1231ddbafc0415f86d296eeb2c03fed1f61025dc53a5767592ff589a78a0925c2463bb75f8082bf0da52ddd65807fda3ec204bb8a74aeceb25feb134f14124b848c776ebf01057e1b4a5bbacb00ffb47d8402383a742b038ceb52f300a7a3fceb9899a1a3c1dafc50d4c77596020f68fb07f47074e8560719d6a5e6014f47f9d73133434783b5f8a1a98eeb2c041ed1f60fe1a20f5b79745bd8c898651e0f5990e2114ab4c73bf15d932dd658084da3ec1fb3441eb6f2e8b7b19130ca3c1eb321c42295698e77e2bb265bacb0109b47d83f66883d6de5d16f63226194783d664388452ad31cefc5764cb7596021368fb07ec5d1a066990906f1c18f8b6ffa3269903519cbf9af8b06d97eb2c0427d1f60fd74646657ff78360effeb795f73cab5a014f7bdb32f1627f30d6580850a3ec1fad189f23acc5694497ca3553e66fb4dbfd4b3a1262e2c6a262acb010a247d83f59313e47598ad2892f946aa7ccdf69b7fa967424c5c58d44c5596021448fb07eb2627c8eb315a5125f28d54f99bed36ff52ce8498b8b1a898ab2c042891f60fd64510b761301aca7761e70c72b740507e50612ef141636b716658085133ec1fac72e2944d2d9bbd1a409a7b64ede6837c4b8683a252c6f122dcb010a277d83f58d5c5289a5b377a348134f6c9dbcd06f8970d0744a58de245b9602144efb07eb1a44b76bf83d51c947f36501336fff070d8de34491b1bdecb82c04289ef60fd6331581309d51061547b3902a5ed65c3615c808e520637d7d715808513eec1fac652b02613aa20c2a8f672054bdacb86c2b9011ca40c6fafae2b010a27dd83f58ca5604c2754418551ece40a97b5970d857202394818df5f5c5602144fbb07eb194381bdd975e932cf569477aeea93fd8a8ec8985001bed8f8bc04289f860fd63277037bb2ebd2659ead28ef5dd527fb151d9130a0037db1f17808513f0c1fac64e6c81cf0a50af368d71e413b29b5d8a9e5e686ffd6fb7e230010a27e283f58c9b6515f6c177c0efd2b08e4f5d2d193d3769133bf7df71686102144fc607eb1935563e462fc5e4625d2de2c6b25090a2697e68d3ecbee474c304289f8d0fd63269388ee50c622b4772288bb55c977f6ccda91403d67dca8d8708513f1b1fac64d1711dca18c4568ee451176ab92efed99b522807acfb951b0e10a27e363f58c9a26e4decde5f0fa0806ef4fd6a545bdb3150926b56f72bda1d2144fc6d7eb1934368ae32699481c3b8aab022cc9f15de5d4d6732aaee59583b4289f8dbfd6326855d6ebd7fff660a2922266d913489e4b54710c152dcb454778513f1b8fac64d0946efd3acd52e970a1113031a5f71f1653a63dea2b96a4cf00a27e372f58c9a1119f2000680bfb0cbeeec2e2cb5420ac5210a194272d63de1144fc6e6eb19342133e4000d017f6197ddd85c596a84158a42143284e5ac7bc2289f8dcdd632684267c8001a02fec32fbbb0b8b2d5082b1484286509cb58f784513f1b9bac64d0845ba258e0dc6009174427995da06e7e23b493261096b39309a27e373858c9a10743570a6e8f2294e655155ab3373b24421568a81e2d68ca1444fc6e71b193420d12c06d89f4a7ac8476f0dd5e64d4707ed713ac395ad3382989f8dce4632684192580db13e94f5908ede1babcc9a8e0fdae275872b5a6705313f1b9c8c64d08324b01b627d29eb211dbc375799351c1fb5c4eb0e56b4ce0a627e373918c9a10642215c4fc7b9fe6db844d12eb1d01abf164dfbdc7d69b654d4fc6e724193420c7442b89f8f73fcdb7089a25d63a0357e2c9bf7b8fad36ca9a9f8dce483268418e14696c9ec4e21e25ddfa73a46a64d7c03fc1531c5a6f39363f1b9c9164d0831b28d2d93d89c43c4bbbf4e748d4c9af807f82a638b4de726c7e373922c9a1063651a5b27b1388789777e9ce91a9935f00ff054c7169bce4d8fc6e724593420c6c2f5dbda2fd7373e6bc99c51b4984e5fcaa4cf4dfd37b6db2f8dce48c268418d75ebb7b45fae6e7cd79338a369309cbf95499e9bfa6f6db65f1b9c9184d0831ae49894f38cc305252bf2d3c651c71bfed55762f7c4def5acce37392319a10635b1f24f71e6ec3275d4b20a0c22f41a7d5572ebaf59be0599ac6e724643420c6b53e49ee3cdd864eba964141845e834faaae5d75eb37c0b3358dce48c868418d6a08a63526916f202cf948ab00b364c75008fd47d36f830a6c1b9c9191d0831ad3114c6a4d22de4059f291560166c98ea011fa8fa6df0614d837392323a10635a62298d49a45bc80b3e522ac02cd931d4023f51f4dbe0c29b06e724647420c6b4c4531a9348b790167ca4558059b263a8047ea3e9b7c185360dce48c8e8418d6981675ab15ed5485876150d8032caa9cfb3c16d933f8324ac2b9c9191e0831ad2f2ceb562bdaa90b0ec2a1b006595539f6782db267f06495857392323c10635a5e59d6ac57b552161d8543600cb2aa73ecf05b64cfe0c92b0ae724647820c6b4bc3fbfb15c4106aef2d74ce8115bb30fd48cf9259cc193fa16ce48c8f1418d69770b91bb65586fe09d7b5ff81aadc447a3c634a7368329982e9c9191e3831ad2ed172376cab0dfc13af6bff0355b888f478c694e6d0653305d392323c70635a5da2e46ed9561bf8275ed7fe06ab7111e8f18d29cda0ca660ba7246478e0c6b4bb45c8ddb2ac37f04ebdaffc0d56e223d1e31a539b4194cc174e48c8f1c18d69768452e0f025d608c8f82c5a9a2d2a2a2370f8ccf65329b26eac9191e3931ad2ecf166e76b191239bd6d2517b3d9ba36c68cb5bfac76537f1d692323c73635a5d9d2cdced63224737ada4a2f67b3746d8d196b7f58eca6fe3ad246478e6c6b4bb3a59b9dac6448e6f5b4945ecf66e8db1a32d6feb1d94dfc75a48c8f1cd8d6976743f860e395f7f616e5f5201e4d3798b410722323829c132b59191e39c1ad2ece70b1e751f956145948b6a2bc19d513e7cba86c06d5384096c2323c73935a5d9cd163cea3f2ac28b2916d457833aa27cf9750d80daa70812d846478e726b4bb39a2c79d47e558516522da8af067544f9f2ea1b01b54e1025b08c8f1ce4d697673458f3a8fcab0a2ca45b515e0cea89f3e5d436036a9c204b61191e39c9ad2ece683df9aaa62c76dc008368e411cb720fc654ae62d238423ac3323c73945a5d9ccf0805adf92f503ab8d397f01b8d424787559f21a1708619876478e729b4bb399d100b5bf25ea07571a72fe0371a848f0eab3e4342e10c330ec8f1ce536976733a2016b7e4bd40eae34e5fc06e35091e1d567c8685c218661d91e39ca6d2ece674402d6fc97a81d5c69cbf80dc6a123c3aacf90d0b8430cc3b23c7394da5d9cce80c6d383fcb662e45064529b0ca82a0700634761408633c77478e729c4bb399cf18da707f96cc5c8a0c8a5361950540e00c68ec2810c678ee8f1ce5389767339e31b4e0ff2d98b9141914a6c32a0a81c018d1d850218cf1dd1e39ca712ece673c6369c1fe5b31722832294d865415038031a3b0a04319e3ba3c7394e25d9cce7852e5dca98cc567083118c3049e882efb0f89bd3d86356b7578e729c5bb399cef31de11ffefed50c82ef7ae01336e85f0cb55d6780c6c7aebf1ce538c767339dd63bc23ffdfdaa1905def5c0266dd0be196abacf018d8f5d7e39ca718ece673ba538aa0ac9617c5d888a4dffcc4183fbdd999b5dd31b38fb0c7394e32d9cce77333279a0602920e68de0fe7f17e8ea7765f75c7b76368c3628e729c66b399cee5664f340c05241cd1bc1fcfe2fd1d4eecbeeb8f6ec6d186c51ce538cd67339dca58b0c0c4e0aabc5b4505c7bdf098c5d42a197ada8da4b18b39ca719bce673b933d73da3697b7fb6e56d1b773d78fb3a3007551b21b4b07177394e3389cce772506fa0d1a05d279947a6996dfa57d8f40ad2cff613697b22fe729c672399cee490df41a340ba4f328f4d32dbf4afb1e815a59fec26d2f645fce538ce47339dc921be834681749e651e9a65b7e95f63d02b4b3fd84da5ec8bf9ca719c8e673b92437d068d02e93cca3d34cb6fd2bec7a056967fb09b4bd917f394e3391cce772486fa0d1a05d279947a6996dfa57d8f40ad2cff613697b22fe729c672399cee4906b53fbed90b1b54719f903eca610101051e24823d2f7e9fde538ce48339dc91f62ba5087f7c5ed4600b82fd1427e481b5006ec44a5f177fcca719c91673b923d5186f9bcc5ee5d43ce36879a7b5ab8314c5034864be493fa94e33923ce7724792f204c26623f3d3f6933372ced13985d44e2c50997cacbf629c672489cee48f15e40984cc47e7a7ed2666e59da2730ba89c58a132f9597ec538ce49139dc91e2489389465f5f77b5719304abaaac896fbfcd70235f2cd3d9a719c92373b923c31d396b3995217222afec314f4bb73ada2bdd3c43be5b4bb44e339247e77247853a72d6732a42e4455fd8629e976e75b457ba78877cb697689c67248fcee48f0a00f805932ae84b428c76ed35253b13635bb74d0bf96ed2d238ce49209dc91e1301f00b2655d0968518edda6a4a7626c6b76e9a17f2dda5a4719c92413b923c2603e0164caba12d0a31dbb4d494ec4d8d6edd342fe5bb4b48e33924827724784c07c02c9957425a1463b769a929d89b1addba685fcb769691c6724904ee48f0980f805932ae84b428c76ed35253b13635bb74d0bf96ed2d238ce49209dc91e1301f00b2655d0968518edda6a4a7626c6b76e9a17f2dda5a4719c92413b923c2603e0164caba12d0a31dbb4d494ec4d8d6edd342fe5bb4b48e33924827724784c0081522424a8823fe083cc28a93e7d9a887e8e1f9b76b0d1d6724904fe48f097f102a4484951047fc1079851527cfb3510fd1c3f36ed61a3ace49209fc91e12fe205489092a208ff820f30a2a4f9f66a21fa387e6ddac34759c92413f923c25fc40a9121254411ff041e614549f3ecd443f470fcdbb5868eb3924827f24784bf80d647cd17ee4c298509250a134dbc2832ad07b9876b275d7724904ff48f097ef1ac8f9a2fdc98530a124a14269b7850655a0f730ed64ebaee49209fe91e12fde3591f345fb930a6142494284d36f0a0cab41ee61dac9d75dc92413fd23c25fbc6b23e68bf72614c284928509a6de14195683dcc3b593aebb924827fa4784bf78625a25c4c4aeac3cd5eb320b441a502d594a15846b29017824904ff58f097eef50c6a4365fbfdb31789c8c0e7e92c8555ed68705d653a6f149209fec1e12fddd2d9fa11995e2391abdff4014f383b8a569ef6a08aca8f1e392413fd93c25fbb95b3f42332bc472357bfe8029e707714ad3ded4115951e3c724827fb2784bf7724290dd132deb6722c4c3284bc46d0a905400041fb2a56b8f4904ff65f097eee3113412d3323950fd564c788f7f383d1b5442643c654c7b1f9209fecce12fddc5226825a66472a1faac98f11efe707a36a884c878ca98f63f2413fd99c25fbb8a44d04b4cc8e543f55931e23dfce0f46d510990f19531ec7e4827fb3384bf771415b2ef46682d0aa27f29ec73f02010d54e557de02a657cfd904ff668097eee272b65de8cd05a1544fe53d8e7e04021aa9caafbc054caf9fb209fecd012fddc4e56cbbd19a0b42a89fca7b1cfc08043553955f780a995f3f6413fd9a025fbb89c39a9d2e017cad7cbc6158b97775eaea51eee4afe532d8bed827fb3414bf771377353a5c02f95af978c2b172eeebd5d4a3ddc95fca65b17db04ff668297eee26e72b9a42d358de1e6e51c5655d3d8e28f27fb87f64cb7d3b709fecd062fddc4db7185a107417e468596fed4a39e0fed18fc396be999714b6f13fd9a0d5fbb89b56f1d9abb595f0fc2fac3d13f327e022ca4b533d032e43adf27fb341bbf7713696a4d8e238920a23dc24dca765b5a2c53f5acc39d65ca19bf4ff668387eee26d160ad74f3e8a3c7335161bce4ad1280a2979be337cb95d77f9fecd071fddc4da14d6d4294a7aa111e6f89a1c15083293fdb7a226c972d53003fd9a0e4fbb89b4126ecddd625b6a4f4abd96b7a97647a7a6336a0d62e5c4a017fb341caf77136814dd9bbac4b6d49e957b2d6f52ec8f4f4c66d41ac5cb89402ff668395eee26d0227c5d0056d3d168a7c2bd5e253f011e4391cdf55b972cc06fecd072cddc4da034f8ba00ada7a2d14f857abc4a7e023c87239beab72e5980dfd9a0e59bb89b4062b2998c28b56dce1bd757f81461e6f8b90b5d953e5ccd41cfb341cb47713680b5653318516adb9c37aeaff028c3cdf17216bb2a7cb99a839f6683968ee26d01638b8bbb703bdf63ec29c25fd0ed7e628ef19c14c9734f474ecd072d2dc4da02b7171776e077bec7d85384bfa1dafcc51de3382992e69e8e9d9a0e5a5b89b40566ef54788e55a5bb2d736bfec31bdc09e68a9612f5cd575d4b341cb4c713680ab69fce7bea1173a1d7b33a7d059d9a9377d951e5bb9ac8faa66839699e26d0155600c282a1890f6f2c32d7798aa117a69a76c98b4735ac355cd072d34c4da02a94c2aa9010784709d532117294a811ccdfb1b8d65e6b72aac9a0e5a6a89b405512467aaaee56b63f27308564a8b606196a27976c8cd6ff95a341cb4d613680aa148cf555dcad6c7e4e610ac9516c0c32d44f2ed919adff2b4683969ac26d015421db103686c10128198e7812223dfae553628372035c18969d072d3594da02a833b6206d0d820250331cf024447bf5caa6c506e406b8312d3a0e5a6b29b40550602d6664e86a2ccbe30642c8085dce14f84e3387dd707c9a841cb4d663680aa0b05accc9d0d45997c60c859010bb9c29f09c670fbae0f935083969acc6d0154160b59993a1a8b32f8c190b2021773853e138ce1f75c1f26a1072d3598da02a82c16b33274351665f1832164042ee70a7c2719c3eeb83e4d420e5a6b31b40550582d6664e86a2ccbe30642c8085dce14f84e3387dd707c9a841cb4d663680aa0b05accc9d0d45997c60c859010bb9c29f09c670fbae0f935083969acc6d015416041abec4e7f15b243e5d148196d967bdbe5107b72c1f40e1172d3598ea02a82bf0f6a3149d48de73f9868b82ad18b1fb2766352e283e9c023e5a6b31e4055057d1ed46293a91bce7f30d17055a3163f64ecc6a5c507d38047cb4d663c80aa0afa3da8c52752379cfe61a2e0ab462c7ec9d98d4b8a0fa7008f969acc79015415f40763e2fb7ad1bcb4900be94e82b7258e5f5cf3111f4fa5202d3598f302a82be70ec7c5f6f5a379692017d29d056e4b1cbeb9e6223e9f4a405a6b31e6055057ce1d8f8bedeb46f2d2402fa53a0adc96397d73cc447d3e9480b4d663cc0aa0af9c3b1f17dbd68de5a4805f4a7415b92c72fae79888fa7d290169acc79815415f3802508864837e4e00cd84bce021d080e0a2118d0ef4fbf603d3598f312a82be6f04a110c906fc9c019b0979c043a101c144231a1de9f7ec07a6b31e6255057cde094221920df938033612f380874203828846343bd3efd80f4d663cc4aa0af9bc128443241bf270066c25e7010e840705108c6877a7dfb01e9acc79895415f3782508864837e4e00cd84bce021d080e0a2118d0ef4fbf603d3598f312a82be6f04a110c906fc9c019b0979c043a101c144231a1de9f7ec07a6b31e6255057cde0203471cdb5f602eb2df560006a7e602330a59fba3eff24f5d663cc4ba0af9bbf4068e39b6bec05d65beac000d4fcc046614b3f747dfe49ebacc79897415f377e0ce41fe3ae3a8e64849ba7f9a057a8876ed8dae5fbfe37d8598f312f82be6efb19c83fc75c751cc909374ff340af510eddb1b5cbf7fc6fb0b31e625f057cddf633907f8eb8ea3992126e9fe6815ea21dbb636b97eff8df61663cc4be0af9bbec6720ff1d71d4732424dd3fcd02bd443b76c6d72fdff1bec2cc79897c15f377d85a5456e7ba0b69001680a791fbd8b07199d00a5cbfe5218698f312f92be6efaf40bb067c4a7954b7f9c7771bee0f88dddfe270b67fcbe70e31e625f357cddf5d0d8865a56b552c27c055162fd27d39b66c073d69ff99721d63cc4be7af9bbeb91b10cb4ad6aa584f80aa2c5fa4fa736cd80e7ad3ff32e43ac79897cf5f377d7236219695ad54b09f015458bf49f4e6d9b01cf5a7fe65c8758f312f9ebe6efae46c432d2b5aa9613e02a8b17e93e9cdb36039eb4ffccb90eb1e625f3d7cddf5c86498b3038bb54533d2178af51e31c3616cb6329cf998c5d73cc4be7bf9bbeb8f5543beb3edcd0d1f70f53de232c1aebd85aec136f3332faf79897cf8f377d71d3699d614b1fc9cf6aeb0a3bc5be18575b79fde6ae668035ff312f9f2e6efae396d33ac2963f939ed5d614778b7c30aeb6f3fbcd5ccd006bfe625f3e5cddf5c726679b0ff9e54f6928788b6e965e43dd18ac1d5a899a1b180cc4be7cc9bbeb8e35905baac130c6fdcdbd795cac226a39dc1c6074e334507029897cf9a377d71c53e1dce04fc7b62718475538d7aab6f362fce6a99668bb206312f9f356efae389084df4b6cf59479ad5b0cf12ebb506670bdf312fcd19080d625f3e6bddf5c711109be96d9eb28f35ab619e25d76a0cce17be625f9a32101ac4be7cd7bbeb8e222137d2db3d651e6b56c33c4baed4199c2f7cc4bf34642035897cf9af77d71c44426fa5b67aca3cd6ad8678975da833385ef9897e68c8406b12f9f35eefae388810f1a419cbf6fc6527d31926b1ae8e6b6a356ef9d19224d725f3e6bedf5c710f21e3483397edf8ca4fa6324d635d1cd6d46addf3a32449ae4be7cd7dbeb8e21e43c690672fdbf1949f4c649ac6ba39ada8d5bbe74648935c97cf9afb7d71c43c139f797b361a65e10b5ef12d83d29b55fdedd3cb8c92caba2f9f35f7fae38877273ef2f66c34cbc216bde25b07a536abfbdba797192595745f3e6beff5c710ee4e7de5ecd86997842d7bc4b60f4a6d57f7b74f2e324b2ae8be7cd7dfeb8e21dc290e24868735b1c027bdb16414f302aa9bb0fa596497f9d27cf9afc0d71c43b7521c490d0e6b63804f7b62c829e605553761f4b2c92ff3a4f9f35f81ae38876e304aeac6f33949b86bbced884a2a32a51b06456292618b4af3e6bf045c710edb6095d58de6729370d779db109454654a360c8ac524c31695e7cd7e08b8e21db64d3e03c8a347a9997bb9de191f06f28f185b71874987d12ccf9afc1271c43b6b268e603e1cf1d5eac439e42a346c0d18dcf93f0b9311465a9f35f825e38876d54d1cc07c39e3abd58873c85468d81a31b9f27e1726228cb53e6bf04bc710edaa264bd9a54a29da62ddadb8a0c80e5c5e2027582b4c46bd6b7cd7e0988e21db534c97b34a9453b4c5bb5b7141901cb8bc404eb056988d7ad6f9afc1311c43b6a62541bf41ff09ec43437d0a7b169799732cdfbcaa311c99aef35f826338876d4b4a837e83fe13d88686fa14f62d2f32e659bf79546239335de6bf04c6710eda96211955b4d28a33c4daba51e450bc8dc75fc14ea5c4740abccd7e098de21db52b4232ab69a5146789b574a3c8a1791b8ebf829d4b88e815799afc131bc43b6a561077af80208b51cb37af6f8939505f182b47969411d1cef435f826388876d4ab20ef5f004116a3966f5edf1272a0be30568f2d2823a39de86bf04c7110eda95641debe00822d472cdebdbe24e5417c60ad1e5a5047473bd0d7e098e221db52ac0fcfd4addabd11118a41a441c0e120bc067f109d8e901ba2afc131c543b6a5571f9fa95bb57a22231483488381c241780cfe213b1d2037455f82638a876d4aae3f3f52b76af4444629069107038482f019fc42763a406e8abf04c7150eda955c0a90fe1bac4b0b441ed34a05fd672ddae03ae0e9748281167e098e2b1db52ab71521fc37589616883da6940bface5bb5c075c1d2e905022cfc131c563b6a556e2a43f86eb12c2d107b4d2817f59cb76b80eb83a5d20a0459f82638ac76d4aadc5487f0dd62585a20f69a502feb396ed701d7074ba41408b3f04c7158eda955b835223a679b1336f9b9fac857ccd105a8aff06a944829b568e098e2b2db52ab6f6a4474cf36266df373f590af99a20b515fe0d52890536ad1c131c565b6a556de609b424b42af5e9eb4b1495729a23e9d6c04064e20a879a482638acc6d4aadbb4d48dd435bc13ff53628baa649a2a535844a68994152974a04c71599da955b7526a413338de502a239179d4489a37265b4d72d2f82a6d295098e2b34b52ab6e94d4826671bca0544722f3a891346e4cb69ae5a5f054da52a131c56696a556dd226a2a57b0df68d40b1249d0a1cebf1917f9f10bb0a9cee552638acd3d4aadba34d454af61bed1a8162493a1439d7e322ff3e21761539dcaa4c7159a7a955b746269cee990e3cb7ba91589c206a0dee40aabe9ee92a755d5598e2b35052ab6e8b4d39dd321c796f7522b13840d41bdc81557d3dd254eabaab31c566a0a556dd16268613110f5561a2122898799e95e0fd573cd7a1a9d71957638acd424aadba2b4d0c26221eaac344245130f33d2bc1faae79af4353ae32aec7159a84955b7456262aa4f113b80940156889de70b5abf00935ba83a75e095e8e2b350a2ab6e8ab4c5549e2277012802ad113bce16b57e0126b75074ebc12bd1c566a14556dd15624bcec712542a7b822684f71b934d7bad119460b9d79c97b38acd429aadba2ab4979d8e24a854f7044d09ee37269af75a2328c173af392f67159a85355b745561f060a716b6d2198566765bedb3186e5f0a7742b75e8c9ede2b350a7ab6e8aab3e0c14e2d6da4330accecb7db6630dcbe14ee856ebd193dbc566a14f56dd1556082a8272841709192663bef3632443926ee02caad7a4cbb88acd429fadba2aab105504e5082e12324cc77de6c6488724ddc05955af499771159a853f5b74555620aa09ca105c2464998efbcd8c910e49bb80b2ab5e932ee22b350a7eb6e8aaac4154139420b848c9331df79b19221c9377016556bd265dc4566a14fd6dd155580eba7fd517d3144a3302172e28a261219a4526aa7a4e5f89acd429fbdba2aaaf1d74ffaa2fa6289466042e5c5144c243348a4d54f49cbf1359a853f7b745555e3ae9ff545f4c5128cc085cb8a289848669149aa9e9397e26b350a7ef6e8aaabc01e6575594fb250964d6e1693b7131077e6b9150d274a04e66a14fdfdd15557703ccaeab29f64a12c9adc2d276e2620efcd722a1a4e9409ccd429fbfba2aaaee07995d5653ec9425935b85a4edc4c41df9ae454349d281399a853f7f745555dc0f32baaca7d9284b26b70b49db89883bf35c8a8693a50273350a7efee8aaabb81e6575594fb250964d6e1693b7131077e6b9150d274a04e66a14fdfdd15557703ccaeab29f64a12c9adc2d276e2620efcd722a1a4e9409ccd429fbfba2aaaee005a82e12152bc511027e8246d2aa69da4726b0319d29b79aa853f7f845555dbf0b505c242a578a2204fd048da554d3b48e4d60633a536f3550a7eff08aaabb7e16a0b84854af144409fa091b4aa9a7691c9ac0c674a6de6aa14fdfe1155576fc2d417090a95e288813f4123695534ed23935818ce94dbcd5429fbfc22aaaedf85a82e12152bc511027e8246d2aa69da4726b0319d29b79aa853f7f845555dbf041181aef7bdb24d81c9670d24bab634391186230a53897560a7eff09aaabb7df0e428e8bce18cc6805f3099c8db4ee81ce73205e4a72d2ad14fdfe1455576fbd1c851d179c3198d00be613391b69dd039ce640bc94e5a55a29fbfc28aaaedf7a390a3a2f386331a017cc267236d3ba0739cc817929cb4ab453f7f851555dbef47214745e70c663402f984ce46da7740e739902f253969568a7eff0a2aabb7de8703b4169b7ef49382bf6c1c0d1ad1017937461e1a72eced24fdfe1465576fbcf6c88db804641152824b3ab7999b84829d32b1fc04e5f41a59fbfc28daaedf79d65240fad62e4ad08162d7eeb29ceb84e52989b7d9cc0274c3f7f851c55dbef39565a78079c2bdcc7f92125ce49fb9897517392f83981f2997eff0a39abb7de7138c748bc0eba3c47bf0873948a5559294f2981ed73058933fdfe1474576fbce1718e91781d74788f7e10e72914aab2529e5303dae60b1267fbfc28e8aedf79c26f2f7b9d114b73d6c8e7f64a1fb38c9fe8e863b2cc17c8d0f7f851d25dbef3836a714fe6f8f96a655e96148c35c5413a7e132362983135a2eff0a3a5bb7de70560f4f87ac855578289f2511061e8aa6fa868a2c230640f46dfe1474c76fbce094dfc49a2670d31bce0aaca18ba2f7cd9fd13a18160c9c28ebfc28e99edf79c11280aebf1a47ce6318e1bbc296abd21aea6699effc195291e7f851d34dbef38215015d7e348f9cc631c377852d57a435d4cd33dff832a523cff0a3a69b7de70422c3e087368561b7e0535189da152aeb545e8d7fc0656487afe1474d46fbce083587c10e6d0ac36fc0a6a313b42a55d6a8bd1aff80cac90f5fc28e9a8df79c1063d0a7a7a77baf0afe19a8a6e7ba8e2cfc3e5bbed195ac5ecf851d352bef3820b06274da1c5d864178ffb3cd4edafed9a340dd3d732b72fdaf0a3a6a67de704150c4e9b438bb0c82f1ff679a9db5fdb34681ba7ae656e5fb5e1474d4cfbce082a189d36871761905e3fecf353b6bfb668d0374f5ccadcbf6bc28e9a99f79c1054313a6d0e2ec320bc7fd9e6a76d7f6cd1a06e9eb995b97ed7851d3533ef3820a86274da1c5d864178ffb3cd4edafed9a340dd3d732b72fdaf0a3a6a67de70415050fc0ce5916f05a9cc2dc295ac5bdb412dfcd6e356e79f5f1474d4d0bce0829f2e0a7277f9408e0b6521ad234f15de7d083c09c3add0e2bf28e9a9a279c1053d5c14e4eff2811c16ca435a469e2bbcfa107813875ba1c57e51d35344f3820a7a443c228cbb64bae5614cdc8532b5a1eecd32830bb7452efda3a6a68ae70414f3148a9dc64d2bf8828f5fe1025bc96bd846a762146e8c01fc474d4d16ce0829e529153b8c9a57f1051ebfc204b792d7b08d4ec428dd1803f88e9a9a2d9c1053ca522a771934afe20a3d7f84096f25af611a9d8851ba3007f11d35345b3820a794306746df3fc246cc47c5300ad4a986bce17d6ca07461b3e33a6a68b770414f2760ce8dbe7f848d988f8a6015a9530d79c2fad940e8c367c674d4d16ee0829e4e4daf7429d56b9de8ebdae823490442ee32380e7ed188738de9a9a2dec1053c9b277141008139be89a47bf83e8866add710b278faa3128b1cd35345be820a79354ee2820102737d1348f7f07d10cd5bae2164f1f546251639a6a68b7d0414f26a29d75caedb497cde5eb608f217f8df56ef0c3fe78c4bd0744d4d16fb0829e4d353aeb95db692f9bcbd6c11e42ff1beadde187fcf1897a0e89a9a2df61053c9a6336fcb6843887631479e4bc05641a55668735b9b3130e5d235345bed20a7934b66df96d08710ec628f3c9780ac834aacd0e6b7366261cba46a68b7da414f269659d1864de4845b7ceb3f56f94f64bd544e0fca69c4c53b49d4d16fb5829e4d2b3fb565489f6b39b1a344d5ea9527a2a34861f0d0898c1a94a9a2df6c053c9a550b7d233e1538f61b134fd3cd20ad6d413d063d9e1319d92a5345bed90a7934a916fa467c2a71ec36269fa79a415ada827a0c7b3c2633b254a68b7db214f269522df48cf854e3d86c4d3f4f3482b5b504f418f6784c6764a94d16fb6429e4d2a45be919f0a9c7b0d89a7e9e69056b6a09e831ecf098cec9529a2df6c853c9a54843e48c8e29f1e46901c364ca0134fc0e7ca635de319f36a6345bed91a7934a8f13db71c92a464b89d04cf18bf8c82017a58ec7b96340114d68b7db244f26951d27b6e392548c9713a099e317f190402f4b1d8f72c680229ad16fb6489e4d2a3a4f6dc724a9192e274133c62fe320805e963b1ee58d004535a2df6c913c9a54742aede6f62894df064f2db457bc9f28b7d8b899c81a022e6c45bed9237934a8e755dbcdec5129be0c9e5b68af793e516fb171339034045cd88b7db246f26951ce37c9f48578b5fed1097cf956e8dacada0f24c31d680a5db216fb648ee4d2a39b6f93e90af16bfda212f9f2add1b595b41e49863ad014bb642df6c91dc9a547366b3a2ac2b93a7dfbf2ba0d5399c95362e8d56872a02b1ac95bed923c934a8e6b6286ae3248d77eafb23a429f29f0cec07ded2ce24057d993b7db247a26951cd5511fb51168118017313aad364a3fc57ba81cb5c180b157286fb648f54d2a39a92e51c2cfa68582e62f3b82648addb2f1fc7bc78001645251df6c91eb9a5473515ca3859f4d0b05cc5e7704c915bb65e3f8f78f0002c8a4a3bed923d734a8e6a2455963eb70788e5089b4318a21d4f3c29e3179fd0592ed487db247af6951cd4316c52083b7539f58e02e8b0c3a080f7fe8a54ff70b277e91fb648f5fd2a39a852d8a41076ea73eb1c05d161874101effd14a9fee164efd23f6c91ebfa547350a5b14820edd4e7d6380ba2c30e8203dffa2953fdc2c9dfa47ed923d7f4a8e6a14423b5cca90ff7d7ece3a8059c69ea3f9f16cdbb5593d9890db247aff951cd42710891241f8617db5693b28ab839b6fee8f1c1367b27cd522b648f6002a39a84d21122483f0c2fb6ad27651570736dfdd1e3826cf64f9aa456c91ec005473509a42244907e185f6d5a4eca2ae0e6dbfba3c704d9ec9f3548ad923d800a8e6a134105aeabc996e7063169f6d541339a76f2522f73a93e84d16b247b00251cd426720b5d57932dce0c62d3edaa826734ede4a45ee7527d09a2d648f6004a39a84ce416baaf265b9c18c5a7db5504ce69dbc948bdcea4fa1345ac91ec0094735099c0ee9ae91a1d605d081c19298902b6373d55a15d19f440cb6923d80138e6a13371dd35d2343ac0ba1038325312056c6e7aab42ba33e88196d247b00271cd4266e3ba6ba468758174207064a6240ad8dcf556857467d1032da48f6004e39a84cdc035fcd39e512b13bdad2bcbc77b9439957130a89fa2209b591ec009d735099b706bf9a73ca256277b5a57978ef728732ae261513f444136b23d8013ae6a1336e0d7f34e7944ac4ef6b4af2f1dee50e655c4c2a27e88826d647b00275cd4266dc1afe69cf289589ded695e5e3bdca1ccab898544fd1104dac8f6004eb9a84cdb835fcd39e512b13bdad2bcbc77b9439957130a89fa2209b591ec009d735099b706bf9a73ca256277b5a57978ef728732ae261513f444136b23d8013ae6a1336e06405a7261b0ed1ae81755715e4af0e507104fe7b888411657b00275dd4266dbf541da6f90c802614cfb0d623bfbc449b8e4c58f41109c6cbf6004ebca84cdb7d344da69eef62cee16c27d43f75d6b131c8db0de522153198ec009d7a5099b6f9689b4d3ddec59dc2d84fa87eebad626391b61bca442a6331d8013af4a1336df25d48f32893edbe3d7d6578f5cdb8ecc1cfae939188566a64b00275ea4266dbe346a43efdfe3dff32c79119e391d0017e4b9f832010ae78ca6004ebd584cdb7c5195ad6a8d2de811d5be85bbf19fe2af74381623d215e9595c009d7ac099b6f8932b5ad51a5bd023ab7d0b77e33fc55ee8702c47a42bd2b2b8013af581336df12656b5aa34b7a04756fa16efc67f8abdd0e0588f4857a565700275eb0266dbe2456e90df36d568ba2ac0905f0c64f7fb4c84d6de60af650af004ebd614cdb7c4739e47493b10f99fd24d833d982fd27643cdd37c915ee455f009d7ac399b6f88d73c8e927621f33fa49b067b305fa4ec879ba6f922bdc8abe013af587336df11a73a42afb9aa0eaac6026f75e0252c58b9fb73b2157bab97d0275eb0f66dbe233735aaea40ba458108d1416b3fb03b311ebb0d23faf7716fb04ebd61fcdb7c46572c7b5f4edab32d8e6ee555fec658e1e83a4007c5eefd1f709d7ac409b6f88c971a1c496b1b8e8699aa2d2b7cf294437b38a5cf5bde147ef13af588236df11916f55e1da39d4538b020bcd6794b0b06a135715e87bc433df275eb1056dbe23216abe1c614a0b29cdd0ddc2c71fbf88ced2f087cdf78a0bbf4ebd620bdb7c4641618e916f6a78d6536e81ad8635dd399852236b98ef15bb7f9d7ac418b6f88c814f2f7b8bab542f5ea9c9830462189b2b5089332ede2d1b003af588326df119012a714fc42d0ae17520592e00ba8f5e514d54c25abc5bda0175eb1065dbe2320154e29f885a15c2ea40b25c01751ebca29aa984b578b7b402ebd620cbb7c4640235d797bd8a8e088c4e2adffae09ba13fe1956567f1710c06d7ac41986f88c8036baf2f7b151c11189c55bff5c137427fc32acacfe2e2180daf588330df1190066370b7a3009aa4e90571a7e378ccacfa3297f19cc5c5d41c5eb10662be23200b52f3c7f2d797cc89d7a977bee7f781ef11723f368b8d4c39bd620cc67c46401531f9e89285921bcb7c191775c64d2bd8cf26da6a171c3c747ac4198df88c802963f3d1250b243796f8322eeb8c9a57b19e4db4d42e3878e8f588331bf119005253f9faf6ecaaf1e5bd2a85cf0f92d75de8ddc5a55c7295d2eb106638e23200a334064e9aafb86683471b33961583d6b67dfde747b8e6cfa6d620cc72c4640145680c9d355f70cd068e36672c2b07ad6cfbfbce8f71cd9f4dac4198e588c8028a5c2b931795441cc4e932f6504c6d82d4a439f91be39ce29c588331cc1190051344697edc00eabc419f2c14988f392da3f4b64e34c73b6939b106639923200a2514e55664d837fb3b0b1e512914d0834295aef8668e787674620cc7334640144929caacc9b06ff676163ca25229a106852b5df0cd1cf0ece8c4198e668c8028925395599360dfecec2c7944a453420d0a56bbe19a39e1d9d188331ccd19005124333d0bd398225c9025b8b1409ce2420f59ba1f3173c557a41066399b3200a247667a17a73044b9204b71628139c4841eb3743e62e78aaf4820cc73366401448e590687fb36ebf4f863a8ecfa69e73038132ad8c2cf1702914198e66dc802891b3e1f68a3443a6ca8941801ecca2c886ad2980d829e2fa9238331ccdc90051235085129f35ed75c08f4f62bd18ab738d0517277023c60f648066399ba200a246910a253e6bdaeb811e9ec57a3156e71a0a2e4ee0478c1ec900cc73374401448d22144a7cd7b5d7023d3d8af462adce34145c9dc08f183d920198e66e8802891a442894f9af6bae047a7b15e8c55b9c6828b93b811e307b240331ccdd1005123481124f7e2c3d843471c28e510a1d1b4ffc369cc20c611088166399ba300a2468f2249efc587b0868e3851ca2143a369ff86d398418c221102cc73374601448d1e4493df8b0f610d1c70a394428746d3ff0da730831844220598e66e8c02891a3c153a17c2f5249cf0ae0d507d04ebcff8c790bd033089e80c31ccdd19051234772a742f85ea4939e15c1aa0fa09d79ff18f217a066113d0186399ba320a2468ee54e85f0bd49273c2b83541f413af3fe31e42f40cc227a030c73374641448d1dc35e316c47f876a3d3d30abe01dbca7c0e8c844168450e4628e66e8c92891a3b76bc62d88ff0ed47a7a6157c03b794f81d190882d08a1c8c51ccdd1925123476e639eb3bed4802bacc188d7786d50c6fe4f636c571145358b399ba325a2468edb534fc02a7f62da114fd7d6e8d0ffb5f74b0934ab228c0f177337464c448d1db532b1d901d52836da6c75d5c9985d93e94254c5534519c22fe66e8c99891a3b696563b203aa506db4d8ebab9330bb27d284a98aa68a33845fccdd1933123476d256d9bcb42b035e217e9d7f1e57d4779fb595714a1468acc099ba32672468eda339c5d2152c693efaca012634a607173a176d3e9128d2fd82337464cf48d1db45738ba42a58d27df594024c694c0e2e742eda7d2251a5fb0466e8c99e91a3b68a7329a10188077ea2f4cac0ca8e7a84e309f75641a34d9a09cdd1933e23476d1372659aafe6717ffdb65ba98d135331c0c0310880469cd8149ba3267d468eda2570dd8e0ca34582b3397d7b121d048b7c2ca46cfd8d3b542a37464cfb8d1db4496dcd74c61ced881e3fc11e1c30673ef3058b35f81a784c556e8c99f81a3b689167ad4239103d92f44c486430572ca5e0b758c7ed34f23cabdd1933f13476d1215b6cdd1ef6dda8a06556f058a4b773bc1af3ebd769e61d58ba3267e368eda24142ec12eac41dd3f8977408a93fcd0f72e22a33abd3cddeb27464cfc7d1db448111ea7e825e9e2aa8fbae394a75f846e07096c354a79d6165e8c99f90a3b6890123d4fd04bd3c5551f75c7294ebf08dc0e12d86a94f3ac2cbd1933f21476d120247a9fa097a78aaa3eeb8e529d7e11b81c25b0d529e758597a3267e428eda24041b664cbfcb53d7ffaa37f24ba6205efe30f876a23cecaf30464cfc861db4480736cc997f96a7afff546fe4974c40bdfc61f0ed4479d95e608c99f90c3b68900e6d9932ff2d4f5ffea8dfc92e98817bf8c3e1da88f3b2bcc11933f21876d1201c6744beab310142b51e85ba5527611fec3406110ee7671d833267e431eda240375a9bd6033865082209d19ca2452067d3144e7e1acecfdf0764cfc864db44806d414a04b3472c92fbe069613c809ef7a0d4df58329da1620fc99f90cab68900d90ea6621364bba8af8d98ea70f79c173c56010c623b446820933f21966d1201b11d4cc426c977515f1b31d4e1ef382e78ac0218c47688d041267e432cda2403623a99884d92eea2be3663a9c3de705cf158043188ed11a0824cfc8659b44806c401456947fc3fc834398d7b7fb33ee1dd5c4abf0eda24e50599f90cb468900d87028ad28ff87f9068731af6ff667dc3bab8957e1db449ca0b33f21968d1201b0e0515a51ff0ff20d0e635edfeccfb8775712afc3b6893941667e432d1a240361c0a2b4a3fe1fe41a1cc6bdbfd99f70eeae255f876d127282ccfc865a344806c381456947fc3fc834398d7b7fb33ee1dd5c4abf0eda24e50599f90cb468900d87028ad28ff87f9068731af6ff667dc3bab8957e1db449ca0b33f21968d1201b0e0515a51ff0ff20d0e635edfeccfb8775712afc3b6893941667e432d1a240361c02ec6fcaaf6469cd49383e7d195cf16a8d1a1e36a127426cdfc865a354806c37f5d8df955ec8d39a92707cfa32b9e2d51a343c6d424e84d9bf90cb46a900d86fe472e4b58af7cf60a1ad5c73e4d9a829df2c9e9a549d23f38f21968d6201b0dfb1a6eef5e355c6ecc0271b67491932d3691d62f4793a62272e432d1ad40361bf534dddebc6ab8dd9804e36ce923265a6d23ac5e8f274c44e5c865a35a806c37ea69bbbd78d571bb3009c6d9d2464cb4da4758bd1e4e9889cb90cb46b500d86fd45f89d39e8145f917e053db9c82f791af3af3d6399d32b79821968d6b01b0dfa74b25ffe9d8ee74e78d6ddf30fc4d4b59222a08703a671331432d1ad70361bf4d225e5880883f6c86e7a1e659eef8beacf0966cdd74cfca63865a35af06c37e9944bcb101107ed90dcf43ccb3ddf17d59e12cd9bae99f94c70cb46b5e0d86fd32158bbaaef76034d36b4dc15fb24122ae6e9c0f72d340cd8f1968d6bd1b0dfa632b17755deec069a6d69b82bf6482455cdd381ee5a6819b1e32d1ad7a361bf4c6562eeabbdd80d34dad37057ec9048ab9ba703dcb4d03363c65a35af46c37e98c38702e2491642953273432f588673d6e2122d7939a081079cb46b5e9d86fd31770e05c4922c852a64e6865eb10ce7adc4245af27341020f3968d6bd3b0dfa62e6dd3113f1bf328046996f3ce17fb1db330cdba4b6821e5e82d1ad7a861bf4c5b67b87b2b0e48d2c09ff40f94265463610dddd093d0456fd15a35af51c37e98b55b834f02f2f428390cae47204306eebcc7fdfd24a08c83a3b46b5ea486fd31694318f6b2bc4ad329e622b6387c6c05743c3e5646411aab4868d6bd4a0dfa62d1124446124ef8290b990b9468ef3632e324bf08898236fa91d1ad7a951bf4c5a124888c249df05217321728d1de6c65c6497e1113046df523a35af52a37e98b42491118493be0a42e642e51a3bcd8cb8c92fc222608dbea4746b5ea546fd316841e34893f4e23cb149522cb3f700fbf13d23aa04911b9788f8d6bd4a9dfa62d073c69127e9c4796292a45967ee01f7e27a47540922372f11f1ad7a953bf4c5a0e04e47daa0ef1af0a215154f5b69d2449f52cdd2146e7863f35af52a87e98b41b09c8fb541de35e1442a2a9eb6d3a4893ea59ba428dcf0c7e6b5ea550fd3168361391f6a83bc6bc28854553d6da749127d4b374851b9e18fcd6bd4aa1fa62d06c2723ed50778d78510a8aa7adb4e9224fa966e90a373c31f9ad7a9543f4c5a0d84e47daa0ef1af0a215154f5b69d2449f52cdd2146e7863f35af52a87e98b41b028a20deeb49863fbf6f0c6aeca02b13951de0025dcf26be7b5ea5510d316835f51441bdd6930c7f7ede18d5d94056272a3bc004bb9e4d7cf6bd4aa21a62d06be2e9a9067a8c412a7a88942b31e68ecdff3ba5c9473cb539fd7a954444c5a0d7b5d3520cf5188254f511285663cd1d9bfe774b928e796a73faf52a88898b41af6467c9a4b7972cd566eeb32c47001db7a7b2bce4ecf2ef2805ea55112316835eb190b8d43c9481d64aa9c8d80d661deefa299f89a9e5f8901bd4aa22562d06bd532171a8792903ac955391b01acc3bddf4533f1353cbf12037a95444ac5a0d7aa642e350f25207592aa72360359877bbe8a67e26a797e2406f52a88958b41af54546ec2cb20a36ddd21aa93fea96d1f77c11220d1f2fdec0eea55112c16835ea734efde4317a95e72101b4ff5493866ea2e669da0e5fd7c1ed4aa22592d06bd4d69dfbc862f52bce420369fea9270cdd45ccd3b41cbfaf83da95444b25a0d7a9a5fd1d1b93507fc800d3367cd1b3fc3a365dcd28097f7947c52a88965b41af5334bb5fc1f40727bb7e72cf7922cddaf4177fc00fe2ff0ccf9a55112cc6835ea65237e50eb57477a279b20171c5019867d9c3a5df95fe33df44aa22599d06bd4c946fca1d6ae8ef44f36402e38a0330cfb3874bbf2bfc67be895444b33a0d7a9921a0b9c5a33806b563946846936c441f11d2bd3e27f8e9bd22a88966841af5323341738b46700d6ac728d08d26d8883e23a57a7c4ff1d37a455112cd0835ea646682e7168ce01ad58e51a11a4db1107c474af4f89fe3a6f48aa2259a106bd4c8c5c6f3b7e7265dd6996fa4b41ac80378395a0fb10fc7682925444b3430d7a991744f0cfa9bb2e3d8afababe7b4f5e9701d784521ef8eea925a88966871af5322d15f3f8004cbefdcdc23ba4ee951b55fe5b4b003af1def64c5112cd0f35ea64592be7f000997dfb9b847749dd2a36abfcb6960075e3bdec98a2259a1e6bd4c8b257cfe00132fbf73708ee93ba546d57f96d2c00ebc77bd931444b343cd7a991643bb218af3c5a7125dea34f6c9f38d7ed869a5dd48ef956638896687aaf5322c703768a0b4f1765038a0cc6d134cfd7d5b97717a61df450c8112cd0f65ea6458d06ed14169e2eca0714198da2699fafab72ee2f4c3be8a1902259a1ecbd4c8b1a0dda282d3c5d940e28331b44d33f5f56e5dc5e9877d1432044b343d97a9916341bb4505a78bb281c50663689a67ebeadcbb8bd30efa28640896687b2f5322c683768a0b4f1765038a0cc6d134cfd7d5b97717a61df450c8112cd0f65ea6458d06ed14169e2eca0714198da2699fafab72ee2f4c3be8a1902259a1ecbd4c8b1a069b4db809c3bc39a4ff7dc452a541d690a0845847d15d6054b343d98a991633f5f7c0fae0eda09ec6cb5e0824b0662ccc052e705fa2d500b96687b325322c67d4b0a7808f4169690a631e8fc8c6aed942ce82a08f45c44182cd0f665a6458cf9222748bebe8fafd91929f9f10f3403230612b00ee8ba2c3159a1eccc4c8b19f1444e917d7d1f5fb23253f3e21e6806460c25601dd1745862b343d998991633e214af7ba7d0a1421c316e0fbc332e3486c48d1c38a2ea54c66687b332322c67c3295ef74fa142843862dc1f78665c690d891a387145d4a98ccd0f66646458cf8652bdee9f42850870c5b83ef0ccb8d21b123470e28ba953199a1eccc8c8b19f0c318e35eb5b6c93995836a5d98fcfcc30d0ab3dc217544a34343d999291633e17631c6bd6b6d92732b06d4bb31f9f9861a1567b842ea89468687b332522c67c2e524b305a4414d11d2da0bf5e359d58bdeeef53055d52ccd1d0f6664b458cf85b30a8b9615e8c24f22807a6b46198d9768a210207baa73da4a1eccc978b19f0b5615172c2bd1849e4500f4d68c331b2ed1442040f754e7b4943d9992f1633e16a4eb53e32509316806ce4c2c97cc18dd4d4c6641bea9e9a9387b3325f2c67c2d3297cd5117788afb8a68fad8aefe143a455cf2434d53ed9280f6664bf58cf85a552f9aa22ef115f714d1f5b15dfc28748ab9e4869aa7db2501eccc97eb19f0b4a3205acf2b485419a6704de23b5e3368c037eecd054fd08a13d9992fe633e1693640b59e5690a8334ce09bc476bc66d1806fdd9a0a9fa11427b3325fcc67c2d2654290c77a877892168d9a086cdeb022aba3e0f3e53f5c685f6664bfa8cf85a4b3464719c275194fa9e79690592342c5020be7a79a7ed310ceccc97f619f0b49568c8e3384ea329f53cf2d20b246858a0417cf4f34fda6219d9992fec33e1692a5da41f1d73a8d6a246abcc0e3f2ed93b2f3c45e39fb66834b3325fd967c2d253475a96e7bdb42ffc5a1dc01474bbda710abae7c43f6e746a6664bfb3cf85a4a51ac7867c51cae2b08101a820dfd5dcdcc1b82b857ede8cd5ccc97f689f0b4949358f0cf8a395c56102035041bfabb9b98370570afdbd19ab9992fed13e1692926b1e19f1472b8ac20406a0837f57737306e0ae15fb7a33573325fda27c2d2524624e8c8f64b9983bd4d368fef50d0ee0ba03b828f6f60aaf664bfb45f85a4a4750af71cb9fd5b32f766cf9f5e07845bc2049cc4eededb95fcc97f68cf0b4948d2d713c44160de916b9a01be3b74eb372ecd5f49adbdd16c0992fed1ae16929195ae278882c1bd22d734037c76e9d66e5d9abe935b7ba2d81325fda35c2d2523241d749bd2e9a2712b3469786d398f5c65f9a2e686f75ff0364bfb46c85a4a4630fc0ec273396d0dd335357059d9013876b76b8cddeeda207c97f68da0b4948c51f81d84e672da1ba66a6ae0b3b20270ed6ed719bbddb440f92fed1b41692918a3f03b09cce5b4374cd4d5c1676404e1daddae3377bb6881f25fda3682d2523140a19b9e6731909a16760e024e2dec43607f8226bf76eb43f4bfb46d15a4a4627143373cce6321342cec1c049c5bd886c0ff044d7eedd687e97f68da2b4948c4e2866e799cc6426859d8380938b7b10d81fe089afddbad0fd2fed1b456929189c50cdcf3398c84d0b3b07012716f621b03fc1135fbb75a1fa5fda368ad25231382dadf71407f31cce42d42a46244a6b5b2bc482bc76ece7f5bfb46d16a4a4626f5b5bee280fe6399c85a8548c4894d6b657890578edd9cfeb7f68da2d4948c4de42ca34fcf62ef5f0d816d1108787d5675b5466eedbb543d7fed1b45b929189bb11a6c2a6c2c06e997cf3ca19056dd2c962eb29dab76c2bb0fda368b825231375234d854d8580dd32f9e794320adba592c5d653b56ed85761fb46d1704a4626ea469b0a9b0b01ba65f3cf286415b74b258baca76addb0aec3f68da2e0948c4dd419486de2ec65f783b46478c021ccbe45c39baad2bb630188ed1b45c229189ba73290dbc5d8cbef0768c8f18043997c8b873755a576c60311da368b845231374e6521b78bb197de0ed191e3008732f9170e6eab4aed8c0623b46d1708a4626e9c5655c7c439923ed56fe9edf904c41a28c91fb292db19b04868da2e1248c4dd3738bde83549870062ac9a03e9ffe65c4c3e81c122b6350491d1b45c259189ba6d717bd06a930e00c5593407d3ffccb8987d0382456c6a0923a368b84b231374da6f09f981fc7e84427f2e379ff5f7992ba6496087d8d5b64846d170974626e9b36a264bb0cf5f8b3ccb229737e24d5a51f8d51d0cb1ad10918da2e12f8c4dd365605ef00e75219931630b5667baf8dc9e9dec9616635bc5241b45c260189ba6c94cd038c9c0a5b51a92dcd4c76c4fe137e81b8829c6b92e49368b84c131374d9125b2ca4057adececf27fd186cefdea6a7c796c508d7400936d170983626e9b214b659480af5bd9d9e4ffa30d9dfbd4d4f8f2d8a11ae80126da2e1306c4dd364222dd81ae351a366b96c56e133255d1a49e280d3f35d1a64eb45c260e89ba6c8345bb035c6a346cd72d8adc2664aba3493c501a7e6ba34c9d68b84c1d1374d90617885f65aacb5c6627dbe044bfb56e8d24e290f9d7483d3bd170983b26e9b20b2f10becb5596b8cc4fb7c0897f6add1a49c521f3ae907a77a2e130764dd364165e217d96ab2d71989f6f8112fed5ba34938a43e75d20f4ef45c260ec9ba6c82c485553da2cbd65e90ba52a1df4099c63d356e3cbba438ddf8b84c1da374d90571cbd00612fdd4e89e4107c33de7160c252f023947488bfc0170983b56e9b20ad397a00c25fba9d13c820f867bce2c184a5e04728e9117f802e13076add36415a72f40184bf753a279041f0cf79c583094bc08e51d222ff005c260ed5ba6c82b471fa5bb6554cf706ed4a0996e9e92e0d43c378a0a447a201b84c1dac74d905677007101980fc70c5a75a3b25ca30841533c94d3e4890e80470983b59e9b20acd6c2078dfd85b64431b7a9e438abf302513d4f67991237409e13076b4d364159964534a6c87194b3e03bb647f0bdc8844d3ec48f022488c14c260ed6aa6c82b3154b8ed85e4951933d43cf0f60e173884541aeddd4492bc2a84c1dad64d905661358433b89f8cb51f754009e4128c9903547837b789271c560983b5ad9b20acc16b0867713f196a3eea8013c825193206a8f06f6f124e38ac13076b5b364159826223278f54955735a1c64f8840908c07fe233adb249e1559260ed6b76c82b3035058a7cb7f8d31231052c708777f400aa888d1b3493dceb34c1dad6fd90566052cc3a843d57ce4fded6bb608e55ca80ffd53ff63927d4167983b5ae0b20acc0959875087aaf9c9fbdad76c11cab9501ffaa7fec724fa82cf3076b5c1641598123f20f9bc2c5616af8275001b8bd0c83aa192598b49f6a99f60ed6b83c82b30230a544c252f0eb016d1b0282f0dffb86fef670f1393eef73fc1dad7089056604514a8984a5e1d602da360505e1bff70dfdece1e2727ddee7f83b5ae1120acc08a29513094bc3ac05b46c0a0bc37fee1bfbd9c3c4e4fbbdcff076b5c224159811452a26129787580b68d8141786ffdc37f7b38789c9f77b9fe0ed6b84482b3022831571affc74d8424e7c8aae8d659aef9a2b34d363ef117fd1dad708a0566044f62ae35ff8e9b0849cf9155d1acb35df345669a6c7de22ffa3b5ae1140acc089e516ec4abf398934b6be8d39b4fc4e3e1370f90d5fbc603f576b5c2291598113b2eefe204bd93a94ea497cf2e95e7efbd1a617da8f78dabebed6b84532b3022755ddfc4097b27529d492f9e5d2bcfdf7a34c2fb51ef1b57d7dad708a6566044ea47d1e0bfccb127f25f2564b24dfde6ef15c852a0de3853b0b5ae114dacc089d31bb61a2c6fc4d29c8b10f15c9259f5d8d7d3013ebc724b626b5c229c598113a5376c3458df89a5391621e2b924b3ebb1afa6027d78e496c4d6b84538b302274a6ed868b1bf134a722c43c5724967d7635f4c04faf1c92d89ad708a7166044e9469c32a105489179c254db2dc892dd6c16ada65f2e393ff145ae114e3cc089d275f98accd7f74b1f017618db108b9d57d81f727e2c729a229b5c229c898113a4d4b43b247d54be697fb89435a07d1d2f5b030abc28e54e8546b845392302274992299bd3c80fa4fe7c3d8aeac0601cde60ca3b3821cab74a9d708a7256044e93145337a7901f49fcf87b15d580c039bcc194767043956e953ae114e4ac089d26216794d9eda4bc256dc28e2a80e655f92ded12a0572af76a85c229c968113a4c32cf29b3db49784adb851c5501ccabf25bda2540ae55eed50b845392d0227498659e5367b692f095b70a38aa039957e4b7b44a815cabddaa1708a725a044e930c3fdcc5a3a8c0956eae0d3d3869892491a2cbac28957d5943e114e4b5089d26170bcbe3f427e3ad9528e0a268c970711df1d9b44e2afc5688c229c96b113a4c2d1797c7e84fc75b2a51c144d192e0e23be3b3689c55f8ad11845392d62274985a2f2f8fd09f8eb654a38289a325c1c477c766d138abf15a2308a725ac44e930b45e5f1fa13f1d6ca9470513464b8388ef8ecda27157e2b446114e4b5889d2616848d097ef549d5c0a5ad04e848d6539d9c9dda0dfafc70c8d229c96b213a4c2cf1db3888b7f9d3acc8266c50111289bae3ffd9dbc5f8fbd1b45392d652749859d3b671116ff3a759904cd8a022251375c7ffb3b78bf1f7a368a725aca4e930b3a02e07adad4d76de9d6613bfc3b0096b3ac38d2ee7e40986e14e4b5959d26167305c0f5b5a9aedbd3acc277f876012d675871a5dcfc8130dc29c96b2b3a4c2ce60b81eb6b535db7a75984eff0ec025aceb0e34bb9f90261b85392d656749859cc1703d6d6a6bb6f4eb309dfe1d804b59d61c69773f204c370a725acace930b3982e07adad4d76de9d6613bfc3b0096b3ac38d2ee7e40986e14e4b5959d26167305c0f5b5a9aedbd3acc277f876012d675871a5dcfc8130dc29c96b2b3a4c2ce6044310f620c3dfd2d65152706b683d4e5ba77179c9027bf86392d656849859cbf14747770eede7d1296f076056365d1c621308b362051230d725acad1930b397d28e8eee1ddbcfa252de0ec0ac6cba38c4261166c40a2461ae4b595a3261672fa51d1ddc3bb79f44a5bc1d8158d97471884c22cd881448c35c96b2b464c2ce5f42fb614344d566b4c8449d823118cb62bb5c6b5ae028abc6c92d6568d9859cbe75f6c28689aacd6990893b04623196c576b8d6b5c051578d925acad1b30b397ce4aeaa97e0bbc2fe9dded88843c9100a9835d32b50a2c95b34b595a3761672f9b21e7aba8eddae28b88a139006f80294db2fcc167145acf6796b2b46fc2ce5f3543cf5751dbb5c51711427200df00529b65f982ce28b59ecf2d6568df859cbe6a13b107508dce0ce5ef4b0bf9b45ecd3178356199516ce19f5acad1c00b397cd327620ea11b9c19cbde9617f368bd9a62f06ac332a2d9c33eb595a3801672f9a64ec41d4237383397bd2c2fe6d17b34c5e0d5866545b3867d6b2b47002ce5f34c299a933144d2e9e7471e87c5995491866ded68c78b68b0fbd6568e0159cbe6975335266289a5d3ce8e3d0f8b32a9230cdbdad18f16d161f7acad1c02b397cd2e327ca571e9ae2a54e940470e5bb06e1463f7ff1b2da467f0595a3806672f9a5b64f94ae3d35c54a9d2808e1cb760dc28c7effe365b48cfe0b2b4700cce5f34b65604ee747d1b2c0b71c74431651fe04c3c225869b69343c26568e01a9cbe696b381c3595d098daceb054b05ac09de89324870cd06d282b85cad1c036397cd2d570386b2ba131b59d60a960b5813bd126490e19a0da50570b95a3806c72f9a5aa6c832f0418c5edf28e18e962f8d5ca473e5e8f3eb4a252182b4700d9e5f34b536518b6b507ee5e9ce8f7fabde809bc8928ff7a7a69464831568e01b4cbe696a55643c616e63f3ff19eb61d73c671a10cfe4150f1d28e3463ad1c036a97cd2d493899e4daa2e1029b0a3262df83416a14a8c4fde0a51e0cc85a3806d62f9a5a917133c9b545c205361464c5bf0682d4295189fbc14a3c1990b4700dac5f34b5226e79ec1761e68d23f58fb3760363d04d4f56537f9479d72268e01b59be696a43690630db9a2f9cffb7e58ee3fd25c8954aef02fc28f55245d1c036b47cd2d4855e1eba640ac1bcb73c9145bff0a9b925422061f551ec488ca3806d69f9a5a909484fcd74ebe5fc2645e8b377d7b19a4530831fe7a3da351a4700dad4f34b52111cb1f396ae2e7b0458978ee7a5c15c850d489bcc47b60e358e01b5aae696a4213963e72d5c5cf608b12f1dcf4b82b90a1a9137988f6c1c6b1c036b55cd2d484272c7ce5ab8b9ec11625e3b9e9705721435226f311ed838d63806d6ab9a5a908471a1f56247d65ada91829f3524690c2316873a5f3db215ad700dad5834b521076f564371660f386cefcb66623f304040d950d0bb7b65cf5be01b5ab1696a420d6abedf8fa280f391ac5cf4bc74bea87c5ee3fd73f6cd42b8c036b563d2d48419619017cc1b6469db25801170dfdb78f36a0a56e4ed9c2972806d6ac8a5a908314f3288450d2b566e17c64ad9b61519e1805709c6db39f6e600dad5924b5210612a776936f0b92f93fc52bdab62885bbdacf06f8ab67591cd01b5ab2596a420c154eed26de1725f27f8a57b56c510b77b59e0df156ceb239a036b564b2d48418235effd8899474107be111ea5807f96f160041a27d9d7eb3506d6ac975a9083036bdffb11328e820f7c223d4b00ff2de2c008344fb3afd66a0dad592eb521060663d24ecf3b7f86d6c50aa28df85c83c02c52c49c676150d51b5ab25e6a420c0b53b6f64b4d61906556db6d13e7172f7b04e7e535cec445ab36b564bdd4841815338045437125a3827a7d021fc48c86f0b61226689d8a2f576d6ac97ca908302967008a86e24b4704f4fa043f89190de16c244cd13b145eaedad592f9521060525a136dba9af910c1b6ba3077089043bd848af59f762a615eb5ab25f3a420c0a3403934220c54a43b3a3a88e6077eaf75b558473bec5666be6b564be8484181450c84c0f0ef0bcb2e413b39c4055b86e616f2ea74d8ae717dd6ac97d190830289190981e1de17965c827673880ab70dcc2de5d4e9b15ce2fbad592fa321060512321303c3bc2f2cb904ece710156e1b985bcba9d362b9c5f75ab25f46420c0a2464260787785e597209d9ce202adc3730b79753a6c5738beeb564be8c84181448545e67bbc71f359be079c4384c16965c1b71034a8ae8bbde6ac97d1a0830288f34cf282464a0edef8db9b0688e8b54b2e324629215d31bbdd592fa351060511d699e5048c941dbdf1b7360d11d16a965c648c5242ba6377bab25f46a20c0a23a5f4ef93e68e63a7603ace99a308b7ac638d3e645574e12f8564be8d5418144734ab04b29a82ef7a3d41ffb2c57751d871dea2887ae9dc9f1ac97d1ab830288e52172ef0026c071ff75061e50a5486308e816ad0c5d3d37e4592fa358060511c942e5de004d80e3feea0c3ca14a90c611d02d5a18ba7a6fc8b25f46b00c0a239211de14ad71644ab5a0dea13a8b7fb41e4c9d102e74f6839264be8d611814472323bc295ae2c8956b41bd427516ff683c993a205ce9ed0724c97d1ac230288e46477852b5c5912ad6837a84ea2dfed079327440b9d3da0e4992fa358460511c8c1b02fe186184d864d3bb31cc525bc8ed112add70a7b5c09425f46b09c0a239173605fc30c309b0c9a7766398a4b791da2255bae14f6b81284be8d6138144722e6c0bf861861361934eecc731496f23b444ab75c29ed7025097d1ac270288e45c642a496fe28945de6a9fb65a893c6f63359947823dafa8a22fa3584f0511c8b75466eb8c9b750e74a20594ad08d706c11774eb017b60f5455f46b09f0a23916d34e02fc60d4c9fa110d15152080c357cdb2c31fff6c38e8bbe8d613f144722d969c05f8c1a993f4221a2a2a410186af9b65863ffed871d177d1ac27e288e45b25f9317c50b95013c100b6d40168efdee18f323fcdb0fde2ffa3584fd511c8b634b388836ed8c852fecdd0278237c23d6de28a3f6b6216060f46b09fba23916c52283691ab17b8d17a6802ce83d566fa86893a3ea6c4464c2e8d613f844722d894506d23562f71a2f4d0059d07aacdf50d12747d4d888c985d1ac27f088e45b12161ffd179c50b71666c6db98ebb7e69c4e90eba6b113370ca3584fe211c8b6232c3ffa2f38a16e2ccd8db731d76fcd389d21d74d62266e1946b09fc423916c46587ff45e7142dc599b1b6e63aedf9a713a43ae9ac44cdc328d613f884722d88c3d124169b8e83b6b02fd04bf541d5cdd20c9b932889b5c661ac27f118e45b1170636db804832f98dd2c031769e98e1b4edd5ce6211385ccd3584fe241c8b622d0c6db7009065f31ba58062ed3d31c369dbab9cc42270b99a6b09fc483916c45a18db6e0120cbe6374b00c5da7a6386d3b757398844e17334d613f890722d88b431b6dc024197cc6e96018bb4f4c70da76eae731089c2e669ac27f120e45b1168636db804832f98dd2c031769e98e1b4edd5ce6211385ccd3584fe241c8b622d052edc8b5dcc1b47224cc56cbc97a5e9866fc283f270d3da7b09fc484916c459f31edea188fe5eb9c165ed58f8952e52b7a3aac7b4e1c1f50613f890a22d88b3d63dbd4311fcbd7382cbdab1f12a5ca56f47558f69c383ea0c27f121445b1167a53ca010f15fa312826417e361ba9bca8952d0dea3872214284fe24298b622cf333a65acb0256e508194924642db1a14bd69c77d170e5e68609fc485416c459e5674cb59604adca10329248c85b634297ad38efa2e1cbcd0c13f890a82d88b3ca5aabc3d8dfbe16d831eab988ad24ad2a06b43b42c3993e1927f121515b1167934169e05e95deb068309b9b0950a7824eb9aad282873420334fe242a3b622cf250ee6196a021fe3882dfd5e0a97ad2c981f9801020e69e4679fc485486c459e491dcc32d4043fc7105bfabc152f5a59303f3002041cd3c8cf3f890a90d88b3c923b9865a8087f8e20b7f5782a5eb4b2607e60040839a7919e7f121521b1167924034323fce7619ef93cb1184cb3c78cbba902640d7350c73dfe242a44622cf247068647f9cec33df279623099678f19775204c81ae6a18e7bfc485488c459e48e0d0c8ff39d867be4f2c46132cf1e32eea4099035cd431cf7f890a91188b3c91c1a191fe73b0cf7c9e588c2659e3c65dd4813206b9a8639eff12152231167923834323fce7619ef93cb1184cb3c78cbba902640d7350c73dfe242a44622cf247068647f9cec33df279623099678f19775204c81ae6a18e7bfc485488c459e48e05cdb57e6aeca4106f90c3b24e84156e4ecdb5f59d4337380890a91198b3c91bf45c9087a33f704c5bede9e41c6e0d5c485f91ab0a8688b02121522341679237d17a469a13e508c434a83647b841fd383b834915e50d2ba05242a44692cf246f92f48d3427ca118869506c8f7083fa707706922bca1a5740a485488d259e48df25e91a684f942310d2a0d91ee107f4e0ee0d24579434ae81490a911a4b3c91be44935a5b6c8e6e4d220e14bd4175cc4186de6e6ef8697742a2152234a679237c71e7da41a68304c5c0e88bfa02517b02b881029dc0d308c5542a44695cf246f8d3cfb4834d06098b81d117f404a2f6057102053b81a6118aa85488d2b9e48df1a0608e9167723b42806e926788abce8a8cc83036d34c3d5560a911a583c91be330c11d22cee4768500dd24cf11579d151990606da6987aaac152234b079237c661823a459dc8ed0a01ba499e22af3a2a3320c0db4d30f55582a446960f246f8cc304748b3b91da140374933c455e7454664181b69a61eaab05488d2c1e48df198608e9167723b42806e926788abce8a8cc83036d34c3d5560a911a583c91be3304d2f7b7bbad907b8a9eaf7094dfb3d143ca2c9a3987c4ec252234b089237c65f26714fa44c149229209c160a9254a2232587ef4430fa4185a4469612246f8cbd4ce29f489829245241382c1524a944464b0fde8861f4830b488d2c2448df197a25d7973e06b4cb5c4f3680223fb0b0874262190dc3eaaa17911a584991be32f34baf2e7c0d6996b89e6d00447f61610e84c4321b87d5542f2234b093237c65e62370b5a4f135b02909a02880f520ea17b5cac0340fac4c5f4469612746f8cbcb46e16b49e26b605213405101ea41d42f6b9580681f5898be88d2c24e8df1979619d52f409b39435bf346c9fbcae1d059836d5ccd3eb2d57e11a5849e1be32f2b33aa5e81367286b7e68d93f795c3a0b306dab99a7d65aafc234b093c37c65e566754bd026ce50d6fcd1b27ef2b8741660db57334facb55f8469612786f8cbcac5abbd2b1b02c9d9766fc77d64d6caac6c7ad4266f5984ff18d2c24f1df1979574189fe1036bbbde69abf17a491377d883b9ce0caeb3243e41a5849e4be32f2ad0f2654cd43d9fe850244574118cd230b237c1d92d6662bc934b093ca7c65e5591e4ca99a87b3fd0a0488ae82319a461646f83b25accc579269612794f8cbcab23c9953350f67fa1409115d0463348c2c8df0764b5998af24d2c24f29f19795640544ff16f53276dfdee8e200bcc74053c8234893b333024aa5849e54e32f2ac70a89fe2dea64edbfbdd1c401798e80a790469127666604954b093ca9c65e558e1513fc5bd4c9db7f7ba38802f31d014f208d224ecccc092a961279538cbcab1c2a27f8b7a993b6fef7471005e63a029e411a449d999812552c24f2a719795638544ff16f53276dfdee8e200bcc74053c8234893b333024aa5849e54e32f2ac7034b23b8b7cb15eb3a9e2680f8f463273b0ab6e736661ed55b093ca9d65e558df69647716f962bd6753c4d01f1e8c64e76156dce6ccc3daab6127953acbcab1be5edb46dac927fd86744fc8363376f1c96ef015ca99895957c24f2a769795637b49c8e66268b27dc4b565b8645d4c0b8d8a228792331456b0849e54ee2f2ac6f51fa42571a7c77e41379198c0b0f63f15c0876b21662a5162093ca9dd5e558de93f484ae34f8efc826f23318161ec7e2b810ed642cc54a2c4127953babcab1bd20aa2ee7375807bbcab0c8afaba372451ae60088298aae98924f2a776795637a31545dce6eb00f779561915f5746e48a35cc011053155d31249e54eecf2ac6f462a8bb9cdd601eef2ac322beae8dc9146b980220a62aba62493ca9dd9e558de8c5517739bac03dde5586457d5d1b9228d73004414c5574c4927953bb3cab1bd1836413fe42e6a3e827d8ed7a399d06d159242e4268ab03c934f2a776895637a2f6c827fc85cd47d04fb1daf4733a0da2b2485c84d156079269e54eed12ac6f45e6517583d900b7cc1c30186865d9fdc50f54dec972ac2964e3ca9dda3558de8bb56410927f6797c3b52c93504b19de09c96de352b5586d09d7953bb47ab1bd17538946afcc3557b2e725892015999e933d9fec653ab0f453bf2a776905637a2e97128d5f986aaf65ce4b12402b333d267b3fd8ca7561e8a77e54eed20ac6f45d26e64049fe3b86f7196286ffd5cc5ccca143d754bac3eb8f0ca9dda4258de8ba368da61ec9dd3619af91707f2afe9c18ed4bd4694587f15e2953bb485b1bd17455dc71c86120945edbef437dd5631ab1855bce925b0ffcfc62a77690c637a2e8947a091b8fa750e934aae97b2a2c17e2b57bc2e486201438d54eed219c6f45d111b537c1ecb4c9fde6223575d3be124515bbab88dc4042b1ba9dda4348de8ba2136a6f83d96993fbcc446aeba77c248a2b775711b8808563753bb48691bd174426d4df07b2d327f79888d5d74ef8491456eeae2371010ac6ea77690d237a2e88466ae39a330c781aadde0e2e1d5674a858a18206b2022fcde4eed21a56f45d107596ecbf337f1860d8887edbba12cbd05c0729cd340479dbd9dda434bde8ba20d3eeff09346458ed2ddd6036f38b7a2062d2795a38090df7c3bb48698bd17441909f239d362eda05d88722ed667cd6c0706918744012362f977690d327a2e883113e473a6c5db40bb10e45daccf9ad80e0d230e880246c5f2eed21a64f45d106227c8e74d8bb6817621c8bb599f35b01c1a461d10048d8be5dda434c9e8ba20c44f91ce9b176d02ec439176b33e6b6038348c3a20091b17cbbb486993d17441882b35f5e3053c889053e9155e7334e86b155ad03d1237d3987690d328a2e8830f566bebc60a791120a7d22abce669d0d62ab5a07a246fa730ed21a65145d1061e38ea3038eb54a4f91c6a7d71c331c9a701ad9cf148e0f262da434ca38ba20c3b71d46071d6a949f238d4fae38663934e035b39e291c1e4c5b4869947174418766fbb199083b5169c3e701dbf03254e96b2f8cfc223856d8c690d328f2e8830eb6b888bcdddccaff049a66375fca8c5281233fb81470c7f19d21a651f5d1061d56323704891fbe2986012eee3efafb24ad0aa52ff8e1aa234a434ca3fba20c3a95259393dfa5a47e88cec05bfd5bd8c904d9701fc1c36e86a486994807441875130c4cb28cb171288e69e3377a1d9411b47705ff5386f74d590d32901e8830ea161899651962e2511cd3c66ef43b282368ee0bfea70dee9ab21a65203d1061d424f25855002beccdb673ef5d67dc32c67ca03dbd1e1bf7757434ca408a20c3a832a5d634cdbe01c6e9b4413a4f1e480ca404a13a0c38092af869948124418750554bac699b7c038dd36882749e3c90194809427418701255f0d3290248830ea0a3587e5e045e2f47239d6768bbdf02b23ad6aaa800e03eebf1a65204a1061d4136b0fcbc08bc5e8e473aced177be056475ad555001c07dd7e34ca409420c3a8266231f02dedee5480b4200226ee1ed48961ed05fd38115efd699481294187504b50763908b23f2bb935062c45d29bd10d701c67f7702461fbd3290253830ea0952cfecabe3ae0da2a36d280839b95ca158c7b2bebe04a67f8a65204a8061d412959fd957c75c1b4546da50107372b942b18f657d7c094cff14ca409500c3a8252400d83a5c1e5eb60a8102a0664b55050de2f0bac812b43e3994812a1187504a30c2d5ff85a2e59791ce67c04bfc8c89c68a0735602582bc83290254330ea0945185abff0b45cb2f239ccf8097f919138d140e6ac04b0579065204a8661d4128a30b57fe168b965e47399f012ff232271a281cd580960af20ca40950cc3a82514616affc2d172cbc8e733e025fe4644e345039ab012c15e4194812a1987504a284ee8583279481a499b2de843f2eab1c13649915d25846084290254340ea0944f29e30911c8f2b74b0321f87fdc338b7d18d57eb74b0a65095204a8691d41289d53c6122391e56e960643f0ffb86716fa31aafd6e9614ca12a40950d23a82513a339e7cf3fa2d5fe3d94e09f7672c55ef0f9856da2c2b38264812a1a57504a273673cf9e7f45abfc7b29c13eece58abde1f30adb45856704c9025434aea0944e65a8c4c7cbf18024731fe4fd5930f7fb6eaa3b765b0ae849a204a8696d41289cb412af1a65492874630c2c7a31c7d27688189cac8615ead3540950d2ea82513950e683bf97f8791442e4bb73e2f5876cbaf55f18dc2befe6b812a1a5e504a27291cd077f2ff0f22885c976e7c5eb0ed975eabe31b857dfcd7025434bca0944e5239a0efe5fe1e4510b92edcf8bd61db2ebd57c6370afbf9ae04a8697941289ca47341dfcbfc3c8a21725db9f17ac3b65d7aaf8c6e15f7f35c0950d2f28251394872961844cedb96fab1819bdaebe594b5a1a174d92bf18ab912a1a5e604a2728f713e89367419b0ad2fc95fadce295165ef8545af57e4b97325434bcd0944e51d6e8f6b19be95e4122c58e75392b0cac68b4ce75bafcb16e74a86979b1289ca3969312ee0538e4adc2577f69f1bbfbd87c2dc2ab45f97d1cf950d2f37251394715e74b66d7d7f187017b615362ddda30a31fab165bf3147a02a1a5e6f4a2728e148fbc587d160b397fc32526452196e0f1037bec87e6433415434bcdf944e51c11e09e3bc7923e9e7c52accc09a910418ccb1d98dfcca0a83a86979c0289ca3813c13c778f247d3cf8a559981352208319963b31bf994150750d2f380513947020439e79ebaf22a56e1715afa60a2385ddf09c234f329ce0fa1a5e701a2728e030873cf3d75e454adc2e2b5f4c14470bbbe138469e6539c1f434bce0344e51c0610e79e7aebc8a95b85c56be98288e1777c2708d3cca7383e86979c0689ca380c21cf3cf5d79152b70b8ad7d30511c2eef84e11a7994e707d0d2f380d13947018439e79ebaf22a56e1715afa60a2385ddf09c234f329ce0fa1a5e701a2728e030134f4c8434a7cd93faf187440aa533b68d7aa29b653b65f534bce0354e51c05f269e9908694f9b27f5e30e88154a676d1af54536ca76cbea6979c06a9ca380be4d3d3210d29f364febc61d102a94ceda35ea8a6d94ed97d4d2f380d53947017c268cbcce7ba0ef57a45262184b87c5af181770d829dcd3aaa5e701ab728e02f74d19799cf741deaf48a4c430970f8b5e302ee1b053b9a7554bce0356e51c05ee26454be6c4e640165e0fb059247d3eb70ca01f5da774f2ab979c06aeca380bdb4c8a97cd89cc802cbc1f60b248fa7d6e19403ebb4ee9e5572f380d5d947017b625278847e9fb83114504e95c885322d6dec2d9739dd56eaf5e701abc28e02f6b4a4f108fd3f706228a09d2b910a645adbd85b2e73baadd5ebce0357851c05ed620b079cc7e508efce0d9cd6a17aab356274dc1cb77575ebe79c06af1a380bdab4160f398fca11df9c1b39ad42f5566ac4e9b8396eeaebd7cf380d5e347017b560ed43fdecfa4beab502d5da05508f5534979632add5f1efae701abc78e02f6ab1da87fbd9f497d56a05abb40aa11eaa692f2c655babe3df5ce03578f1c05ed563b50ff7b3e92faad40b576815423d54d25e58cab757c7beb9c06af1e380bdaac02b457a3538878124e3114fa9ea5d294f80d7553eafa9bd8380d5e3d7017b5570568af46a710f0249c6229f53d4ba529f01aeaa7d5f537b0701abc7ae02f6aae0ad15e8d4e21e04938c453ea7a974a53e035d54fabea6f60e03578f5c05ed55c15a2bd1a9c43c0927188a7d4f52e94a7c06baa9f57d4dec1c06af1eb80bdaab82b457a3538878124e3114fa9ea5d294f80d7553eafa9bd8380d5e3d7017b5570568af46a710f0249c6229f53d4ba529f01aeaa7d5f537b0701abc7ae02f6aae039284181b880874b590b669f9fd2cd38af9fb0f7bea89a0f03578f5d05ed55bf7250830371010e96b216cd3f3fa59a715f3f61ef7d51341e06af1eba0bdaab7e70b35eb3b8649fe530f3c27675a95cdd6ac11fdbfaa40c3d0d5e3d7517b556fb6d791614472bc2822eadace4e1b0e1b581c49bb4f549bc7b1abc7aeb2f6aadf5670484d564ba07bc2a2181c1b9bfeb65afcb9366ea951cf73578f5d75ed55be95a1b62579fd6923021092b7b69ddfec60bd982cad52bddef6af1ebafbdaab7d140491d5c160fa7180ed87eeeca1a2586c3f56192aa595fdfd5e3d7607b556fa10ca493650281d0e7ea7725d58a927308342d1f2254b463c0abc7aec1f6aadf41194926ca0503a1cfd4ee4bab1524e610685a3e44a968c781578f5d83ed55be8232924d940a07439fa9dc97562a49cc20d0b47c8952d18f02af1ebb07daab7d0465249b28140e873f53b92eac54939841a168f912a5a31e055e3d760fb556fa08565b8efcfe7f9136743885509f85587def144e224b47e00bbc7aec206aadf40f38c976a6d361a524b53732993568d8f68a6af8419691641878f5d841d55be81d7192ed4da6c34a496a6e65326ad1b1ed14d5f0832d22c830f1ebb083aab7d03a6f38334823e9174aa1a2f25ccc018bd4d5ee3d035a473462e3d76108556fa0736a82bf3d1e34b14d100c0cb18e613fa4581ed603b4900cc6c7aec211aadf40e56117d72712cbe551ecde415b1320a7435c8008046921bd8e8f5d842455be81c94e4206fafbfa4d5ba682aaae1c9f768165426c05d2451f1e1ebb0849ab7d0391289666a2ce571d6f19cb7d542f9d14fd76c73408a48be23d3d76109456fa0721512ccd459cae3ade3396faa85f3a29faed8e68114917c47a7aec2128adf40e422e6bf3380fbef87433f41d48b4d27bf0875f2c1f92312cf5f5d842525be81c835cd7e6701f7df0e867e83a9169a4f7e10ebe583f246259ebebb084a4b7d0390645c2258d155e64889c969d1ac9a817bcc9bf0c7b48c657d8d761094a6fa0720b1796a3c7011f4bc905f3622d89ae57743fc074f3918e53b2aec21295df40e4152f2d478e023e97920be6c45b135caee87f80e9e7231ca7655d84252bbe81c82a5e5a8f1c047d2f2417cd88b626b95dd0ff01d3ce46394ecabb084a577d03905448c776e4df5ce0fffc61396443d0e39caa4603998c744196761094affa0720a71da14676951c44b7c5889ac07dffef3400ce633018ea272dec212960f40e414d3b428ced2a38896f8b113580fbffde68019cc66031d44e5bd84252c1e81c829a029772872ad39596e2e892f9ee5de4caaf7be8bd63aa40b8b084a584d0390533052ee50e55a72b2dc5d125f3dcbbc9955ef7d17ac754817161094b09a0720a660a5dca1cab4e565b8ba24be7b977932abdefa2f58ea902e2c212961340e414cc14bb9439569cacb7174497cf72ef26557bdf45eb1d5205c584252c2681c8299829772872ad39596e2e892f9ee5de4caaf7be8bd63aa40b8b084a584d0390533052ee50e55a72b2dc5d125f3dcbbc9955ef7d17ac754817161094b09a0720a66031eefa778b47e87086eae6738dd75aa68b3c8b55ea91d22d212961350e414cbf63ddf4ef168fd0e10dd5cce71baeb54d167916abd523a45a4252c26a1c82997e53ce428b03822479e871c1c62dbb9294d9348954aa48ecb584a584d5390532fb33aeddc2dd66cbab9da9ab8451d54d245eab6ea654937d6c094b09ab720a65f5675dbb85bacd97573b535708a3aa9a48bd56dd4ca926fad812961356e414cbea5acdcfb84bfdb166436cd6093db35c8c26f01696524f99b1252c26aec82997d341adf81d6e5de584539fd40a71c4e112fa228929a4a0d7634a584d5e90532fa50f6e48e7b31e4dc07405d00cd9e7ea20a0876e50494352c794b09abe20a65f491edc91cf663c9b80e80ba019b3cfd441410edca09286a58f2961357c414cbe923db9239ecc793701d0174033679fa882821db941250d4b1e52c26af882997d2407849fea6f54f0bb6cf4a85ec59d78ffb07dce7f4a1c3a3da584d5f20532fa470f093fd4dea9e176d9e950bd8b3af1ff60fb9cfe9438747b4b09abe40a65f48e1e127fa9bd53c2edb3d2a17b1675e3fec1f739fd2870e8f6961357c814cbe91c3c24ff537aa785db67a542f62cebc7fd83ee73fa50e1d1ed2c26af902997d238045c5753cbb18e6e9c10ade45035b7f5b41f43f1a1c547db584d5f21532fa46f08b8aea797631cdd38215bc8a06b6feb683e87e3438a8fb6b09abe42a65f48de11715d4f2ec639ba7042b79140d6dfd6d07d0fc687151f6d61357c854cbe91bc22e2ba9e5d8c7374e0856f2281adbfada0fa1f8d0e2a3edac26af90a997d237845c5753cbb18e6e9c10ade45035b7f5b41f43f1a1c547db584d5f21532fa46f0179d43264c94508b4edbe481fd1526b1302ada3138aa9f6c09abe42b65f48ddf2f3a864c9928a1169db7c903fa2a4d626055b46271553ed81357c856cbe91bbe5e750c993251422d3b6f9207f4549ac4c0ab68c4e2aa7db026af90ad97d2377c48fc71df3b05071243a54c07df075d842d992d86c5569f614d5f215c2fa46ef71e0b3c6b4c6c90dc5410c007b46ce3030774b70a8aaee2c39abe42b95f48dded3c1678d698d921b8a821800f68d9c6060ee96e15155dc587357c8572be91bbda043f4a5a0814c6291d092816c811b406ca1538272abd2f0f6af90ae67d2377b3087e94b410298c523a12502d9023680d942a704e557a5e1ed5f215ccfa46ef6610fd2968205318a47424a05b2046d01b2854e09caaf4bc3dabe42b99f48ddecc21fa52d040a63148e84940b6408da03650a9c13955e9787b57c85733e91bbd9843f4a5a0814c6291d092816c811b406ca1538272abd2f0f6af90ae67d2377b3013fba3edd8fb47db6deb2ad0f894a8d3eee960e257a785ee5f215cd0a46ef65f27f747dbb1f68fb6dbd655a1f12951a7ddd2c1c4af4f0bdcbe42b9a148ddecbe4fee8fb763ed1f6db7acab43e252a34fbba583895e9e17b97c85734291bbd97c2bef781b9e3cc1933c1f7e7fbb036e9a238d630fbd3dd373f90ae6862377b2f757def0373c798326783efcff7606dd34471ac61f7a7ba6e7f215cd0c46ef65ee3bd0391b4f558904bd4421f6e26be2633a77e83bf4f8f1d0e42b9a198ddecbdb03b2cae3750d94c1474e6be5bb35ecc121322c74e9f387a2c85734341bbd97b5076595c6ea1b29828e9cd7cb766bd982426458e9d3e70f4590ae6868377b2f6a0ecb2b8dd43653051d39af96ecd7b30484c8b1d3a7ce1e8b215cd0d06ef65ed41d96571ba86ca60a3a735f2dd9af6609099163a74f9c3d1642b9a1a0ddecbda83b2cae3750d94c1474e6be5bb35ecc121322c74e9f387a2c85734341bbd97b50026bb51b78151ae0b693a4af5d1bc01ed287ea9a3e72985a0ae6868477b2f69f04d76a36f02a35c16d27495eba37803da50fd5347ce530b415cd0d08ef65ed3e09aed46de0546b82da4e92bd746f007b4a1faa68f9ca61682b9a1a11decbda7c135da8dbc0a8d705b49d257ae8de00f6943f54d1f394c2d057343423bd97b4f826bb51b78151ae0b693a4af5d1bc01ed287ea9a3e72985a0ae6868477b2f69f04d76a36f02a35c16d27495eba37803da50fd5347ce530b415cd0d08ef65ed3e026ff9f8adba93ae571af53cf3d4e2faf4e3d028c9ca7ba83b9a1a11eecbda7bf4dff3f15b75275cae35ea79e7a9c5f5e9c7a0519394f75077343423dd97b4f7e2810d6d845076e4d93837734eb96e6b7e536662f72a08e0fe686847cb2f69efb5021adb08a0edc9b2706ee69d72dcd6fca6ccc5ee5411c1fcd0d08f965ed3df62c55b40dea803bee1ad404cba4b9c2da411bf4baca83dc409a1a11f3cbda7beb58ab681bd50077dc35a80997497385b48237e9759507b881343423e797b4f7d63d6928e48063727038163b2689453363b0b22ee82a111503686847d02f69efab06e4aa75d72967983cf29e4508e88ec20da6b9cd5423ce07d0d08fa15ed3df550dc954ebae52cf3079e53c8a11d11d841b4d739aa8479c0fa1a11f42bda7beaa1b92a9d75ca59e60f3ca791423a23b08369ae735508f381f43423e857b4f7d54372553aeb94b3cc1e794f228474476106d35ce6aa11e703e86847d0af69efaa86e4aa75d72967983cf29e4508e88ec20da6b9cd5423ce07d0d08fa15ed3df55068a7a767bb8f75bf6b19f0991370003c611995a7847b64fb1a11f42cda7bea9f5d61a77c4d816e36a2fa092a1d3e28736e75874c08f86df73423e85ab4f7d53d46d5a7a571655f2512ba3a4c30da78e1892d6a9511f27fef6847d0b669efaa7919bda7f7b92d4101f23a9c90581319bdbe9d312723e6a3dfd08fa16dd3df54f1337b4fef725a8203e4753920b026337b7d3a624e47cd47bfa11f42dba7bea9e266f69fdee4b50407c8ea7241604c66f6fa74c49c8f9a8f7f423e85b74f7d53c459ff986a9fcc8ac75e9b0c7ab6f6f5e8a12be5361f36c2ff847d0b6f9efaa7874011898215fb984689fc40ed644c13cbee9a26693e6f2a0008fa16e03df54f0d0c356bb10259b344e0bea9d2bef64f928976a8cf7cdff80111f42dc17bea9e19186ad76204b36689c17d53a57dec9f2512ed519ef9bff00223e85b82f7d53c3230d5aec40966cd1382faa74afbd93e4a25daa33df37fe00447d0b705efaa786461ab5d8812cd9a2705f54e95f7b27c944bb5467be6ffc0088fa16e0bdf54f0c84f6913bcfbfdb705d8b0c523e5c3212343ace8f4ce0124121f42dc18bea9e18f2ae48026ce5df0c37e27b23fc1e46a41339c2de69c03ec253e85b8327d53c31d55c9004d9cbbe186fc4f647f83c8d48267385bcd3807d84a7d0b7064faa7863a37a459480fda45c5c564f0f6fdefd0ff7ab3139770115495fa16e0caf54f0c736f48b2901fb48b8b8ac9e1edfbdfa1fef566272ee022a92bf42dc195ea9e18e66aa3bdcd15cb99cee259ebd3ee1d6bf8970eaa5ac046f658e85b832cd53c31cb6159d44701f9b6559179ff9fd298ffebda5fb0b2808f90b2d0b7065aaa7863954ec6013ada55ef62efba27379b9027d26101bd620120c566a16e0cb654f0c729299e5b228b0e617dac3a76672d7e779f6e45d6c102432ece42dc196da9e18e51533cb645161cc2fb5874ecce5afcef3edc8bad8204865d9c85b832db53c31ca2328bc537029c08ae7db00194ac5806786559b701090e5f3a0b7065b7a786394365178a6e0538115cfb60032958b00cf0cab36e02121cbe7416e0cb6f4f0c728656416d88e0d2a571c3862e4aa7be41dc41a93801243b20e92dc196df9e18e50b389533be9807cd9b53d2848d45daabb32f94cbff4877e5d35b832dc03c31ca15712a677d300f9b36a7a5091a8bb557665f2997fe90efcba6b7065b807863942a6e6727a73681b9251c103a2d0dc8d6c76a958bfa21e13b4e6e0cb701f0c7285368e0a7fb4365f50204e69c5211efd589816d73f143c41a9ddc196e04e18e50a55dd3a8a35d2e6cbbd693609c1a3dd30daf1d43df8789d93cb832dc0ac31ca14947b9a9f390bf5c2f79ece9302ad9ce160a7ce3bc0f15567a7065b816863942911b85ac93f7e13b16c09ffa584c11c426c13c23751e2c50f5e0cb702e0c728521370b5927efc2762d813ff4b09823884d827846ea3c58a1ebc196e05c18e50a426e16b24fdf84ec5b027fe9613047109b04f08dd478b143d7832dc0b831ca1484683fbd4c956c5b6dd1c5faba56ec4930b62377a5f1642bb0065b8171639429075c91d346013b399370521d6ca436ba5c18894b48e2c9fb610cb702e3c728520d4535ff38d8d8f5dead6a62d13ecb9cb2dd54f28ec5959ac3196e05c88e50a419167e571e88146e75279aed9a73f5616066ec411a8b2cd98732dc0b921ca148312cfcae3d1028dcea4f35db34e7eac2c0cdd882351659b30e65b817243942906259f95c7a2051b9d49e6bb669cfd585819bb1046a2cb3661ccb702e48728520c4400511a11705f661099d94cb960932fde3a464d15968703a96e05c91e50a41870c1c7bef046e6f79e001518f22708df6738b259fb2d284762dc0b924ca14830d1838f7de08dcdef3c002a31e44e11bece7164b3f65a508ec5b8172499429061a3071efbc11b9bde78005463c89c237d9ce2c967ecb4a11d8b702e49328520c3460e3df7823737bcf000a8c7913846fb39c592cfd969423b16e05c92650a418684dda179d1d497a55ccdb40ea1d670761e4f4b5f82d29eb63dc0b924da14830cf27c687e710f57763667ca9cc312c36be762bc7ed5a557ac8b817249c4290619d4f8d0fce21eaeec6ccf9539862586d7cec578fdab4aaf591702e49388520c33a2b2c78491a38604566b8cf28bb0f02f484f17bb269578f23e05c92720a4186735658f0923470c08acd719e51761e05e909e2f764d2af1e47c0b924e414830ce638c439d13f4403cd67a9649ae29a33ccc0084ac6a55fe090817249c9290619cb718873a27e88079acf52c935c53467998010958d4abfc12102e49392520c33966f233ff1d37291ed6b6bba6380c6f72dac6387179581264305c92725a418672b6a58d8907d47a692a39d9cbef7ec165605096a2c2b03f0870b924e4c4830ce5560c409cdd0f1cfdd14016175e63654a6b65530555609850f17249c9990619ca94d9a6c4878462271f4c8eae3c2cad14818ecbca7ac14ae1f2e49393420c339512747313dc6eec79bb657fdbf7bf3ca8ade1bd54c582b003f5c927269418672a14e8e627b8ddd8f376caffb7ef7e79515bc37aa98b056007eb924e4d2830ce542292f1da3f21da126a6261ef5e62d522624b1b12e60ada4fe7249c9a60619ca83525e3b47e43b424d4c4c3debcc5aa44c4963625cc15b49fce493934c0c33950630cecf3c9ed90752655ea3cf8f1370933f0920b682b837fac927269918672a0b619d9e793db20ea4cabd479f1e26e1267e12416d05706ff5924e4d3230ce54164f4d959f51c6a0016240b73632abea47a866ded70ae283ec249c9a65619ca82b2aad83eb79efc2ba914796645bb5fc89fd1019ab15c6abd9493934cbc3395055555b07d6f3df8575228f2cc8b76bf913fa2033562b8d57b2927269978672a0aa36c8685abe218da211e4818965361a22a082c2a9571c536624e4d3300ce541536d90d0b57c431b4423c90312ca6c344541058552ae38a6cc49c9a66019ca82a66733fa17cee8b94014582e1d8b3690852e4d66a25c72f19993934cc13395054b5a7a4cdc7433f537f57684330ccb490508dd2941b8e7873427269983672a0a954106f265beca6d27b7b3305e0ff4ba04bdfcae8071d0b2694e4d3307ce5415290e203d7853f75d073c2c88b416479c04283bb8fde3a308d39c9a66109ca82a511c407af0a7eeba0e785911682c8f3808507771fbc74611a73934cc21395054a23880f5e14fdd741cf0b222d0591e7010a0eee3f78e8c234e7269984272a0a9447101ebc29fbae839e16445a0b23ce02141ddc7ef1d18469ce4d33084e54152886e16303215d8532b8f8eb3395ad7e83d2ffdebdb3a32313ac9a6610aca82a50f683eb9110213290eebe38e6aac0df8750c3e33b374660676934cc21695054a1d5c8fcaceda88d4d5a48d44cd4e7a18e4c4bec363e8cdb0ee2699842e2a0a94394531ee4a8b742c6315e0b192935259c435bfe2c4d19d05dd4d33085d5415287116763541ed4adb7df8878b1d1d02db8317c22186a33bafbb9a6610bba82a50e12cec6a83da95b6fbf10f163a3a05b7062f84430d46775f7734cc21775054a1c259d8d507b52b6df7e21e2c74740b6e0c5f08861a8ceebeee699842eea0a943843fc402bc40b95ea7910280e0de7504136a53683219df21ddd33085de415287070b9a5e2557d54006eecb29b9b348302180e92c6133bfe7bca6610bbd82a50e0d1734bc4aafaa800ddd9653736690604301d258c2677fcf794cc2177b054a1c1a2e6978955f55001bbb2ca6e6cd20c08603a4b184ceff9ef299842ef60a9438345cd2f12abeaa003776594dcd9a41810c074963099dff3de533085dec1528706845b83b0253b68326b978c3932ae12a12bad522103c001fcb6610bbd92a50e0cf1782ceb17dcf89053fb7af1e4c207c2021eca01d7801e397cc2177b354a1c19d2f059d62fb9f120a7f6f5e3c9840f84043d9403af003c72f9842ef66a943833a5e0b3ac5f73e2414fedebc793081f08087b28075e0078e5f3085decd528706744828ce38c4decae1ca83a0ea576208fbbba75ce8c010c0bf610bbd9ba50e0ce71c63f51e6020187b61cd69cca52239f2239115ce8023257fc2177b384a1c19cd38c7ea3cc04030f6c39ad3994a4473e447222b9d00464aff842ef6709438339a718fd479808061ed8735a7329488e7c88e44573a008c95ff085dece1287067346f32019fd7634692db31765d1f6ff78bc8cb0a71011acfff10bbd9c350e0ce676a765bec85290fdd832914b2353e17123dd870df023743ff2177b387a1c19ccd60ff1085e0b4a272d318515c60da561f27f33dbb04702bff42ef6710438339994e1079b897cbc79d72f6cab0b812d438fc28d77308e1fbff85dece218706733128334c1e05fa11f2b2b3bd596683d06ca4940ae311c59c000bbd9c440e0ce6615066983c0bf423e565677ab2cd07a0d9492815c6238b3800177b38881c19ccc22cdf8924ee4aca8297951d5d906d69ad3e928789471814012ef671113833998359bf1249dc9595052f2a3abb20dad35a7d250f128e3028025dece222706733063f907d408f8dacc22b1a9d6e3813ceafa68c7a221c61f405bbd9c445e0ce660b0b33532df57ddc3c22fb62d46685c559f95b504138c58c0c77b3888cc19ccc151666a65beafbb87845f6c5a8cd0b8ab3f2b6a082718b1818ef6711198339982a2ccd4cb7d5f770f08bed8b519a171567e56d4104e3163031dece223306733054599a996fabeee1e117db16a3342e2acfcada8209c62c6063bd9c44660ce660a83f478b8c2e404679fc7c553e5eba7d9a41f760108c5a64c87b3888cd19ccc14f0aa16fc532e30fabc5bed274b3d3232f30311c1e18b66d91f671119b3399829d1542df8a65c61f578b7da4e967a6465e6062383c316cdb23ece223366733053a2a85bf14cb8c3eaf16fb49d2cf4c8cbcc0c4707862d9b647d9c4466cce660a74550b7e2997187d5e2df693a59e9919798188e0f0c5b36c8fb3888cd99ccc14e83629550004937d7428b34f4333905aedaf541dde8b687d20671119b4399829cf6c52aa000926fae851669e866720b5db5ea83bbd16d0fa40ce2233687330539e64b7acace8b078886f936504c49f93b16992d3772da398829c4466d1e660a73b5581b206a7c373c8abecf2017f9d4f5d7f6802eb5b48d5063888cda4ccc14e753715bcba25e96a4924a00bfaf598c6b5ab1261d3b6934e0d71119b4a99829ce96e2b79744bd2d492494017f5eb318d6b5624c3a76d269c1ae2233695330539d268694b956e082bdc5f4657e3ccc142d1588be34bda4edc36c4466d2b660a73a35ce4efd7b272da708b52d7bf8fe0ad9d5d5a2294b49f5c6e888cda57cc14e74545dc385c3b483798e36bd777161f833566f6a12669405cde1119b4b09829ce8917cac9654cf2f1e9939dd6e6229d2e657a2f9e49d2825dbd2233696230539d112f9592ca99e5e3d3273badcc453a5ccaf45f3c93a504bb7a4466d2c460a73a225f2b259533cbc7a64e775b988a74b995e8be79274a0976f488cda588c14e74444a68a3d73dfa120469b4df290b479b267dbf4e4b941491ea119b4b12829ce88720e3a05b5256a6c0a02fe64a0ced5e47a7c0f894282ac7d5233696260539d10d41c740b6a4ad4d81405fcc9419dabc8f4f81f12850558faa466d2c4c0a73a21a0fa0da1a1fbd1dba4d85c1202a13a1194b463e4da0acc3558cda589914e744331f41b4343f7a3b749b0b824054274232968c7c9b415986ab19b4b13229ce88663e8368687ef476e936170480a84e84652d18f93682b30d5633696264539d10cc0919297dd44b708a38f430f946fb30c506744e6a0567bead66d2c4c9a73a2197123252fba896e11471e861f28df6618a0ce89cd40acf7d5acda589934e74432e2464a5f7512dc228e3d0c3e51becc31419d139a8159efab59b4b13269ce8865c48c94beea25b8451c7a187ca37d9862833a273502b3df56b3696264d39d10cb81da4f08a1b198b5b5c09378c6611344b1387429d567d8ed76d2c4c9b73a2196f3b49e114363316b6b8126f18cc226896270e853aacfb1daeda589936e74432de02a61ad542c8b0253ceb06298ea2f926fa5f667259f7df5eb4b1326ece8865bb054c35aa8591604a79d60c531d45f24df4becce4b3efbebd696264dd9d10cb760a986b550b22c094f3ac18a63a8be49be97d99c967df7d7ad2c4c9bb3a2196ec1530d6aa16458129e758314c7517c937d2fb3392cfbefaf5a589937674432dd82a61ad542c8b0253ceb06298ea2f926fa5f667259f7df5eb4b1326ece8865bb054c35aa8591604a79d60c531d45f24df4becce4b3efbebd696264dd9d10cb76035990dfd888e8c070787b25b9f1c71b9441bf8937df97bae2c4c9bb4a2196ebf6b321bfb111d180e0f0f64b73e38e3728837f126fbf2f75c589937694432dd7e627690a2f89cb2d3eae4f16672cfeedfbcb23e4af7e792b9b1326ed38865bafb50ff79f2c79be85fa2900ac4dbfe05ba25a6d892efd0c9746264dda810cb75f52e114c92659a537711e63d81ae5a336ef7900d22dfa336e9c4c9bb512196ebe95c229924cb34a6ee23cc7b035cb466ddef201a45bf466dd3899376a2432dd7d244578af66ccbd094145f1dfeafc6f5b68a8290887e8e7fa81326ed45865bafa314c16e99affa23dff58463f555ec1367c1477d0dfd1ea351264dda8c0cb75f452982dd335ff447bfeb08c7eaabd826cf828efa1bfa3d46a24c9bb518196ebe8a5305ba66bfe88f7fd6118fd557b04d9f051df437f47a8d4499376a3032dd7d14321dcd7a5633a1b778e947a2a5bec338b67e446ce8f6be8a326ed46165bafa27643b9af4ac67436ef1d28f454b7d86716cfc88d9d1ed7d1464dda8c2cb75f44e54898e962f310995b06b46828d5934dd863b6db0a3dc9e29c9bb518696ebe89b352575d934c495e32d9cb4fd111091b5b8b9375e47bae0549376a30e2dd7d1356a4aebb269892bc65b3969fa2221236b71726ebc8f75c0a926ed461c5bafa26a60a83011a974da448338fbec3aa06ed18f2739761eed25534dda8c39b75f44d34d62b8d0294c3740d3381fd06b9f059dca90cee93ddbeea79bb518746ebe89a526d7ca4d28faf13973366798cd9c33364163f9cf7bb98150376a30e9dd7d13494daf949a51f5e272e66ccf319b38666c82c7f39ef77302a06ed461d3bafa2692277181e17a4e479d999fc65b2ccef4d3b1d2433aeee7a941dda8c3a875f44d234ee303c2f49c8f3b333f8cb6599de9a763a48675ddcf5283bb518750ebe89a4629d86032bf9ba12e33454164a999fb49738b68e8bba0490876a30ea2d7d1348b53b0c0657f37425c668a82c95333f692e716d1d177409210ed461d45afa269163373d977d4d1077099db2d8a9cc615207a6fff9fee82c822da8c3a8c5f44d22b66e7b2efa9a20ee133b65b15398c2a40f4dfff3fdd059045b5187518be89a45659e1be8c29a6a07a3432de2269767c7c96025a7cba0cc48c6a30ea327d1348ab3fd5d5c529afc3ac352be43cc94b20f3d84710f6741b2d19d461d465fa2691550bbe043729c20a10371df07188f469e25cd07de9e837fe34a8c3a8ccf44d22a9177c086e538414206e3be0e311e8d3c4b9a0fbd3d06ffc6951875199e89a45522ef810dca7082840dc77c1c623d1a7897341f7a7a0dff8d2a30ea333d1348aa45df021b94e105081b8ef838c47a34f12e683ef4f41bff1a5461d4667a269154847f29c1f728323bb3ea52f1085a4c620794a3a9b8381874b8c3a8cd044d22a8f1bf790ebbb68ca2e4a10861901a7b43b9ed6d1340704b298187519a189a4551d37ef21d776d1945c94210c32034f68773dada2680e09653030ea33431348aa3a6fde43aeeda328b928421864069ed0ee7b5b44d01c12ca6061d46686269154746bcee00ab1a8d42a1d4a58c0039bc9d7a2f8e59d382738c1c3a8cd0d4d22a8e763b018c239b42b0c075ad977fd95bba9f23427377050158487519a1b9a4551cd53728a3149cad8cfdb7bdae7f1899f4e90aaaa6be0a1cf0a0ea33438348aa39932f76d0f69f8345783bdddc7d9716697cd97b0d4c14542151d4668716915473165eeda1ed3f068af077bbb8fb2e2cd2f9b2f61a9828a842a3a8cd0e2d22a8e6257f00cea7e435415dbbd9f175c23c259e2a11f500516ac557519a1c6a4551cc33bf27281d2e92ae384416626aea5acae71849a9d0a2efcabea33438e48aa398503f73db07c34d87ed548f44553a981578f4b9137145f9d58d466871d9154730907ee7b60f869b0fdaa91e88aa75302af1e97226e28bf3ab1a8cd0e3b22a8e6120fdcf6c1f0d361fb5523d1154ea6055e3d2e44dc517e7563519a1c764551cc241fb9ed83e1a6c3f6aa47a22a9d4c0abc7a5c89b8a2fceac6a33438ec8aa398483f73db07c34d87ed548f44553a981578f4b9137145f9d58d466871d9154730900afa0ebc5cfd929275e4b0a26b8e52ec95b482df8bf54f1b8cd0e3b32a8e611f15f41d78b9fb2524ebc96144d71ca5d92b6905bf17ea9e3719a1c766551cc23e2be83af173f64a49d792c289ae394bb256d20b7e2fd53c6e33438eccaa39847c57d075e2e7ec9493af2585135c729764ada416fc5faa78dc66871d99547308f83bb34472a63babdf2b11321eaf4356c4078a89f5bf5695b9cd0e3b33a8e611ef0378e19222d9da7622e88c3554e4d582bb576fe87eaecf749a1c766851cc23dd06f1c32445b3b4ec45d1186aa9c9ab0576aedfd0fd5d9ee93438ecd0a39847ba0de386488b6769d88ba230d55393560aed5dbfa1fabb3dd26871d9a147308f741bc70c9116ced3b1174461aaa726ac15dabb7f43f5767ba4d0e3b3428e611ee8378e19222d9da7622e88c3554e4d582bb576fe87eaecf749a1c766851cc23dd06f1c32445b3b4ec45d1186aa9c9ab0576aedfd0fd5d9ee93438ecd0a39847ba06a4abd358cd9204086e9354d2f9388a9821e561cabb58127871d9a157308f73f60a7d317f014c338da9892925585394db07f0836576ca6500e3b342be611ee7d4d61fedcb68c092981f74d1ca1689a960d406c69aedaf0a11c766858cc23dcf926d65666437a950ad0b4c231392f5d26c6c334d05db7854338ecd0b29847b9f14dacaccc86f52a15a1698462725eba4d8d8669a0bb6f0a8671d9a165308f73e2276bb245e44cd6e30f9930bcdb1b9c95c74f2f3e76dfb90de3b342cb611ee7c34ed7648bc899adc61f326179b637392b8e9e5e7cedbf721bc7668596c23dcf8629c121c46795de440b2aeaeb62cc9a51c97f18f6db8088388ecd0b2e847b9f0b53824388cf2bbc881655d5d6c59934a392fe31edb70110711d9a165d08f73e163316dfbe74b9fbc7f971d3a581909141d23ebfd86e03c4e33b342cbb11ee7c2b662dbf7ce973f78ff2e3a74b03212283a47d7fb0dc0789c67668597623dcf856586dd7a6a94a71d7b28d768dfca06d01f53d5b5eb810b78decd0b2ed47b9f0ab3cee07fa28f7666731e11513ef9f01fe96bd12ba7023131cd9a165db8f73e15505ee68a128514f863088521fd59c2bf7d9bc8171e047ca3ab342cbb81ee7c2a90bdcd14250a29f0c6110a43fab3857efb37902e3c08f9475668597703dcf855217b9a284a1453e18c221487f5670afdf66f205c7811f28eacd0b2ee07b9f0aa42f734509428a7c31844290feace15fbecde40b8f023e51d59a165dc0f73e15485ee68a128514f863088521fd59c2bf7d9bc8171e047ca3ab342cbb81ee7c2a9049df6cd1e08c737dddd06bf2a9e3a6f5e3d28a3908faeb5768597704dcf8551f1fd13250977b69b38866ffdd4a2575e673e7706f11f77aafd0b2ee0ab9f0aa3d3fa264a12ef6d36710cdffba944aebcce7cee0de23eef55fa165dc1573e1547a0b5721ef34502985ee62276d1ef3ff947be01db947df8ec042cbb82be7c2a8f316ae43de68a0530bdcc44eda3de7ff28f7c03b728fbf1d8085977057cf8551e62d5c87bcd140a617b9889db47bcffe51ef8076e51f7e3b010b2ee0af9f0aa3cc5ab90f79a2814c2f73113b68f79ffca3df00edca3efc7602165dc15f3e154798418477a01b651b16b2e89ec9e59e21426a4437917dfa90052cbb82bf7c2a8f2f0f1b47ed0d2cb8e53297658bc19a6a7f80cacb1ffbf6c40b5977057ff8551e5d1e368fda1a5971ca652ecb178334d4ff0195963ff7ed8816b2ee0afff0aa3cba3c6d1fb434b2e394ca5d962f0669a9fe032b2c7fefdb102d65dc15ffe154797404ec98153fc849e16181545603317bf6b298b4fcdfb7c45bcbb82c00c2a8f2e709d9302a7f9093c2c302a8ac0662f7ed653169f9bf6f88b7977058018551e5ce13b26054ff212785860551580cc5efdaca62d3f37edf116f2ee0b0030aa3cb9c2764c0a9fe424f0b0c0aa2b0198bdfb594c5a7e6fdbe22de5dc16006154797384ec98153fc849e16181545603317bf6b298b4fcdfb7c45bcbb82c00c2a8f2e7029a55b54cf6bbee3fcf0b2b85c8da6d0ff58fb98f6fa2f7a77058019551e5cdf534ab6a99ed77dc7f9e16570b91b4da1feb1f731edf45ef4ee0b0032aa3cb9be32a7c60014117e47c088f2d96894c33ea9a64a60dbea61eadc1600665479737b654f8c002822fc8f8111e5b2d129867d534c94c1b7d4c3d5b82c00cca8f2e6f656b170ad26a87bd6cee9f35d98b134f552db85806fab2bac7058019a51e5cdeb39753a0723b37a656a9a0eb327c091e551f966fddf57fb59e0b00335a3cb9bd572ea740e4766f4cad5341d664f8123caa3f2cdfbbeaff6b3c160066b479737aa71e740c965306c4d772e62c495606f8ff427f7f47d61916882c00cd78f2e6f536fe0da3fa0c35b52bb22ed81211f071a94924be5fac4c6d2058019b01e5cdea56bd40d2c17e9395d430c02fa389c362fd566f3c8f58b31a50b0033613cb9bd4963ba73050634f57252de2dec6796945a5710438eeb18074b160066c379737a9153873eb6e2cc6d9c728283d0c58b50af5a62e31ad631b2972c00cd87f2e6f5213320d61a9bfb5df0b1cb2f998174c95961082232ac65092f58019b10e5cdea416641ac3537f6bbe163965f3302e992b2c210446558ca125eb0033621cb9bd4825895b117464ffa7a93f2e65dfc314d603062e4c7b195c8be60066c449737a9033d3dbadb630277acf4abf4b3eec0c2bb0d08258c632d357dc00cd88a2e6f5205068dce639c677211b61e115fd3dfad70c652a715c65c0efc8019b1155cdea4090d1b9cc738cee4236c3c22bfa7bf5ae18ca54e2b8cb81df90033622ab9bd48121a37398e719dc846d878457f4f7eb5c3194a9c5719703bf20066c455737a9024346e731ce33b908db0f08afe9efd6b86329538ae32e077e400cd88aae6f5204868dce639c677211b61e115fd3dfad70c652a715c65c0efc8019b1155cdea40905dcc25206350c4ee908853f27253d61376973eb5cb838391033622ac9bd4811f47aaa2ed9d040c94edd6cfdcdb05d4219970d9689708ab23066c455a37a9023d1b679e88106a9be1a873c7b1ac69d03ddf240ece2e12fa470cd88ab56f52047936cf3d1020d537c350e78f6358d3a07bbe481d9c5c25f48e19b1156adea408f26d9e7a2041aa6f86a1cf1ec6b1a740f77c903b38b84be91c33622ad5bd4811e4674f4ced59b761c51064658559aca9e9a562d26e7099763966c455ac7a9023c75ab0f28789d14641ed8ef302a9b77bcdf70800d9e1349073cd88ab59f520478d41743dbbea050f3ba7e40dfd49cd1f969a525db0c26ac4e89b1156b4ea408f190efad424aa6ca12f1c8e43f289f86727e0e7175e84d72dd23622ad6ad4811e311df5a84954d9425e391c87e513f0ce4fc1ce2ebd09ae5ba46c455ad5a9023c623beb5092a9b284bc72390fca27e19c9f839c5d7a135cb748d88ab5ab520478c403e8f9d229c78c30b138478c46216139b37b16f126bb1292b1156b57a408f18707d1f3a4538f186162708f188c42c27366f62de24d762525622ad6af4811e30e0fa3e748a71e30c2c4e11e31188584e6cdec5bc49aec4a4ac455ad5e9023c61c1f47ce914e3c618589c23c62310b09cd9bd8b78935d8949588ab5abd20478c383e8f9d229c78c30b138478c46216139b37b16f126bb1292b1156b57a408f1870093192f20f5408cdf3cf1980ba8a4f311ba53a21d763f65722ad6af5811e30df126325e41ea8119be79e330175149e62374a7443aec7ecae455ad5eb023c61be24c64bc83d502337cf3c6602ea293cc46e94e8875d8fd95c8ab5abd60478c37c498c97907aa0466f9e78cc05d4527988dd29d10ebb1fb2b9156b57ac08f186f81f2b87cdcba30f9709b7c0039f031b0c6695fe1a764109732ad6af5911e30def3e570f9b97461f2e136f80073e063618cd2bfc34ec8212e655ad5eb223c61bde08c077e404eec113f3a52806726a942c469a5466d905c9cdab5abd65478c37bb1180efc809dd8227e74a500ce4d528588d34a8cdb20b939b56b57aca8f186f762301df9013bb044fce94a019c9aa50b11a69519b64172736ad6af5951e30deec4603bf202776089f9d2940339354a16234d2a336c82e4e6d5ad5eb2a3c61bdd81819d6ed254e93f70718a85f1d076abf15e7a26a905e40dbb5abd65578c37baf3033adda4a9d27ee0e3150be3a0ed57e2bcf44d520bc81b76b57acaaf186f75e60675bb4953a4fdc1c62a17c741daafc579e89aa4179036ed6af5955e30deebc4ce1101600d72270058b6af0de997df35b7f6f5182f3aadead5eb2acc61bdd7725d478d8d810c797d7dcfdd9b39123e163413aa005e8f9be5abd655a8c37baed4ba8f1b1b0218f2fafb9fbb3672247c2c68275400bd1f37cb57acab5186f75da23643c1036a5a1172c3a1f5ec4a2b7803947467d17a58afa6af5956b30deebb346c878206d4b422e58743ebd89456f00728e8cfa2f4b15f4d5eb2ad661bdd76619a348edb0f907147daea57308e905fb915f75f15e97cfeaabd655adc37baecb334691db61f20e28fb5d4ae611d20bf722beebe2bd2f9fd557acab5b86f75d96668d23b6c3e41c51f6ba95cc23a417ee457dd7c57a5f3faaaf5956b70deebb2c592ca01a5e2abb5bba3b53903da657d7373e0b87f4c023565eb2ad6f1bdd76573e6b98e192b7f96f413ccf1871aad7a91abe730ce981eaadbd655adf37baecad08e98a6ffbd275964f3fc628d9b3d74ce1bf4216d305795c7acab5bf6f75d95911d314dff7a4eb2c9e7f8c51b367ae99c37e842da60af2b8f5956b7edeebb2b223a629bfef49d6593cff18a366cf5d3386fd085b4c15e571eb2ad6fdbdd76564474c537fde93acb279fe3146cd9eba670dfa10b6982bcae3d655adfb7baecac81aaaffac9389dc1cc0c28a85919b9cc8c8367d6a305939c8acab5bf7f75d958f3555ff592713b8398185150b23373991906cfad460b273915956b7efeebb2b1e6aabfeb24e277073030a2a16466e732320d9f5a8c164e722b2ad6fdfdd76563c616a561172b1639dd2da7c24833b0e40edf6474e82cb7246655adfc0baecac774ee704cfbbc549f3727b2040fcd4447c882eea9a0598888dcab5bf8275d958ed29e0624c4ded169eb1bc6879f006b0f3bca031310b32b51c956b7f05ebb2b1d953c0c4989bda2d3d6378d0f3e00d61e77940626216656a392ad6fe0bd76563b23393e1de0e16dd3293b7c9dfb678ebc99ec320c12ccc787355adfc18aecac7636727c3bc1c2dba65276f93bf6cf1d7933d8641825998f0e6ab5bf8315d958ec65a61e0250ebdf7821ba54f76d041d721274edf01b33385ce56b7f063bb2b1d8b40d618f6f3de71bc0410c6e596e1d63cfae01a006668af9dad6fe0c876563b150dbe8a9abe1f662fd4e7b5c32421d474a2028ffdccd3033c5adfc191ecac76291b7d15357c3ecc5fa9cf6b864843a8e944051ffb99a60678b5bf8323d958ec5236fa2a6af87d98bf539ed70c908751d2880a3ff7334c0cf16b7f0647b2b1d8a46df454d5f0fb317ea73dae19210ea3a510147fee669819e2d6fe0c8f6563b14867fb0258b858e5b51b41842a387b6f44cc6b5bd9cd31d7c6adfc191fcac7628f5c085d5e47144e220349304c67550684451913b09a65538e5bf83240958ec51d44231369648b1efbd3588890c50835033674835e34cc4b1db7f064822b1d8a3914587f7f9f78c0af73773919806e9201192b62b9699a3a3c6fe0c905563b147128b0feff3ef1815ee6ee723300dd24023256c572d3347478dfc1920aac7628e25161fdfe7de302bdcddce46601ba480464ad8ae5a668e8f1bf83241558ec51c42ed654a9d2288833687ff0c3f9d2b803759d71c84cd375e47f06482bb1d8a3875daca953a4511066d0ffe187f3a57006eb3ae39099a6ebc8fe0c905763b1470e476bab541f04a3856ec5eb07dda9080882b8231e334f7b92fc1920afc7628e1b1ae9af55146bc9c2aa51fe07b1b0380bb1b2a23966a09b26f83241608ec51c3535d35eaa28d7938554a3fc0f6360701763654472cd41364df06482c11d8a386a6ba6bd5451af270aa947f81ec6c0e02ec6ca88e59a826c9be0c905823b1470d4635fd35579c0d0cd1f56183583dfe85839d76dc835067d38c1920b057628e1a752d1ff57c9e424520b725862fe1df8ab1ff1378d6a0e9e728324160bec51c34d31b6575c6a2acb5be3aad8bdf29a1950ec24cb17d41ee0e606482c18d8a38699636caeb8d45596b7c755b17be53432a1d849962fa83dc1cc0c905831b1470d3252ebb61e7f0db0275b718aefc0c68d3e5cd5885c507d27991920b064628e1a6331e9c4e9d47de30683a93dd777eb427765ed6cb5a0fbf333324160c9c51c34c563d389d3a8fbc60d07527baeefd684eecbdad96b41f7e6666482c1938a38698a53b96c54285a0ed1db6b1f55d60b31d843f80ed383f170cdc90583281470d313338531552716a05b839c66a3a2748bab343279a407e4859c920b065128e1a625670a62aa4e2d40b70738cd4744e917566864f3480fc90b3924160ca251c34c4a5a271e0172bd0425db37c286803056a77d0c428d1f93ba73482c1945a3869893406094afbbdc8b038335ad04f6bed549a65ae1173f2918e79058328c470d31250cd3820c4e1b98bed3318201e3dbd28df8f81e2b7e53d5d020b065198e1a624919a704189c37317da6630403c7b7a51bf1f03c56fca7aba04160ca331c34c492334e0831386e62fb4cc608078f6f4a37e3e078adf94f574082c1946638698924669c106270dcc5f6998c100f1ede946fc7c0f15bf29eae81058328cc70d31248594a7971b81c0ea4ffde4816341b50da3bc43eb4e53f01030b065199e1a6248f3ea74b90469aa001cc82b8245e94c9af23cad966ca7fa607160ca334c34c491d0960efcd6397c2bb65cb9840b387bb58f3d80eca9500f00f2c19466a8698923912c1df9ac72f8576cb973081670f76b1e7b01d952a01e01e58328cd50d3124722583bf358e5f0aed972e6102ce1eed63cf603b2a5403c03cb06519aa1a6248e44b077e6b1cbe15db2e5cc2059c3ddac79ec07654a807807960ca335434c491c8222155830fdeae6e297fac032ed9dd89e9c348a65010a4f3c19466a96989238f4442ab061fbd5cdc52ff58065db3bb13d386914ca02149e78328cd52d312471e1497aeb915dd3c7072c4d804b1c59e22534f7e96404437d006519aa6a6248e3b292f5d722bba78e0e589b009638b3c44a69efd2c80886fa00ca3354d4c491c76525ebae45774f1c1cb136012c71678894d3dfa590110df4019466a9a989238ec30cfce75854c663b62ece81d848b190d46be50af02236281328cd536312471d7619f9ceb0a98cc76c5d9d03b0916321a8d7ca15e0446c5026519aa6c6248e3ae4f519282eb941ba55879c86e088a8c2fc73b9eb9088f2e05ca3354d9c491c75b2ab57db2ad8aba027db9b8d40773405a3ab9996f1120000c9466a9b489238eb5556afb655b157404fb7371a80ee680b4757332de2240001928cd536912471d6a36e84f778c8d6ac1c3ad0b48142b29639728c1b94481a433519aa6d3248e3ad36dd09eef191ad583875a1690285652c72e51837289034866a3354da6491c75a667b3968b08982dbedb7a5518470acd8908e562e2120834ce466a9b4d9238eb4b5b7985c2e792de3583bad2288473c30cbe0d21c124120d9d8cd5369c2471d69543056432a5883f22d43bcc48ff45ae14285c9f7f4825bf3c19aa6d3948e3ad29121d2112217300fd753dc089f4e98422fcfb9afb904d22793354da7391c75a51243a422442e601faea7b8113e9d30845f9f735f7209a44f266a9b4e7238eb4a24874844885cc03f5d4f70227d3a6108bf3ee6bee413489e4cd5369ce471d69441cfb613de1fa8aa376b42c479daa4912941f33d9826ab7ca9aa6d39d8e3ad28739f6c27bc3f51546ed68588f3b549225283e67b304d56f95354da73b1c75a50e73ed84f787ea2a8ddad0b11e76a9244a507ccf6609aadf2a6a9b4e7638eb4a1c73ed629be636d7d382678a34e3b0708f4d3bfac913576255d5369ced71d6943773ed1de4a2d0325ed1953c61bdbf091946ba518f26b068acaa6d39dbe3ad286d73ec94761c02e7756ff0a0bb71dc3a2d39b6ff1b4d62755a54da73b8c75a50d973eb81990e6851a2aca7696eda169c551fb05a339ac68eb5a9b4e7728eb4a1b173e95bdef33325fd2614fad5aa8b60a4eba31064358ec16c5369cee61d69436173e5106abcc8ceb218f01da34b74e94483887cc56b1f26d9a6d39dcd3ad286c173dc79824ff4201bfea6633e8d47fa83b3535587d63ff1b44da73b9b75a50d8173cb4bb1764ac2efca12ee7510ee1d0212e9070cac8187699b4e7737eb4a1b0173a8f00fc2f8089760ec04e2183a61fed2146a165904b2d4369cee70d6943601736438cc5c5293e68e9e31bc26d2ebf8506b3029b20b09a96d39dce2ad286c0172daca458f07aa84ea028b704403ffeb4d18bc506417b753da73b9c65a50d80171c7ed37f471d7c1a0cb3ed87e6627d14673d49dc83112a8b4e7738db4a1b0016fa2331cbf46323b0e5ca5a8f32a779d392a05389063c95269cee71c694360016b56bee654eee72de97f7349dcb317351e96666e20c936a5d39dce39d286c00162bfd679804051139fc50e8bafc45664e96f28d94194114ca73b9c74a50d80015192059fd6e324df0c50450f55e6d4c47f20adaf8329c69a4e7738ea4a1b00012f3663ec8428cc75e566b216a22bd183aa83b75c065531359cee71d5943600015e6cc7d9085198ebcacd642d4457a30755076eb80caa626b39dce3ab286c000248ebe85ee705b48f6260f0527f0d6e095651396d195668d773b9c75750d800031dea296aa46debd69188089cf479040d58e4ced732ae75afe7738eafa1b000053bd452d548dbd7ad23101139e8f2081ab1c99dae655ceb5fcee71d5f4360000a03bafe57681a321212e64a6bc84238300fd59759cabb7ac09dce3abf86c000130775fcaed034642425cc94d7908470601fab2eb39576f5813b9c757f0d8000260eebf95da068c8484b9929af2108e0c03f565d672aedeb027738eafe1b00004c1dd7f2bb40d190909732535e4211c1807eacbace55dbd604ee71d5fc360000983bafe57681a321212e64a6bc84238300fd59759cabb7ac09dce3abf86c00013003722399d9a8c4fa298f7570fea52dfca6f547365770fc14b9c757f1d800025f06e44733b35189f4531eeae1fd4a5bf94dea8e6caee1f829738eafe3b00004be0dc88e6766a313e8a63dd5c3fa94b7f29bd51cd95dc3f052e71d5fc76000097c1b911ccecd4627d14c7bab87f5296fe537aa39b2bb87e0a5ce3abf8ec00012f83722399d9a8c4fa298f7570fea52dfca6f547365770fc14b9c757f1d800025f06e44733b35189f4531eeae1fd4a5bf94dea8e6caee1f829738eafe3b00004be0689b3f234093c14230a384379fa9a72469942992dc40a92f71d5fc77000097bf5d48d6f3578a053c2e0d306735b176437f6aaf22b882f65fe3abf8ef00012f7d46a4069385768d3028e088c661c11481ab17ba42710790c0c757f1df00025ef9195a65d3e14f9d181e873984b9e050fe0271d081e210c5828eafe3bf0004bdf132b4cba7c29f3a303d0e730973c0a1fc04e3a103c4218b051d5fc77e00097be26569974f853e74607a1ce612e78143f809c742078843160a3abf8efc0012f7c456e5874be0df6b78c0fff41dc560afeabfd0e00c1087d015757f1df90025ef8739dd6744982159a94ec61033811f87d02be41c152111442beafe3bf3004bdf0d73bace893042b3529d8c2067023f0fa057c8382a42228857d5fc77e60097be1a7387f5bf36e7e95d07de68c5fadc473b5bd2cc518446b4b0abf8efcd012f7c337322442b44325571dc82f983ec16b67163e7f4a0088f0d6257f1df9b025ef8657256e1035ec72d9b85cc1affce8b94dd7412453d111fbec5afe3bf3704bdf0c970c01ab393f0ddeed85e5df7937551b59466e6772241218c5fc77e6f097be1916d928e13fe443e957d82e3e71d48cb65d51028eb4483e719bf8efcdf12f7c321673774d4d2eaffe2c7cbefc630efbec65662add3890972347f1df9bf25ef86415a8142567c38827d5c5e0784583da5875907b7a412148869fe3bf37f4bdf0c814114dd59ced387b285823700a6d973095e51cb45242ab4d4fc77e6ff97be19010e3c13607409921cd7ca95f944110e0d68e5f28748570daaf8efce002f7c32011c7826c0e8132439af952bf288221c1ad1cbe50e90ae1b55f1df9c005ef8640238f04d81d02648735f2a57e510443835a397ca1d215c36abe3bf3800bdf0c80471e09b03a04c90e6be54afca2088706b472f943a42b86d57c77e70017be190086fd38eb416fba485496f878c376f08d13aa1847185727eb08efce003f7c3200f6bb976150459cbc25fa53710653c399d218564e00ae6a1621df9c008ef86401d638544d6df161a3c8c109618c0d69b34ef4d25bd15cee6c53bf38012df0c8039531ce25a948eb730e4e75429780b5e648adca7772b9f718b77e70026be190071324c1d61ff7ff1199694d04ae674e4c3c1fbaaeb57408717efce004e7c3200e164983ac3feffe2332d29a095cce9c98783f755d6ae810e2fdf9c009cf86401c25542ce34d462471e271969239031bb09b43107aa5d03c060bf38013af0c803833697f5167f2710f41af8fa3f16c19e0e14a46b51ba0924c27e700276e19007056d2fea2cfe4e21e835f1f47e2d833c1c2948d6a374124984fce004edc3200e0a66722d06d2fec68838aa10f45164a032fed40943e826370af9c009dc86401c1358f6b2ba7c600fc83e1a49e099276860a9ea6e84d04e1216f38013ba0c8038253dffbe21cf22a24848fabbb928acf8bc00173906a09dc82ee7002775190070490811d4f074a7c7485ebb9f6a47b81972ac70ce0a413d345ece004eeb3200e0911023a9e0e94f8e90bd773ed48f7032e558e19c14827a68bd9c009dd66401c122204753c1d29f1d217aee7da91ee065cab1c3382904f4d17b38013bacc8038244408ea783a53e3a42f5dcfb523dc0cb956386705209e9a2f670027759900704880d2fa7b420def73db8801e9c71dfbf25734f3ca113d4e9ede004eeb4200e090f1a5f4f6841bdee7b71003d38e3bf7e4ae69e794227a9d3dbc009dd68401c121e34be9ed0837bdcf6e2007a71c77efc95cd3cf2844f53a7b78013bad08038243c697d3da106f7b9edc400f4e38efdf92b9a79e5089ea74f6f002775a1007048785f0cd3eee451f69354c811bf145a1a51e136260e3d5042df004eeb4300e090ef4a2c008a9f066fde76564b761f125c9e6eaea8197aa229bf009dd68701c121dd206a59c2146f6274b972bee43482e137899fac2ff545f77f013bad0f038243b940d4b38428dec4e972e57dc86905c26f133f585fea8beefe02775a1e070487720dbbbfb528200c8ab2912388c869acd8d2c10cbcd51981fd04eeb43d0e090ee31b777f6a504019156522471190d359b1a5821979aa3303fa09dd687a1c121dc636eefed4a080322aca448e2321a6b3634b0432f3546607f413bad0f438243b8c6dddfda94100645594891c46434d66c6960865e6a8cc0fe82775a1e87048771867ce53ff58634b62f5d860847cf8f587d85327ca5199c3d14eeb43d1e090ee2f5baf00ab8729197db876e900f050130a5ce8ab91a3352ba39dd687a4c121dc5d43705a03e4b4b5b33db3f9f9d6fe4e0f6613b320466bfb483bad0f4a8243b8b912f30cb49fcbee1e482e1beba45ac4197869c23d8cd99a91775a1e960487717125e619693f97dc3c905c37d748b58832f0d3847b19b33522eeb43d2c090ee2e24bcc32d27f2fb87920b86fae916b1065e1a708f633666a45dd687a58121dc5c423aabe51d4c1f3aa0e370755193448c66f906de966ce788cbad0f4b1243b8b8747557ca3a983e7541c6e0eaa3268918cdf20dbd2cd9cf11975a1e9624877170e1abd51f4296a516005a2454c5b2f4b146a8413a29b3b8633eb43d2c590ee2e1b357aa3e852d4a2c00b448a98b65e9628d508274536770c67d687a58b21dc5c366af547d0a5a94580168915316cbd2c51aa104e8a6cee18cfad0f4b1643b8b86c61fce84e21b50db7f9d8525acfd8809e0062f911d9ddd5a05a1e962d877170d7500c294919cc9e27c076ccad960f2936ad084e20b3bd4f41b43d2c5c0ee2e1ad2c2aab3f09fbbf074db3c153227c7a680652f83e677c4284687a58b91dc5c3595855567e13f77e0e9b6782a644f8f4d00ca5f07ccef88508d0f4b1723b8b86b23cbd05a8fe517ed503952d448050119ac58e3cf69df2ae12a1e962e577170d63058c63fed3058061d3f08280f6fe4b30375ed5ea3be7002643d2c5cbee2e1ac50b18c7fda60b00c3a7e10501edfc96606ebdabd477ce004c87a58b97dc5c358a16318ffb4c1601874fc20a03dbf92cc0dd7b57a8ef9c00990f4b172fb8b86b142c631ff6982c030e9f841407b7f25981baf6af51df3801321e962e5f7170d62858c63fed3058061d3f08280f6fe4b30375ed5ea3be7002643d2c5cbee2e1ac503d9ed88737128ef24ad67816d6278e01981d19447ce1a8c97a58b97ec5c3589f075009bb4487a09c62731825a2ad43fddc7c8e85f9c4f593f4b172fe8b86b13d0ea01376890f4138c4e6304b455a87fbb8f91d0bf389eb27e962e5fd170d627a1d4026ed121e827189cc60968ab50ff771f23a17e713d64fd2c5cbfa2e1ac4f43a804dda243d04e31398c12d156a1feee3e4742fce27ac9fa58b97f45c3589e80112f4611edc8c7df3f7aa52213267d8740b445c9c50fd404b172fe9b86b13cf0225e8c23db918fbe7ef54a44264cfb0e81688b938a1fa80962e5fd370d6279e044bd1847b7231f7cfdea94884c99f61d02d11727143f5012c5cbfa6e1ac4f3c0897a308f6e463ef9fbd529109933ec3a05a22e4e287ea0258b97f4dc3589e78112f4611edc8c7df3f7aa52213267d8740b445c9c50fd404b172fe9b86b13cf0225e8c23db918fbe7ef54a44264cfb0e81688b938a1fa80962e5fd370d6279e044bd1847b7231f7cfdea94884c99f61d02d11727143f5012c5cbfa6e1ac4f3c0158c893c44a8c1b1c89b51088f921434b1e48a4b288044268b97f4dd3589e77f2b191278895183639136a2111f24286963c914965100884d172fe9ba6b13cefe563224f112a306c7226d44223e4850d2c792292ca201109a2e5fd374d6279dfc3876a28efba8904611a0b03c72eec9a03b66ae564403c5355cbfa6eaac4f3bf770ed451df751208c23416078e5dd934076cd5cac88078a6ab97f4dd5589e77ee6dece2e8c504c3d01348e8e9c2194e7b99dd15561010b8d672fe9babb13cefdb67ec1e7e606c0a57f357f9cb7a90c4f1dffc86a9202315ade5fd37586279dfb55bea95a9973a9767b3761b8eeb7fb1de6c3b694f4047cf5ccbfa6eb1c4f3bf6943e7840004d7b18733b25f15cd5d8bb784b92e9b809142ba97f4dd6489e77ed113e160ace011e5c6342ae62391193f69b5b4b934012429762fe9baca13cefda127c2c159c023cb8c6855cc4722327ed36b697268024852ec5fd37594279dfb424f8582b380479718d0ab988e4464fda6d6d2e4d00490a5d8bfa6eb284f3bf6842b1d5e13d6f1b0e96e1d59147f28234859e8259d0922efb27f4dd6519e77ed07563abc27ade361d2dc3ab228fe504690b3d04b3a1245df64fe9baca33cefda0e3887d0fc3229465d853b8c49f2feb51c13e2f271248d62cafd37594779dfb41b710fa1f864528cbb0a771893e5fd6a3827c5e4e2491ac595fa6eb28ef3bf68366e319c9d9f079c2de1b4591fc258fc6afbce25c192372f2cf4dd651ee77ed06b687591e81471bb13902eda377b1020d0a3dea7802470025ae9baca3ecefda0d55cfd7c7cff45f8deed23dc66ec7e699bf3ffaafd48e1a8b6d375947e9dfb41a9460d51a6d4ee7475a70de0c5cf5afb329441b1f791c4f56ea6eb28fe3bf68351182cfbfa803f6ba31ae1e98395141e5fd4c5bfec238b8ede4dd651fd77ed06a13059f7f5007ed74635c3d3072a283cbfa98b7fd847171dbc9baca3faefda0d4260b3efea00fdae8c6b87a60e5450797f5316ffb08e2e3b79375947f5dfb41a844d7a3880d85ddfd0a3d574149eff1af952705b5e1c5e1af36eb28fecbf6835072706c9ae871e425914711021345c5ded512312b938bdd9e7dd651fda7ed06a0d4e0d935d0e3c84b228e2204268b8bbdaa2462572717bb3cfbaca3fb4fda0d41a282d7f66f2db8c1c1e8a687cc7cf9faff0cea6e1e2f90ba075947f6afb41a833505afecde5b718383d14d0f98f9f3f5fe19d4dc3c5f21740eb28fed5f68350662cc85648a1d0b32846efc9eb159ca6ba6f7cf7848be5d282d651fdaced06a0cb5990ac9143a166508ddf93d62b394d74def9ef0917cba505aca3fb59da0d41963f33b1cf5da54f58e8854fa44cd0c2e46a363a0f2f98ee0c5947f6b4b41a832b0a79bc4b91ad21699dd0c7408fffadc380aed01b5f338019b28fed6a6835065514f37897235a42d33ba18e811fff5b87015da036be670033651fdad4d06a0caa29e6f12e46b485a677431d023ffeb70e02bb406d7cce0066ca3fb5a9a0d4195453cde25c8d690b4cee863a047ffd6e1c057680daf99c00cd947f6b5341a832a833ae1d65f1349951a9d29c00f6590432b72f5db2f339a59c28fed6a78350654f675c3acbe26932a353a53801ecb208656e5ebb65e6734b3851fdad4f06a0ca9e5acace449b34e7fe741097fbcfc238c588ffd2c8cce83a71a3fb5a9f0d41953b41a7f5360ccc52b4b4e757ef95e29985be42018e99d218e447f6b53f1a832a750f624318effb28213694d7d722235b0628c65f1a33a5d5c98fed6a7f350654e91ec48631dff650426d29afae4446b60c518cbe34674bab931fdad4fe6a0ca9d23d890c63bfeca084da535f5c888d6c18a3197c68ce9757263fb5a9fcd41953a407247174563bc3c1816ce6b10779002bf27554ce9d30524d7f6b53faa832a7470e48e2e8ac77878302d9cd620ef20057e4eaa99d3a60a49afed6a7f550654e8e1c91c5d158ef0f0605b39ac41de400afc9d5533a74c14935fdad4feaa0ca9d1c39238ba2b1de1e0c0b6735883bc8015f93aaa674e982926bfb5a9fd541953a387247174563bc3c1816ce6b10779002bf27554ce9d30524d7f6b53faa832a747070a087379ddafae7fa62fe18e57e2d78faecf5d0a60bedb0ed6a7f560654e8df6d53671c12187887c18c2429c15a82eca21c479e4c197f62dad4fead0ca9d1bd66b926e4fa9373c74fde704b79132dd3f07aeb399834a2c6b5a9fd5b1953a3795984a676cb896a466c83088ee88483a28d383270306ae98e6b53fab732a746f13f1ba59a6d755744a5cc3915c7672f3fc6b2c0dd60d7771dd6a7f56f654e8de10a49a3e1b14d3141185e9a23852c867a39a7ddb7c1b0923cad4feadfca9d1bc1149347c3629a628230bd34470a590cf4734fbb6f836124795a9fd5bf953a378229268f86c534c504617a688e14b219e8e69f76df06c248f2b53fab7f2a746f04524d1f0d8a698a08c2f4d11c296433d1cd3eedbe0d8491e56a7f56fe54e8de0830ac96c7eb3596c952afca3049268f9e46c037791b0ac7cbd4feadfda9d1bc0f61592d8fd66b2d92a55f9460924d1f3c8d806ef236158f97a9fd5bfb53a3781e4ec4b3cc8338dddd178550b91af86673c74339e16c2cc33053fab7f7a746f03b299bc045dcd43e71fbd0c96a2c4ef4e23ac8cfbfd85b2a61a7f56ff04e8de0755337808bb9a87ce3f7a192d4589de9c475919f7fb0b654c34feadfe09d1bc0ea328159c449b37c7fbc094da0a799fb8397659afc616e4d879fd5bfc23a3781d36502b3889366f8ff78129b414f33f7072ecb35f8c2dc9b0f3fab7f84746f03a65617bfbdfd3074b6bceb5e7a94c6160909d8c7ee85bada1f7f56ff09e8de074b3841d828d0c36c25469ce4ed1fea540cbff3ebda0b77583ffeadfe14d1bc0e957083b051a186d84a8d39c9da3fd4a8197fe7d7b416eeb07ffd5bfc29a3781d2a6d19b9501970334ce739bbac7607782dac120b652ddf0500fab7f85446f03a536645cb4d0942e9519b399f50e26d1856046672c75bbfae02f56ff0a98de074a5589def46e8e8555b03396699bb3858a6b50f418bb7810006eadfe1541bc0e9493d4e373aa8332d6dd338f52b6cced9481660df146f03a40ed5bfc2a93781d29106aec72226c8dd937338124ecffbda8ad9041a25de08ec1eab7f85536f03a5210d5d8e444d91bb26e670249d9ff7b515b208344bbc11d83d56ff0aa6de074a421abb1c889b23764dcce0493b3fef6a2b641068977823b07aadfe154dbc0e9484357639113646ec9b99c092767fded456c820d12ef04760f55bfc2a9b781d29086aec72226c8dd937338124ecffbda8ad9041a25de08ec1eab7f85536f03a521061eb3cf1af7e352633c871d1f5d97955ccc5a0b8c11f27d66ff0aa6ee074a41f4fe8d290355eed0434570b9be2111aa645cd9d6e823ff3addfe154dec0e9483d2be3fdcd41205cc035743f2fba805d4737dd96da04818b5cbfc2a9be81d2907957c7fb9a8240b9806ae87e5f7500ba8e6fbb2db4090316b97f85537d03a520f23ba24fe1dae3f5b8a29724b6e05f9d178bb8b7651207d173ff0aa6fb074a41e30356f8708c2a6e2911f47165b71d6229c3b3cac7241146e8fe154df70e9483c506adf0e11854dc5223e8e2cb6e3ac4538767958e48228dd1fc2a9bee1d29078a0d5be1c230a9b8a447d1c596dc7588a70ecf2b1c90451ba3f85537dc3a520f141ab7c384615371488fa38b2db8eb114e1d9e5639208a3747f0aa6fb874a41e28356f8708c2a6e2911f47165b71d6229c3b3cac7241146e8fe154df70e9483c506adf0e11854dc5223e8e2cb6e3ac4538767958e48228dd1fc2a9bee1d29078a061d074cfe0fe0cfc49e28165bdb6b26b99350dc604535e4085537dc4a520f13f4fb3424c985e9cb0608b2ac371cb8cd1deac778908a860820aa6fb8a4a41e27d2b78dd46071fbc188ddc7d7ed9f5419e699b4b0f11526505154df7159483c4f956f1ba8c0e3f78311bb8fafdb3ea833cd336961e22a4ca0a2a9bee2b290789f239f5cdc4f2e1731a04381df35e332e7452af8839454b38155537dc57520f13e373eb9b89e5c2e63408703be6bc665ce8a55f10728a96702aaa6fb8aea41e27c673e98fc0a1e84f1fdda69fc56f2ae1cbf7007ce2152e845654df715e483c4f8b73e5782e1a3320f788136782d4b3eb929a4355c12a5eacada9bee2bd90789f1573dd49090ac8c4a6dcecf6fd9fc5ff1fe0c9077f54befd5c537dc57c20f13e2973cceabeebf40c0586a015f335ea263a6dd46afba97f9eb9a6fb8af941e27c5173ac2e2aae4a9ac2da0653de6232746f87eb31f45300e1744df715f383c4f8a1736ab50232f7b83d80d2cfb4bac310d9bc18bfe5a60366e99bee2be80789f14172e7c2b13c51f332ce6bc7616be449ae2473dbc84c0871d437dc57d10f13e28171e1de0f4f06691d699db6bace26bb56f52a138d981287a96fb8afa31e27c5016fd614cb746f54f2a001956d92ab9ea8969683183026b353df715f473c4f8a016bbe8243bf412c9d0cc952d31bb5654bd96f622d604f0aa8bee2be8f789f1401638f5d3454e4dbf1e658cd9e2dc8f2925f212057c09fb9527dc57d1ff13e280153311315802c3a9b9977c33451f00d1f6a849cac814116a5fb8afa40e27c500132747ed7d6baf7eeffb5ae609a3e4239814b95560283d14cf715f482c4f8a00164e8fdafad75efddff6b5cc1347c847302972aac0507a299ee2be90589f1400255e4540c314e6273cb9ce17a5f5730e0b170b1550a10e934dc57d20c13e2800337db00c538ff479f63ffeaecb50c89bc0f23bea71423766ab8afa41927c500056fb6018a71fe8f3ec7ffd5d96a1913781e477d4e2846ecd5715f48324f8a000a6b7e5bc1ba5fa1355cc5d3aaca904eeae8d15699508f7dabe2be90659f140013630f10304b21c5228651cf4d8b7ec5d07de5092fa1209f58c57d20cc3e2800255230790d6ca60cfcd969c6930d5bb39ba80c6e5c4242e2b28afa41997c50004930734ac7afae9cb17f99b51e11158f31fc5b38b58487696615f48333f8a0009160e6958f5f5d3962ff336a3c222b1e63f8b6716b090ed2cc2be90667f14001224ddf83cb951cf57dcb2cfc703ab464c29daf3ed3121f499957d20cd0e280024327d16044009c6db3632020d86bc6f17fe7a0d9a324403733afa419a2c50004854fa2c0880138db66c64041b0d78de2ffcf41b34648806e675f4833458a00090a2b57d9bcd8d439855946ab59a579edfa4ac5c289910280cfbe90668c1400121356afb379b1a8730ab28d56b34af3dbf4958b85132205019f7d20cd18280024263971bfa039b368cd31e0d55e8c45dfe3d7596623440ba73ffa419a315000484b72e37f407366d19a63c1aabd188bbfc7aeb2cc4688174e7ff4833462a000909671d9572dbd3025ec94497d722775a78a09a7f48a10304100e90668c64001212b6fc5070850c2ce90f55922dc4549770ebf92451120622602d20cd18d800242556b9c66bd77e81fd9b7786db080f116182b66e61f40c5f006a419a31c000484a9634b2627c632c26b3bb70358f840542b0310283b818d840e483346390009095152a8a4fc62c8078e44342ea9e6ded050b262ac74031cac1d90668c73001212a13163a2a59bf291d4552e854bc41bc89c1107b4e5063afc3c20cd18e70024254162c7454b37e523a8aa5d0a9788379138220f69ca0c75f878419a31ce00484a8251a0e343462cca0921803d2706cd4a6af0612f9118ed94f18334639d009095032f541f3362bc16ca0fc6a24603f8bcd08d04bb1f31dccde40668c73b01212a055ea83e66c5782d941f8d448c07f179a11a09763e63b99bc80cd18e760242540a4962d57a6152dde00be0b11006411b3ce0554879c774db9119a31ced0484a8131ed803a199083e77e4878a1802e05e746cececf08eeb5b23334639db090950253db0074332107cefc90f143005c0bce8d9d9d9e11dd6b646668c73b61212a04a077267333a837c975ee4505801dfa1cc5ff60fbf3baf108dcd18e76d242540930ee4ce667506f92ebdc8a0b003bf4398bfec1f7e775e211b9a31ceda484a81261dc99cccea0df25d7b914160077e87317fd83efceebc423734639db49095024c3b933999d41be4baf72282c00efd0e62ffb07df9dd78846e68c73b69212a04980338cbe07e9a4c2dbb0b2d78145844c0aba357f0baf2acddd18e76d34254092f067197c0fd34985b76165af028b089815746afe175e559bba31ceda684a8125e0ce32f81fa6930b6ec2cb5e051611302ae8d5fc2ebcab3774639db4d095024bc19c65f03f4d2616dd8596bc0a2c226055d1abf85d79566ee8c73b69a12a04978338cbe07e9a4c2dbb0b2d78145844c0aba357f0baf2acddd18e76d34254092f067197c0fd34985b76165af028b089815746afe175e559bba31ceda684a8125e05a4550cc7cf58e268f9185fd0c6f58259518582bbcacdb75639db4d195024bbf409cfa45d04d9f04ebe933f20f3cd845d6730c54795b5aebc73b69a42a04977d0d4c4d3876fdc0c1a4988fdc14d7d886592874a5f2b859d88e76d34954092ef91a989a70edfb818349311fb829afb10cb250e94be570b3b11ceda692a8125df2353134e1dbf7030692623f70535f621964a1d297cae1676239db4d255024bbe46a6269c3b7ee060d24c47ee0a6bec432c943a52f95c2cec473b69a4aa04977c860d72c34463e8ed2164f25b943dbb0603ec9a65c2b874189e76d34964092ef8f4dc0b11562dfa05bf964736a7e1588bb29d5a8b557102714ceda692d8125df1d2793bad79c21c36fbf8f0eccf2893970ffedad67ae21f22a9db4d25c024bbe394f2775af384386df7f1e1d99e51272e1ffdb5acf5c43e4553b69a4b804977c722a61440b46e99076cb02632bc0830dbeabf9119bb8896cab76d34971092ef8e354c288168dd320ed9604c65781061b7d57f223377112d956eda692e2125df1c6359768d9f208c492f8cfb4a6f86a5ef55c26a26be22756aedb4d25c524bbe38b6b2ed1b3e4118925f19f694df0d4bdeab84d44d7c44ead5db69a4b8a4977c716626ffc149e859503b004fa93d807a3d01cdce5ac889efebc6d34971592ef8e2b50f250d6136dacbf2cd01d1fa66d6f9ae5fc2756113fa179da692e2c25df1c552df6fa58fd3ddc362666623743390730783aaaa92280e6f4b4d25c594bbe38a95bedf4b1fa7bb86c4cccc46e86720e60f07555524501cde969a4b8b2977c715243ee4210cb59f390665fb0d5034244bc8d2d06a18a053fd3d34971662ef8e2a313eedcce6d1669d8998589a1fce2b173c69c6940140c23a8a692e2cd5df1c54527ddb99cda2cd3b1330b1343f9c562e78d38d280281847514d25c59abbe38a8a4fbb7339b459a76266162687f38ac5cf1a71a50050308ea29a4b8b3577c715142b893f203f15d17c98f27507dd73b398e125a5fda062c1463497166bef8e2a2757127e407e2ba2f931e4ea0fbae76731c24b4bfb40c5828c692e2cd7df1c544e3a37552dd2b9c8aa308ffc176c2cf65e30d8f3f3818ca919d25c59b0be38a89b008103087bd6140c2de62026ceb814b70df443e4031af634a4b8b3627c71513501020610f7ac28185bcc404d9d70296e1be887c80635ec69497166c4f8e2a26a02040c21ef585030b798809b3ae052dc37d10f900c6bd8d292e2cd89f1c544d404081843deb0a0616f31013675c0a5b86fa21f2018d7b1a525c59b13e38a89a808103087bd6140c2de62026ceb814b70df443e4031af634a4b8b3627c71513501020610f7ac28185bcc404d9d70296e1be887c80635ec69497166c4f8e2a26a02040c21ef585030b798809b3ae052dc37d10f900c6bd8d292e2cd89f1c544d404081843deb0a0616f31013675c0a5b86fa21f2018d7b1a525c59b13e38a89a800d156128ac768ee5b2e64ec6ae72df08a08640001af7d8a5b8b3627d715134ff1a2ac25158ed1dcb65cc9d8d5ce5be11410c800035efb14b7166c4fae2a269fe345584a2b1da3b96cb993b1ab9cb7c22821900006bdf6296e2cd89f5c544d3fc68ab094563b4772d973276357396f84504320000d7bec52dc59b13eb8a89a7f85d686b379dcb7112fb2b1462dd8c1884b4a65bfeaf7f2e5c8b3627d815134fef46e32f1c11f964ddc31c50bdb1765904158f13fa5f0000ba166c4fb12a269fdd19d8b6e4fa554c7352fec973594ada02d76083f1be01a5752cd89f63544d3fb933b16dc9f4aa98e6a5fd92e6b295b405aec107e37c034aea59b13ec6a89a7f726762db93e95531cd4bfb25cd652b680b5d820fc6f80695d4b3627d8d5134fee45ad80fd4a90ce65264bc7392c0b4f81167467b8af00ecfaa66c4fb1ba269fdc741c27856287c4f5c963f0f1d77c8181d7acf5312e01f4355cd89f63844d3fb8d0f974959275b2170f9444632e5ee5835a1e10222c0402aac9b13ec7189a7f7191f2e92b24eb642e1f2888c65cbdcb06b43c20445808055593627d8e3134fee323e5d25649d6c85c3e51118cb97b960d68784088b0100aab26c4fb1c6269fdc6408cca376113b8e3f96e8598f25d0e9a7bb4a6d130202f965d89f638d4d3fb8c7119946ec22771c7f2dd0b31e4ba1d34f7694da260405f2cbb13ec71a9a7f718e23328dd844ee38fe5ba1663c9743a69eed29b44c080be597627d8e3534fee31c46651bb089dc71fcb742cc792e874d3dda5368981017cb2ec4fb1c6a69fdc63818dc900dea1b66b13b4bc0ea536cc27660e92d2d20313a5e89f638d5d3fb8c6f31b9201bd436cd62769781d4a6d984ecc1d25a5a406274bd13ec71aba7f718de63724037a86d9ac4ed2f03a94db309d983a4b4b480c4e97a27d8e3574fee31bc52f6d91c273db841a7242f4a91c43badb38bc566018b76f54fb1c6af9fdc637732000ae524ddf33b1b0e868d19e69f561359e6c9031891eb9f638d603fb8c6ed640015ca49bbe676361d0d1a33cd3eac26b3cd92063123d73ec71ac07f718dda5412844169da4fa43900422c5df8a552f9a9f7210c63ebaf7d8e3581fee31bb33437612faa1722003ec6ac50b24f72a09f964a3f18c97b5ffb1c6b04fdc63765686ec25f542e44007d8d58a1649ee5413f2c947e3192f6bff638d609fb8c6eca5cefdd6b7ebf0ab8c7e0d93abf9bf27d2a9b84f963279180ec71ac14f718dd9345f21383d3e098295c87da6d75960cf5017965efc650c702d8e3582aee31bb2517f67fb47e23b30a85d5dcd2e18a41e4af3527dc8ca33206b1c6b056dc6376492fecff68fc4766150babb9a5c31483c95e6a4fb91946640d638d60adb8c6ec925fd9fed1f88ecc2a1757734b86290792bcd49f72328cc81ac71ac15b718dd9244bc65650c7801b0bfb750e8f02b0372025eb9ae1651b34368e3582b7e31bb247239f054e6562b8cfc3b04515fbbe963af81991bfca380c6e1c6b0570c637648d473e0a9ccac5719f87608a2bf77d2c75f033237f947018dc38d60ae18c6ec91a1a8e6de66bed65f6db873c4fe55880e68ca8a2fc28e1d5b971ac15c418dd9233351cdbccd7dacbedb70e789fcab101cd195145f851c3ab72e3582b8831bb24666a39b799afb597db6e1cf13f9562039a32a28bf0a38756e5c6b05710637648cc6085c7e035cdb26ea9000a7721222f2f118773de471051cc8d60ae21c6ec91974d1de86d41fde7951ec63ce638a28658cf5143b98e22479a1ac15c448dd9232d264e29875a5e51e20a52a1c467a334ac4ae4e3701c4633353582b88a1bb246594c9c530eb4bca3c414a54388cf46695895c9c6e0388c666a6b05711437648cb2254afeca3fdbca3ff610af0994eafaabd7d5e9bd711a70d5d60ae2296ec919634a95fd947fb7947fec215e1329d5f557afabd37ae234e1abac15c452dd9232c6213e53d5d5d1abb7a508e41e4a0a12aa0b9a02f2c46b6758582b88a6bb24658b427ca7ababa3576f4a11c83c94142554173405e588d6ceb0b057114d7648cb16110ba8042da9319660e9b8711e8672a2daaa67c811af416260ae229bec91962b221750085b52632cc1d370e23d0ce545b554cf90235e82c4c15c4537d9232c56442ea010b6a4c65983a6e1c47a19ca8b6aa99f2046bd058982b88a6fb24658ac146f98ce43ac0f6ad413eb80ea91bd1181959a3d8d7baf14057114e0648cb15728df319c87581ed5a827d701d5237a23032b347b1af75e280ae229c0c91962ae51be63390eb03dab504fae03aa46f446065668f635eebc5015c453819232c55c2f8f1f1ef3c2fe0e6d6583ff4aec1086b8ef2de96bdf1ca12b88a70424658ab75f1e3e3de785fc1cdacb07fe95d8210d71de5bd2d7be394257114e0848cb156e4a4ed528a56e7af1825c37f5220e6a158fff13a2af7e1685ae229c1191962adb20b002fe213f789ad17e97e23a7afc25cc4083425efdd10c5c453824232c55b5416005fc427ef135a2fd2fc474f5f84b98810684bdfba218b88a70484658ab6a0ed264a55b60652312c08780e04a1891dd4469067bf8e8327114e0918cb156d31da4c94ab6c0ca4625810f01c0943123ba88d20cf7f1d064e229c1231962ada63b4992956d81948c4b021e03812862477511a419efe3a0c9c453824632c55b4c02a57dd7b165abd062ca63fef8aeec899665a430dfc8e59488a7048d658ab697054afbaf62cb57a0c594c7fdf15dd9132ccb4861bf91cb29114e091acb156d2e0a95f75ec596af418b298ffbe2bbb226599690c37f239652229c1235962ada5c152beebd8b2d5e8316531ff7c577644cb32d2186fe472ca44538246b2c55b4b82a57dd7b165abd062ca63fef8aeec899665a430dfc8e59488a7048d658ab697054afbaf62cb57a0c594c7fdf15dd9132ccb4861bf91cb29114e091acb156d2e03571ce992fcd76d07f5f27b622194a6045ab6834f23b092329c1235a62ada5bf6ae39d325f9aeda0febe4f6c443294c08b56d069e4761246538246b4c55b4b7e61d9931195985df9ca42c6d07ec3517bc2effcd0c8edc88da7048d6a8ab696fb4fc57ed001933eab614bb598f3e4caf23222559e91dd351c4e091ad6156d2df52b9d564cd989000e8f5d9329de27bddf1087073a23bc0e399c1235ad2ada5be9573aac99b312001d1ebb2653bc4f7bbe210e0e7447781c7338246b5a55b4b7d23a87b1e03c8682f20a3c749f6efd1f76ee5e78e58ef1dce77048d6b5ab696fa30121bc6d4f6f889be13f1136d45866e888ff4dc81de55dcfe091ad6c56d2df45024378da9edf1137c27e226da8b0cdd111fe9b903bcabb9fc1235ad8ada5be8a0486f1b53dbe226f84fc44db51619ba223fd37207795773f8246b5b15b4b7d14090de36a7b7c44df09f889b6a2c3374447fa6e40ef2aee7f048d6b62b696fa28121bc6d4f6f889be13f1136d45866e888ff4dc81de55dcfe091ad6c56d2df45024378da9edf1137c27e226da8b0cdd111fe9b903bcabb9fc1235ad8ada5be8a0486f1b53dbe226f84fc44db51619ba223fd37207795773f8246b5b15b4b7d1401cf08f548e26d0a86c4ec36222919c3f2be9400bf2b08bf148d6b62c696fa27f39e11ea91c4da150d89d86c44523387e57d28017e56117e291ad6c58d2df44fe73c23d52389b42a1b13b0d888a4670fcafa5002fcac22fc5235ad8b1a5be89fc7396d351479907fb2f3c43090aeb09f40b8c5c5c9586038b46b5b1644b7d13f7733fff4f659492ae2b3eae0a0c343be2c35b14b62b0dab178d6b62c996fa27ed7292574ba18ba8142343840c0ec69fc032f88569561cfa301ad6c5942df44fd9713707441979d2e0134d301013eb677b123366cfac3b986135ad8b295be89fb16e80673509562877f36088181e34f6f0d0a9299c5878d4c36b5b1653b7d13f6169132716e90ed3a7b387382832c815dc4d94af35b0f34d87d6b62ca86fa27ec15e38a6daa8802a0733d498485bee53b3476bba6861e83f10ad6c5951df44fd814883a6622762d6c6346f5888ae3acf613b19d0cdc3d222225ad8b2a4be89fb011d19a5712528304435a4d90952d3c6bd2275fd9887a5e845b5b1654a7d13f6013a334ae24a5060886b49b212a5a78d7a44ebfb310f4bd08b6b62ca94fa27ec020078ee716b0343c8a3598c1d41ad42ef361a525f1e994517d6c5952af44fd80300f1dce2d606879146b3183a835a85de6c34a4be3d328a2fad8b2a55e89fb00601e3b9c5ac0d0f228d66307506b50bbcd869497c7a65145f5b1654abd13f600c03c7738b581a1e451acc60ea0d6a1779b0d292f8f4ca28beb62ca957a27ec018078ee716b0343c8a3598c1d41ad42ef361a525f1e994517d6c5952af44fd80300f1dce2d606879146b3183a835a85de6c34a4be3d328a2fad8b2a55e89fb00601e3b9c5ac0d0f228d66307506b50bbcd869497c7a65145f5b1654abd13f600c03c7738b581a1e451acc60ea0d6a1779b0d292f8f4ca28beb62ca957a27ec01800500ca17d9a64b5b26524539a3a11730c694bb1b9946bbd7c5952af54fd802ff0a01942fb34c96b64ca48a7347422e618d297637328d77af8b2a55ea9fb005fe1403285f66992d6c994914e68e845cc31a52ec6e651aef5f1654abd53f600bfc280650becd325ad9329229cd1d08b98634a5d8dcca35debe2ca957aa7ec017f8500ca17d9a64b5b26524539a3a11730c694bb1b9946bbd7c5952af54fd802ff02c2b9ba80b2bee1c970ecf2c6a810e137ed9bf7028d91ef9b2a55eaafb005fdf585737501657dc392e1d9e58d5021c26fdb37ee051b23df3654abd55f600bfbe3cc0c74d03123b2a290164a9a0626048a7a959bda3661fe7ca957aacec017f7b0593e746dc86f90c1ec8f14b3722e88bfb950f7846cde3d0952af55ad802fef50b27ce8db90df2183d91e2966e45d117f72a1ef08d9bc7a12a55eab5b005fdea164f9d1b721be4307b23c52cdc8ba22fee543de11b378f4254abd56b600bfbd42c9f3a36e437c860f6478a59b917445fdca87bc2366f1e84a957aad6c017f7a8593e746dc86f90c1ec8f14b3722e88bfb950f7846cde3d0952af55ad802fef503e8f41886741a43ba5e4515edabb397a1ee44b05d9be1e13a55eab5c005fde9f0930dbbda4e5cb2f188ecab5abd49aeeea0af208b37de0284abd56b900bfbd3d1261b77b49cb965e311d956b57a935ddd415e41166fbc050957aad72017f7a7a24c36ef693972cbc623b2ad6af526bbba82bc822cdf780a12af55ae402fef4f44986dded272e5978c47655ad5ea4d777505790459bef014255eab5c805fde9e81f20148724bf35a955b2d352b3a7d6e94cf17c8837dfa685abd56b910bfbd3cf3e40290e497e6b52ab65a6a5674fadd299e2f9106fbf4d0b57aad72217f7a79e0892aac9695f595d23917542c4fd839fe0084e1ddf803e17af55ae452fef4f3b11255592d2beb2ba4722ea8589fb073fc0109c3bbf007c2f5eab5c8a5fde9e76224aab25a57d65748e45d50b13f60e7f802138777e00f85ebd56b914bfbd3cec4495564b4afacae91c8baa1627ec1cff004270eefc01f0bd7aad72297f7a79d8153d05436c58188a05dd7c24463661f8acc73ddaf805857bf55ae453fef4f3af2a7a0a86d8b031140bbaf8488c6cc3f1598e7bb5f00b0af7eab5c8a7fde9e75e54f4150db16062281775f09118d987e2b31cf76be01615efd56b914ffbd3cebc35fa82c839234707fbb2091a281137c0127c4ad4c02dcfe0aad722a0f7a79d776bf5059072468e0ff764123450226f8024f895a9805b9fc155ae4541ef4f3aee63fc63cdbaef9ed7bb8e4c6096a306faf633875000b8e383ab5c8a84de9e75db540b20484c41c06743e2c0b923a435f098a96a9d01736b0856b9150abd3cebb53428993d6ee60386548ba96a3da693dbdd95313702e87a11ad722a167a79d7696851327addcc070ca91752d47b4d27b7bb2a626e05d0f4235ae4542cf4f3aed25cb4bda291fa90d11ef4cda0ecf8776a229720d90ba38c47b5c8a85ae9e75da3457bd3f1fa57a45a0aafc339d04f16cef1709daf1748bc906b9150b6d3cebb45170a0090cb11cb6be225ae6b96fc55988f23975b2e931d21d722a16ea79d76892e140121962396d7c44b5cd72df8ab311e472eb65d263a43ae4542dd4f3aed125c2802432c472daf8896b9ae5bf156623c8e5d6cba4c74875c8a85ba9e75da2444625d332ef0de16ddf39b54ae40d4bf255f16d6749a8d0fb9150b763cebb44714d7131334443ee588ad5ea152dfd178f70089a9e936be20722a16ed79d7688d29ae262668887dcb115abd42a5bfa2f1ee011353d26d7c40e4542ddaf3aed11a535c4c4cd110fb9622b57a854b7f45e3dc0226a7a4daf881c8a85bb5e75da23432caf146788479e412311d028d5cb3c26446a94c49b795049150b76ccebb44676595e28cf108f3c824623a051ab96784c88d5298936f2a0922a16ed99d7688ce573e1dc6b8746a48158a9c022bd0f7043d5d012e26dff8134542ddb43aed119b3a8e943a474b5747f7db5ffc4e00160326fc5e594dc194278a85bb6975da2335012f812164f93147bc7ce7f0925e5400fa3b18af9b84cc50150b76d3ebb44669025f0242c9f2628f78f9cfe124bca801f476315f370998a02a16eda7d7688cd204be048593e4c51ef1f39fc249795003e8ec62be6e133140542ddb4faed119a4097c090b27c98a3de3e73f8492f2a007d1d8c57cdc266280a85bb69f5da2334812f812164f93147bc7ce7f0925e5400fa3b18af9b84cc50150b76d3ebb44669025f0242c9f2628f78f9cfe124bca801f476315f370998a02a16eda7d7688cd204be048593e4c51ef1f39fc249795003e8ec62be6e133140542ddb4faed119a4023d2e95f52fb26960b3a204125882877c9ceb3cac267cc0b85bb69f6da23347f47a5d2bea5f64d2c167440824b1050ef939d679584cf98170b76d3edb44668fe1b5dfe2a224f1d0ff9aea8fc8c7ec9d9d37d2b2809a0d42f16eda7dc688cd1fb36bbfc54449e3a1ff35d51f918fd93b3a6fa56501341a85e2ddb4fb8d119a3f66d77f8a8893c743fe6baa3f231fb27674df4aca0268350bc5bb69f71a23347ec670249fde8db6b379a3b6fdc5a5476c9482bb53d4d084579b76d3ee444668fd75a16eca8a8195927013d07b0ab07158d3c99c6779a122ef46eda7dc988cd1fad404031fe26953505cf4037594c6c53152575e8ec342601e9ddb4fb94119a3f590c92bca9238cecc36b4696aa8f36ce24f72e2dd5684da7d4bb69f72923347eb1192579524719d986d68d2d551e6d9c49ee5c5baad09b4fa976d3ee524668fd62324af2a48e33b30dad1a5aaa3cdb3893dcb8b755a1369f52eda7dca48cd1fac46495e5491c67661b5a34b55479b67127b9716eab426d3ea5db4fb94919a3f588553e233f0f314eee812f92a0e9cb0a4a1f25395384dc214cb69f72933347eb0f368e9f2af4c52094cf254d39c9f43c8eea8ccea409b9e69a6d3ee527668fd61d6d1d3e55e98a41299e4a9a7393e8791dd5199d481373cd34da7dca4ecd1fac3a664cd558a977050b095b5cdf1e2f1a365675968d26e93e6ab4fb949e9a3f587358ac035e29508ccddf7ce1b632bc5c67592d89174dd420d669f7293e347eb0e53d6a5f6929039c538bbfeb645bd6e0c95e9d6e2b9ba9e5add3ee527d68fd61c906e7177f2869bb5ee445fec0ae0be98d697d385437556f5ca7dca4fbd1fac3910dce2efe50d376bdc88bfd815c17d31ad2fa70a86eaadeb94fb949f7a3f587221b9c5dfca1a6ed7b9117fb02b82fa635a5f4e150dd55bd729f7293ef47eb0e443738bbf9434ddaf7222ff605705f4c6b4be9c2a1baab7ae53ee527de8fd61c886e7177f2869bb5ee445fec0ae0be98d697d385437556f5ca7dca4fbd1fac391068f54891e399ee945586000db7db59a7dbe96683eaaf8f95fb949f7b3f58721f5dfce9d09d965fe077d228136614db4a64152904d560c32cf7293ef77eb0e43d480c2c4e118f4278bc6a781ec287de8f746cae06aac32a5aee527deffd61c8791c2ab148f98107a9459b18357b6de519951bb80a5587f8b6dca4fbe0fac390f138556291f3020f528b36306af6dbca332a377014ab0ff16db949f7c1f58721e270aac523e6041ea5166c60d5edb79466546ee029561fe2db7293ef83eb0e43c46d67e2f4a26ac001f99ee9a3d1cd50c755201c4fac4169b7e527df08d61c878766e21e961b3802bbc003fb3f99f8c9895682949c58847770ca4fbe12ac390f0d59d695d90cd2882f4cce1e772a4fbb0d59478535b10a92e2949f7c2658721e193fbf845ef0079316666264e64afd9e155ed166686216c9c6293ef84db0e43c310b91616ab671a8e4998af1c48c59642569e528cdc42f378d527df09c61c878611722c2d56ce351c93315e38918b2c84ad3ca519b885e6f1aa4fbe138c390f0c22e4585aad9c6a392662bc71231659095a794a33710bcde3549f7c2718721e1845c8b0b55b38d4724cc578e2462cb212b4f29466e2179bc6a93ef84e30e43c30845286f583d7d110165754440bbf46a514a94e8d942f51cd627df09c71c87860f1663375d515ca4ba97b0b0796e46fc9d416c2daf85ebddad4fbe138f390f0c1d2cc66ebaa2b949752f6160f2dc8df93a82d85b5f0bd7bb5a9f7c271e721e183a598cdd75457292ea5ec2c1e5b91bf27505b0b6be17af76b53ef84e3ce43c30743f2c13976147a88c8a4babc368960ce4b7a3c9792f60916b7df09c7ac87860e70a6a7fdb98f1d3d0e15d7f7ec78a41c41b89eeef5ec2c6d7fbe138f690f0c1cd14d4ffb731e3a7a1c2bafefd8f1483883713dddebd858daff7c271ed21e1839a29a9ff6e63c74f438575fdfb1e2907106e27bbbd7b0b1b5fef84e3da43c307345353fedcc78e9e870aebfbf63c520e20dc4f777af61636bfdf09c7b487860e6832ba5666657fbfc5e29e1fe46f02443c64e14af2ec2e1180be138f6a0f0c1ccf6574accccaff7f8bc53c3fc8de048878c9c295e5d85c23017c271ed41e18399e56fbb2466c6181cf573ea789b26738ec3fc787c8b0b9ea03f84e3da93c30733b3a09bd39af2586567b43770b5b2c99d32bd16b8e61757808f09c7b537860e6750025d32034ad8f64c34d160eacb75ba103e53319c2ec9412e138f6a7f0c1cce9004ba640695b1ec9869a2c1d596eb74207ca663385d92825c271ed4fe18399d200974c80d2b63d930d34583ab2dd6e840f94cc670bb2504b84e3da9fc30733a4012e9901a56c7b261a68b07565badd081f2998ce1764a09709c7b53f860e6748025d32034ad8f64c34d160eacb75ba103e53319c2ec9412e138f6a7f0c1cce9004ba640695b1ec9869a2c1d596eb74207ca663385d92825c271ed4fe18399d200974c80d2b63d930d34583ab2dd6e840f94cc670bb2504b84e3da9fc30733a4012e9901a56c7b261a68b07565badd081f2998ce1764a09709c7b53f860e6748025d32034ad8f64c34d160eacb75ba103e53319c2ec9412e138f6a7f0c1cce9004ba640695b1ec9869a2c1d596eb74207ca663385d92825c271ed4fe18399d200235ed97f8ca015c5011e62aad3ccac0a410ec308b251ef85e3da9fc40733a3ff46bdb2ff19402b8a023cc555a7995814821d861164a3df0bc7b53f880e6747fe198dbeab08e2d9cbd13fb2a34590d823b07d681fc94962188f6a7f111cce8ffb331b7d5611c5b397a27f65468b21b04760fad03f9292c4311ed4fe22399d1ff66636faac238b672f44feca8d1643608ec1f5a07f252588623da9fc44733a3fec58804e051d79511656c3bd1222e4e918302d9cfb4a4cb4c57b53f889e6747fd73d12f4b7115524e47a4da21c3c27fa2b0c9d95f3949b0d8bf6a7f114cce8ffad0638421af90ccc80c1616c306eae1c50c57d87e42937bf18ed4fe22a99d1ff590c708435f219990182c2d860dd5c38a18afb0fc8526f7e31da9fc45533a3feb218e1086be43332030585b0c1bab8714315f61f90a4defc63b53f88aa6747fd6431c210d7c86664060b0b61837570e2862bec3f2149bdf8c76a7f1154ce8ffac8638421af90ccc80c1616c306eae1c50c57d87e42937bf18ed4fe22a99d1ff590531a9c0bf7fc12cff8f3ae05cc21b2135bf3588226f9871ea9fc45543a3feb1f324790c4c65aa857bead84038ea18c2164290d014df4b23e53f88aa9747fd63d648f21898cb550af7d5b08071d431842c8521a029be9647ca7f11552e8ffac7a55309bbfefcd2416c77c380630e458803ce6900237d46cfa4fe22aa6d1ff58f33673902cb5fccae55bbe98045826d8fb260f7c016faa7df59fc4554ea3feb1e56ce720596bf995cab77d3008b04db1f64c1ef802df54fbeb3f88aa9d47fd63ca65e0995fae55ae4d3bc0880956f98be744804c02beab9bd77f11553b8ffac79357d38b6c330ddf524447380aa4513fc93542f4027d58dbaffe22aa781ff58f253bb96f853c7e415c5554980d3f00a78d16c84401fab35b60fc4554f13feb1e49038537b74f5f0570776f5812745f7714d9d2e400f5685ac2f88aa9e37fd63c91070a6f6e9ebe0ae0eedeb024e8beee29b3a5c801ead0b585f11553c6ffac79220e14dedd3d7c15c1ddbd6049d17ddc53674b9003d5a16b0be22aa78dff58f2441c29bdba7af82b83bb7ac093a2fbb8a6ce972007ab42d617c4554f1bfeb1e48838537b74f5f0570776f5812745f7714d9d2e400f5685ac2f88aa9e37fd63c91070a6f6e9ebe0ae0eedeb024e8beee29b3a5c801ead0b585f11553c6ffac792206d604680ae23ded5a89c2c950e3bed3120fb5c3a5a1854bf22aa78e0f58f243f66d2e5ae32aa40631dfe812212d6025cee391471b4324d7f4554f1c2eb1e487d59b824093bb7037e08c32a3c1c0a2cb488b484e068663eff8aa9e386d63c90f93f82a0bf4dd089b3de4c7c702e728163bdab65bdd0ce22001553c70eac7921f10b179a2b7203961f895f20d853432ac227992778a19de8012aa78e1e58f243e1162f3456e4072c3f12be41b0a68655844f324ef1433bd002554f1c3cb1e487c22c5e68adc80e587e257c83614d0cab089e649de28677a004aa9e387963c90f8458bcd15b901cb0fc4af906c29a1956113cc93bc50cef4009553c70f2c7921f083d8bfb63f69be4b062b8357d2a90d41d25d4d38719e02413aa78e1e68f243e0f072a4f74c39a4c18923692f24b7fd034f7ec030b33c1ec2854f1c3ce1e487c1d0e549ee987349831246d25e496ffa069efd806166783d850a9e3879c3c90f83a1ca93dd30e69306248da4bc92dff40d3dfb00c2ccf07b0a153c70f387921f07439527ba61cd260c491b497925bfe81a7bf6018599e0f6142a78e1e70f243e0e872a4f74c39a4c18923692f24b7fd034f7ec030b33c1ec2854f1c3ce1e487c1d0715c474549ac05ca1398864166582e99a9c2bd63783f290b9e3879c4c90f839f6ecae73769ba8e4bf3f7347ac30e852dffc7d6c3f07ff6183c70f38a921f073d69a8271ba9d79f4fb4b490ed7c7b3256abd20984e101903178e1e716243e0e795f62a6e42a11c157362f49d2ef548ca803e66f06c204c463f1c3ce2d487c1cf14ad7a6752a8605663924bb9dd507414ab40f3a0a840b2cc8e3879c5b90f839e121c1a5972b6e8d843f0f9f33a06caa901460d0120817fd92c70f38b821f073c143834b2e56dd1b087e1f3e6740d9552028c1a024102ffb258e1e717043e0e7821318ef09841cb8c8c904a4c67810d23afdc59c4520619a4c1c3ce2e187c1cf032631de13083971919209498cf021a475fb8b388a40c334983879c5c30f839e064c63bc261072e32324129319e04348ebf71671148186693070f38b861f073c0c24d9d0f8f74848fe14eb4e2bb6e4b9d29a6f3e26030e7661e1e7170d3e0e781749b3a1f1ee9091fc29d69c576dc973a534de7c4c061cecc3c3ce2e1a7c1cf02e1f799c90b383a6b0207360a6d1f10f4515ff54950c3b7d88879c5c35f839e05b3ef3392167074d6040e6c14da3e21e8a2bfea92a1876fb110f38b86bf073c0b609f8caefa4711d784e93aa933e22650f043fae5130ef9a231e7170d8e0e7816b13f195df48e23af09d2755267c44ca1e087f5ca261df34463ce2e1b1c1cf02d627e32bbe91c475e13a4eaa4cf889943c10feb944c3be688c79c5c363839e05ac4fc6577d2388ebc2749d5499f113287821fd7289877cd118f38b86c7073c0b582b9f07a71d745a3cb600d12bd88478eaf03d41100efb4632e7170d8f0e7816af573e0f4e3ae8b4796c01a257b108f1d5e07a82201df68c65ce2e1b1e1cf02d5e3a8e77494c33ebaaa4c96ca758700ba66d37603d3beebccc9c5c363d39e05abb012f473f6eca5a0d16590146a73e3f4786b11c7777df1d9a38b86c7b73c0b575025e8e7edd94b41a2cb2028d4e7c7e8f0d6238eeefbe3b347170d8f6e7816aea04bd1cfdbb2968345964051a9cf8fd1e1ac471dddf7c7668e2e1b1edcf02d5d4097a39fb7652d068b2c80a3539f1fa3c3588e3bbbef8ecd1c5c363db9e05aba812f473f6eca5a0d16590146a73e3f4786b11c7777df1d9a38b86c7b73c0b575025e8e7edd94b41a2cb2028d4e7c7e8f0d6238eeefbe3b347170d8f6e7816aea04bd1cfdbb2968345964051a9cf8fd1e1ac471dddf7c7668e2e1b1edcf02d5d4023b5f8643b8f8942f946cb4b957dcbbe04d097b8ef90711d5c363dbae05aba7f476bf0c8771f1285f28d96972afb977c09a12f71df20e23ab86c7b75c0b574fe1aea3a3dc4a0a7c3b1e155264c5556f2bf84bae0be43687670d8f6ec816ae9fb35d4747b89414f8763c2aa4c98aaade57f0975c17c86d0ece1b1edd902d5d3f66ba8e8f712829f0ec785549931555bcafe12eb82f90da1d9c363dbb205aba7ec63642a9afb67c0d55bd0d12a5908df90a8683302f21ce7b486c7b7650b574fd752daade2cd3204628467ca4ca86fe71bfd12c202e43b736a0d8f6ecb16ae9fad31c7b47270c68b7cd595bc91473df632a667e002c8788ad51b1edd972d5d3f59638f68e4e18d16f9ab2b79228e7bec654ccfc00590f115aa363dbb2e5aba7eb253312a76997cb0ab231d1a3d135600c545e1dc0821e3cf556c7b765db574fd633274ad9a095be40e13005c721d0a29853806140d43c942abd8f6ecbc6ae9fac564e95b3412b7c81c2600b8e43a14530a700c281a87928557b1edd978d5d3f58a55e50f14fbd212f018c799c06a86ce0f8c5aac320f26aeb063dbb2f2aba7eb1337dc76d6ce06a897fe555b78cb6bc419c4f7b4611e4f0161c7b765e6574fd6256fb8edad9c0d512ffcaab6f196d7883389ef68c23c9e02c38f6ecbccae9fac4a6b8434080e7d2517c61b95db240d3861c0212d81793da9881edd979a5d3f5893631ac0bcf35ccce758fd53ae3e7898be2c84b6fff27cf7113dbb2f35ba7eb1255247da26bd1c1c867ec0cf54734f5977054bc9fce4fb92237b765e6c74fd624930a20cfa509abbc4ca47c6a0dcfcdae8b6d9eff6c9f8c847f6ecbcd9e9fac491614419f4a1357789948f8d41b9f9b5d16db3dfed93f1908fedd979b3d3f589224e9a8c9618cd71caf5e5427b6a51939d87aa1bd827e4c520dbb2f368a7eb1243294771d907fd664db890aceecb014f35bb9693ad4fcb2e42b765e6d24fd62485528ee3b20ffacc9b712159dd96029e6b772d275a9f965c856ecbcda49fac490a31302010f6581beeaf08dbb3226364d19a9caab23f2e5d0bdd979b4a3f58921362604021ecb037dd5e11b76644c6c9a3353955647e5cba17bb2f36947eb1242650d2d8f0afc2f27288e996c47febbb4116b506c5fcbb1830765e6d29fd62484b2db80a8e35e8679cde995580f6359e7cd9ac6988f977d461ecbcda54fac490955b70151c6bd0cf39bd32ab01ec6b3cf9b358d311f2efa8c3d979b4a9f589212a42f282e5ae04212b472b7dfbcf34a1ee12f40220e5e0f588b2f36954eb12425311f75e78326ac50e5b1d23ef94c76bd6d22a603ecbc38f1265e6d2aad62484a523eebcf064d58a1cb63a47df298ed7ada454c07d97871e24cbcda555ac49094a47dd79e0c9ab14396c748fbe531daf5b48a980fb2f0e3c49979b4aab589212941bcd4c6e69b8ab2aa5af47749c9986b13d955df35e1e1c942f369557b1242527379a98dcd37156554b5e8ee939330d627b2abbe6bc3c39285e6d2aaf62484a4e6f3531b9a6e2acaa96bd1dd272661ac4f65577cd78787250bcda555ec490949c6a7cbc202427dc0cfa40639cdb2a5d8498ed4b97f0f288a279b4aabe89212937610bd0ed1eb23ad1c146ef31acb2e303de1cf32ce1e6b545f369557e1242526d4e29fa8713c6f85b4f54065b4fc3ee02687c4256c3cf0e8ce6d2aafd2484a4d928664dbafdf0736e6b6e34ae95e603ff7d3ae0aa879fc11acda555fb490949b150cc9b75fbe0e6dcd6dc695d2bcc07fefa75c1550f3f82359b4aabf6921293622dab8f98ce2450717a7efab24df637f8a12ddea71e80a86c369557ee242526c35b571f319c48a0e2f4fdf5649bec6ff1425bbd4e3d0150d86d2aafdc484a4d8642c097100ef3c47db6c212c12e3707dd30f9d6997a0445b1da555fb990949b0b119386ccf44a0bb33a4a4d7a52cc37b50e36092ff40a2f64b4aabf742129361523270d99e894176674949af4a5986f6a1c6c125fe8145ec969557ee842526c2a464e1b33d1282ecce92935e94b30ded438d824bfd028bd92d2aafdd084a4d85418ae8f1478b2e0519f1893ca8cbfe5a31df2a57ca0531f26a555fba20949b0a7315d1e28f165c0a33e312795197fcb463be54af940a63e4d4aabf7441293614e62ba3c51e2cb81467c624f2a32ff968c77ca95f2814c7c9a9557ee882526c29c5186d1509bf98544c58ac64c5c5d55139bd787e2029a9d362aafdd114a4d85372f1ffb4e0e558d4157dbb490af18d221e3f16bc10536de6d555fba23949b0a6d5e3ff69c1cab1a82afb769215e31a443c7e2d7820a6dbcdaaabf7447293614da489245e50fb8b7bd2c34fa3ab2c170823c080b0114dd1db6557ee88f526c29b31d36e476f5d3f23225301c6d5be108ff245271ff29bbdf6daafdd11fa4d853653a6dc8edeba7e4644a6038dab7c211fe48a4e3fe5377bedb55fba23f49b0a6ca00edea88adb24b80618699ad65e24bf73d8c23f9a6f121b7abf7447f93614d9301dbd5115b649700c30d335acbc497ee7b1847f34de2436f57ee88ff26c29b2603b7aa22b6c92e01861a66b597892fdcf6308fe69bc486deafdd11fe4d85364c076f54456d925c030c34cd6b2f125fb9ec611fcd37890dbd5fba23fc9b0a6c980edea88adb24b80618699ad65e24bf73d8c23f9a6f121b7abf7447f93614d9301dbd5115b649700c30d335acbc497ee7b1847f34de2436f57ee88ff26c29b2603b7aa22b6c92e01861a66b597892fdcf6308fe69bc486deafdd11fe4d85364c003079d03af8842e89012feaae7842399725458d078927fd6fba23fcab0a6c97f060f3a075f1085d12025fd55cf084732e4a8b1a0f124ffadf7447f95614d92fe0c1e740ebe210ba2404bfaab9e108e65c9516341e249ff5bee88ff2ac29b25fc183ce81d7c4217448097f5573c211ccb92a2c683c493feb7dd11fe5585364bf83079d03af8842e89012feaae7842399725458d078927fd6fba23fcab0a6c97f060f3a075f1085d12025fd55cf084732e4a8b1a0f124ffadf7447f95614d92fe04df99998b8733cdbd185d2b1d7670e574158901b24a199bfe88ff2ad29b25fbf28058bde4748fc6f6fd1cd5ba52c44a92ef37c334944d780d11fe55b5364bf7d500b17bc8e91f8dedfa39ab74a5889525de6f8669289af01a23fcab6a6c97efa2c288825f38674758c0d5d668b0f3a9f68104cca25150204447f956e4d92fdf35851104be70ce8eb181abacd161e753ed02099944a2a040888ff2adc9b25fbe63cb47944a47c548dfcfb9d92229b12784c838f259455ac1211fe55ba364bf7cb057b4b361f5b2bd3c6bd631c3b944ceb45497a4828acfc2523fcab756c97ef950af6966c3eb657a78d7ac638772899d68a92f4905159f84a47f956ead92fdf2a15ed2cd87d6caf4f1af58c70ee5133ad1525e920a2b3f0948ff2add5b25fbe542bda59b0fad95e9e35eb18e1dca2675a2a4bd2414567e1291fe55bab64bf7ca857b4b361f5b2bd3c6bd631c3b944ceb45497a4828acfc2523fcab756c97ef9503b7bbf70c1c7fd30a4728b7f68e7c5635571a50215a128a57f956eae92fdf29f0309d78e59f27d1915ab3ef6c82db2c15725a6012b43f54bff2add5e25fbe53d0613af1cb3e4fa322b567ded905b6582ae4b4c025687ea97fe55babc4bf7ca7a0c275e3967c9f46456acfbdb20b6cb055c969804ad0fd52ffcab757897ef94f4184ebc72cf93e8c8ad59f7b6416d960ab92d30095a1faa5ff956eaf12fdf29e8309d78e59f27d1915ab3ef6c82db2c15725a6012b43f54bff2add5e25fbe53d0613af1cb3e4fa322b567ded905b6582ae4b4c025687ea97fe55babc4bf7ca7a04e883c435301c8fd3795e5aa01cad85075abdc47d0fef700cab7578a7ef94f3f2922d1337c6614b23bf1f34bf9f3d89b979a148ca1ff9202956eaf15fdf29e7d5245a266f8cc296477e3e697f3e7b1372f34291943ff24052add5e2bfbe53cfa309d9d7ac7fad580bc8df527de2d8a690aaaae2f87ffec0b55babc58f7ca79f3613b3af58ff5ab01791bea4fbc5b14d215555c5f0fffd816ab7578b1ef94f3e64e88ce97f64dd8babefdfc976f14519ed6ed14bb2001542e56eaf164df29e7cb2923f5dcc2fe342d4ac22126d486cb385a1c857340044c5dadd5e2cabe53cf955247ebb985fc685a9584424da90d9670b4390ae6800898bb5babc5957ca79f2a30a2301fe25b536cf7ceac93487954dc14b471ca0012d577b7578b2bf94f3e536144603fc4b6a6d9ef9d592690f2a9b82968e3940025aaef6eaf1657f29e7ca64e9b192c5fcfd06bac00da4518437b6aff142325004cf9dfdd5e2cb0e53cf94b29488b059602238f24c7dc8226e51ed0aa6aa247009b97c0babc5962ca79f2955291160b2c04471e498fb9044dca3da154d5448e01372f817578b2c594f3e52a313484c32e6b10f45fe59a0091f2a33d55ece51902700303eaf1658c29e7ca53626909865cd621e8bfcb340123e5467aabd9ca3204e00607d5e2cb1853cf94a650e46bb9900ec6894c5c8ffa3e28b4f003f5f06109c1b010abc59631a79f294b2ddb301ff6800fca657f47ec72af91dab42e3cbf13850422578b2c644f3e52955bb6603fed001f94cafe8fd8e55f23b5685c797e270a0844af1658c89e7ca52a437f192cb062c1e162c347a9c11c6f657cfb4ef94e15b48a5e2cb1923cf94a5313108b063728067a924cb74b789706c5a638f9ef9c2d0d15bc59632579f294a52621160c6e500cf524996e96f12e0d8b4c71f3df385a1a2b78b2c64af3e5294a4c422c18dca019ea4932dd2de25c1b1698e3e7be70b43456f1658c95e7ca52942496b0de8fa2b68c5f2be253bb165e27de0a2b79e16a0caee2cb192ccf94a527492d61bd1f456d18be57c4a7762cbc4fbc1456f3c2d4195dc59632599f294a4e1e6d1c2714ed5ce94975b146e2b7a09a246b09e485a9d6bc8b2c64b43e52949b3cda384e29dab9d292eb628dc56f413448d613c90b53ad791658c9687ca5293605c6c9492a17f65cf29ced13813caa633dee838f16a8fef32cb192d1f94a526b0b8d9292542fecb9e539da27027954c67bdd071e2d51fde6596325a3f294a4d6171b2524a85fd973ca73b44e04f2a98cf7ba0e3c5aa3fbccb2c64b47e52949ac2e364a4950bfb2e794e7689c09e55319ef741c78b547f799658c968fca5293585c6c9492a17f65cf29ced13813caa633dee838f16a8fef32cb192d1f94a526b044eb81d219614e562063ca681df374626a12cddfd521826696325a40294a4d5f15e95c5109251f640d8dbcc8324510bf8067f7bcaa44a8ce2c64b48152949abd2bd2b8a2124a3ec81b1b7990648a217f00cfef795489519c58c96902a529357a57a5714424947d903636f320c91442fe019fdef2a912a338b192d2054a526af43b5d3b351f8b7dd839340e398886adf6af8219e25226ea726325a40b94a4d5e702cccf1715797e683f2e446b076b83e80b468fc1a44f78e5c64b48182949abcd05999e2e2af2fcd07e5c88d60ed707d0168d1f83489ef1cb8c9690305293579a0b333c5c55e5f9a0fcb911ac1dae0fa02d1a3f06913de397192d2060a526af34166678b8abcbf341f97223583b5c1f405a347e0d227bc72e325a40c14a4d5e682cccf1715797e683f2e446b076b83e80b468fc1a44f78e5c64b48182949abcd05999e2e2af2fcd07e5c88d60ed707d0168d1f83489ef1cb8c9690305293579a03f461e7234c21cc7985742b9d13f21fd7de64c6613dfdd7292d2060b526af33f0a9e95913fe6bc46fd74ad6b98dc6bf5a80ef4c927c15ee625a40c17a4d5e67d153d2b227fcd788dfae95ad731b8d7eb501de9924f82bdcc4b48182f49abccfa2a7a5644ff9af11bf5d2b5ae6371afd6a03bd3249f057b989690305e935799f454f4ac89ff35e237eba56b5cc6e35fad4077a6493e0af7312d2060bd26af33e835fbb1c0d4ce4727a410feb18424e7552d31a88f7c1792635a40c17b4d5e67cf6bf76381a99c8e4f4821fd630849ceaa5a63511ef82f24c6b48182f69abccf9e64011fb0299b9f565d0a22be06f1c54f6108fe3af05fed8e690305ee35799f3b5414980d2999c16486da6d740441b2996e545872e0c17f1dd2060bdd6af33e75343b88c729960580da7b02dffee18d2d88eb0ce2c184a23ca40c17bbd5e67ce96877118e532c0b01b4f605bffdc31a5b11d619c58309447948182f77abccf9d25d007bc97cba98bb36b23377f1e45cb0cfee8f8806142cf390305ef05799f3a34613503fcfd7b42e3a2a8ee7da26e15c4c1f7b0d0c29fde82060bde1af33e7451838f92c7611eb14411b45c7aaabeab34481521718559fd140c17bc45e67ce893071f258ec23d62882368b8f5557d5668902a42e30ab3fa28182f788bccf9d1260e3e4b1d847ac51046d171eaaafaacd1205485c61567f450305ef11799f3a244dda221086f1db59d5a056354bbd7d94d04cecb5c2aea28b060bde23f33e744727c69ccde446396b7806d4628dd923244cdc3568855ee9170c17bc48e67ce88d4f8d399bc88c72d6f00da8c51bb2464899b86ad10abdd22e182f7891ccf9d11a2b2ccbe4677b6865ace179822dc2b48bdfb3319f157d485d305ef12499f3a233565997c8cef6d0cb59c2f3045b856917bf66633e2afa90ba60bde24933e7446638c5883e7450244e804c0e00ad68fa2a2b0f227955f6c575c17bc49367ce88cb718b107ce8a0489d00981c015ad1f454561e44f2abed8aeb82f78926cf9d11966f2879a6a7a313f1cdf65ffaac0210a3587ee5e257dcb9d805ef124e9f3a232b6a634bfa25a8aa9b68b2e7ed4e6249415d4027c1afbb17b10bde249e3e74465560d8f0a121b3d7ee9e2bf7d29322ba7d66c2ab805f77d36317bc493d7ce88ca94dc439ef19ca3295091e179d1ca39cf579c7b2fdbef14ac72f78927bf9d11951279acc8b09f6e7e1df0257322fa561e59fd1c1f87de4398f5ef124f8f3a232a14f35991613edcfc3be04ae645f4ac3cb3fa383f0fbc8731ebde249f1e74465422a7d8ad8fe3e223f48cf84c0b4f3af912b8963def7928a3e7bc493e4ce88ca8354fb15b1fc7c447e919f098169e75f225712c7bdef25147cf78927c99d11950636088410cf5b0bb4f0043afaca2ce63f5a67eb78de4bccfaef124f943a232a0b6c1108219eb61769e00875f59459cc7eb4cfd6f1bc9799f5de249f2874465416643468f013ceb18b8cd713e31f11c0f815e209e07930d7ecbc493e51e88ca82b547b2a8cfdffe5cee6744fbe3481a9ead8066fbdf26353da78927ca4d11950553508adc6d2624e5599aec7745f617bd05c4f3b78e4c84bb5f124f94aa232a0a96a115b8da4c49cab335d8ee8bec2f7a0b89e76f1c990976be249f2954465415260350fc81febbc0e338145c973e4173c1d7f49e09322d2d8c493e52b88ca82a34c7c783d1639fad433c8b38ade265672e740efbe264749b28927ca5811950545250b492702d6786034578f0db2aad4e07ac43b794c903766124f94b1232a0a894a16924e05acf0c068af1e1b6555a9c0f58876f299206ecc249f296246541512203f7d48e1bc64389e24642ec1097b7c975349e232428199493e52c58ca82a23407efa91c378c8713c48c85d8212f6f92ea693c464850332927ca58b195054460d104dd05d54139a4557b8b2fa8415ed098f8385c90baa6624f94b1732a0a88b1a209ba0baa827348aaf7165f5082bda131f070b921754cc49f2962e654151163441374175504e69155ee2cbea1057b4263e0e17242ea99893e52c5cca82a22c68826e82eaa09cd22abdc597d420af684c7c1c2e485d533127ca58b9950544585d1735b2aba3bc5c2241b3279e9f86cb453a945990bc4a634f94b1742a0a88af4640c4122da9fb7011498e47339d359136b784b0217a38c79f2962e95415115d1893e0d131b67997ef5944865d98931d19b1655d42f615903e52c5d3a82a22b93127c1a2636cf32fdeb2890cbb31263a3362caba85ec2b207ca58ba750544572624f8344c6d9e65fbd65121976624c7466c595750bd85640f94b174ea0a88ae450b15f3664164f7747904c2ae322c0e379cd86e717b25082f2962e9e415115c72d7517199e8f21a65be6c04dbca3a9c19fdd69cb2f664506e52c5d3d82a22b8d5aea2e333d1e434cb7cd809b794753833fbad3965ecc8a0dca58ba7b0544571a41e6b513509f09513c61292ee8eccf012bb80329bd9ab81c94b174f70a88ae330fdfc2d377a0955a45887a55c837c5fd03b262507b37143a2962e9ef15115c651fbf85a6ef412ab48b10f4ab906f8bfa0764c4a0f66e287452c5d3de2a22b8ca3f7f0b4dde8255691621e95720df17f40ec98941ecdc50e8a58ba7bc544571940b106f4893672d89f909faa6381c57e2c9d56e80d9ba45d24b174f79a88ae3271620de9126ce5b13f213f54c7038afc593aadd01b3748ba4962e9ef35115c64e2c41bd224d9cb627e427ea98e0715f8b2755ba0366e917492c5d3de6a22b8c9c58837a449b396c4fc84fd531c0e2bf164eab7406cdd22e9258ba7bcd445719383d194d360cd55b575d65d25b7823a6274999440a9ba60125b174f79b88ae326f0644f318f00d39668791ccaee6a574493f74e412374da64c62e9ef38115c64dd0c89e631e01a72cd0f23995dcd4ae8927ee9c8246e9b4c98c5d3de7022b8c9ba1913cc63c034e59a1e4732bb9a95d124fdd39048dd3699318ba7bce045719374322798c78069cb343c8e6577352ba249fba72091ba6d3263174f79c08ae326e8644f318f00d39668791ccaee6a574493f74e412374da64c62e9ef38115c64dd054b0bbcad809af88beffbdd4cb0cb1229adede43e9b66d8d5d3de7032b8c9b9f3573d0428675e1c94ac5a3a18c778a3fe2001884d36e7f1bba7bce075719373d6ae7a0850cebc392958b474318ef147fc4003109a6dcfe3774f79c0eae326e7a61e199b6f03a09dcf7dcb67e283c50fa3442be104dbba06fe9ef381e5c64dcf34fd58c1ab6d69671bc7f94f446d6c9ef14c7d81d9b78e4e0d3de703db8c9b9e52bbd70e2440faf9b45c551e0840bbbd8d5d20c3836f36dc2a7bce07c719373c9577ae1c4881f5f368b8aa3c1081777b1aba418706de6db854f79c0f8e326e7923b081c35e6a14124e3db6f7a068d175e038a8cdddbcf5b0b9ef381f2c64dcf2302229118a3a50501947d06ec037856b6b35775b8b7a05a183de703e68c9b9e4504452231474a0a0328fa0dd806f0ad6d66aeeb716f40b4307bce07cd19373c8a088a44628e94140651f41bb00de15adacd5dd6e2de816860f79c0f9a326e7914111488c51d28280ca3e837601bc2b5b59abbadc5bd02d0c1ef381f3464dcf2282229118a3a50501947d06ec037856b6b35775b8b7a05a183de703e68c9b9e4504452231474a0a0328fa0dd806f0ad6d66aeeb716f40b4307bce07cd19373c8a014b69ed5bfa3c31cec07e2f8d473d5a7821fca2ae8182a1079c0f9a426e7913f296d3dab7f478639d80fc5f1a8e7ab4f043f9455d0305420f381f3484dcf227e52da7b56fe8f0c73b01f8be351cf569e087f28aba060a841e703e6909b9e44fc31c74f5ad3809b9f2d053fbe99fcd536bd40ad5440c2f484ce07cd22373c89f7638e9eb5a701373e5a0a7f7d33f9aa6d7a815aa88185e9099c0f9a446e7913ee532f96182464f13480db26f25e517cd5a145114e030d7614381f3489dcf227db327184dd1f2c6520ce7c75dcb30121a5eecc7e99061c9029703e6914b9e44fb564e309ba3e58ca419cf8ebb96602434bdd98fd320c392052e07cd22973c89f6a55d86c215314173b06b7ff6ac262ae92677456611873e4a6c0f9a453e7913ed337c330ef7c8ab12dda3626cd7b23851f7b2b08bf30e96d4e81f348a8cf227da56f8661def915625bb46c4d9af6470a3ef656117e61d2da9d03e691519e44fb4a6b1f1c6ac88d476f359ec32de2ec3c7898ee7ef9c3a7593b07cd22a43c89f69362509182677d11963803ae53bc36a0ebde1f59f0875056770f9a45497913ed2550b37bb1a55ca5e43ccd849f6ecb69d268810fde0ea250ef1f348a93f227da492d795010211bce8046613136d3f4fb9f7d447bb91d4645df3e691528e44fb4915af2a02042379d008cc2626da7e9f73efa88f7723a8c8bbe7cd22a51c89f692241f798ed5ad1bcb8e64aecd346321678a1544ae1751abb7df9a454a4913ed24310018a878c05fc29995c019e82c254ebeeeaf1bfea371afcf348a94a227da4852003150f180bf85332b8033d0584a9d7ddd5e37fd46e35f9e691529444fb490a40062a1e3017f0a66570067a0b0953afbbabc6ffa8dc6bf3cd22a52889f692140c1eace93692640497a634ec0c70cf5a2399e9fc51ba7be89a454a5213ed2427183d59d26d24c8092f4c69d818e19eb44733d3f8a374f7d1348a94a427da484e307ab3a4da4990125e98d3b031c33d688e67a7f146e9efa2691529484fb4909c60f56749b4932024bd31a76063867ad11ccf4fe28dd3df44d22a52909f6921384dfd27403f88c301472976b8bd6b1d9ce5e0fbc21ba9628aa454a5223ed2426f280ca72d557408ba5b19156971346334780453813754691648a94a457da484dd50194e5aaae81174b6322ad2e268c668f008a7026ea8d22c9152948afb4909ba2c44f5622c32a5a1392a7d9dbb2fb4cc8c53aa01dd53485a22a52916f69213735889eac458654b427254fb3b765f699918a75403baa690b4454a522ded2426e63d262e35872d193cb1701e6ee31cfb2cdd910404754ec5698a94a45cda484dcb065eb517e4bcb5312fa664d5bc981e5467646405ea9f2ed4152948bab4909b950cbd6a2fc9796a625f4cc9ab79303ca8cec8c80bd53e5da82a5291756921372a197ad45f92f2d4c4be999356f26079519d919017aa7cbb5054a522ead2426e5432f5a8bf25e5a9897d3326ade4c0f2a33b23202f54f976a0a94a45d5a484dca865eb517e4bcb5312fa664d5bc981e5467646405ea9f2ed4152948bab4909b95057e8fba96df928ddc192c2af8961f28798cedcba53e77e83a52917579213729f3be44fffb254d4734febad5709220d09dde01571a7d0a1084a522eb02426e53d03daf8ac3b0c2b9e6c9d82a608a2420e680286e04fa2e61194a45d61484dca7907b5f1587618573cd93b054c1144841cd0050dc09f45cc232948bac2909b94f20f6be2b0ec30ae79b2760a9822890839a00a1b813e8b984652917585213729e41ed7c561d8615cf364ec153045121073401437027d17308ca522eb0a426e53c83daf8ac3b0c2b9e6c9d82a608a2420e680286e04fa2e61194a45d61484dca79007716e3437e7f68560767cb90aa669c7ac933806f45e6633948bac2a09b94f1f0ee2dc686fcfed0ac0ecf972154cd38f5926700de8bccc672917585413729e3e1dc5b8d0df9fda1581d9f2e42a99a71eb24ce01bd17998ce522eb0a826e53c7c3b8b71a1bf3fb42b03b3e5c855334e3d6499c037a2f3319ca45d61504dca78f803293bf054e1eb0dd42df388a0c4c4757575dc6c45e8073a48bac2a19b94f1ef065277e0a9c3d61ba85be711418988eaeaebb8d88bd00e74917585433729e3de0ca4efc15387ac3750b7ce22831311d5d5d771b117a01ce922eb0a866e53c7bc1949df82a70f586ea16f9c45062623ababaee3622f4039d245d6150cdca78f783293bf054e1eb0dd42df388a0c4c4757575dc6c45e8073a48bac2a19b94f1ef065277e0a9c3d61ba85be711418988eaeaebb8d88bd00e74917585433729e3de0566154c20edd462cd8430a20278f455809b9770e7a0372932eb0a867e53c7bbf38d50230f41d0f117d4c3c38457cb2aabfb54a19f40889275d6150d0ca78f77d71aa0461e83a1e22fa9878708af965557f6a9433e811124ebac2a1a194f1eefa6f666170a6d6befdc1f718d90c50f2a5ab178464d023c89e7585434429e3ddf36adf1b8e241000b350b459aa0f000d46027164c6a049353deb0a868953c7bbe561d08fc91e82841e6e2edb4c145e4286b125258a40940e7cd6150d13a78f77c94fb3783f13678af4a923de901f1aad080e8ca7118129c0faac2a1a284f1eef912b79492afd3198a11f0de5183493820ac95baa20025525f6585434519e3ddf2156f29255fa6331423e1bca306927041592b7544004aa4becb0a868a33c7bbe4239f77d58cb28e53c48fdbc58c8ac3025d1b1047d09563bda6150d14778f77c830001535e6cb44d305ec1a0a987b688464fa464f712ae1bb5c2a1a28ff1eef9050002a6bcd9689a60bd8341530f6d108c9f48c9ee255c376b8543451fe3ddf20a00054d79b2d134c17b0682a61eda21193e9193dc4ab86ed70a868a3fc7bbe414000a9af365a26982f60d054c3db442327d2327b89570ddae150d147f8f77c828001535e6cb44d305ec1a0a987b688464fa464f712ae1bb5c2a1a28ff1eef9050002a6bcd9689a60bd8341530f6d108c9f48c9ee255c376b8543451fe3ddf20a00054d79b2d134c17b0682a61eda21193e9193dc4ab86ed70a868a3fc7bbe414000a9af365a26982f60d054c3db442327d2327b89570ddae150d147f8f77c828001535e6cb44d305ec1a0a987b688464fa464f712ae1bb5c2a1a28ff1eef9050002a6bcd9689a60bd8341530f6d108c9f48c9ee255c376b8543451fe3ddf20a00054d79b2d134c17b0682a61eda21193e9193dc4ab86ed70a868a3fc7bbe414000a9af365a26982f60d054c3db442327d2327b89570ddae150d147f8f77c828001535e6cb44d305ec1a0a987b688464fa464f712ae1bb5c2a1a28ff1eef9050002a6bcd9689a60bd8341530f6d108c9f48c9ee255c376b8543451fe3ddf20a00054d79b2d134c17b0682a61eda21193e9193dc4ab86ed70a868a3fc7bbe41400035c18f06fcfab2189d1aebd33a814fccdebde5540ddc8551d147f8f87c827fff6b831e0df9f564313a35d7a675029f99bd7bcaa81bb90aa3a28ff1f0f904fffe631894c8ca4d4b1a4131d744e063672e2739f14d3773b948451fe3e2f209fffb5243823e6afd18ec4f29d681b724f656fab63e976ee916918a3fc7c6e413fff530995d29ac5cb4906b19d4fb64a814a8a1aed92bddd3d124147f8f8ec827ffe96132ba5358b96920d633a9f6c9502951435db257bba7a24828ff1f1d904fffd24e77cd5387d554f9792d7be588fe7a9d32fdc0ac7750e89151fe3e3c209fffa32901f353e60d2caabf211fc3085b1d35123ddd55eea37523a3fc7c79413fff455203e6a7cc1a59557e423f8610b63a6a247bbaabdd46ea4747f8f8f2827ffe8a301a25fc6e973562c94aa70417ca9ccef539d154ba8f788f8ff1f1e604fffd1360344bf8dd2e6ac592954e082f95399dea73a2a9751ef11f1fe3e3cc09fffa264c7af09e90bf5842f1f0c40855889b368129a14fea3f863f3fc7c79913fff44b250839e9f7e1333db0a7b008a16f5e67ae959e9cd480b07f7f8f8f3327ffe8954a1073d3efc2667b614f601142debccf5d2b3d39a90160feff1f1e664fffd12a20334054b5e74fae8f64e81a7c1ba1996698d670520465fefe3e3ccd9fffa253406680a96bce9f5d1ec9d034f8374332cd31ace0a408cbfdfc7c799b3fff44a60cdf59ffadffc1720a59c861e6ccae6046a5b5be48133bfcf8f8f3377ffe894b19beb3ff5bff82e414b390c3cd995cc08d4b6b7c902677f9f1f1e66efffd1296337d67feb7ff05c8296721879b32b9811a96d6f9204ceff3e3e3ccddfffa252c66facffd6ffe0b9052ce430f36657302352dadf24099dfe7c7c799bbfff44a585a07f8a7b65e99d87262ae1663290dff169db7e1813563d08f8f3378ffe894af402249fc431fb668b18b8424bcb043f8d97dcbc0026c6ba21f1e66f2ffd1295d0c56eca55ca1ef892fdd30416fbeafec5f3df37d04da7b453e3ccde6ffa252b918add94ab943df125fba6082df7d5fd8be7be6fa09b4f68a7c799bcdff44a572315bb2957287be24bf74c105befabfb17cf7cdf41369ed14f8f3379bfe894ae462b7652ae50f7c497ee9820b7df57f62f9ef9be826d3da29f1e66f37fd1295c851812302a0817b4aca992c0ef24926c0a02193cd4da95854e3ccde70fa252b8f2f149eb21765794d61f88015daf0757bec8583979b5454aac799bce2f44a571d5e293d642ecaf29ac3f1002bb5e0eaf7d90b072f36a8a9558f3379c5e894ae3a4864d37533f867ed54a8284f621ffdea5e586a5b6d52f6ac1e66f38cd1295c731cdbff973e53529276167896ba9e23cf68f330b3daa791593ccde71aa252b8e539b7ff2e7ca6a524ec2cf12d753c479ed1e66167b54f22b2799bce3544a571ca736ffe5cf94d4a49d859e25aea788f3da3ccc2cf6a9e4564f3379c6a894ae39472f25566c8fd174b7d79ecadcb4f4675f3dbe19bd53e2ecae66f38d61295c72771f7037a685cb14ec7ba01538cfcb4e693fa1f34aa7e0196ccde71ad252b8e4d70005fa1a71be5555c3a2a9f105791c7d4369a6654fda72e99bce35b4a571c996c1317f0249a4d62853a7d36170d4b8a54af90c9a9fcf25e3379c6b794ae39316438888d1f971d7cd73b22642478bf0f55a17d9053fb88bd66f38d70295c7261548369c71590bdb17b3c6cc03f4fa6195785571da7f8b57bcde71ae152b8e4c135192c3b0183fe1ac33f017874fd742d5b4d0a384ff30ef89bce35c3a571c9816a3258760307fc35867e02f0e9fae85ab69a14709fe61df1379c6b874ae3930260770998dc727b22d9c22dd9ca53f8b0197684de3fcddfe36f38d70f95c726034d006bde8f4778fd804a83ab8b06195adf2f65b97f9d63c7de71ae202b8e4c0526133069f4f174b2cd5b2f4f0c6a5ab06aa1276fff3c6b90bce35c41571c98094c2660d3e9e2e9659ab65e9e18d4b560d5424edffe78d72179c6b882ae393012245f1a54aa2855830232e534280792bc56c6f9bcfcf35243f38d71065c72602348be34a95450ab060465ca68500f2578ad8df379f9e6a487e71ae20cb8e4c0461d8ec1ff7f03d8c3d591bcc8967c72ec075e42f0f3ceed10ce35c41a71c9808b3b1d83fefe07b187ab2379912cf8e5d80ebc85e1e79dda219c6b8834e3930116024d60aad271e5c7230d1b1a504ff3aac9bb67c0cf3d584438d7106ac726022b049ac155a4e3cb8e461a3634a09fe7559376cf819e7ab08871ae20d58e4c0456093582ab49c7971c8c346c69413fceab26ed9f033cf56110e35c41ab1c9808ac126b0556938f2e391868d8d2827f9d564ddb3e0679eac221c6b883563930115824d60aad271e5c7230d1b1a504ff3aac9bb67c0cf3d584438d7106ac726022b049ac155a4e3cb8e461a3634a09fe7559376cf819e7ab08871ae20d58e4c045601f6a836172dbf480900cee8c0a5b12ad1b1c4c30cf57b50f35c41ab2c9808abf3ed506c2e5b7e9012019dd1814b6255a363898619eaf6a1e6b8835659301157e09bc6632a1d254ba0cf9e2281fca72af18b38cc03d60783dd7106acc26022afb1378cc6543a4a97419f3c4503f94e55e316719807ac0f07bae20d5984c0455f626f198ca874952e833e788a07f29cabc62ce3300f581e0f75c41ab309808abec4de331950e92a5d067cf1140fe539578c59c6601eb03c1eeb8835661301157d827d8bbd6f387ce589c644a79f30552ec377b2800d60927de7106acc36022afaf4fb177ade70f9cb138c894f3e60aa5d86ef65001ac124fbce20d5986c0455f5e2b754808a481bc1a3e5751dfc27373ab8a2efc005826437ac41ab30e808abebb56ea9011490378347caea3bf84e6e757145df800b04c86f58835661d01157d7639e778cf68697320c6236f77002bf6a8d4fe4bfe609ab1ec106acc3b022afaeb73cef19ed0d2e6418c46deee0057ed51a9fc97fcc13563d820d598760455f5d673b03bea78084f3ae553e5d3f70e029e003b8bf6826c6bb141ab30ed08abebab7372d081c673212d976df39fe47a2d36acb973ea04da7b63835661db1157d75572f7f9b06348c512fba20f37bf52826805b543d109b69ac806acc3b722afaea972024c0d9cf40cddc40a466775032ccab7ace39f136ed9910d59876f455f5d517016f0c8104a9c7354dab4c6e06481901b9c233b26df57231ab30edf8abebaa16c403a3cf6f7bb9e767b9185b7272b1ae37aa2734dc0524735661dc0157d75416492cd26c451f9f4b9bd4b0364ac7e307337a0e39b82488f6acc3b812afaea815537f2fa5f0676a14040bdfebfb7245b92b19dc43706351fd598770355f5d50136823ea1946f6ffa4d47a3f575cc70b1d1a597856e0e0e40ab30ee07abebaa016d047d4328dedff49a8f47eaeb98e163a34b2f0adc1c1c815661dc0f57d75402661b5333282042a101e4b7cdcd8feac1f2d8ba12b839dd03acc3b81fafaea8035848ff1326a307f9d08f9793917dfd7e91f3d02270755e08598770405f5d50053ca456d323a892ab6de5571f195a22f7d029fc41e0ec6011b30ee081bebaa009055b06531db3a80ea890d63629126dea4c965480c1da6424661dc1047d7540110ab60ca63b67501d5121ac6c5224dbd4992ca90183b4c848cc3b8208faea8022156c194c76cea03aa24358d8a449b7a9325952030769909198770411f5d500442ad83298ed9d40754486b1b148936f5264b2a4060ed3212330ee0823ebaa008855b06531db3a80ea890d63629126dea4c965480c1da6424661dc1047d7540110377323108cd7848cdee0eebd18abe5443f0cec153b4e288dc3b82090aea8021f6ee6462119af0919bdc1dd7a3157ca887e19d82a769c511b877041215d50043e69dee4ef09c094eb4849e2ec590dbd0ba8760c51ed3a46380ee08243baa0087b5fd0228ae9e3ac8e5d59edd0a879a211fd2e74a0da7630711dc10488754010f54bb29dc2aa29dbd4877a039947516c1ea69f453eb4ee04e33b820911ea8021e9237794322ab63a60dbba2f2a85010037f980e67a69ddadc777041224d50043d146ef2864556c74c1b7745e550a02006ff301ccf4d3bb5b8eee082449aa0087a219f0a975813b6c3b3baee4a20a6228da9245f5e6a7785b1edc10489454010f4333e152eb0276d876775dc94414c451b5248bebcd4ef0b63db8209128a8021e8667c2a5d604edb0eceebb92882988a36a4917d79a9de16c7b7041225150043d0c5b97a458e03de491aa3d4d08496f6ecf3e720b323bc47cf7e08244a3a0087a174341a15e96de4bdb2140c208893d059929267261778a9df0c10489484010f42d12959b6a041f1a6e0f47ac0908d8332cfe8f40bfef16dfe2820912918021e859252b36d4083e34dc1e8f581211b06659fd1e817fde2dbfc5041225230043d0b24a566da8107c69b83d1eb0242360ccb3fa3d02ffbc5b7f8a08244a460087a16420bf33fcf75b5628470388403d1fc162a0bc61fc78b8a3151048948d010f42c7417e67f9eeb6ac508e0710807a3f82c54178c3f8f171462a2091291a021e858e0f0f28a0b3cfdb58e8d448f8eadd2d852f33e3eee2e4305541225235043d0b1b1e1e5141679fb6b1d1a891f1d5ba5b0a5e67c7ddc5c860aa8244a46a087a16363c3ca282cf3f6d63a35123e3ab74b614bccf8fbb8b90c155048948d410f42c6c048b9db274e15d7f13686fbf4d47942425e17b74172326ab091291a921e858d709173b64e9c2bafe26d0df7e9a8f28484bc2f6e82e464d561225235243d0b1ae122e76c9d38575fc4da1befd351e50909785edd05c8c9aac244a46a487a1635c245ced93a70aebf89b437dfa6a3ca1212f0bdba0b919355848948d490f42c6b848b9db274e15d7f13686fbf4d47942425e17b74172326ab091291a921e858d701d860efb728e329a39d41fe19f50ac7f6871ca7fe4667962225235253d0b1adf3b0c1df6e51c653473a83fc33ea158fed0e394ffc8ccf2c444a46a4a7a1635be022a949aa09b4d20b416a77e73a0d9f84e0985fc919b89898948d495f42c6b7b0455293541369a41682d4efce741b3f09c130bf9233713131291a92be858d6f608aa526a826d3482d05a9df9ce8367e1382617f2466e262625235257d0b1adec1154a4d504da6905a0b53bf39d06cfc2704c2fe48cdc4c4c4a46a4afa1635bd822a949aa09b4d20b416a77e73a0d9f84e0985fc919b89898948d495f42c6b7b0455293541369a41682d4efce741b3f09c130bf9233713131291a92be858d6f6016b77f54fd35cae4d2700794de94a60e2ea3db2166e406635235257e0b1adebf2d6efea9fa6b95c9a4e00f29bd294c1c5d47b642cdc80cc6a46a4afc1635bd7e5addfd53f4d72b9349c01e537a529838ba8f6c859b90198d48d495f82c6b7afc41ce5354c010d9de6046649eeb03586c216135083721d71b91a92bf158d6f5f70faeff56568436748d52f135cc64d8d2ef04c60d6e455238235257e3b1adebed1f5dfeacad086ce91aa5e26b98c9b1a5de098c1adc8aa47046a4afc7635bd7da3ebbfd595a10d9d2354bc4d73193634bbc131835b91548e08d495f8ec6b7afb4098a535f8a84365c375db1a65984ee9224688c68722c35c21a92bf1e8d6f5f671314a6bf15086cb86ebb634cb309dd2448d118d0e4586b8435257e3d1adebece26294d7e2a10d970dd76c6996613ba4891a231a1c8b0d7086a4afc7a35bd7d9c4c529afc5421b2e1baed8d32cc277491234463439161ae10d495f8f46b7afb3824b78ea57ea5e87b42a1425d8ead111cf2cb228422c50022a92bf1e9d6f5f66f496f1d4afd4bd0f6854284bb1d5a2239e5964508458a00455257e3d3adebecde1ef09342d0fa24a4d74b316e31126c6e776ee60d8b15a48ba4afc7a85bd7d9bb3de12685a1f44949ae9662dc6224d8dceeddcc1b162b4917495f8f50b7afb37607d4a5b81a4b154b29f2edb0baa7d9b489fdf4332c58362f92bf1ea26f5f66eb0fa94b7034962a9653e5db61754fb36913fbe86658b06c5f257e3d44debecdd61f5296e0692c552ca7cbb6c2ea9f66d227f7d0ccb160d8be4afc7a89bd7d9bac3ea52dc0d258aa594f976d85d53ecda44fefa19962c1b17c95f8f5137afb3758095cb42e7b13d76a6bf50303a0dbc3434c219f2fc58506fa2bf1ea27f5f66eaf12b9685cf627aed4d7ea060741b7868698433e5f8b0a0df457e3d44febecdd5e2572d0b9ec4f5da9afd40c0e836f0d0d30867cbf16141be8afc7a89fd7d9babc4ae5a173d89ebb535fa8181d06de1a1a610cf97e2c2837d15f8f513fafb3757821dd9b94879ff95e8c165832041a5c2f6e5c4ef9585213a3bf1ea2805f66eaef43bb37290f3ff2bd182cb0640834b85edcb89df2b0a427477e3d4500becdd5de1388c6fef4e26831fd1f88c006c798b865b397e26149f28ffc7a8a027d9babbb27118dfde9c4d063fa3f11800d8f3170cb672fc4c293e51ff8f51404fb3757764e231bfbd389a0c7f47e23001b1e62e196ce5f898527ca3ff1ea2809f66eaeec285890a47d75c447b5c26df82c9aedbdd9df1b100a513880e3d45014ecdd5dd750b12148faeb888f6b84dbf05935db7bb3be362014a27101c7a8a029d9babbae2d749b3ecc3993d6a3cfdfd8a8c9def213bec83d294686048f514054b375775b5ae9367d987327ad479fbfb15193bde4277d907a528d0c091ea280a966eaeeb641e4c5a80748d2125c05a75a9985a3c2fb3d7cf1a51bbc133d450153cdd5dd6b0fdbe3fce4f426dc84d176ad29696f80a2bd55e04a391c277a8a02a89babbad51fb7c7f9c9e84db909a2ed5a52d2df01457aabc09472384ef5140551375775aa3f6f8ff393d09b721345dab4a5a5be028af5578128e4709dea280aa26eaeeb540af17893fe03b99bf351dd6141a9a3ffc22d0aff51ca853cd4501545dd5dd6a715e2f127fc077337e6a3bac2835347ff845a15fea3950a79a8a02a8bbabbad4e2bc5e24ff80ee66fcd47758506a68fff08b42bfd472a14f35140551775775a9c578bc49ff01dccdf9a8eeb0a0d4d1ffe116857fa8e5429e6a280aa2eeaeeb5383b29e1ecb69e1c7701e3fe0c10f867f6cf130bf21ca9f7ce4501545ed5dd6a6f02661c86439ebba5d08e2410184ef7e84a6873e13955939d8a02a8beabbad4dd04cc390c873d774ba11c4820309defd094d0e7c272ab273b1405517d5775a9ba099872190e7aee9742389040613bdfa129a1cf84e5564e76280aa2faaeeb53741330e4321cf5dd2e84712080c277bf4253439f09caac9cec501545f55dd6a6e82661c86439ebba5d08e2410184ef7e84a6873e13955939d8a02a8beabbad4dd04cc390c873d774ba11c4820309defd094d0e7c272ab273b1405517d5775a9ba025997a3dbe116c2bf04f2bfe0a1c220d465f544b55668b6380aa2fabeeb5373f4b32f47b7c22d857e09e57fc1438441a8cbea896aacd16c701545f57dd6a6e7e227841a3cea833678e02d7f01eceb02fc5bfad2a559bd18f02a8beb0bad4dcfb44f083479d5066cf1c05afe03d9d605f8b7f5a54ab37a31e05517d6175a9b9f615f35f3c1103505604d187b87198e8b9c34110a65670ea3d0aa2fac3eb5373eb2be6be782206a0ac09a30f70e331d1738682214cace1d47a1545f587d6a6e7d657cd7cf0440d415813461ee1c663a2e70d04429959c3a8f42a8beb0fad4dcfac3bad528d5e7d0567f35265bb83256dc8c64ae12fb388f5e95517d6205a9b9f57036cfdc7935c8d87b36af36efca9038c38d81e5c67138fd3aa2fac41b5373ead06d9fb8f26b91b0f66d5e6ddf952071871b03cb8ce271fa7545f58836a6e7d5a0db3f71e4d72361ecdabcdbbf2a40e30e36079719c4e3f4ea8beb106d4dcfab41b67ee3c9ae46c3d9b579b77e5481c61c6c0f2e3389c7e9d517d620da9b9f56836cfdc7935c8d87b36af36efca9038c38d81e5c67138fd3aa2fac41b5373ead06d9fb8f26b91b0f66d5e6ddf952071871b03cb8ce271fa7545f58836a6e7d5a06751ca91ad85e4a4a78303b7209f0b08e249f316c4e598eb8beb106e4dcfab3f5ab5edd0316e4c011bcc2f66379c3e0c70d6422a89ccd5d817d620dd9b9f567d417e344d393f1aba045e86c46596a4138deee052139b4fb12fac41bc373eacf90f0ec14748e0b82bd5833580c18b7021c8201ca1273843635f5883796e7d59f11e1d828e91c17057ab066b018316e043904039424e7086c6beb106f2dcfab3e23c3b051d2382e0af560cd603062dc087208072849ce10d8d7d620de5b9f567c4048862e71d68441678dfd3fe02b9a908ed43410639c3bf1bfac41bcc73eacf870910c5ce3ad0882cf1bfa7fc05735211da86820c73877e37f5883798e7d59f0e12218b9c75a11059e37f4ff80ae6a423b50d0418e70efc6feb106f31cfab3e1c24431738eb4220b3c6fe9ff015cd48476a1a0831ce1df8dfd620de639f567c3848862e71d68441678dfd3fe02b9a908ed43410639c3bf1bfac41bcc73eacf8701d1eb590836b0586e8c0a7b84d93491854aa7cc4387987805883798f7d59f0df3a3d6b2106d60b0dd1814f709b269230a954f98870f30f00b106f31efab3e1be008d2eeee40e98d36fc8c6d92cab4c5bfeec4f0de1e7c202620de63ef567c37b011a5dddc81d31a6df918db2595698b7fdd89e1bc3cf8404c41bcc7deacf86f60234bbbb903a634dbf231b64b2ad316ffbb13c37879f0809883798fbd59f0dec046977772074c69b7e4636c9655a62dff762786f0f3e1013106f31f7ab3e1bd808d2eeee40e98d36fc8c6d92cab4c5bfeec4f0de1e7c202620de63ef567c37b011a5dddc81d31a6df918db2595698b7fdd89e1bc3cf8404c41bcc7deacf86f60234bbbb903a634dbf231b64b2ad316ffbb13c37879f0809883798fbd59f0dec046977772074c69b7e4636c9655a62dff762786f0f3e1013106f31f7ab3e1bd8019414790e4fb5627958d0124a1aa83f9989169dee7c3a6630de63ef667c37aff32828f21c9f6ac4f2b1a0249435507f33122d3bdcf874cc61bcc7deccf86f5fe65051e4393ed589e5634049286aa0fe66245a77b9f0e998c3798fbd99f0debfc561c9533fe3d33f4792e311d03b247c770cdaaf43e1ed7196f31f7b43e1bd7f7384b8314d2dceaa0bf228a31fdc2b7898dddb1e57c3f5233de63ef697c37afed70970629a5b9d5417e451463fb856f131bbb63caf87ea467bcc7ded2f86f5fda6d40650021d62d3ac95050bfed690620e3b92392f0feecd0798fbda6f0debfb3669322ad1a0edd2d5f66c977d130343c73b4a322e1ff7da1f31f7b4ee1bd7f6559389e070a803d128b93bae798be907393aba242c4009f44e63ef69ec37afec93e8394baeb62fcdce3ed9dc727db48e1d399a0828802e28acc7ded3e86f5fd9109198222ad287c7194a163864614b9be53759d021007691698fbda7e0debfb21123304455a50f8e32942c70c8c29737ca6eb3a04200ed22d31f7b4fc1bd7f6422466088ab4a1f1c652858e191852e6f94dd67408401da45a63ef69f837afec8448cc11156943e38ca50b1c3230a5cdf29bace810803b48b4c7ded3f06f5fd9081daa7ad7a8ea49d116dc605c57a9c3dfe39c2c1e0078356a8fbda7e1debfb20f3b54f5af51d493a22db8c0b8af5387bfc738583c00f06ad51f7b4fc3bd7f641e02bc440b7a0ba9fc2837a9695505377a3ab30c7501e279ab3ef69f887afec83b05788816f41753f8506f52d2aa0a6ef4756618ea03c4f3567ded3f10f5fd90760af1102de82ea7f0a0dea5a55414dde8eacc31d40789e6acfbda7e21ebfb20ec15e2205bd05d4fe141bd4b4aa829bbd1d59863a80f13cd59f7b4fc43d7f641d82bc440b7a0ba9fc2837a9695505377a3ab30c7501e279ab3ef69f887afec83b05788816f41753f8506f52d2aa0a6ef4756618ea03c4f3567ded3f10f5fd907603b235b8b594d01c1dab0824d37ac06895905793d78a00ed0bda7e21fbfb20ebf02590fc388fc863b82272c9265b6350d5e4d4e77f141c1a27b4fc4407f641d7d04b21f8711f90c77044e5924cb6c6a1abc9a9cefe2838344f69f8880fec83afa09643f0e23f218ee089cb24996d8d435793539dfc5070689ed3f1101fd9075f412c87e1c47e431dc113964932db1a86af26a73bf8a0e0d13da7e2203fb20ebe82590fc388fc863b82272c9265b6350d5e4d4e77f141c1a27b4fc4407f641d7d04b21f8711f90c77044e5924cb6c6a1abc9a9cefe2838344f69f8880fec83afa02256498f1584119856914c9163eb6b523f95f9f950720c9fd3f11020d9075f3f44ac931e2b082330ad229922c7d6d6a47f2bf3f2a0e4193fa7e22041b20ebe7e156b7ee92c72c919270b5a3d860bd543aa9a43e241c9d6804fc44084641d7cfb2ad6fdd258e592324e16b47b0c17aa87553487c48393ad009f888108c83af9f655adfba4b1cb24649c2d68f6182f550eaa690f8907275a013f1102119075f3ec376e4ff639f8cb810520f9e426bcd21801147b0f0e5058037e22042420ebe7d76edc9fec73f197020a41f3c84d79a4300228f61e1ca0b006fc44084841d7cfae69cb9885be45b0bbe14a0f889151705ab09448393943040ef888109183af9f5b5fa989b852ede42f8f5a4709190108b00d6aec6f7287ac1ef1102124075f3eb54b656c1d7c3e4b16eb7ab60a2860395ac71834dbe510fc3ee22042490ebe7d6922dd30e7cedf18e5a3bb940c471e9ab03a72c5b4ca239c7ec44084931d7cfad145ba61cf9dbe31cb477728188e3d356074e58b69944738fd888109263af9f5a217871c4c11dee64e5bb4782912d892bb960d72d0289015fc1102124d75f3eb432f0e389823bdcc9cb768f05225b125772c1ae5a051202bf82204249aebe7d6865e1c7130477b99396ed1e0a44b624aee5835cb40a24057f044084935d7cfad0c484b3b0d6559b52aaa69e9408d22bdd75cadf27e448253e18810926caf9f5a171ca8cec7a115ed0d2199fa7910a3a3a9659e40f989064bc4102124da5f3eb42d39519d8f422bda1a4333f4f221474752cb3c81f3120c9788204249b4be7d685a72a33b1e8457b4348667e9e4428e8ea5967903e624192f10408493697cfad0b47158cee9df11eb20d995fbc07b7b4545d93463c948340221810926d3f9f5a1676ec3f680948658f97ff21f78ed54b2865eab238f9069a84402124da8f3eb42cd699a45adff6f34aaccaa66e9d1078d076998a31c20d4f48904249b52e7d685995f46e408d540ec0d661af5cb986d42097f73a23541ab8d13084936a6cfad0b314aa020be80e45ad298fc138f2738ac0dab29a0678358be2710926d4e9f5a166121529a29d82b385cfebe4f1644cf801602959ccc06b3204f2124da9e3eb42cc142a53453b05670b9fd7c9e2c899f002c052b39980d66409e4249b53c7d685982115cc154370f642bc7bf6451099c2852b698cf2d1ace253d84936a79fad0b30322b982a86e1ec8578f7ec8a2133850a56d319e5a359c4a7b0926d4f3f5a1660645730550dc3d90af1efd91442670a14ada633cb46b3894f6124da9e7eb42cc0c16f8634e8edda4160ac14a80433f6a906108d565d672cded249b53d0d68598172df0c69d1dbb482c15829500867ed520c211aacbace59bda4936a7a1ad0b302e5be18d3a3b7690582b052a010cfdaa418423559759cb37b4926d4f435a16605c43d573214d4fa36822d07bfa10597c7db489072bb398136a24da9e87b42cc0b713bd3eef7101c98812671fec171120f615546a546731cad549b53d106859816d277a7ddee203931024ce3fd82e2241ec2aa8d4a8ce6395aa936a7a20d0b302da4ef4fbbdc4072620499c7fb05c4483d85551a9519cc72b5526d4f441a16605b429fc50285e70cef85fff2758aee72fab56e5aea0398ffaab4da9e88442cc0b6753f8a050bce19df0bffe4eb15dce5f56adcb5d40731ff5569b53d108859816ce3403994e5025be994cc2c55ab1fae6a807d9167de6418eae36a7a2120b302d9b6807329ca04b7d3299858ab563f5cd500fb22cfbcc831d5c6d4f442416605b365c20bde616f97d1cffd13d62be49c29acba6b5f49907deb9da9e88492cc0b66b4453d47904557cf1cc68a2bd72f1ad30438fc7e632116174b53d109359816cd514ba019edf0d7c9b65976d72dc41825b3361ebc9642466ea6a7a2127b302d9a92974033dbe1af936cb2edae5b88304b666c3d792c848cdd4d4f4424f6605b35252e8067b7c35f26d965db5cb7106096ccd87af2590919ba9a9e8849ecc0b66a431e265a3cece6792f981938ed86a3ad44751ba482124db5453d1093e9816cd4763c4cb479d9ccf25f303271db0d475a88ea374904249b6a8a7a2127d302d9a8e539bef3c119c2103b2cc76335807134bc989451d849511524f4424fb605b351b334a3724f99ac4bf325f145ea66c4e923f54e638092bc6a59e8849f7c0b66a3566946e49f335897e64be28bd4cd89d247ea9cc7012578d4b3d1093ef816cd46a593b3540bccd95b496427972900f6243a995f4dd24b0be977a2127e002d9a8d33e88c32e4ffdae20f94b1add167cec81ff6e45b74963212ff4424fc105b351a50923df09765ddef9bf5c5db2235800feab1ee76b92c7e660e8849f830b66a3491247be12ecbbbdf37eb8bb6446b001fd563dced7258fccc1d1093f0616cd4692248f7c25d9777be6fd7176c88d6003faac7b9dae4b1f9983a2127e0c2d9a8d24491ef84bb2eef7cdfae2ed911ac007f558f73b5c963f33074424fc185b351a481e5049443c407253c28c031a2bde37e55e30d2b62c800a0f8849f831b66a348f3ca092887880e4a78518063457bc6fcabc61a56c5900141f1093f0636cd4691e05537dbdc7644c06d6f63460a5d707902505a6d5b201cc3f2127e0c7d9a8d23b0aa6fb7b8ec8980dadec68c14bae0f204a0b4dab6403987e424fc18fb351a476154df6f71d91301b5bd8d182975c1e4094169b56c80730fc849f831f66a348ec2a9bedee3b226036b7b1a3052eb83c81282d36ad900e61f9093f063ecd4691d85537dbdc7644c06d6f63460a5d707902505a6d5b201cc3f2127e0c7d9a8d23b036821065c2ec0392ab8cb40cb13f19ff4cf736b3403b2be524fc18fc351a475f6d0420cb85d8072557196819627e33fe99ee6d66807657ca49f831f86a348ebe661a9a43e21291027af8f82abb5a8ff7e01f36ca00ee539593f063f1d4691d7b58478d349a87a4bcc2b8184d6d1347ea6c80c99101de4b2c27e0c7e4a8d23af53ca173160b71cc3152365892d084b7cf8543ef1f03be3a594fc18fca51a475e905553ed8ed461b1a7132d91d97679799b6ca3a3b077e18b39f831f95a348ebd10aaa7db1da8c3634e265b23b2ecf2f336d9474760efc31673f063f2b4691d7a21554fb63b5186c69c4cb64765d9e5e66db28e8ec1df862ce7e0c7e568d23af442aa9f6c76a30d8d38996c8ecbb3cbccdb651d1d83bf0c59cfc18fcad1a475e885553ed8ed461b1a7132d91d97679799b6ca3a3b077e18b39f831f95a348ebd1036ba33ca7f25e605f3214baae3511b318589a35defc4ba74f063f2b5691d7a1f6d746794fe4bcc0be6429755c6a236630b1346bbdf8974e9e0c7e56ad23af43e66fb27d6d2fa1acf994b56a383a294c0c268e974bf148dd4c18fcad6a475e87b5a08a85a7c56b856ff5cd53efda3517c31142ee67e2abfaa831f95ae48ebd0f54023a961cf0ff365cb7fd275f1a4caf30e6ab9c9fc572356063f2b5d91d7a1e90c59ab707482698363c5cce3d9a7bde0c917cf90f8afeaad0c7e56bc23af43d118b356e0e904d306c78b99c7b34f7bc1922f9f21f15fd55a18fcad78475e87a23166adc1d209a60d8f17338f669ef783245f3e43e2bfaab431f95af08ebd0f4462cd5b83a4134c1b1e2e671ecd3def0648be7c87c57f556863f2b5e11d7a1e8851ad0fb41e891aee0922f63590da06073dbf550c8b004ed1c7e56bc33af43d0f2f6c78151374b893df0c14631812340927c10616160241a48fcad78775e87a1d5ed8f02a26e97127be1828c6302468124f820c2c2c0483491f95af0eebd0f43a49c439012435650748f6798456a6f81f4b467455580aaa933f2b5e1ed7a1e8731f9acaaf1ecd4cc65eb31b00a3ac183942cf44a7b016f9277e56bc3eaf43d0e53f35955e3d9a998cbd66360147583072859e894f602df24efcad787d5e87a1ca0a7d83695197b5d1479293fa850e88dfb77f6e9bc05d889ef95af0fbbd0f439314fb06d2a32f6ba28f2527f50a1d11bf6efedd3780bb113df2b5e1f77a1e872629f60da5465ed7451e4a4fea143a237eddfdba6f0176227be56bc3eef43d0e4c53ec1b4a8cbdae8a3c949fd4287446fdbbfb74de02ec44f7cad787dde87a1c9833ea8f41efdddfcc45ef67a04746b5f6243945b905da2df095af0fbcd0f4392f67d51e83dfbbbf988bdecf408e8d6bec48728b720bb45be12b5e1f79a1e8725e5bbc95b495da01e8e483c6791378ffd33d2772e1176a5bc356bc3ef443d0e4bb438b84160216868995cdb4ea1d5027a1269141bf2ed65b87ad787de987a1c975132960d8da8f8fcaf86191cc30fe773cf964df7b5dae5b105af0fbd40f4392e92652c1b1b51f1f95f0c3239861fcee79f2c9bef6bb5cb620b5e1f7a81e8725d24ca583636a3e3f2be1864730c3f9dcf3e5937ded76b96c416bc3ef503d0e4ba4255d5f73aadf010f8fd2b6597e51e1e2776957d7ed747c83d787dea17a1c97474ababee755be021f1fa56cb2fca3c3c4eed2afafdae8f907af0fbd42f4392e8e2187d67b81de86f60c11015defa5af8489e7bb5cb5d396105e1f7a86e8725d1b430facf703bd0dec182202bbdf4b5f0913cf76b96ba72c20bc3ef50dd0e4ba361231b29adddc9e8ffd0a2d6fb4f4e60cd3e1496fd74ffc42787dea1ca1c9746b24636535bbb93d1ffa145adf69e9cc19a7c292dfae9ff884f0fbd4394392e8d648c6ca6b77727a3ff428b5bed3d398334f8525bf5d3ff109e1f7a8728725d1ac1d9fed83c5477737b51793759e0558614b4ca77bba818614c3ef50e60e4ba3573b3fdb078a8eee6f6a2f26eb3c0ab0c296994ef775030c2987dea1cc1c9746ae02920ebbeb805f96a12475ce6e73897fd974f9ebea07bc540fbd4399392e8d5b05241d77d700bf2d4248eb9cdce712ffb2e9f3d7d40f78a81f7a8732725d1ab60a483aefae017e5a8491d739b9ce25ff65d3e7afa81ef1503ef50e64e4ba356c149075df5c02fcb50923ae73739c4bfecba7cf5f503de2a07dea1cc9c9746ad82920ebbeb805f96a12475ce6e73897fd974f9ebea07bc540fbd4399392e8d5b05241d77d700bf2d4248eb9cdce712ffb2e9f3d7d40f78a81f7a8732725d1ab60309607a7b67a686015e39b93934087f10980d6f781f0b904ef50e64f4ba356bf612c0f4f6cf4d0c02bc7372726810fe21301adef03e17209dea1cc9e9746ad7e4e6a774bb04c243824549646436047bed245b7db07c48814bd43993e2e8d5afb28e7474436facb28156f54847d1eb77850cdcbb30f8ab42a7a87327d5d1ab5f551ce8e886df596502adea908fa3d6ef0a19b97661f156854f50e64faba356bea2faf75bdb24daf5822837a09ead905dbef798ac93e2c74aaea1cc9f6746ad7d35f5eeb7b649b5eb04506f413d5b20bb7def315927c58e955d43993ece8d5afa64ad02fa39f99401856d4101fa1c23f6a6a288721f8b376aca87327dad1ab5f4b21b2b7f4159502e87a6e483739e2a6cf80936a40f168915a50e64fb6a356be9543656fe82b2a05d0f4dc906e73c54d9f0126d481e2d122b4a1cc9f6d46ad7d2a12dd387d2cb68e59b67f48d4dde8c338ae900500c5a3e96a43993edb8d5afa5325ba70fa596d1cb36cfe91a9bbd186715d200a018b47d2d487327db71ab5f4a64b74e1f4b2da3966d9fd235377a30ce2ba401403168fa5a90e64fb6e356be94c22fc1c963c16f58580c06e9ee5a441c020c284032d20ef531cc9f6dd6ad7d29745f8392c782deb0b0180dd3dcb488380418508065a41dea63993edbad5afa52e1802cb05c6be58cdcfc7e2738cef2efb2f4c6c09b485614d7327db76ab5f4a5b3005960b8d7cb19b9f8fc4e719de5df65e98d813690ac29ae64fb6ed56be94b6600b2c171af963373f1f89ce33bcbbecbd31b026d2158535cc9f6ddaad7d296c4c28b0db0c5549264b053b945dd79fd426a5bc4aa42cae6c993edbb65afa52d72463ba62ef0d150462d09f20b20d67a2f98dd492485b00da327db76db5f4a5ad48c774c5de1a2a08c5a13e41641acf45f31ba92490b601b464fb6edb6be94b5a1da142389296d6c95808a47abe93c6869279ae46216da769c9f6ddb7d7d296b33b428471252dad92b01148f57d278d0d24f35c8c42db4ed393edbb6fafa52d660297618f20bddddd2ce8b9e2f0ad4214f629151585b841a827db76e05f4a5acb052ec31e417bbbba59d173c5e15a8429ec522a2b0b7083504fb6edc0be94b5960a5d863c82f77774b3a2e78bc2b50853d8a4545616e106a09f6ddb817d296b2c14bb0c7905eeeee96745cf17856a10a7b148a8ac2dc20d413edbb702fa52d658297618f20bddddd2ce8b9e2f0ad4214f629151585b841a827db76e05f4a5acb052ec31e417bbbba59d173c5e15a8429ec522a2b0b7083504fb6edc0be94b596031eabc7505d9fa0306f4a0b421aead383687a15e6e120e0af6ddb818d296b2bf63d578ea0bb3f4060de94168435d5a706d0f42bcdc241c15edbb7031a52d657e53bd4a80edca6ac3e898aac87d18dcdb8660e176b849dc2cdb76e0644a5acafb338cedaeb1f7583f9df77d88f08fe1b1b9041eea70955c5ab6edc0c994b595f56719db5d63eeb07f3beefb11e11fc36372083dd4e12ab8b56ddb8193296b2bea5a460f679e3fe3b644a41e1bb89daec19052d7a6c257156bdbb7032752d657d3409e777c12e24a24560e642f6799857dcce80b4a84afced8b76e064fa5acafa50d4f47a4fc27170078e2f056c59132f646127292096141b26edc0ca04b595f491a9e8f49f84e2e00f1c5e0ad8b2265ec8c24e52412c28364ddb8194096b2be92353d1e93f09c5c01e38bc15b1644cbd91849ca48258506c9bb7032812d657d246a7a3d27e138b803c71782b62c8997b2309394904b0a0d9376e065025acafa486106d2fc98d3f2bf5af52d644f71575f0d69851d9615bf27edc0ca05b595f48f4e1ffea6080a683682b082c09540d6b8c71566382c2d2250db81940c6b2be91d285255f8e6775324d2272d7920dfd56c3a6d286d585be8a2b7032819d657d23950a4abf1cceea649a44e5af241bfaad874da50dab0b7d1456e065033acafa4722d5bb090703fcf4b1562dddc79dd7dab95f6fdb26171468bdc0ca068595f48e35ab76120e07f9e962ac5bbb8f3bafb572bedfb64c2e28d17b81940d0b2be91c641811aee9761bfe422519f69ddd41ea9041e52c685c6be30703281a2657d238b0f148e8a05260280116966cbb206654cb47f018a0b8f2061e0650345cafa47151e291d140a4c050022d2cd97640cca9968fe0314171e40c3c0ca068b95f48e2a3c523a2814980a0045a59b2ec8199532d1fc06282e3c818781940d172be91c5404b6ccfcff9296b858115e5586915260503a684d5c7aa71003281a2f57d238a7096d99f9ff252d70b022bcab0d22a4c0a074d09ab8f54e200650345eafa4714e12db33f3fe4a5ae1604579561a45498140e9a13571ea9c400ca068bd5f48e29c25b667e7fc94b5c2c08af2ac348a930281d3426ae3d538801940d17abe91c5384b6ccfcff9296b858115e5586915260503a684d5c7aa71003281a2f57d238a7022ebf84cc8b559c2cef1f2a8c8887404b38f65a88f568601650345ebfa4714df45d7f099916ab3859de3e5519110e809671ecb511ead0c02ca068bd7f48e29be17c239dff937e9c3088df29b187ff80d7a7ff29f3d5bbc06940d17b0e91c537b2f8473bff26fd386111be53630fff01af4ffe53e7ab7780d281a2f61d238a6f65f08e77fe4dfa70c2237ca6c61ffe035e9ffca7cf56ef01a50345ec3a4714dec4a2427aca021d0d01135bcd0ba5de8668041f0f6eadf8435a068bd8848e29bd7205aa80616a62457ef31a1996b19f8c7acc63dead5c0ac6c40d17b1191c537ad40b5500c2d4c48afde634332d633f18f598c7bd5ab8158d881a2f623238a6f5a0d7cf8c530fb1417898cae5da2c60b195f5b53a8570455b20345ec474714deb31af9f18a61f6282f13195cbb458c1632beb6a750ae08ab64068bd88e8e29bd6635f3e314c3ec505e2632b9768b182c657d6d4ea15c1156c80d17b11d1c537acc6be7c62987d8a0bc4c6572ed163058cafada9d42b822ad901a2f623a38a6f59863e1e4ffe613c43065910dd222bed990a1f796827046ff21345ec475714deb2f53d622aca28a0b1897e8439c3bdbdb1bf0318901e08fa24368bd88ebe29bd65d33be9e061b7698e8fc96af306e15de328ca56e00c120e887d17b11d8c537acb9677d3c0c36ed31d1f92d5e60dc2bbc65194adc018241d10fa2f623b18a6f59725b0cd0c5443ce65bbf20e4b9aeb5a0c4ded814000485462045ec476414deb2e3422bfa375edc4f6f4b07f16b53c9698469f283fd090c30418bd88ec929bd65c5106a4d1b941b219662d60ace9df0fb03802763f7121a048417b11d93537acb8920d49a372836432cc5ac159d3be1f607004ec7ee243409082f623b26a6f5971241a9346e506c86598b582b3a77c3ec0e009d8fdc486812105ec4764d4deb2e240f64c189773b8f6ae3767e6ce5e60016ad7d7bb590d1c821bd88ec9b9bd65c471ec98312ee771ed5c6ecfcd9cbcc002d5afaf76b21a390437b11d93737acb88e3d930625dcee3dab8dd9f9b39798005ab5f5eed643472086f623b26e6f59711c073864f8903efe0ee87a1b5f258e28b0182e39a9868fe50eec4764dddeb2e2370e70c9f1207dfc1dd0f436be4b1c5160305c73530d1fca1dd88ec9bbbd65c46e1ce193e240fbf83ba1e86d7c9638a2c060b8e6a61a3f943bb11d93777acb88dc39c327c481f7f07743d0daf92c714580c171cd4c347f2877623b26eef59711b873864f8903efe0ee87a1b5f258e28b0182e39a9868fe50eec4764dddeb2e2370731ef7bede424494dc0993dca8233dfdb209912dd1fe45de88ec9bbcd65c46df7250482a92e70be184d94fb146a4a3f610557e58a3fe2fbe11d9377aacb88dbd70b2e901fc309a7ad678c75a83a76fe6cced58ae47fe037d23b26ef659711b796d782ab0cec3b7ad79b7b6acfdad07c8461d0d598ffdaafb4764ddedb2e236f16702ae0e73e9f212c0359551f1b8378b387c76b01ffcf9f78ec9bbdc65c46de15a17b4c9be3666dd4d31529bd9ce97111d3b495d3ffb97f01d9377b9cb88dbc14041c24052cf50726728cd2fa9fb561ce6b8eeb77ff8d3e13b26ef749711b7810c95dd2d7c01239c9b17c2574a54d43479b4396bfff34bc3764ddeea2e236f01192bba5af8024739362f84ae94a9a868f36872d7ffe69786ec9bbdd45c46de02325774b5f0048e726c5f095d295350d1e6d0e5afffcd2f0dd9377ba8b88dbc0464aee96be0091ce4d8be12ba52a6a1a3cda1cb5fff9a5e1bb26ef751711b780855702b849674bc817e424d6c9bab6b424785f2bcff36603864ddeea3e236f00f36f2afb6034bfbbac94ac2d12db4fe7f3b4e4176fe6e6471c9bbdd48c46de01d6de55f6c0697f775929585a25b69fcfe769c82edfcdcc8e39377ba9188dbc03a67dd1784e39271a2f1f1333cad3221f7997b61d8f9bb35c826ef752411b780735bcc87b69d8765fdb0a88e7150c26be9df391faef3780f914ddeea49236f00e543ab681a11714eb32e1744da97e2ffce6ab49b5ae6f1c3239bbdd49346de01c9136928e0f945201e28f4b1ad2624279781ab92b2cde52a48377ba9278dbc039126d251c1f28a403c51e9635a4c484f2f035725659bca54906ef7524f1b7807224da4a383e5148078a3d2c6b498909e5e06ae4acb3794a920ddeea49e36f00e44275b9fb4a08b83a9146bb561277f64b6b99ef1936f2af642bbdd493d6de01c874eb73f694117075228d76ac24efec96d733de326de55ec8577ba927adbc0390e2980d77f5890915c1e74fd7c945bbad592be224abcad7d0bef7524f6b780721b5301aefeb12122b83ce9faf928b775ab257c4495795afa17deea49ed6f00e4363215b6aa38a4c828469a1dea47cd1350f73ae527f2b79830bdd493dbde01c86b642b6d54714990508d343bd48f9a26a1ee75ca4fe56f30617ba927b7bc0390d654693355b8f5a358e72e9fa11592753e892df09ccae004c3f7524f70780721ab34e4bf58484dc9699b23673a21831277be9e3d3695c1ad88eea49ee1f00e435569c97eb0909b92d33646ce74430624ef7d3c7a6d2b835b11dd493dc3e01c86aa5fa5560df799a85e3953c4e07c6a71d9a6bb50d757085a24ba927b88c0390d534b5d04c8c595d3743f6db1b8ef330badf9b8fdabae12584a7524f71280721aa522cc623e618e29a04ba18b69d4c43f569fb457545c265495ea49ee2600e435494598c47cc31c5340974316d3a9887ead3f68aea8b84ca92bd493dc4c01c86a921743e1a65c9b2938fb4c559f496f25552b13b94e709af658a927b8990390d5232e87c34cb9365271f698ab3e92de4aaa5627729ce135ecb1524f71320721aa465d0f8699726ca4e3ed31567d25bc9554ac4ee539c26bd962a49ee2640e43548c463165dfbb3bcc7fa728d4f241d752a404e0267084d956c6493dc4c91c86a9171875246c4cda1bb71b17d1dc7a0ccd42b602a8de09b4518d927b8993390d522d30ea48d899b4376e362fa3b8f4199a856c0551bc1368a31b24f71326721aa45a61d491b133686edc6c5f4771e833350ad80aa37826d1463649ee264ce43548b44fbb7c0f3d336070a584b6dbc6c492105c57a2ed4da4306d93dc4c9ac86a91672b8950cb50c9439917cf95af83e74c1b64f1a1d79b4a04dc27b8993690d522cd5712a196a19287322f9f2b5f07ce9836c9e343af369409b84f71326d21aa459a3a379bda1987911c2c047eb605fb58684008e35b6d29b7719ee264db43548b33008190610971a4f024cf25640254d8cb2c5422b3da5512e43dc4c9b786a91665010320c212e349e0499e4ac804a9b19658a84567b4aa25c87b89936f0d522cca0206418425c693c0933c95900953632cb1508acf69544b90f71326de1aa45994040c83084b8d278126792b2012a6c65962a1159ed2a89721ee264dbc3548b32808190610971a4f024cf25640254d8cb2c5422b3da5512e43dc4c9b786a91665010320c212e349e0499e4ac804a9b19658a84567b4aa25c87b89936f0d522cca0206418425c693c0933c95900953632cb1508acf69544b90f71326de1aa45994040c83084b8d278126792b2012a6c65962a1159ed2a89721ee264dbc3548b32800da2b9b6480772dc9beb8bfa4b36f32700650fd75514883ec4c9b787a91664ff1b45736c900ee5b937d717f4966de64e00ca1faeaa29107d89936f0f522cc9fe368ae6d9201dcb726fae2fe92cdbcc9c01943f5d545220fb1326de1ea45993fc6d15cdb2403b96e4df5c5fd259b7993803287ebaa8a441f6264dbc3d48b327f8663df41156d9b0818b7ee79ca9cd5a6ab2935972514a27ed4c9b787b91664fef588e40cf8415e3bae3c3f73149f8dcd011690ee1a295f3db9936f0f822cc9fdd3d2eda4bde8e4a2d944e165a8a4fe19acf1479c0452d8bb8326de1f145993fb906700d44937f1712f56254ad0afdeb304a6b4f7d8a5cbb7164dbc3e38b327f710ce01a8926fe2e25eac4a95a15fbd66094d69efb14b976e2c9b787c71664fee219c035124dfc5c4bd58952b42bf7acc129ad3df62972edc5936f0f8e2cc9fdc433806a249bf8b897ab12a56857ef5982535a7bec52e5db8b26de1f1c5993fb886700d44937f1712f56254ad0afdeb304a6b4f7d8a5cbb7164dbc3e38b327f7105a14013f464565167910bd99561b8e03f9ac4bae4b99122d9b787c72664fee1f403a5b2b62ed4ce4bee7a32aa29544029f9af3599733c85c36f0f8e5cc9fdc3d0c870f039c3d1c814a956e4d3b88afffeb7842b02e6934b96de1f1cc993fb879190e1e07387a3902952adc9a77115fffd6f085605cd26972dbc3e399327f70f2321c3c0e70f472052a55b934ee22bfffade10ac0b9a4d2e5b787c73264fee1e46438781ce1e8e40a54ab7269dc457fff5bc215817349a5cb6f0f8e64c9fdc3c8548348e69a344acc761d0ccbaee927f963c686ffe694ef97de1f1cca93fb878f3518ea7a0acb1850b900418f543077ed73cf69fccd2b8330bc3e399627f70f1d6a31d4f4159630a17200831ea860efdae79ed3f99a570661787c732c4fee1e3a60760295018ee3fab0c72e35472007b07b8003f034afb0c3f0f8e6599fdc3c734cfe5dd6d9804aad2e548462849e375ba34263dd69610588e1f1ccb43fb878e5260f145a89631812296f30bcff9a96b1f2c723b7d2c3af12c3e399697f70f1c94c1e28b512c6302452de6179ff352d63e58e476fa5875e2587c732d2fee1e392244eaa16fbeee3007282eaebf4c882c2775eeadc4b10604c0f8e65a6fdc3c723489d542df7ddc600e505d5d7e9910584eebdd5b89620c0981f1ccb4dfb878e461d4d0108c61e0eb996d1d3a7c980330489be076e2c4325313e39969cf70f1c8b3a9a02118c3c1d732da3a74f93006609137c0edc58864a627c732d39ee1e391601465ccfeedabd9e280d76971c5ef40cd33a79b5b10e38c5f8e65a74dc3c722b028cb99fddb57b3c501aed2e38bde819a674f36b621c718bf1ccb4e9b878e4560519733fbb6af678a035da5c717bd0334ce9e6d6c438e317e39969d370f1c8ac0a32e67f76d5ecf1406bb4b8e2f7a06699d3cdad8871c62fc732d3a6e1e391581465ccfeedabd9e280d76971c5ef40cd33a79b5b10e38c5f8e65a74dc3c722b028cb99fddb57b3c501aed2e38bde819a674f36b621c718bf1ccb4e9b878e4560519733fbb6af678a035da5c717bd0334ce9e6d6c438e317e39969d370f1c8ac02f40c0a443c151cbd381738625d82e64497f36d5871e06fd732d3a6f1e39157f5e8181488782a397a702e70c4bb05cc892fe6dab0e3c0dfae65a74de3c722afe49155b3de567c9e71acbf6108dbee18bd23f37531c79bff6ccb4e9bd78e455fb1e3d0f28a1321686025e141911dbeb1250c0caa338f523ee9969d37bf1c8abf53c7a1e5142642d0c04bc283223b7d624a181954671ea47dd32d3a6f7e39157ea0506954f5b2adccfd63e785c3dcdd443ef458689e3d633bb65a74df0c722afd30a0d2a9eb655b99fac7cf0b87b9ba887de8b0d13c7ac6776cb4e9be18e455fa6141a553d6cab733f58f9e170f737510fbd161a278f58ceed969d37c31c8abf4c2834aa7ad956e67eb1f3c2e1ee6ea21f7a2c344f1eb19ddb2d3a6f8639157e98506954f5b2adccfd63e785c3dcdd443ef458689e3d633bb65a74df0c722afd302ce502983bbe1cb29495337fb018b07894f32d397ac81b6db4e9be19e455fa5f59ca0530777c3965292a66ff603160f129e65a72f59036db69d37c33c8abf4be3fa6630dc55af5821f1af5f6b6c0e9dd000f10e2eb2211b7d3a6f8689157e97b0b5f1ec861186dbc0afc13e563dffbb4ac607dc2d645c770a74df0d222afd2f516be3d90c230db7815f827cac7bff76958c0fb85ac8b8ee14e9be1a4455fa5ea2d7c7b218461b6f02bf04f958f7feed2b181f70b59171dc29d37c3488abf4bd45af8f64308c36de057e09f2b1effdda56303ee16b22e3b853a6f8691157e97a842044532e7e95e787c87664e345de345724a382a645e1b0b74df0d232afd2f4f101ae312a6353fa8c5d4f4945f19ee8590d6cc51c8bdda17e9be1a4755fa5e9d2035c6254c6a7f518ba9e928be33dd0b21ad98a3917bb42fd37c348eabf4bd3a406b8c4a98d4fea31753d2517c67ba16435b314722f7685fa6f8691d57e97a740ce97142080c7ffdfb6dcc9aef2d9c2732f8be8b45f074c04df0d23bafd2f4e719d2e2841018fffbf6db9935de5b384e65f17d168be0e9809be1a4775fa5e9ce33a5c5082031fff7edb7326bbcb6709ccbe2fa2d17c1d30137c348eebf4bd39c674b8a104063ffefdb6e64d7796ce13997c5f45a2f83a6026f8691dd7e97a7385aa96ccd572a829783a2f1a6e937ea6ddbce44b15f08f005df0d23bbfd2f4e6f4165324784b787e6d40c0b45c8cdfcd663dee55fbe13840cbe1a4778fa5e9cdd0edcbd3bdfd1928574de3e8387fa21a7740026bc7c28ac1a7c348ef2f4bd39b91db97a77bfa3250ae9bc7d070ff4434ee8004d78f8515834f8691de5e97a73723b72f4ef7f464a15d378fa0e1fe8869dd0009af1f0a2b069f0d23bcbd2f4e6e402f8428bd4ef16e373b81c14362f35364c4391e0e14704d4e1a47798a5e9cdc705f08517a9de2dc6e77038286c5e6a6c988723c1c28e09a9c348ef314bd39b8e0be10a2f53bc5b8dcee07050d8bcd4d9310e4783851c13538691de6297a7371c17c2145ea778b71b9dc0e0a1b179a9b2621c8f070a3826a70d23bcc52f4e6e382f8428bd4ef16e373b81c14362f35364c4391e0e14704d4e1a47798a5e9cdc705f08517a9de2dc6e77038286c5e6a6c988723c1c28e09a9c348ef314bd39b8e04a22fba212283b94bacd2d05822b758dbd26d43551c2d939691de62a7a7371bf20584ff0fab2f9e142608202fab5131626900467a3875673d23bcc55f4e6e37d40b09fe1f565f3c284c10405f56a262c4d2008cf470eace7a47798abe9cdc6fa0d739870c12e6a3cd6483003e132745346826d9b8e1efdd048ef3158d39b8df31ae730e1825cd479ac906007c264e8a68d04db371c3dfba091de62b1a7371be635ce61c304b9a8f35920c00f84c9d14d1a09b66e387bf74123bcc5634e6e37cc6b9cc386097351e6b241801f0993a29a34136cdc70f7ee8247798ac69cdc6f98634bdfb8e94926853149283609856d2f146935b5e1f181058ef3158e39b8df2f52aa181ea8f4cfc22f58786409690258d514c768c3e4a60c1de62b1d7371be5d316688ea284c223c2b7718c009302cac566beace87caf0193bcc563be6e37cb962cd11d45098447856ee318012605958acd7d59d0f95e0327798ac77cdc6f97251ac7c5577930ba87aa28af81b1edaac05f207371f2d6465ef3158f09b8df2e32f6b5157c5889a08c20b3de82c9bdd52b8266a6b3e5c6cccde62b1e2371be5c55ed6a2af8b11341184167bd05937baa5704cd4d67cb8d999bcc563c46e37cb8a49bf9e0bec84eadad4f31f98a8cd9d458cdc05a9f9735734798ac789dc6f97131f9194c4af6c586d76ac672947f96285c5fa6750f2e85269f3158f14b8df2e253f2329895ed8b0daed58ce528ff2c50b8bf4cea1e5d0a4d3e62b1e2971be5c4a0a58abbf9413e46da777c49d1643b211c42bf940cba2eda8cc563c53e37cb89314b1577f2827c8db4eef893a2c8764238857f2819745db5198ac78a7c6f971262962aefe504f91b69ddf1274590ec84710afe5032e8bb6a33158f14f8df2e24c52c55dfca09f236d3bbe24e8b21d908e215fca065d176d4662b1e29f1be5c498319d14a617a0c992444271c95a994916ef01f009ba307e8dc563c53f37cb892f633a294c2f4193248884e392b532922dde03e0137460fd1b8ac78a7e6f97125e5286ab4534e5a900ddcfef1d60c34c56684a1c23e8c39e38158f14fddf2e24bb311faf37402dd4b988660632b7e4c0a77cd69444d188e0712b1e29fcbe5c4975623f5e6e805ba97310cc0c656fc9814ef9ad2889a311c0e2563c53f97cb892ea50911589d719d59dee5e40c2d5f12a989f9cad10462525c5ac78a7f3f97125d32d3483c084962df3a982a97da2407d2beb7bb61d8c4bef8c58f14fe8f2e24ba55a690781092c5be7530552fb4480fa57d6f76c3b1897df18b1e29fd1e5c4974a40e467aee8bb3a8672d0cdee7f601caa5a3134733131623263c53fa4cb892e930ddb280aa7d8f7c4b267c3d4f51e614f60a4c4e362646865c78a7f4a97125d251bb650154fb1ef8964cf87a9ea3cc29ec14989c6c4c8d0cb8f14fe952e24ba4a376ca02a9f63df12c99f0f53d479853d8293138d8991a1971e29fd2a5c4974946ed940553ec7be25933e1ea7a8f30a7b0526271b1323432e3c53fa54b892e92869c4d95753f1ff02f342654748443cf0b68eaa3326482a5d78a7f4aa7125d24f5f9c0b5b7e4680bdb34af28686e6a1dc195fb0634c91f8bbf14fe955e24ba49d4b4a6f63d2ef8433335c0d05042b6bb2df01bcc399259578e29fd2acc497493922a737747c418b1e337e4201feb4ff606a45d584324ccef2c53fa55a892e9271454e6ee8f883163c66fc8403fd69fec0d48bab0864999de58a7f4ab5125d24e216af367ec768af309abf2ffff132257c5559b20dc934dfcc14fe956b24ba49c32d5e6cfd8ed15e61357e5fffe2644af8aab3641b9269bf9829fd2ad6497493865abcd9fb1da2bcc26afcbfffc4c895f15566c83724d37f3053fa55ac92e9270c418c0ca311a7fc3ca2bfa7f77fef53dd570fec6b49a8a261a7f4ab5a25d24e170f2a71f2f9b27b31124577e6f63ccfb55a6234d39352e8c44fe956b54ba49c2d1e54e3e5f364f662248aefcdec799f6ab4c469a726a5d1889fd2ad6a9749385a3ca9c7cbe6c9ecc44915df9bd8f33ed56988d34e4d4ba3113fa55ad52e9270b40565e844a3f65c405ef1e72fa844a5a57f5402999a98ea237f4ab5ab5d24e1670acbd08947ecb880bde3ce5f50894b4afea805333531d446fe956b56ba49c2ce1597a1128fd971017bc79cbea1129695fd500a666a63a88dfd2ad6ad7493859c2b2f42251fb2e202f78f397d42252d2bfaa014ccd4c7511bfa55ad5ae9270b38565e844a3f65c405ef1e72fa844a5a57f5402999a98ea237f4ab5ab5d24e167038cf6141552e0ac3ab030decfef2dcaa96c2af30531ee870e956b56ca49c2cdf719ec282aa5c158756061bd9fde5b9552d855e60a63dd0e1d2ad6ad9493859be6f4fddb22b1aadc678d25fabf2299aa5074d18be4c7d45c4a55ad5b39270b37b6ab214112c97de44be6ae74fdab15d44badc8d7998fc2f8a4ab5ab6824e166f5617680cf2f923f41499bf697abc0e28421fb76f031fa0315956b56d149c2cde94eff5a4b3587013a5ffe15274ddfed02f03949dd63f5aa2c2ad6ada393859bd12a110d434170852c8cc25246921e02008cb4efb7c7ecf85955ad5b48270b37a154221a8682e10a591984a48d243c04011969df6f8fd9f0b2ab5ab6904e166f4234568db9dc249769ffcf71123ed62ffcdf161adc1fb5856656b56d219c2cde8368ad1b73b8492ed3ff9ee2247dac5ff9be2c35b83f6b0accad6ada433859bd065d6c8f9446f4e05fcc03ec40f1b6e7ee289ac76d7ed7b99a5ad5b48770b37a0b46eb77d5644c437764ce0079d9cbf7d6fd77ead7fdb11735b5ab690fe166f41519e948579efb09a6966228eba9f617a8a73231acfb63d26c6b56d220c2cde82933d290af3df6134d2cc451d753ec2f514e646359f6c7a4d8d6ada441859bd05267a5215e7bec269a5988a3aea7d85ea29cc8c6b3ed8f49b1ad5b48830b37a0a45b5c9b69ce3acfec7fd76f55460ee53fe5d3e964db2037645ab69107166f414742cb8f8072d82290cc7506a2827bf27a77ea2ec6b64212c9b56d220f2cde828d11a977adbc12c7d965b0353cfb560cef9c16b98a6c85c9946ada441f59bd05192352ef5b78258fb2cb606a79f6ac19df382d7314d90b9328d5b4883eb37a0a3246a5deb6f04b1f6596c0d4f3ed5833be705ae629b2172651ab69107d66f41464195e161ab6f8c182fa47d1dfd10e8f778cf82850642ff0a456d220fbcde828c732bc2c356df18305f48fa3bfa21d1eef19f050a0c85fe148ada441f79bd0518e6578586adbe3060be91f477f443a3dde33e0a14190bfc2915b4883ef37a0a31c570309828e288ecf9f04b6f67ed2a3b714039e8021812923b69107df6f4146373a186bb1f2b3a0570acf95e4f4036f68d44998fd4303f6486d220fbfde828c6d00433010bbc9c365e26553c1de6506cc54d58df786099091da441f80bd0518d900866021779386cbc4caa783bcca0d98a9ab1bef0c132123b4883f017a0a31b2010cc042ef270d9789954f0779941b31535637de1826424769107e02f414636402198085de4e1b2f132a9e0ef3283662a6ac6fbc304c848ed220fc05e828c6c80433010bbc9c365e26553c1de6506cc54d58df786099091da441f80bd0518d900866021779386cbc4caa783bcca0d98a9ab1bef0c132123b4883f017a0a31b2010cc042ef270d9789954f0779941b31535637de1826424769107e02f414636402198085de4e1b2f132a9e0ef3283662a6ac6fbc304c848ed220fc05e828c6c80433010bbc9c365e26553c1de6506cc54d58df786099091da441f80bd0518d90012727a2469e94e7c976dabb4c06bc0a4575e4b091322c7b5883f017b0a31b1ff24e4f448d3d29cf92edb576980d78148aebc961226458f6b107e02f6146363fe49c9e891a7a539f25db6aed301af02915d792c244c8b1ed620fc05ec28c6c7fc1fa629d025acf69c8833859df9bc2d1d6734b4459917e1ad41f80bd9518d8ff73f4c53a04b59ed3910670b3bf3785a3ace69688b322fc35a83f017b2a31b1fee0aaaffed6d165d29ed943e6fdd4edc7049152d1364612ab607e02f6646363fdb1555ffdada2cba53db287cdfba9db8e0922a5a26c8c2556c0fc05ecc8c6c7fb62aabffb5b45974a7b650f9bf753b71c12454b44d9184aad81f80bd9918d8ff6c5557ff6b68b2e94f6ca1f37eea76e38248a9689b230955b03f017b3231b1fed836c25783a7c85556a60a0ef5cb4beeff3d952d3346144f617e02f6656363fdaf6d84af074f90aaad4c141deb9697ddfe7b2a5a668c289ec2fc05eccac6c7fb5e671bb6bb7583d81264ee63cf238de3f7a29710ca1852e186f80bd9968d8ff6bb5a49c623c16a32dc96a2ef963d79efe9f1707d9130a7670ef017b32e1b1fed7540a5e4f45936e870fa0c0724715207ce8f23571f6150721ee02f665d363fdae90d5e229588d05399c0de3640d9023797ca890a3bc2a2883ec05eccbb6c7fb5d11abc452b11a0a73381bc6c81b2046f2f951214778545107d80bd9976d8ff6ba235788a5623414e670378d9036408de5f2a2428ef0a8a20fb017b32edb1fed7446af114ac46829cce06f1b206c811bcbe544851de151441f602f665db63fdae8861f482056367bc53daa98c058681a17754d2ffb92a2a27ed05eccbb7c7fb5d0f4ffb5cb79d31fb5f8219400303616ae955e85b6f5455f3db0bd997708ff6ba1d2c09121c10c67976d0f8a7fdfd20fdcd581312dba8ad8bb717b32ee21fed743958122438218cf2eda1f14ffbfa41fb9ab02625b7515b176e2f665dc43fdae8723c36a11d197c689310a8c7efeae21f300c8ea76ba2b7d2dd5eccbb897fb5d0e3047f9ae7095b53ddee17b7d7cc22665ac55faad4457149bbbd997713ff6ba1c508ff35ce12b6a7bbdc2f6faf9844ccb58abf55a88ae293777b32ee27fed7438a11fe6b9c256d4f77b85edf5f3089996b157eab5115c526eef665dc4ffdae871423fcd7384ada9eef70bdbebe611332d62afd56a22b8a4dddeccbb89ffb5d0e2847f9ae7095b53ddee17b7d7cc22665ac55faad4457149bbbd997713ff6ba1c501c05b58e01ccfe758fbd22f17aaaf3535837b685ae2adb78b32ee280ed74389f380b6b1c0399fceb1f7a45e2f555e6a6b06f6d0b5c55b6f1665dc501dae8713e7016d6380733f9d63ef48bc5eaabcd4d60deda16b8ab6de2ccbb8a03b5d0e27c6c40051ce4ca76644aaf3f83cbb5c2956e00102a71587fc6997714086ba1c4f7649262e69ff76f806224a6ff8dc9ad2588427c51e2b2a38e32ee2811d74389ed55371e7a165161b8910f75f711f18245bcc754a0c566eb1d65dc5024ae8713d9368095a103054628eee513e61a412c8625d1053e8acf7a3bcbb8a04a5d0e27b16d012b42060a8c51ddca27cc3482590c4ba20a7d159ef47797714094ba1c4f626614af30e2779b5b885a77905f62da13438670f72b3f8cf02ee2812a74389ec3583bb70e9b51b96edd7b1718b523dc21334f3deb5680bde15dc50255e8713d853c89c6ca0d05f59587bc562960a5e03d12e0d7d3ad031fc3bb8a04acd0e27b090525e640f06e6de2dc3ed44ab7a9e874d2040ba45a07e3887714095aa1c4f6110a4bcc81e0dcdbc5b87da8956f53d0e9a4081748b40fc710ee2812b54389ec2214979903c1b9b78b70fb512adea7a1d348102e91681f8e21dc50256a8713d844292f320783736f16e1f6a255bd4f43a690205d22d03f1c43b8a04ad50e27b088525e640f06e6de2dc3ed44ab7a9e874d2040ba45a07e3887714095aa1c4f611030cf20cae4303f1354a0b14eeb9b3694ecc3d08840fe150fe2812b55389ec21f619e4195c8607e26a941629dd7366d29d987a11081fc2a1fc50256aa713d843e4f4edbd867237f051f48ed33a4cb024e5f519e1e03f9f8408a04ad55e27b087b2ab0105da4a980c20b58025f3ff42c976ae5983907f5948214095aacc4f610f5556020bb4953018416b004be7fe8592ed5cb30720feb29042812b55989ec21ea36d29a23690885bffa263174f62eda5857d8bce11fd7f60950256ab413d843d36da53446d2110b7ff44c62e9ec5db4b0afb179c23fafec12a04ad56827b087a6675cc13a7a8499b7b55eedcbcf19915c0ba54f817f617c264095aad14f610f4b5acbdb21cb6bb6273784038f94914ab2c38cfafffec49c4d812b55a39ec21e9541aa0ef06d39ef063bce2f171f80bd60335c51fcfd8adc9c0256ab483d843d290f66768db0d660c444628626355fa2bb12fafff6fb175d3904ad56917b087a511ecced1b61acc18888c50c4c6abf457625f5ffedf62eba72095aad22f610f4a23d99da36c3598311118a1898d57e8aec4bebffdbec5d74e412b55a45ec21e94407460d1a5d1588d9efda5929a15b3dd3441a5bb4d8bc8dc9256ab48cd843d2870e8c1a34ba2b11b3dfb4b25342b67ba68834b769b1791b924ad56919b087a50e1d18346974562367bf6964a6856cf74d10696ed362f2372495aad233610f4a1c3a3068d2e8ac46cf7ed2c94d0ad9ee9a20d2dda6c5e46e492b55a466c21e943800732a52a7bb1056ca6bba920c12052eede8174a8bca809356ab48ce843d286f00e654a54f7620ad94d7752418240a5ddbd02e9517950126ad56919d087a50de01cca94a9eec415b29aeea48304814bbb7a05d2a2f2a024d5aad233a10f4a1bc039952953dd882b6535dd490609029776f40ba545e54049ab55a467421e943780732a52a7bb1056ca6bba920c12052eede8174a8bca809356ab48ce843d286f00e654a54f7620ad94d7752418240a5ddbd02e9517950126ad56919d087a50de01cca94a9eec415b29aeea48304814bbb7a05d2a2f2a024d5aad233a10f4a1bc039952953dd882b6535dd490609029776f40ba545e54049ab55a467421e943780732a52a7bb1056ca6bba920c12052eede8174a8bca809356ab48ce843d286f007266fdfc4c83304ca43b4c101a6885d67c70f1149502caae56919d097a50ddff70e054a56f68e351153cc0182b2f33a7a5243e262a07395dad233a13f4a1bbfd6dd301f7b5344959f73fa8284cbc8f49f68ad849541016bc5a467428e94377f967b85c9c40cb156bbb4578488fd7468e99580c8fa821d179b48ce852d286eff15b8311e557f8ad8f43511889160cb517def2751c504546f46919d0a6a50ddfe143187c778653ddd65368590a2277922a6a274635a08c31e9d233a14e4a1bbfc11243519be30a3e647396da0c3b4d4c4f8090e868411a07d4a467429d94377f812486a337c6147cc8e72db418769a989f0121d0d082340fa948ce853b286eff02490d466f8c28f991ce5b6830ed35313e0243a1a104681f52919d0a7650ddfe041e2ce58beeb475db697cf859d0c88a76b0c99f3f08d1e2a6233a14eda1bbfc073c59cb17dd68ebb6d2f9f0b3a19114ed61933e7e11a3c54c467429db4377f80e04c5eedc91345a2572ba095f398051d56f68d8f923492e998ce853b786eff01b098bddb92268b44ae57412be7300a3aaded1b1f246925d3319d0a76f0ddfe0361317bb7244d16895cae8257ce6014755bda363e48d24ba6633a14ede1bbfc06c262f76e489a2d12b95d04af9cc028eab7b46c7c91a4974cc67429dbc377f80d84c5eedc91345a2572ba095f398051d56f68d8f923492e998ce853b786eff01b024d0343efcedc766240753df266862a8995d7b21692777329d0a76f1ddfe035f49a0687df9db8ecc480ea7be4cd0c55132baf642d24eee653a14ede3bbfc06be1f5329a8ca19a0505ce377748fffb29d11b84882a49f80cb7429dbc877f80d7b3ea65351943340a0b9c6eee91fff653a23709105493f0196e853b790eff01af6095eff4ffec903f9405405ca365cf26ef3237e07927fa72ed0a76f22dfe035eb12bdfe9ffd9207f280a80b946cb9e4dde646fc0f24ff4e5da14ede45bfc06bd6257bfd3ffb240fe501501728d973c9bbcc8df81e49fe9cbb429dbc8b7f80d7ac4af7fa7ff6481fca02a02e51b2e79377991bf03c93fd3976853b7916ff01af5822024dacc2f2c24bd206849b5c2d4ee9de7a3c7627fc16ee0a76f22efe035eaf44049b5985e58497a40d0936b85a9dd3bcf478ec4ff82ddc14ede45dfc06bd5e141b8f5fe22d8be714e03a65671363a2262b4dd59ff1ffb929dbc8bcf80d7abb28371ebfc45b17ce29c074cace26c7444c569bab3fe3ff7253b79179f01af576506e3d7f88b62f9c5380e9959c4d8e8898ad37567fc7fee4a76f22f3e035eaec2ceed3abe7cee1f073c7fb232ef9450bdd9ccaa9ff91a1ca4ede45e8c06bd5d759dda757cf9dc3e0e78ff6465df28a17bb399553ff2343949dbc8bd180d7abae3fcda75c759e0a799be61484b2433c2a22b586a4fe482b2a3b7917a401af575b0bada765c19e97ab049251015ae4a04ef1ad6946fc91fa5576f22f49035eaeb5175b4ecb833d2f560924a202b5c9409de35ad28df923f4aaede45e9206bd5d6a2eb69d97067a5eac124944056b92813bc6b5a51bf247e955dbc8bd240d7abad45d6d3b2e0cf4bd582492880ad72502778d6b4a37e48fd2abb7917a481af575a846eccf08f04bfd6815eb380da4a82ce9c718f06cc92149586f22f49135eaeb4f19ebf6beb6fa7d87f89c98133fae81ce3a743cd6924436b1de45e9236bd5d69d33d7ed7d6df4fb0ff13930267f5d039c74e879ad24886d63bc8bd246d7abad3a67afdafadbe9f61fe272604cfeba0738e9d0f35a4910dac77917a48daf575a745b720ea28e366ef791aae891f3d2366c7fe442b19223598ff22f491c5eaeb4e742f675f1f2cf60a6f01bf91bde0294d3ac0ae16024485720e45e9239bd5d69cd11ff4490bc014405acfe1a2fb26351a204581ebd48925242c8bd24747abad39923fe89217802880b59fc345f64c6a34408b03d7a9124a485917a48e8f575a73247fd1242f0051016b3f868bec98d468811607af52249490b22f491d1eaeb4e641c0c7d32b66ca2e534b6f9758978b50acf0351e74494361745e923a4d5d69cc73818fa656cd945ca696df2eb12f16a159e06a3ce89286c2e8bd24749abad398e7031f4cad9b28b94d2dbe5d625e2d42b3c0d479d1250d85d17a48e93575a731c6c76424289c799e1727df3a44223d051245ceb3724a354bb2f491d27aeb4e63764fedd31e9f1b67ab1c20f407aa5c89cf4fc326b49484d775e923a505d69cc6d56101310aa45efad304a4678eba9b934963ac0d392923eefbd2474a1bad398d938327ece2aee62122d5ab4e9cdb19a63d8b7dda4252621e07a48e94475a731b17064fd9c55dcc4245ab569d39b6334c7b16fbb484a4c43c0f491d288eb4e63626cdc53e5821c0b008230fb9f2d24918a0f21d28d949a2b82e923a512d69cc6c365cb0077da9a98b8d1281f3650a74b0eca8601182935fb06d2474a26ad398d8557a8599c8b97b4296f16666497acbe18414e5e2d526d9a0ea48e944e5a731b093b630be5ed91eb0aaaf2f4c125b7a42b2edf1857a4dcd81e491d289db4e6361102d87078b18658cd22ac117a41cd70510a008cac49bb543d923a513c69cc6c2105b0e0f1630cb19a455822f4839ae0a2140119589376a87b2474a278d398d8420b61c1e2c61963348ab045e90735c144280232b126ed50f648e944f1a731b08416c383c58c32c66915608bd20e6b8288500465624ddaa1ec91d289e34e6361082d87078b18658cd22ac117a41cd70510a008cac49bb543d923a513c69cc6c2105b0e0f1630cb19a455822f4839ae0a2140119589376a87b2474a278d398d8420422e76d937f8b60077ca868869ba3c3d2c65870f6ed6b3658e944f1b731b083f106f465f4653eeb8bc5b3508c9d2a075050d6a1bddaf0acc1d289e37e636107d20de8cbe8ca7dd7178b66a1193a540ea0a1ad437bb5e15983a513c6fcc6c20fa41bd197d194fbae2f16cd423274a81d41435a86f76bc2b3074a278df98d841f40f8c8ba70901f87daf9fd03e44f32ba2d4adacdbed79fa61e944f1c031b083e71f19174e1203f0fb5f3fa07c89e65745a95b59b7daf3f4c3d289e380636107ce3e322e9c2407e1f6be7f40f913ccae8b52b6b36fb5e7e987a513c700c6c20f9c0876b5e51e7246a549c4a9ea1df7851151afc2dc6bd177104a278e028d841f3710ed6bca3ce48d4a938953d43bef0a22a35f85b8d7a2ee20944f1c051b083e6e21dad79479c91a952712a7a877de144546bf0b71af45dc41289e380a36107cdc43b5af28f392352a4e254f50efbc288a8d7e16e35e8bb882513c70146c20f9b8137db6febd86ed0c6910c699d5d6790fc73e89c3bd191505a278e029d841f36f26fb6dfd7b0dda18d2218d33abacf21f8e7d13877a322a0b44f1c053b083e6de4df6dbfaf61bb431a4431a675759e43f1cfa270ef464541689e380a76107cdbc280010a2c299eb1b154c5cc6a511f078e636aa1ae8ca4c2e13c7014fc20f9b77500021458533d6362a98b98d4a23e0f1cc6d5435d194985c278e029f841f36ee2c129b37e0ca2f2421f79b128aa5e9de451d0468a32ad4b94f1c0540083e6ddb5825366fc1945e4843ef3625154bd3bc8a3a08d14655a9729e380a80107cdbb63c5cc58c598b3f4854a4944220f5cf73c0b66d9f8cacf6e63c70150120f9b76b04cbe3c589790148760f507c3849c6e22daf373c195b91cd78e02a0341f36ed50997c78b12f20290ec1ea0f870938dc45b5e6e7832b7239af1c0540683e6ddaa132f8f1625e40521d83d41f0e1271b88b6bcdcf0656e4735e380a80d07cdbb54265f1e2c4bc80a43b07a83e1c24e37116d79b9e0cadc8e6bc701501a0f9b76a84cbe3c589790148760f507c3849c6e22daf373c195b91cd78e02a0341f36ed50258ed15e0582abc68eb0377eff970440622943802b73ddb01c0540693e6dda9f4b1da2bc0b05578d1d606efdff2e0880c452870056e7bb60380a80d27cdbb53e224d9e24ec6d31d2078705f3f4ba38fc34e769fdadd11ac1701501a5f9b76a7b449b3c49d8da63a40f0e0be7e97471f869ced3fb5ba23582e02a034bf36ed4f61548d140881749ffeae23fc7c9470beb7fe003f3b7460f06c0540698e6dda9eb2a91a281102e93ffd5c47f8f928e17d6ffc007e76e8c1e0d80a80d31cdbb53d655234502205d27ffab88ff1f251c2fadff800fcedd183c1b01501a639b76a7ac3658e2b1171cd2b723d8263640968756ab427b9aba321c3702a034c836ed4f576cb1c5622e39a56e47b04c6c812d0ead5684f7357464386e054069906dda9eae6575e37132d5cd945c26c0d0f8b84555594c4a67e8ca14dd0a80d321dbb53d5b56fe1f8f3c0e1de08513a999e7ceb2a55edaf0ccd195cdbb1501a644b76a7ab53a0e97cb4e7ebe78d6ed7b2bc5fb8d4569f83d96a32d3f772a034c8a6ed4f569002f8843735fffa97aa11e4f825542858032d72a465c22ef54069915dda9ead1005f1086e6bfff52f5423c9f04aa850b0065ae548cb845dea80d322bbb53d5a200be210dcd7ffea5ea84793e09550a1600cb5ca919708bbd501a645776a7ab44017c421b9afffd4bd508f27c12aa142c0196b95232e1177aa034c8aeed4f568802f8843735fffa97aa11e4f825542858032d72a465c22ef54069915dda9ead1005f1086e6bfff52f5423c9f04aa850b0065ae548cb845dea80d322bbb53d5a200be210dcd7ffea5ea84793e09550a1600cb5ca919708bbd501a645776a7ab44017c421b9afffd4bd508f27c12aa142c0196b95232e1177aa034c8aeed4f568802f8843735fffa97aa11e4f825542858032d72a465c22ef54069915dda9ead1005f1086e6bfff52f5423c9f04aa850b0065ae548cb845dea80d322bbb53d5a2004a33667a566128a2513f66014b683dfb779f0516708d61511a645777a7ab43ff207925a18324d3fc6f44f3fa8d2ea3f19b806629e11c66a334c8aef04f5687fd40f24b430649a7f8de89e7f51a5d47e33700cc53c238cd4669915de09ead0ffa0df6ef32e2f5d2a989d9f7e22b18b7c11a43f4a484733e8dd322bbc23d5a1ff31bedde65c5eba55313b3efc456316f823487e94908e67d1ba64577847ab43fe637dbbccb8bd74aa62767df88ac62df04690fd29211ccfa374c8aef08f5687fcc6fb7799717ae954c4ecfbf1158c5be08d21fa5242399f46e9915de11ead0ff986b814bdb05bfad506a65a61aa7e9a40c5081a64547358cde322bbc24d5a1ff2f6314f062e1e1dd58a191742d463170134d45a8878e6cbdbd6457784aab43fe5d523c39729a263d690fe9105282c1082146cdad0c1cdb1f7bc8aef0965687fcb9308acb920aaefd89ec98489cfbe0383d39ddb61539b7e2f8915de12dad0ff97161159724155dfb13d9309139f7c0707a73bb6c2a736fc5f122bbc25b5a1ff2e24e3d86f5011e78df7f274a6be5df08ef93b93451e6e12fe3457784b7b43fe5c3288d6696d89f7476cb14bccfc21c39d9d3b4c4a0cdc403c78aef0970687fcb85511acd2db13ee8ed9629799f843873b3a76989419b88078f15de12e0d0ff970a2e47f30838e05492f9191b36fecf0f61fb156e803711b31f2bbc25c2a1ff2e135c8fe61071c0a925f232366dfd9e1ec3f62add006e23663e57784b8543fe5c26453224cdb9e3d503b12a94d3f19a6582989815fddc48707daef0970b87fcb84b1676a2484a2a2cbf2f1b519fd992f2ffdd7287f8b89284fc5de12e180ff970952ced44909454597e5e36a33fb325e5ffbae50ff1712509f8bbc25c301ff2e12a59da892128a8b2fcbc6d467f664bcbff75ca1fe2e24a13f17784b8603fe5c2543fc76aef27b3e8b145a0b4f6c2f5bff997d69bc2c495cbe3ef0970c17fcb84a70ba12e8b25ca541a580791e57c49a7eddbef9382892d3bc8de12e183ff97094d17425d164b94a834b00f23caf8934fdbb7df2705125a7791bc25c307ff2e129a2e84ba2c97295069601e4795f1269fb76fbe4e0a24b4ef23784b860ffe5c25345d0974592e52a0d2c03c8f2be24d3f6edf7c9c144969de46f0970c1ffcb84a684625415f3307c45d4d3f464fbaf8a6d86b3b942592d5608ee12e1840f97094cf185cdb6b3c720b726744b4976c4f75ab82b9844825ac651ec25c3082f2e1299d30b9b6d678e416e4ce89692ed89eeb57057308904b58ca3d84b86105e5c2533a61736dacf1c82dc99d12d25db13dd6ae0ae6112096b1947b0970c20bcb84a6744ef93406b9f2de4b06ebccb358d9d556c20e7e3e2d64ccf712e1841897094ce72a04c0ba4a483f4dda9dc15ea811d2a8305f58795acb3def25c308322e1299cd5409817494907e9bb53b82bd5023a55060beb0f2b5967bde4b8610645c25339a34255b95ff837fef373d2d7296a5729b6dbfbde26b2e9bbd970c20c9b84a6733684ab72bff06ffde6e7a5ae52d4ae536db7f7bc4d65d377b2e1841937094ce665ca7c704d4708274a9baddc250f3f26863415386acbc12f75c308327e1299ccb4561e6b67f4387a1203be37c98460ccb72c5030a5979c9efb8610650c253399516d62619d4e991fa0d3deef126ea419191cc6211b2f537e070c20ca284a673292dac4c33a9d323f41a7bdde24dd483232398c42365ea6fc0e1841945094ce6525b58986753a647e834f7bbc49ba9064647318846cbd4df81c308328a1299cca442c3897b7daf128836b59f812db034873aa56c8a97ab6304861065152533994711996ba3d1c0a7c83a3166fa51be9109218d35122f586a0a0c20ca2b4a67328d2332d747a3814f907462cdf4a37d2212431a6a245eb0d4141841945694ce651a4665ae8f47029f20e8c59be946fa44248634d448bd61a828308328ad299cca3418ddb5cb6467c0f99e515fca8452b043b8ac048e7ac4f4516106515b5339946731bb6b96c8cf81f33ca2bf9508a560877158091cf589e8a2c20ca2b6a67328ce6376d72d919f03e679457f2a114ac10ee2b01239eb13d1458419456d4ce6519c53000707f9a08a84bf51264c18f3aa1871a28070d629468c08328adb99cca337321266bcc9a397c14b68749028457c2b8f875cdeac543119106515b83399466d6424cd7993472f8296d0e920508af8571f0eb9bd58a8623220ca2b7067328cda545bf39ffcf0e1bcfa67fa38977418a8ea5fcf77b1526865419456e1ce6519b334ca3fecd0444631c1961c692546594c8101faec62a674cb8328adc49cca336569947fd9a0888c63832c38d24a8cb2990203f5d8c54ce99706515b89399466ca5f3b586017739b7ed31e999c8b778d2cb04a47ae8a9b772f0ca2b7137328cd934a89096d0549b9b573035b310d4d42540cd6eb5a1538925f19456e27e6519b2521246b86e0f5f622b2ccde5a10f8aca2c5f032b12a72c8bf328adc50cca336494248d70dc1ebec456599bcb421f159458be0656254e5917e6515b8a199466c9210a406c85a3a5b4297f9a1603a40da85c40326c1a9ccc6fdca2b7144328cd92321480d90b474b6852ff342c07481b50b88064d8353998dfb9456e2886519b24642901b2168e96d0a5fe68580e9036a17100c9b06a7331bf728adc510ca33648c11328eefa8355ccc8c9332f9c864fc28cc5b920a4e67dbef515b8a229466c91722651ddf506ab999192665f390c9f85198b724149ccfb7dea2b7144528cd922e44ca3bbea0d57332324ccbe72193f0a3316e4829399f6fbd456e288a519b245c15a6d02a180d691c315fbfc6398609410f1eec4f7340837b8adc5115a33648b72b4da054301ad23862bf7f8c730c12821e3dd89ee68106f715b8a22b466c916e569b40a86035a470c57eff18e61825043c7bb13dcd020dee2b7144568cd922dc3948d9fd96cdcb9957c42629c28e72032539be789a05bfdd56e288ae19b245b77291b3fb2d9b9732af884c53851ce4064a737cf1340b7fbaadc5115c33648b6e7135c0a33199b11d2bd6c09f0097f007412955df6818a3765b8a22b966c916db6e7dd9f33995e4f22473a935f78e08092e9507bbd032eaedb7144573cd922db5690e0c93498e4c9c15ad7a63e57a380d096c6b74a06779dc6e288ae89b245b695e2e71d3697f1beff8211cbfc1529814bf1b32e640d097b9dc5115d23648b6d1486f3c53a960ba97bd086177790358242a78c1c981a2d374b8a22ba56c916da11cf0d1542923f7e746d6eae6e864d8430133df9003474aea7144574bd922db4139e1a2a85247efce8dadd5cdd0c9b0860267bf20068e95d4e288ae97b245b68273c34550a48fdf9d1b5bab9ba193610c04cf7e400d1d2ba9c5115d2f648b6d047398e34e1f8241f2037d7f2f3984ea12b5e1587d1a3bfb548a22ba5fc916da0773441f491567069bd3c126566967fc2018050cf734799aaa144574c0922db40d729a973f01308fef744874a4c92e203adc4c75eb68f4d955288ae982245b68197147872ad8c3a296b557114188ba687064db47d3d1eb56ab5115d30548b6d0316ea1670287e9c7e537744a7b07d2f8db75f8eba4a3d85157a22ba60b916da061695526b1e63612823baebcee060419b19834334647b246b044574c1822db40c15ebca610a2cea7bc4423a1d402665b5ddcaac2898f66316188ae983145b68181498ba4ce1bffd230550d6b9ffb2adeb66597e1101ece06c4115d30638b6d03011f29a2490e62271876e0ff37ecb3e56777721e1d3d9db18922ba60c816da06013e5344921cc44e30edc1fe6fd967caceeee43c3a7b3b63124574c1902db40c0208b8e1d10feb1f19a84a24d7a92dbd988a0ad471f6786a258ae983215b6818031171c3a21fd63e33509449af525b7b311415a8e3ecf0d44b15d30642b6d0300622e387443fac7c66a128935ea4b6f662282b51c7d9e1a8962ba60c856da0600c45c70e887f58f8cd425126bd496decc45056a38fb3c3512c574c190adb40c01817a075bdd514745251687572893a01834cefa31c67884659ae983216b681802f2f40eb7baa28e8a4a2d0eae51274030699df4638cf108cb35d30642d6d03005e5e81d6f75451d14945a1d5ca24e8060d33be8c719e211966ba60c85ada0600bc4916069b7f06254a5809d38c402e341513bf74e03c43d6ce74c190b6b40c01771e3e65e3d46ecd4c7cd9cf1076ba9024d3c145bd7889519de983216e681802ed3c7ccbc7a8dd9a98f9b39e20ed752049a7828b7af112a33bd30642dcd03005da050bf03c281db7e9c02d6439d148688dfb4772f2e226ea78a60c85baa0600bb30a17e078503b6fd3805ac873a290d11bf68ee5e5c44dd4f14c190b7540c01766142fc0f0a076dfa700b590e74521a237ed1dcbcb889ba9e2983216ea81802ecc285f81e140edbf4e016b21ce8a43446fda3b9797113753c530642dd503005d9850bf03c281db7e9c02d6439d148688dfb4772f2e226ea78a60c85baa0600bb302d906031da197fefd272af321f6b39ba1530ba5944def315c190b7550c01765f5b20c063b432ffdfa4e55e643ed673742a6174b289bde62b83216eaa1802ecbe4253d9743ec882771690e4c0740b0ee301054562137d70580642dd553005d97b10ba0b9553f387a5f9e7f178de7445c0ae4ce6c126fc84b10c85baab600bb2f52174172aa7e70f4bf3cfe2f1bce88b815c99cd824df90962190b7556c01765ea42e82e554fce1e97e79fc5e379d11702b9339b049bf212c43216eaad802ecbd411e2b55775febfe79c05b3beea0056001ea9920637e5c989642dd55c005d97a723c56aaeebfd7fcf380b677dd400ac003d53240c6fcb9312c85baab800bb2f4e478ad55dd7faff9e7016cefba80158007aa64818df97262590b7557001765e9c1b280368865881f4acf3c5ef4660d7fba18eec2ebf2ff04c216eaae102ecbd37365006d10cb103e959e78bde8cc1aff7431dd85d7e5fe09842dd55c205d97a6e6ca00da2196207d2b3cf17bd19835fee863bb0bafcbfc13085baab840bb2f4dc655273f10926925d346457722964e7d7b8b9bd72f98126620b7557091765e9b756b7408ee8afa772358ed6dc4927f7aa1db5d6e2f303f0c516eaae132ecbd36d3980d9caa7c1d19c37e3d5b088ae174ee7ae09c2e609858b2dd55c275d97a6d97301b3954f83a3386fc7ab61115c2e9dcf5c1385cc130b165baab84ebb2f4db27215bfd77569c928ac557eba191685364afa83089827ba2db755709e765e9b63703dd85bc13615092571256c288b32674237620e3051185c6eaae13decbd36c56c8e096458ceacca17a872d047748cc930b1201960a3d4b9dd55c27cd97a6d89652e6b7587ffdc4bfc170d988547418d0da49c2fc1494d74baab84fab2f4db11566f2f97e6623b4fc4f4432900ecab14c78b945c82943eea755709f665e9b62138f0b7dca326f95756aeae49f8377e243b5984b6052a21d5eaae13edcbd36c4171e16fb9464df2aead5d5c93f06efc4876b3096c0a5443abd55c27db97a6d8826fd5381f62fe68152780e11fd73c208b99a86ed514aa2b58aab84fb82f4db1036bbcc8eb9c5f52e21bc7ea37a4d66911df9339a72955fab255709f715e9b6205638bea840f21287c0455fc67400afa1e6b68cf4b52ad9965aae13ee3bd36c409532a2db4f4a4d3afd57220c676741c378313fa93a55cd6cc55c27dc87a6d88113266b416bfac2a1777aa6984e3466069b26a51244abb5199ab84fb91f4db102164cd682d7f58542eef54d309c68cc0d364d4a2489576a3335709f723e9b6204255ad2907d5132b15ab6fce0b8377a9a175eba08e2aeeea67ae13ee48d36c4083376caabc8088d8e323a5c40efd4d7b3d98199d1955df78d05c27dc92a6d881056ed955790111b1c6474b881dfa9af67b30333a32abbef1a0b84fb9254db1020a69c5039ed885e6445b5d3833eb9414f10ca8d062577f8742709f724b9b6204135f9c5fea876e4f408380985fcd8651dcc593fcc1af00b285e13ee49836c408254b4b1881e53f2138d3c758b7916acbb4376a55805e03090cc27dc9316d88104922a889b0a0e0c5297454d9671933bf631b1706fdbc07b61a84fb9263db1020914551136141c18a52e8a9b2ce32677ec6362e0dfb780f6c3509f724c7b620412216b47f6f59e5975d9e198d945b2d2587189e77f3f0207c6b13ee49906c4082432d68fedeb3cb2ebb3c331b28b65a4b0e313cefe7e040f8d627dc9320d88104865ad1fdbd67965d76786636516cb4961c6279dfcfc081f1ac4fb92641b102090c41b65427a58f3da4bd92949acfc7543371361b9c810587599f724c84620412170f7f00fc2180fe0147eb512d95ecd0618eae9336020cb2b43ee49909c408242d1efe01f84301fc028fd6a25b2bd9a0c31d5d266c041965687dc932138810485a3dfc03f08603f8051fad44b657b341863aba4cd80832cad0fb926427102090b4080a608de26a72c20c20b164a5c4ab0721b6f5ad106739a2f724c84f204121671014c11bc4d4e584184162c94b89560e436deb5a20ce7345ee49909e408242ce2029823789a9cb083082c5929712ac1c86dbd6b4419ce68bdc93213c8104859c4053046f1353961061058b252e2558390db7ad688339cd17b926427902090b380cb8618afd09aed88ed13e4252a8d86cc7b1b6ce06753e30724c84f30412166f1970c315fa135db11da27c84a551b0d98f636d9c0cea7c60e49909e608242cde32e1862bf426bb623b44f9094aa361b31ec6db3819d4f8c1c93213cc104859bc65c30c57e84d76c47689f2129546c3663d8db67033a9f183926427982090b3785798715ca6fd7040b9da0c1d20ebaec7275dc8dd6755870824c84f31412166ef3b433b66245d6339407a403238358588fafdedb7ceacb21149909e638242cddd0298cf791f1d492a4dbaa85c66c9330ca23e376c9d5b082393213cc804859bb905319ef23e3a92549b7550b8cd926619447c6ed93ab6104726427990090b37720a633de47c7524a936eaa1719b24cc3288f8ddb2756c208e4c84f32012166ee414c67bc8f8ea49526dd542e33649986511f1bb64ead8411c9909e640242cddc8298cf791f1d492a4dbaa85c66c9330ca23e376c9d5b082393213cc804859bb905319ef23e3a92549b7550b8cd926619447c6ed93ab6104726427990090b37720324636f49db4cd4b3b703f11a8aaeb233bd0372456c3ace5c84f32022166ee3f648c6de93b699a9676e07e235155d64677a06e48ad8759cb909e640442cddc7e552b347f4d35b7e4ba87243e9909d4879b83388e5b105798213cc809859bb8fb3668c1ab70cdf28141d470752871d109e348cd19b6225331427990140b3771f56cd18356e19be50283a8e0ea50e3a213c6919a336c44a66284f32028166ee3ea65b55f5a999a4cbcd417e9cc98256c2239659063d88af0c609e640512cddc7d3577d176209971c3174f5fb9126a9003f1f0d7cc4b117858d13cc80a359bb8fa53b0c8770e990bb1ab6b21f1a43b02878ea5d55866230af1b27990147b3771f49022b678ea983f8ed3a2a662c7dbe78ec80fd0709c46302374f32029066ee3e910456cf1d5307f1da7454cc58fb7cf1d901fa0e1388c6046e9e640520cddc7d2208ad9e3aa60fe3b4e8a998b1f6f9e3b203f41c27118c08dd3cc80a419bb8fa44115b3c754c1fc769d1533163edf3c76407e8384e231811ba799014833771f48822b678ea983f8ed3a2a662c7dbe78ec80fd0709c46302374f32029066ee3e910456cf1d5307f1da7454cc58fb7cf1d901fa0e1388c6046e9e640520cddc7d22016ec3c573760be06575fb31765fc631aeb841e6e18c231d4cc80a41abb8fa43f2dd878ae6ec17c0caebf662ecbf8c635d7083cdc318463a999014835771f487e5bb0f15cdd82f8195d7ecc5d97f18c6bae1079b86308c7533202906aee3e90fc43743b66916872ea87c3c0b3264140d208634f6dc61332a7640520d6dc7d21f712facf79f933688cdc4da95e42e0a99ebd08fad88c28094fc80a41aeb8fa43ed25f59ef3f266d119b89b52bc85c1533d7a11f5b11850129f9014835d71f487da4beb3de7e4cda2337136a5790b82a67af423eb6230a0253f202906bae3e90fb423e8d47c9ffdc71eaf3372ea0d6374f0948a32c16141ee7f40520d76c7d21f6747d1a8f93ffb8e3d5e66e5d41ac6e9e129146582c283dcfe80a41aed8fa43ece1bb5aa9f56599f328993f3a02bebfbbcfe6b270285095dfe014835dc1f487d9b376b553eacb33e651327e74057d7f779fcd64e050a12bbfc02906bb83e90fb366ed6aa7d59667cca264fce80afafeef3f9ac9c0a142577f80520d7707d21f66c69bfada7892f7c4c1965c4f955be05e29f9b9411284c93f10a41aee1fa43ecd75f91b3fbe8c17b4fff91b1eaa1da33bfeb79841f509acbe314835dc4f487d9ad4b35c0a4a7e57957cbe98bcd3a128f7a8335643ba1373bc72906bb8ae90fb359227dd9f6262d756764993f926a8346efb2ad247442701b8f520d7716d21f66b144fbb3ec4c5aeacec9327f24d5068ddf655a48e884e0371ea41aee2da43ecd621609c0856f1858555f2b2641a06b43b976f6edce09c2123e4835dc5c487d9ac32c13810ade30b0aabe564c8340d68772ededdb9c1384247c906bb8b890fb358658270215bc6161557cac990681ad0ee5dbdbb738270848f920d7717121f66b0c3c605cd84f254562c61f5a04f9b845c663f9ca6d4e1235f341aee2e343ecd61704d3125d74ad0d7d5904dc01e9ceb3877435f0d79c260fe7835dc5c787d9ac2d09a624bae95a1afab209b803d39d670ee86be1af384c1fcf06bb8b8f0fb3585a134c4975d2b435f564137007a73ace1dd0d7c35e70983f9e0d77171e1f66b0b4269892eba5686beac826e00f4e759c3ba1af86bce1307f3c1aee2e3c3ecd61684d3125d74ad0d7d5904dc01e9ceb3877435f0d79c260fe7835dc5c787d9ac2d02674a45b6c043262ed61a835303498e9330076f084c3a0f16bb8b8f1fb35859f4ce948b6d80864c5dac3506a606931d26600ede1098741e2d77171e3f66b0b3e25e4ea1a86734c43824cc8ccb7308b9f784437bf131027c6aee2e3c8ecd6167b4bc9d4350ce69887049991996e61173ef0886f7e26204f8d5dc5c791d9ac2cf623a60116f02fb3c5d5f94b2ad32056788d533af94c42431bbb8b8f24b35859eb474c022de05f678babf29655a640acf11aa675f29884863777171e4966b0b3d61aaa5d08972151cf24ab54a342df81dce18f47e2310ab06fee2e3c93cd6167ab3554ba112e42a39e4956a94685bf03b9c31e8fc4621560dfdc5c79279ac2cf566aa974225c85473c92ad528d0b7e0773863d1f88c42ac1bfb8b8f24f35859eac616540f18f6d1130f220cd120d5a36e1b8bc9b0e885727807171e49f6b0b3d574edcda8ff53ca519b107c21c111295be1dbb921a10aff301e2e3c93fd6167aad29cc0dccc0dbcceb2ed5ac3018835376e7b9803121618a04c5c79280ac2cf55953981b9981b799d65dab58603106a6edcf73006242c314098b8f25015859eab233428fdfd9d1b664881cd8b8586b75d64b285cc18587cc14171e4a03b0b3d56366851fbfb3a36cc91039b170b0d6ebac9650b9830b0f98282e3c94076167aac6591c982c3da95c49ed398ad9580bff53d8e3cf031620d4515c79280fc2cf558b3e4b890551b53b4ba7393daaa67626a25e09fa032c434ca3b8f25020859eab1508a96ab779ccf94f1b38a34d434a753f6856500358883d4871e4a0420b3d56291152d56ef399f29e3671469a8694ea7ed0aca006b1107a90e3c94084167aac5222a5aadde733e53c6ce28d350d29d4fda159400d6220f521c79281082cf558a4454b55bbce67ca78d9c51a6a1a53a9fb42b2801ac441ea438f25021059eab14816a90424733217a980505ccc2b057bf131a75c32888578881e4a0421b3d5628f2d520848e6642f5300a0b998560af7e2634eb865110af1103c94084367aac51e5aa41091ccc85ea601417330ac15efc4c69d70ca2215e22079281086cf558a3c415a79d06ff34003cf490e594e8a0784397d3d91442d6841f250210e9eab14770ec74c4db64902bf6b5844aa937237031f3cd71f885c7484e4a0421e3d5628ed1d8e989b6c92057ed6b0895526e46e063e79ae3f10b8e909c940843c7aac51da3b1d3136d9240afdad6112aa4dc8dc0c7cf35c7e2171d21392810878f558a3b4024cbb1a88aa98b327884d4c91efe013a62914f942e54828250210f2eab1476704997635115531664f109a9923dfc0274c5229f285ca90504a0421e5d5628ece0932ec6a22aa62cc9e21353247bf804e98a453e50b9520a0940843cbaac51d9c1265d8d44554c5993c426a648f7f009d3148a7ca172a414128108797558a3b3824cbb1a88aa98b327884d4c91efe013a62914f942e54828250210f2eab1476704997635115531664f109a9923dfc0274c5229f285ca90504a0421e5d5628ece01f411f4f0108af81aed97b1c72562ce436879a4db953ae0a40843cbbac51d9bf3e823e9e02115f035db2f638e4ac59c86d0f349b72a75c148108797758a3b37e0916d5e8da8540be882c1469bfb6db8b8660c533e5505c2a0210f2efb14766fb122dabd1b50a817d105828d37f6db7170cc18a67caa0b8540421e5df628ecdf6245b57a36a1502fa20b051a6fedb6e2e198314cf954170a80843cbbec51d9bec48b6af46d42a05f44160a34dfdb6dc5c3306299f2a82e1501087977d8a3b37d81d7fb73a7eb68ea04f876e93f1cbe0b3124eaf3b550766a1210f2efc14766faf3aff6e74fd6d1d409f0edd27e397c166249d5e76aa0ecd42421e5df828ecdf5e02113596d13cbd390ae3e247bd8daac6f57d18ea541f3e85843cbbf151d9bebb04226b2da2797a7215c7c48f7b1b558deafa31d4a83e7d0b087977e2a3b37d760844d65b44f2f4e42b8f891ef636ab1bd5f463a9507cfa1610f2efc54766faec1089acb689e5e9c8571f123dec6d5637abe8c752a0f9f42c21e5df8a8ecdf5d82113596d13cbd390ae3e247bd8daac6f57d18ea541f3e85843cbbf151d9bebb04226b2da2797a7215c7c48f7b1b558deafa31d4a83e7d0b087977e2a3b37d760105fbe612591d0fa85beb9e759c8d9b80b88969207d145620f2efc55766faebf20bf7cc24b23a1f50b7d73ceb391b37017112d240fa28ac41e5df8aaecdf5d7e417ef984964743ea16fae79d672366e02e225a481f4515883cbbf155d9bebafc0f104bb602f10a8bfabbf732c4a4f5bb0887108d3e8bcf117977e2acb37d75f71e20976c05e21517f577ee658949eb76110e211a7d179e22f2efc55966faebee3c412ed80bc42a2feaefdccb1293d6ec221c4234fa2f3c45e5df8ab2cdf5d7dc0494b65cedead717a2a5e18e1b85d5d2f07ae066f4601c8ccbbf15669bebafb709296cb9dbd5ae2f454bc31c370baba5e0f5c0cde8c03919977e2acd37d75f6e1252d973b7ab5c5e8a9786386e17574bc1eb819bd18072332efc559a6faebedc24a5b2e76f56b8bd152f0c70dc2eae9783d70337a300e4665df8ab34df5d7db8494b65cedead717a2a5e18e1b85d5d2f07ae066f4601c8ccbbf15669bebafb701ea9244a93bd65ac218259bb6718e258bb9e68db8c05359a77e2acd47d75f6df3d524895277acb584304b376ce31c4b1773cd1b7180a6b34efc559a8faebedbe06b6e9d72558196852cf8ee592c1b15d9abbff6b30167a6adf8ab352f5d7db7b0d6dd3ae4ab032d0a59f1dcb258362bb3577fed6602cf4d5bf1566a5ebafb6f61adba75c956065a14b3e3b964b06c5766aeffdacc059e9ab7e2acd4bd75f6dec35b74eb92ac0cb42967c772c960d8aecd5dffb5980b3d356fc559a97aebedbd86b6e9d72558196852cf8ee592c1b15d9abbff6b30167a6adf8ab352f5d7db7b062ef93918165afc226b804aa4e9453ae03c2496302d0f15cf1566a5fbafb6f5f51f17fcfd92de23c1a36314c9386cf56b3c6eec305a386bae2acd4c075f6debd2ff5584c88be473001328a911d6bc6a813d039830b48b176c559a981ebedbd795feab099117c8e60026515223ad78d5027a07306169162ed8ab35303d7db7af24be7b9def95b9f77d190523c6c0d429afb8342092d2469dc1566a608afb6f5e323e1cc6ac919c1a76fe6cc70ce78ad30a348e00f5a4a77b92acd4c125f6debc547c398d59233834edfcd98e19cf15a614691c01eb494ef72559a9824bedbd78a1b998a57fac989558c6159bb3040dcbd3965dc3a692b82e5ab35304a7db7af13373314aff59312ab18c2b3766081b97a72cbb874d25705cb566a6094fb6f5e266e66295feb262556318566ecc10372f4e59770e9a4ae0b96acd4c129f6debc4c68deab6cacaecd642fd0f5d178650de477713dd0495dbb2e59a98254edbd78975dcfaf862fc01d802c68139ae72843c39b24d79d92bd1a5db35304aadb7af12d47b1b7b935e2bdb825964f2dc4aeaf81e28c0b38257bd8bc66a60956b6f5e2591b75c81f4227fe2817f2c6537fbb86fe715a726d4af95579cd4c12ae6debc4b136eb903e844ffc502fe58ca6ff770dfce2b4e4da95f2aaf39a98255cdbd789626dd7207d089ff8a05fcb194dfeee1bf9c569c9b52be555e735304ab9b7af12c467c099a6e7a273f88c5c5a93f43a5fee3715ef6757cc4fcf6a6095746f5e25875b938bfaa5a76aa8e57edd1fded2e7d71a6e3acbaf9a439fd4c12ae9debc4b0d433970a221b1580997c3e237b403f7a8e11ed1945f362b40a98255d4bd789619128539f119c532cafc4dec675e66174c6e7fff25be6dfa825304abaa7af12c31250a73e2338a6595f89bd8cebccc2e98dcfffe4b7cdbf504a6095754f5e258624a14e7c46714cb2bf137b19d79985d31b9fffc96f9b7ea094c12aea9ebc4b0c4203c2835a48c190faf358b32e98ee25e2042552af371781398255d54d78961874078506b4918321f5e6b1665d31dc4bc4084aa55e6e2f027304abaa9af12c30e0d02f9836892e6f6899c54c39c99b1732d4bb0a8cdc7844f609575545e25861b1a05f306d125cded1338a987393362e65a9761519b8f089ec12aeaa8bc4b0c36340be60da24b9bda2671530e7266c5ccb52ec2a3371e113d8255d5517896186c6817cc1b449737b44ce2a61ce4cd8b996a5d85466e3c227b04abaaa2f12c30d85c41f0e35f90f220668b7431bff93f2d80fd6689dc79e8f709575546e25861af44963a73958466f899dd105b7650a655ae3d2910b8f575ef12aeaa8ec4b0c35d153ecd94016b50a9008048aee2ff74a608bcae1e71ec8fdf255d551e896186b92a7d9b2802d6a1520100915dc5fee94c11795c3ce3d91fbe4abaaa3d12c30d7254fb365005ad42a4020122bb8bfdd29822f2b879c7b23f7c9575547a25861ae43608c54ce1bd07ffd0c86d6f0e59cd2af227ccf08f6622fa2aeaa8f54b0c35c76c118a99c37a0fffa190dade1cb39a55e44f99e11ecc45f455d551ea96186b8e64356de05d56a2b70fe7ddb42fc55ca674e18fbf3d9a2fe9abaaa3d62c30d71b547d346d910fc825ec95e36055e8e14796057b7b7b3603d4575547ad5861ae35350cc187f8821303a5f1eeb8a22fea89d84d52f3f66daba9aeaa8f5bb0c35c696a19830ff10426074be3dd71445fd513b09aa5e7ecdb57535d551eb76186b8d260455eccb86acec6648de2da7f1dd2220d77a7ccd9b852a7baaa3d6fc30d71a34c9d16464738204495e1edacf499cc3ec731ab96b372495075547ae0861ae345254c853964d2c340f88a0351df91c0783aa5b32a66e636a1eaa8f5c20c35c6894a990a72c9a58681f11406a3bf2380f0754b6654cdcc6d43d551eb84186b8d1221446d9269ad8fbbaeee353f74a529db96d928a69b9a7e88aaa3d70930d71a234288db24d35b1f775ddc6a7ee94a53b72db2514d3734fd115547ae1261ae344611240ef67d18c1a6887efcf5c8f2cf6907a6fe976e6b9e23aa8f5c25c35c688b22481decfa31834d10fdf9eb91e59ed20f4dfd2edcd73c47551eb84b86b8d11644903bd9f463069a21fbf3d723cb3da41e9bfa5db9ae788eaa3d70970d71a22c1532d060bf288fec10be0fa63df4a342e97a50b8735e951e547ae12f1ae344572a65a0c17e511fd8217c1f4c7be94685d2f4a170e6bd2a3ca8f5c25e35c688ae54cb4182fca23fb042f83e98f7d28d0ba5e942e1cd7a547951eb84bc6b8d115c35a8dbb2cfa7021852b6a529e6034211f814e1c09af64cf3a3d70979d71a22b76b51b7659f4e0430a56d4a53cc068423f029c38135ec99e747ae12f3ae34456e62b5c77814fe8b1917a0bc9f8e6b30428c95e2ff6bdad7cf8f5c25e85c688adb517de79d005f98e9fc07a1371334887fc56e21fbd7b753a01eb84bd1b8d115b52f0e27e6d721b48bc4d56a661cc738fa371e9ff4af704b413d7097a471a22b695e1c4fcdae43691789aad4cc398e71f46e3d3fe95ee096827ae12f48e34456d2484af84832e954e6e01bd190697b0be388bcdbcfbdc2d105f5c25e92c688ada31ca8493d3c352c858cfdcb18c9543fc1bdbc139c7b87460ceb84bd268d115b453950927a786a590b19fb963192a87f837b782738f70e8c19d7097a4d1a22b68a72a124f4f0d4b21633f72c632550ff06f6f04e71ee1d1833ae12f49a34456d147154a296b80be6e434b480be410026089a22f8e0dc3bd4685c25e935688ada276ebb9dda467a5080362f2974785e740be0884dbeb8794cd1b84bd26bd115b44d69899461635723b839247ae0e71b10126d52f77a70f43da47097a4d8a22b68995f25816f9d10ca283f0f1db9c494481f86e84af1e1ea1f49e12f49b24456d1314a5d5b8c108417084ae4636b7f86b839ba12f1e0c3d5e294c25e936588ada26120cd0fc4f76ab0c8628eeecef56b986e20683fbe87ad692a84bd26cc115b44c1419a1f89eed56190c51ddd9dead730dc40d07f7d0f5ad255097a4d9822b689820f4697c0b40d45d95701e333cc0c89b32de35af71eb748ab12f49b31456d13031e8d2f81681a8bb2ae03c667981913665bc6b5ee3d6e915625e936628ada26063d1a5f02d03517655c078ccf303226ccb78d6bdc7add22ac4bd26cc515b44c0c064716b276ccb18284d5419656c275941b5d33b5f5bbe95997a4d98b2b6898170c8e2d64ed99630509aa832cad84eb2836ba676beb77d2b32f49b31656d1302e191c5ac9db32c60a135506595b09d6506d74ced7d6efa5665e93662cada2605c3238b593b6658c1426aa0cb2b613aca0dae99dafaddf4accbd26cc595b44c0b864716b276ccb18284d5419656c275941b5d33b5f5bbe95997a4d98b2b689817054f52efbaff8b308676e5ac2ceacda7e17e8d2bbb77ecf33f49b31666d1302df35fcb6a43653e8c89ba2dd7d93b7dcf6dc1401746eff4268e93662cdda2605bd6bf96d486ca7d1913745bafb276fb9edb82802e8ddfe84d1d26cc59bb44c0b7a6405333dafb225da3b519dee453d9bd61c9261cebbfeada4a4d98b38689816f3541cbf2835c6ce6c436963d480d95fa6e5671f9a77feff4a49b31671d1302de5344bd6fd41f01f905398efa0f810e74877109b31efffa29593662ce4a2605bc96897adfa83e03f20a731df41f021ce90ee213663dfff452b26cc59c944c0b7925d41b4a1de2300f91b29e67bd6a1c51c8884c8c4c0002e574d98b39389816f234695c1f092a884aa0319f4efa3a1b233bd4bed86800200af9b3167281302de45193ddc8dfbb38c0bd2fa11d73da18c6226da370a0005a5603662ce512605bc89327bb91bf7671817a5f423ae7b4318c44db46e14000b4ac06cc59ca24c0b791264f77237eece302f4be8475cf68631889b68dc2800169580d98b39449816f22456013d1cb3fee3166496b6b1e36a8b0be314144d002ecf02b316728a302de4473814d2e63e6048e495f3955bbd333e12726a8497005f4206662ce515605bc88d7029a5cc7cc091c92be72ab77a667c24e4d5092e00be840ccc59ca2ac0b7911a6c65a445cfe3a64a24947d66eb2b204475ec6e59017eac1a98b39456816f223364dda1387629cf4c15ef22c5ccb46883981b38af02fefc36316728ae02de446555cd9b1dc2b6214ff8a46d838fc6f901dc78cd5b05ff9c6d62ce515d05bc88c937ad8ee85bcec557be0f02ff15ec19fe6533f6b30c00dcdbc59ca2bb0b7911916f5b1dd0b79d8aaf7c1e05fe2bd833fcca67ed661801b9b78b39457616f223226ac8944e459d9816c50233f44e0e8ff4411236c93005177016728aed2de4464361a38149619db2e556ca8fe0927b47e32e66c98f600bd2e12ce515db5bc88c854f595b3f999de8827a5b47b91b54b7c1090fef1bc01949c359ca2bb7b79119092ac50f2c099e53bcc17cb76a2d07977cbe623a3480343787b39457706f223211558a1e58133ca77982f96ed45a0f2ef97cc4746900686f0f6728aee0de4464223726955cfcdbd1aad2b905a0aa7c85eda5cb44cf00d2821fce515dc2bc88c8436e4d2ab9f9b7a355a5720b4154f90bdb4b96899e01a5043f9ca2bb857911908668acae20c9d1c96317aa3e7aa0503fb1436f6f39034bac803945770bf223210b5d6bb4ee6a06157dfc1aa4ed36fea75d33213a6f0698fd01728aee18e446421546e9c289aa6eadb3c4fb71d2645b76b51284d0db0d339e03e515dc32c88c842919e5ddc02b3fde1f56bd0b9cbf151564d14bfdb31a68e008ca2bb8669119085133cbbb80567fbc3ead7a17397e2a2ac9a297fb6634d1c011945770cd223210a267977700acff787d5af42e72fc545593452ff6cc69a3802328aee19a446421445b4146ae306173b282ae84ddef06d32136a24995d348a447515dc33588c842874294e60937256a1cd22331b3d46bce3d1986ef28a692ec8fa2bb866c1190850d113c24bf44ad56f1710c8b5f9f35c474df503a4e4d277d2045770cd923210a192278497e895aade2e21916bf3e6b88e9bea0749c9a4efa408aee19b24642143244f092fd12b55bc5c4322d7e7cd711d37d40e939349df48115dc33648c84286415f37ea6fbcd3a43552a82f4f00c4ba1a6c42e6f693d8d032bb866ca190850c72be6fd4df79a7486aa5505e9e01897434d885cded27b1a065770cd943210a18e57cdfa9bef34e90d54aa0bd3c0312e869b10b9bda4f6340caee19b286421431c3bae4de4b4cc54d2761a3f9f76c08507e263cf7849ee0c1a5dc33651c8428637036ef4763ffb2c5cb8faa736e3df320a7109faed93ddbc35bb866ca490850c6d06dde8ec7ff658b971f54e6dc7be6414e213f5db27bb786b770cd949210a18da0dbbd1d8ffecb172e3ea9cdb8f7cc829c427ebb64f76f0d6ee19b292421431b41b77a3b1ffd962e5c7d539b71ef99053884fd76c9eede1addc3365248428636836ef4763ffb2c5cb8faa736e3df320a7109faed93ddbc35bb866ca490850c6d06dde8ec7ff658b971f54e6dc7be6414e213f5db27bb786b770cd949210a18da067cf763cd52d99e60b6ff5b0ee2aaa96eec11761f770b16fe19b292521431b3f5bb1452680bdb683e3a61359d2b37d2889c48ac0eee306e0c336524b4286367d4374e2f9d7ddefbf94124eab9bc5224bbfcb717eddc7b1c2866ca497850c6cf912fc1ea0861e6236f4eac54f2de86c922bd93efabb9107860cd949300a18d9f125f83d410c3cc46de9d58a9e5bd0d92457b27df577220f0c19b292601431b3e24bf07a82187988dbd3ab153cb7a1b248af64fbeaee441e18336524c0286367c423f34db10755946f741c527165a18c8c0b0c53d2dc89e03166ca498150c6cf8747e69b620eab28dee838a4e2cb4319181618a7a5b913c062cd949302a18d9f0e1bdf8f70f3b8d4759d3771bd8ce45a2ad873ab48722924c69b292606431b3e1b37bf1ee1e771a8eb3a6ee37b19c8b455b0e75690e452498d36524c0c86367c366f7e3dc3cee351d674ddc6f6339168ab61cead21c8a4931a6ca498190c6cf86c6b0ed43474292664b681b5e45d80f9516fdfb640914aca35d949303318d9f0d762300115beb4cf8139c993c0b1601a9d8c01c87e2297386cb292606731b3e1ad50725ad853cc21ba40594f79591e5d35c445ecf9453014da6524c0cf6367c3592cf70e5d7dfac62c4d78c6eaa89ae26634ce35ef8a61cdb5ca49819fc6cf86b159ee1cbafbf58c589af18dd55135c4cc699c6bdf14c39b6b9493033f8d9f0d623fee9222ce4d9b6902a943a298c9b1937f7b33bb2988dad8292606801b3e1ac30bef7cf272fdb989d218af3d27f18b21ab38c373531359b1524c0d01367c358517def9e4e5fb7313a4315e7a4fe31643567186e6a626b362a4981a026cf86b0a2fbdf3c9cbf6e6274862bcf49fc62c86ace30dcd4c4d66c549303404d9f0d6145f7be79397edcc4e90c579e93f8c590d59c61b9a989acd8a92606809b3e1ac284b0a27d4063e1b54ee511bca7576da155fce933231373f1624c0d01467c3584f2226a854e2deb961a9685f8ce14bdc256bdf82616270222d4981a029cf86b09d444d50a9c5bd72c352d0bf19c297b84ad7bf04c2c4e0445a930340539f0d613a14acfa0061dd683e7267a62b7b8d98905bc0658289c22cb6260680a83e1ac273\"\n    ],\n    \"commitments\": [\n      \"0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n      \"0xa572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e\",\n      \"0xa421e229565952cfff4ef3517100a97da1d4fe57956fa50a442f92af03b1bf37adacc8ad4ed209b31287ea5bb94d9d06\"\n    ],\n    \"proofs\": [\n      \"0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n      \"0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n      \"0xa2aeea08a9cd37fb0b089b1938bbe7eedd4ea6120dc70f45d59ad077008d08be115b858350b1eff645148fe4470b65c8\"\n    ]\n  }\n}"
  },
  {
    "path": "testing/files/test_data_incorrect_proof.json",
    "content": "{\n  \"input\": {\n    \"blob\": \"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n    \"commitment\": \"0x93efc82d2017e9c57834a1246463e64774e56183bb247c8fc9dd98c56817e878d97b05f5c8d900acf1fbbbca6f146556\",\n    \"proof\": \"0x8e5995b8136efc6e4a6d915ecfbeef542a44c1749afef58cac423e24e8dc2d03387faea0adc29ad454cdeae0be44d139\"\n  }\n}\n"
  },
  {
    "path": "testing/forge-script/Makefile",
    "content": "#!/usr/bin/make -f\n\n###############################################################################\n###                                Kurtosis                                 ###\n###############################################################################\n\nexport IP_ADDRESS := $(shell ifconfig | grep 'inet ' | grep -v '127.0.0.1' | awk '{ print $$2 }' | head -n 1)\n\nget-ip-address: \n\t@echo \"IP Address: $(IP_ADDRESS)\"\n\n# Starts a Kurtosis enclave containing a local devnet\nstart-forge-script: install-kurtosis get-ip-address\n\tkurtosis run ./testing/forge-script --args-file ./testing/forge-script/forge-config.yaml \\\n\t--enclave forge-devnet\n\n# Stops the running Kurtosis enclave\nstop-forge-script:\n\tkurtosis enclave stop forge-devnet\n\n# Stops and removes the specified Kurtosis enclave\nreset-forge-script:\n\t$(MAKE) stop-forge-script\n\tkurtosis enclave rm forge-devnet \n\n# Removes the specified Kurtosis enclave\nrm-forge-script:\n\tkurtosis enclave rm forge-devnet --force\n\n# Lints Starlark (.star) files in the Kurtosis directory using buildifier\nstar-lint-forge-script:\n\t@$(MAKE) buildifier-install\n\t@echo \"--> Running buildifier to format starlark files...\"\n\tfind ./testing/forge-script -name \"*.star\" -exec buildifier -mode=check {} +\n\n# Automatically fixes formatting issues in Starlark (.star) files using buildifier\nstar-fix-forge-script:\n\t@$(MAKE) buildifier-install\n\t@echo \"--> Running buildifier to format starlark files...\"\n\tfind ./testing/forge-script -name \"*.star\" -exec buildifier --mode=fix {} +\n\n# Marks targets as not being associated with files\n.PHONY: start-forge-script stop-forge-script reset-forge-script rm-forge-script star-lint-forge-script star-fix-forge-script\n"
  },
  {
    "path": "testing/forge-script/README.md",
    "content": "# Smart Contract Deployment Instructions\n\n## General guidelines about `forge-config.yaml`\n\n- The format of the `repository` should be `github.com/<OrgName/Username>/<Repositoryname>`. Refer to the Kurtosis documentation on [locators](https://docs.kurtosis.com/advanced-concepts/locators) for more information.\n\n- The `script_path` should be relative to the `repository` and `contracts_path` (if present).\n\n- For the wallet, currently only `private_key` is supported.\n\n- For `rpc_url`, \n    - URL for externally running network.\n\n    - If you want to spin up a devnet locally, you could use Kurtosis `make start-devnet`.\n        `rpc_url` would be `http://HOST_IP_ADDRESS:8547` , Do not change the port as 8547 is the public port for the execution client node.\n\n- If the smart contract has prerequisites or dependencies, set the `dependency` `status` to true. Ensure that the `dependency.sh` file is completed or provide an appropriate shell script in the `forge-script` folder. This is necessary when additional setup is required before deployment.\n\n## There could be different cases -\n\n- **Contract directory does not use git submodules**\n\n    If the contract directory does not use git submodules, provide the path up to the contracts in the `repository` and leave `contracts_path` as an empty string.\n\n- **Contract directory use git submodules**\n\n    If the contract directory uses git submodules, then we need to clone the whole repository to get the submodules. In that case, we need to provide the `repository` at the root level and `contracts_path` where the contracts are present.\n\n\n## Notes: \n\nIf there's a contract present locally, the only two options supported by kurtosis are :\n\n- The directory should be present inside the same kurtosis package as the current one.\n\n- Use github URL.\n\n    Edge scenario:\n    This would not be supported if the contracts are part of this repository - beacon-kit, in that case, fork the repository into your user profile and use that as a repository.\n\n    I know this is a kind of workaround, until Kurtosis supports local URLs, we don't really have a choice.\n\n    **Example for running contracts in beacon-kit**\n\n    ```bash\n    repository: \"github.com/nidhi-singh02/beacon-kit\"\n    contracts_path: \"contracts\"\n    script_path: \"script/DeployAndCallERC20.s.sol\"\n    contract_name: \"DeployAndCallERC20\"\n    ```\n\n## Example for GitHub hosted repository\n\n```bash\n\nrepository: \"github.com/nidhi-singh02/solidity-scripting/\"\ncontracts_path: \"\"\nscript_path: \"script/NFT.s.sol\"\ncontract_name: \"MyScript\"\n```\n\n## Deploy PoL Smart Contract\n\n```bash\nrepository: \"github.com/berachain/contracts-monorepo\"\ncontracts_path: \"\"\nscript_path: \"script/pol/DeployPoL.s.sol\"\ncontract_name: \"DeployPoL\"\ndependency: \n    status : true\n    path: \"dependency.sh\"\n```\n\n"
  },
  {
    "path": "testing/forge-script/dependency/dependency.sh",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: BUSL-1.1\n#\n# Copyright (C) 2025, Berachain Foundation. All rights reserved.\n# Use of this software is governed by the Business Source License included\n# in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n#\n# ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n# TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n# VERSIONS OF THE LICENSED WORK.\n#\n# THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n# LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n# LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n#\n# TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n# AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n# EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n# TITLE.\n\napk update && apk add --no-cache nodejs npm\n\nnpm --version\nnpm install -g bun\n\nbun --version\n\ncd /app/contracts && bun install\n\necho \"Bun installation complete!\"\n"
  },
  {
    "path": "testing/forge-script/forge-config.yaml",
    "content": "# SPDX-License-Identifier: BUSL-1.1\n#\n# Copyright (C) 2025, Berachain Foundation. All rights reserved.\n# Use of this software is governed by the Business Source License included\n# in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n#\n# ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n# TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n# VERSIONS OF THE LICENSED WORK.\n#\n# THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n# LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n# LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n#\n# TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n# AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n# EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n# TITLE.\n\n# Please refer to the README.md file for more information on how to fill this file.\ndeployment:\n  repository: \"github.com/nidhi-singh02/beacon-kit\"  # give repo name if there are submodules, else give the folder till contracts\n  contracts_path: \"contracts\"  # give the path till contracts, if the repository is the contract folder itself, then leave it empty\n  script_path: \"script/DeployAndCallERC20.s.sol\"  # this must be relative to the repository path + contracts_path(if applicable)\n  contract_name: \"DeployAndCallERC20\"\n  dependency:\n    type: \"none\"  # type can be `git` or `local` or `none`\n    path: \"script/berps/dependency/dependency.sh\"\n  rpc_url: \"http://HOST_IP_ADDRESS:8547\"  # If you spin up local devnet via kurtosis, then public port is 8547\n  wallet:\n    type: \"private_key\"  # currently only private_key wallet is supported. Do not change the type.\n    value: \"0xfffdbb37105441e14b0ee6330d855d8504ff39e705c3afa8f859ac9865f99306\" # private key of the account which will deploy the contract.\n"
  },
  {
    "path": "testing/forge-script/kurtosis.yml",
    "content": "# SPDX-License-Identifier: BUSL-1.1\n#\n# Copyright (C) 2025, Berachain Foundation. All rights reserved.\n# Use of this software is governed by the Business Source License included\n# in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n#\n# ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n# TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n# VERSIONS OF THE LICENSED WORK.\n#\n# THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n# LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n# LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n#\n# TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n# AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n# EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n# TITLE.\n\nname: github.com/berachain/beacon-kit/testing/forge-script\ndescription: |-\n    This is a package that provides a script to deploy a smart contract.\n    It is intended to be used for development/local testing purposes.\n"
  },
  {
    "path": "testing/forge-script/main.star",
    "content": "SOURCE_DIR_PATH = \"/app/contracts\"\nIMAGE_FOUNDRY = \"ghcr.io/foundry-rs/foundry:latest\"\nENTRYPOINT = [\"/bin/sh\"]\nDEPENDENCY_DIR_PATH = \"/app/dependency\"\n\ndef run(plan, deployment = {}):\n    deploy_contracts(plan, deployment)\n\n# Define the function to run the Forge script for deployment\ndef deploy_contracts(plan, deployment):\n    repository = deployment[\"repository\"]\n    contracts_path = deployment[\"contracts_path\"]\n    script_path = deployment[\"script_path\"]\n    contract_name = deployment[\"contract_name\"]\n    rpc_url = deployment[\"rpc_url\"]\n    wallet = deployment[\"wallet\"]\n    dependency = deployment[\"dependency\"]\n    dependency_type = dependency[\"type\"]\n\n    # TODO: Support other wallet options such as mnemonics, keystore, hardware wallets.\n    if wallet[\"type\"] == \"private_key\":\n        wallet_command = \"--private-key {}\".format(wallet[\"value\"])\n    else:\n        fail(\"Wallet type {} not supported.\".format(wallet[\"type\"]))\n\n    folder = plan.upload_files(src = repository, name = \"contracts\")\n\n    dependency_artifact_name = \"\"\n    if dependency_type == \"local\" or dependency_type == \"git\":\n        dependency_path = dependency[\"path\"]\n\n        plan.upload_files(src = \"dependency\", name = \"dependency\")\n        dependency_artifact_name = \"dependency\"\n\n    foundry_service = plan.add_service(\n        name = \"foundry\",\n        config = get_service_config(dependency_artifact_name),\n    )\n\n    if contracts_path:\n        contract_path = \"{}/{}\".format(SOURCE_DIR_PATH, contracts_path)\n    else:\n        contract_path = SOURCE_DIR_PATH\n\n    if dependency_type == \"local\":\n        # Run shell script\n        plan.exec(\n            service_name = foundry_service.name,\n            recipe = ExecRecipe(\n                command = [\"/bin/sh\", \"-c\", \"sh {}/{}\".format(DEPENDENCY_DIR_PATH, dependency_path)],\n            ),\n        )\n    elif dependency_type == \"git\":\n        plan.exec(\n            service_name = foundry_service.name,\n            recipe = ExecRecipe(\n                command = [\"/bin/sh\", \"-c\", \"cd {} && sh {}\".format(contract_path, dependency_path)],\n            ),\n        )\n    if script_path:\n        result = plan.exec(\n            service_name = foundry_service.name,\n            recipe = ExecRecipe(\n                command = [\"/bin/sh\", \"-c\", \"cd {} && forge build\".format(contract_path)],\n            ),\n        )\n        plan.verify(result[\"code\"], \"==\", 0)\n\n        script_output = exec_on_service(\n            plan,\n            foundry_service.name,\n            \"cd {} && forge script {}:{} --broadcast --rpc-url {} {} --json  --skip test > output.json \".format(\n                contract_path,\n                script_path,\n                contract_name,\n                rpc_url,\n                wallet_command,\n            ),\n        )\n\n    exec_on_service(\n        plan,\n        foundry_service.name,\n        \"cat {}/output.json \".format(contract_path),\n    )\n\n    if script_path:\n        # Get the forge script output in a output.json file and grep from it\n        transaction_file = \"grep 'Transactions saved to' output.json | awk -F': ' '{print $2}'\"\n        plan.print(\"transaction_file\", transaction_file)\n\n        transaction_file_details = exec_on_service(plan, foundry_service.name, \"cd {} && {}\".format(contract_path, transaction_file))\n\n        if not transaction_file_details[\"output\"]:\n            fail(\"Transaction file not found.\")\n        exec_output = exec_on_service(plan, foundry_service.name, \"chmod -R 777 /app/contracts && cat {}\".format(transaction_file_details[\"output\"]))\n        plan.verify(exec_output[\"code\"], \"==\", 0)\n\ndef exec_on_service(plan, service_name, command):\n    return plan.exec(\n        service_name = service_name,\n        recipe = ExecRecipe(\n            command = [\"/bin/sh\", \"-c\", command],\n        ),\n    )\n\ndef get_service_config(dependency_artifact_name = None):\n    files = {\n        SOURCE_DIR_PATH: \"contracts\",\n    }\n\n    if dependency_artifact_name:\n        files[DEPENDENCY_DIR_PATH] = dependency_artifact_name\n\n    return ServiceConfig(\n        image = IMAGE_FOUNDRY,\n        entrypoint = ENTRYPOINT,\n        files = files,\n    )\n"
  },
  {
    "path": "testing/networks/80069/app.toml",
    "content": "# This is a TOML config file.\n# For more information, see https://github.com/toml-lang/toml\n\n###############################################################################\n###                           Base Configuration                            ###\n###############################################################################\n\n# default: the last 362880 states are kept, pruning at 10 block intervals\n# nothing: all historic states will be saved, nothing will be deleted (i.e. archiving node)\n# everything: 2 latest states will be kept; pruning at 10 block intervals.\n# custom: allow pruning options to be manually specified through 'pruning-keep-recent', and 'pruning-interval'\npruning = \"everything\"\n\n# These are applied if and only if the pruning strategy is custom.\npruning-keep-recent = \"0\"\npruning-interval = \"0\"\n\n# HaltHeight contains a non-zero block height at which a node will gracefully\n# halt and shutdown that can be used to assist upgrades and testing.\n#\n# Note: Commitment of state will be attempted on the corresponding block.\nhalt-height = 0\n\n# HaltTime contains a non-zero minimum block time (in Unix seconds) at which\n# a node will gracefully halt and shutdown that can be used to assist upgrades\n# and testing.\n#\n# Note: Commitment of state will be attempted on the corresponding block.\nhalt-time = 0\n\n# MinRetainBlocks defines the minimum block height offset from the current\n# block being committed, such that all blocks past this offset are pruned\n# from CometBFT. It is used as part of the process of determining the\n# ResponseCommit.RetainHeight value during ABCI Commit. A value of 0 indicates\n# that no blocks should be pruned.\n#\n# This configuration value is only responsible for pruning CometBFT blocks.\n# It has no bearing on application state pruning which is determined by the\n# \"pruning-*\" configurations.\n#\n# Note: CometBFT block pruning is dependant on this parameter in conjunction\n# with the unbonding (safety threshold) period, state pruning and state sync\n# snapshot parameters to determine the correct minimum value of\n# ResponseCommit.RetainHeight.\nmin-retain-blocks = 0\n\n# InterBlockCache enables inter-block caching.\ninter-block-cache = true\n\n# IndexEvents defines the set of events in the form {eventType}.{attributeKey},\n# which informs CometBFT what to index. If empty, all events will be indexed.\n#\n# Example:\n# [\"message.sender\", \"message.recipient\"]\nindex-events = []\n\n# IavlCacheSize set the size of the iavl tree cache (in number of nodes).\niavl-cache-size = 781250\n\n# IAVLDisableFastNode enables or disables the fast node feature of IAVL.\n# Default is false.\niavl-disable-fastnode = true\n\n# AppDBBackend defines the database backend type to use for the application and snapshots DBs.\n# An empty string indicates that a fallback will be used.\n# The fallback is the db_backend value set in CometBFT's config.toml.\napp-db-backend = \"pebbledb\"\n\n###############################################################################\n###                         Telemetry Configuration                         ###\n###############################################################################\n\n[telemetry]\n\n# Prefixed with keys to separate services.\nservice-name = \"beacond_node\"\n\n# Enabled enables the application telemetry functionality. When enabled,\n# an in-memory sink is also enabled by default. Operators may also enabled\n# other sinks such as Prometheus.\nenabled = true\n\n# Enable prefixing gauge values with hostname.\nenable-hostname = true\n\n# Enable adding hostname to labels.\nenable-hostname-label = true\n\n# Enable adding service to labels.\nenable-service-label = true\n\n# PrometheusRetentionTime, when positive, enables a Prometheus metrics sink.\nprometheus-retention-time = 60\n\n# GlobalLabels defines a global set of name/value label tuples applied to all\n# metrics emitted using the wrapper functions defined in telemetry package.\n#\n# Example:\n# [[\"chain_id\", \"cosmoshub-1\"]]\nglobal-labels = []\n\n# MetricsSink defines the type of metrics sink to use.\nmetrics-sink = \"\"\n\n# StatsdAddr defines the address of a statsd server to send metrics to.\n# Only utilized if MetricsSink is set to \"statsd\" or \"dogstatsd\".\nstatsd-addr = \"\"\n\n# DatadogHostname defines the hostname to use when emitting metrics to\n# Datadog. Only utilized if MetricsSink is set to \"dogstatsd\".\ndatadog-hostname = \"my_beacond_node\"\n\n###############################################################################\n###                                BeaconKit                                ###\n###############################################################################\n\n[beacon-kit]\n# ChainSpec is the type of chain spec to use.\nchain-spec = \"testnet\"\n\n# ChainSpecFilePath is the path to the chain spec file to use.\nchain-spec-file = \"\"\n\n# ShutdownTimeout is the maximum time to wait for the node to gracefully\n# shutdown before forcing an exit.\nshutdown-timeout = \"5m0s\"\n\n[beacon-kit.engine]\n# HTTP url of the execution client JSON-RPC endpoint.\nrpc-dial-url = \"http://localhost:8551\"\n\n# RPC timeout for execution client requests.\nrpc-timeout = \"2s\"\n\n# RPC retry interval for execution client requests.\nrpc-retry-interval = \"100ms\"\n\n# RPC max retry interval for execution client requests.\nrpc-max-retry-interval = \"10s\"\n\n# Interval for the startup check.\nrpc-startup-check-interval = \"3s\"\n\n# Interval for the JWT refresh.\nrpc-jwt-refresh-interval = \"30s\"\n\n# Path to the execution client JWT-secret\njwt-secret-path = \"~/.beacond/config/jwt.hex\"\n\n[beacon-kit.logger]\n# TimeFormat is a string that defines the format of the time in the logger.\ntime-format = \"RFC3339\"\n\n# LogLevel is the level of logging. Logger will log messages with verbosity up\n# to LogLevel.\nlog-level = \"info\"\n\n# Style is the style of the logger.\nstyle = \"pretty\"\n\n[beacon-kit.kzg]\n# Path to the trusted setup path.\ntrusted-setup-path = \"~/.beacond/config/kzg-trusted-setup.json\"\n\n# KZG implementation to use.\n# Options are \"crate-crypto/go-kzg-4844\".\nimplementation = \"crate-crypto/go-kzg-4844\"\n\n[beacon-kit.payload-builder]\n# Enabled determines if the local payload builder is enabled.\n# It should be enabled for validators, but it can be disabled\n# for full nodes.\nenabled = true\n\n# Post bellatrix, this address will receive the transaction fees produced by any blocks\n# from this node.\nsuggested-fee-recipient = \"0x0000000000000000000000000000000000000000\"\n\n# The timeout for local build payload. This should match, or be slightly less\n# than the configured timeout on your execution client. It also must be less than\n# timeout_proposal in the CometBFT configuration.\npayload-timeout = \"850ms\"\n\n[beacon-kit.validator]\n# Graffiti string that will be included in the graffiti field of the beacon block.\ngraffiti = \"\"\n\n# AvailabilityWindow is the number of slots to keep in the store.\n# Setting AvailabilityWindow to 0 disables block store and does not allow the node\n# to serve proof or namespace apis from beacon node-api.\navailability-window = \"8192\"\n\n[beacon-kit.node-api]\n# Enabled determines if the node API is enabled.\nenabled = \"false\"\n\n# Address is the address to bind the node API to.\naddress = \"0.0.0.0:3500\"\n\n# Logging determines if the node API logging is enabled.\nlogging = \"false\"\n"
  },
  {
    "path": "testing/networks/80069/cl-seeds.txt",
    "content": "e56e965bd53832d47cf2f7cc2b7118c20c0c5b19@34.89.234.189:26656,58b349f2d3f2206798aae4f8d87141f095095503@34.159.220.160:26656,9499000274a522d85f91dbdac26945bbe2a144ba@35.234.244.49:26656,a5ccf1b754651ec080dabc7e065d078ab2bc83bb@34.95.45.160:26656,a78ae6958f2f0683d50d8342d00beac991a51b9e@67.213.122.179:26656,2c617ccd984310c0f4f3ce9e226dec6c8eda2435@206.223.224.23:26656"
  },
  {
    "path": "testing/networks/80069/client.toml",
    "content": "# This is a TOML config file.\n# For more information, see https://github.com/toml-lang/toml\n\n###############################################################################\n###                           Client Configuration                            ###\n###############################################################################\n\n# The network chain ID\nchain-id = \"testnet-beacon-80069\"\n# The keyring's backend, where the keys are stored (os|file|kwallet|pass|test|memory)\nkeyring-backend = \"test\"\n# CLI output format (text|json)\noutput = \"text\"\n# <host>:<port> to Tendermint RPC interface for this chain\nnode = \"tcp://localhost:26657\"\n# Transaction broadcasting mode (sync|async)\nbroadcast-mode = \"sync\"\n"
  },
  {
    "path": "testing/networks/80069/config.toml",
    "content": "# This is a TOML config file.\n# For more information, see https://github.com/toml-lang/toml\n\n# NOTE: Any path below can be absolute (e.g. \"/var/myawesomeapp/data\") or\n# relative to the home directory (e.g. \"data\"). The home directory is\n# \"$HOME/.cometbft\" by default, but could be changed via $CMTHOME env variable\n# or --home cmd flag.\n\n# The version of the CometBFT binary that created or\n# last modified the config file. Do not modify this.\nversion = \"1.0.0\"\n\n#######################################################################\n###                   Main Base Config Options                      ###\n#######################################################################\n\n# TCP or UNIX socket address of the ABCI application,\n# or the name of an ABCI application compiled in with the CometBFT binary\nproxy_app = \"tcp://127.0.0.1:26658\"\n\n# A custom human readable name for this node\nmoniker = \"oogabooga\"\n\n# Database backend: goleveldb | cleveldb | boltdb | rocksdb | badgerdb\n# * goleveldb (github.com/syndtr/goleveldb - most popular implementation)\n#   - pure go\n#   - stable\n# * cleveldb (uses levigo wrapper)\n#   - fast\n#   - requires gcc\n#   - use cleveldb build tag (go build -tags cleveldb)\n# * boltdb (uses etcd's fork of bolt - github.com/etcd-io/bbolt)\n#   - EXPERIMENTAL\n#   - may be faster is some use-cases (random reads - indexer)\n#   - use boltdb build tag (go build -tags boltdb)\n# * rocksdb (uses github.com/tecbot/gorocksdb)\n#   - EXPERIMENTAL\n#   - requires gcc\n#   - use rocksdb build tag (go build -tags rocksdb)\n# * badgerdb (uses github.com/dgraph-io/badger)\n#   - EXPERIMENTAL\n#   - use badgerdb build tag (go build -tags badgerdb)\ndb_backend = \"pebbledb\"\n\n# Database directory\ndb_dir = \"data\"\n\n# Output level for logging, including package level options\nlog_level = \"info\"\n\n# Output format: 'plain' (colored text) or 'json'\nlog_format = \"plain\"\n\n##### additional base config options #####\n\n# Path to the JSON file containing the initial validator set and other meta data\ngenesis_file = \"config/genesis.json\"\n\n# Path to the JSON file containing the private key to use as a validator in the consensus protocol\npriv_validator_key_file = \"config/priv_validator_key.json\"\n\n\n# Path to the JSON file containing the last sign state of a validator\npriv_validator_state_file = \"data/priv_validator_state.json\"\n\n# TCP or UNIX socket address for CometBFT to listen on for\n# connections from an external PrivValidator process\npriv_validator_laddr = \"\"\n\n# Path to the JSON file containing the private key to use for node authentication in the p2p protocol\nnode_key_file = \"config/node_key.json\"\n\n# Mechanism to connect to the ABCI application: socket | grpc\nabci = \"socket\"\n\n\n# If true, query the ABCI app on connecting to a new peer\n# so the app can decide if we should keep the connection or not\nfilter_peers = false\n\n\n#######################################################################\n###                 Advanced Configuration Options                  ###\n#######################################################################\n\n#######################################################\n###       RPC Server Configuration Options          ###\n#######################################################\n[rpc]\n\n# TCP or UNIX socket address for the RPC server to listen on\nladdr = \"tcp://127.0.0.1:26657\"\n\n# A list of origins a cross-domain request can be executed from\n# Default value '[]' disables cors support\n# Use '[\"*\"]' to allow any origin\ncors_allowed_origins = []\n\n# A list of methods the client is allowed to use with cross-domain requests\ncors_allowed_methods = ['HEAD', 'GET', 'POST']\n\n# A list of non simple headers the client is allowed to use with cross-domain requests\ncors_allowed_headers = ['Origin', 'Accept', 'Content-Type', 'X-Requested-With', 'X-Server-Time']\n\n# Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool\nunsafe = false\n\n# Maximum number of simultaneous connections (including WebSocket).\n# Does not include gRPC connections. See grpc_max_open_connections\n# If you want to accept a larger number than the default, make sure\n# you increase your OS limits.\n# 0 - unlimited.\n# Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files}\n# 1024 - 40 - 10 - 50 = 924 = ~900\nmax_open_connections = 900\n\n# Maximum number of unique clientIDs that can /subscribe\n# If you're using /broadcast_tx_commit, set to the estimated maximum number\n# of broadcast_tx_commit calls per block.\nmax_subscription_clients = 100\n\n# Maximum number of unique queries a given client can /subscribe to\n# If you're using GRPC (or Local RPC client) and /broadcast_tx_commit, set to\n# the estimated # maximum number of broadcast_tx_commit calls per block.\nmax_subscriptions_per_client = 5\n\n# Experimental parameter to specify the maximum number of events a node will\n# buffer, per subscription, before returning an error and closing the\n# subscription. Must be set to at least 100, but higher values will accommodate\n# higher event throughput rates (and will use more memory).\nexperimental_subscription_buffer_size = 200\n\n# Experimental parameter to specify the maximum number of RPC responses that\n# can be buffered per WebSocket client. If clients cannot read from the\n# WebSocket endpoint fast enough, they will be disconnected, so increasing this\n# parameter may reduce the chances of them being disconnected (but will cause\n# the node to use more memory).\n#\n# Must be at least the same as \"experimental_subscription_buffer_size\",\n# otherwise connections could be dropped unnecessarily. This value should\n# ideally be somewhat higher than \"experimental_subscription_buffer_size\" to\n# accommodate non-subscription-related RPC responses.\nexperimental_websocket_write_buffer_size = 200\n\n# If a WebSocket client cannot read fast enough, at present we may\n# silently drop events instead of generating an error or disconnecting the\n# client.\n#\n# Enabling this experimental parameter will cause the WebSocket connection to\n# be closed instead if it cannot read fast enough, allowing for greater\n# predictability in subscription behavior.\nexperimental_close_on_slow_client = false\n\n# How long to wait for a tx to be committed during /broadcast_tx_commit.\n# WARNING: Using a value larger than 10s will result in increasing the\n# global HTTP write timeout, which applies to all connections and endpoints.\n# See https://github.com/tendermint/tendermint/issues/3435\ntimeout_broadcast_tx_commit = \"10s\"\n\n# Maximum size of request body, in bytes\nmax_body_bytes = 1000000\n\n# Maximum size of request header, in bytes\nmax_header_bytes = 1048576\n\n# The path to a file containing certificate that is used to create the HTTPS server.\n# Might be either absolute path or path related to CometBFT's config directory.\n# If the certificate is signed by a certificate authority,\n# the certFile should be the concatenation of the server's certificate, any intermediates,\n# and the CA's certificate.\n# NOTE: both tls_cert_file and tls_key_file must be present for CometBFT to create HTTPS server.\n# Otherwise, HTTP server is run.\ntls_cert_file = \"\"\n\n# The path to a file containing matching private key that is used to create the HTTPS server.\n# Might be either absolute path or path related to CometBFT's config directory.\n# NOTE: both tls-cert-file and tls-key-file must be present for CometBFT to create HTTPS server.\n# Otherwise, HTTP server is run.\ntls_key_file = \"\"\n\n# pprof listen address (https://golang.org/pkg/net/http/pprof)\n#pprof_laddr = \"0.0.0.0:6060\"\npprof_laddr = \"\"\n\n#######################################################\n###           P2P Configuration Options             ###\n#######################################################\n[p2p]\n\n# Address to listen for incoming connections\nladdr = \"tcp://0.0.0.0:26656\"\n\n# Address to advertise to peers for them to dial. If empty, will use the same\n# port as the laddr, and will introspect on the listener to figure out the\n# address. IP and port are required. Example: 159.89.10.97:26656\nexternal_address = \"\"\n\n# Comma separated list of seed nodes to connect to\nseeds = \"e56e965bd53832d47cf2f7cc2b7118c20c0c5b19@34.89.234.189:26656,58b349f2d3f2206798aae4f8d87141f095095503@34.159.220.160:26656,9499000274a522d85f91dbdac26945bbe2a144ba@35.234.244.49:26656,a5ccf1b754651ec080dabc7e065d078ab2bc83bb@34.95.45.160:26656,a78ae6958f2f0683d50d8342d00beac991a51b9e@67.213.122.179:26656,2c617ccd984310c0f4f3ce9e226dec6c8eda2435@206.223.224.23:26656\"\n\n# Comma separated list of nodes to keep persistent connections to\npersistent_peers = \"\"\n\n# Path to address book\naddr_book_file = \"config/addrbook.json\"\n\n# Set true for strict address routability rules\n# Set false for private or local networks\naddr_book_strict = true\n\n# Maximum number of inbound peers\nmax_num_inbound_peers = 40\n\n# Maximum number of outbound peers to connect to, excluding persistent peers\nmax_num_outbound_peers = 10\n\n# List of node IDs, to which a connection will be (re)established ignoring any existing limits\nunconditional_peer_ids = \"\"\n\n# Maximum pause when redialing a persistent peer (if zero, exponential backoff is used)\npersistent_peers_max_dial_period = \"0s\"\n\n# Time to wait before flushing messages out on the connection\nflush_throttle_timeout = \"10ms\"\n\n# Maximum size of a message packet payload, in bytes\nmax_packet_msg_payload_size = 1024\n\n# Rate at which packets can be sent, in bytes/second\nsend_rate = 5120000\n\n# Rate at which packets can be received, in bytes/second\nrecv_rate = 5120000\n\n# Set true to enable the peer-exchange reactor\npex = true\n\n# Seed mode, in which node constantly crawls the network and looks for\n# peers. If another node asks it for addresses, it responds and disconnects.\n#\n# Does not work if the peer-exchange reactor is disabled.\nseed_mode = false\n\n# Comma separated list of peer IDs to keep private (will not be gossiped to other peers)\nprivate_peer_ids = \"\"\n\n# Toggle to disable guard against peers connecting from the same ip.\nallow_duplicate_ip = false\n\n# Peer connection configuration.\nhandshake_timeout = \"20s\"\ndial_timeout = \"3s\"\n\n#######################################################\n###          Mempool Configuration Option          ###\n#######################################################\n[mempool]\n\n# The type of mempool for this node to use.\n#\n#  Possible types:\n#  - \"flood\" : concurrent linked list mempool with flooding gossip protocol\n#  (default)\n#  - \"nop\"   : nop-mempool (short for no operation; the ABCI app is responsible\n#  for storing, disseminating and proposing txs). \"create_empty_blocks=false\" is\n#  not supported.\ntype = \"nop\"\n\n\n# Recheck (default: true) defines whether CometBFT should recheck the\n# validity for all remaining transaction in the mempool after a block.\n# Since a block affects the application state, some transactions in the\n# mempool may become invalid. If this does not apply to your application,\n# you can disable rechecking.\nrecheck = false\n\n# recheck_timeout is the time the application has during the rechecking process\n# to return CheckTx responses, once all requests have been sent. Responses that\n# arrive after the timeout expires are discarded. It only applies to\n# non-local ABCI clients and when recheck is enabled.\nrecheck_timeout = \"0s\"\n\n# Broadcast (default: true) defines whether the mempool should relay\n# transactions to other peers. Setting this to false will stop the mempool\n# from relaying transactions to other peers until they are included in a\n# block. In other words, if Broadcast is disabled, only the peer you send\n# the tx to will see it until it is included in a block.\nbroadcast = false\n\n# WalPath (default: \"\") configures the location of the Write Ahead Log\n# (WAL) for the mempool. The WAL is disabled by default. To enable, set\n# WalPath to where you want the WAL to be written (e.g.\n# \"data/mempool.wal\").\nwal_dir = \"\"\n\n# Maximum number of transactions in the mempool\nsize = 0\n\n# Limit the total size of all txs in the mempool.\n# This only accounts for raw transactions (e.g. given 1MB transactions and\n# max_txs_bytes=5MB, mempool will only accept 5 transactions).\nmax_txs_bytes = 0\n\n# Size of the cache (used to filter transactions we saw earlier) in transactions\ncache_size = 0\n\n# Do not remove invalid transactions from the cache (default: false)\n# Set to true if it's not possible for any invalid transaction to become valid\n# again in the future.\nkeep-invalid-txs-in-cache = false\n\n# Maximum size of a single transaction.\n# NOTE: the max size of a tx transmitted over the network is {max_tx_bytes}.\nmax_tx_bytes = 1048576\n\n# Maximum size of a batch of transactions to send to a peer\n# Including space needed by encoding (one varint per transaction).\n# XXX: Unused due to https://github.com/tendermint/tendermint/issues/5796\nmax_batch_size = 0\n\n# Experimental parameters to limit gossiping txs to up to the specified number of peers.\n# We use two independent upper values for persistent and non-persistent peers.\n# Unconditional peers are not affected by this feature.\n# If we are connected to more than the specified number of persistent peers, only send txs to\n# ExperimentalMaxGossipConnectionsToPersistentPeers of them. If one of those\n# persistent peers disconnects, activate another persistent peer.\n# Similarly for non-persistent peers, with an upper limit of\n# ExperimentalMaxGossipConnectionsToNonPersistentPeers.\n# If set to 0, the feature is disabled for the corresponding group of peers, that is, the\n# number of active connections to that group of peers is not bounded.\n# For non-persistent peers, if enabled, a value of 10 is recommended based on experimental\n# performance results using the default P2P configuration.\nexperimental_max_gossip_connections_to_persistent_peers = 0\nexperimental_max_gossip_connections_to_non_persistent_peers = 0\n\n#######################################################\n###         State Sync Configuration Options        ###\n#######################################################\n[statesync]\n# State sync rapidly bootstraps a new node by discovering, fetching, and restoring a state machine\n# snapshot from peers instead of fetching and replaying historical blocks. Requires some peers in\n# the network to take and serve state machine snapshots. State sync is not attempted if the node\n# has any local state (LastBlockHeight > 0). The node will have a truncated block history,\n# starting from the height of the snapshot.\nenable = false\n\n# RPC servers (comma-separated) for light client verification of the synced state machine and\n# retrieval of state data for node bootstrapping. Also needs a trusted height and corresponding\n# header hash obtained from a trusted source, and a period during which validators can be trusted.\n#\n# For Cosmos SDK-based chains, trust_period should usually be about 2/3 of the unbonding time (~2\n# weeks) during which they can be financially punished (slashed) for misbehavior.\nrpc_servers = \"\"\ntrust_height = 0\ntrust_hash = \"\"\ntrust_period = \"168h0m0s\"\n\n# Time to spend discovering snapshots before initiating a restore.\ndiscovery_time = \"15s\"\n\n# Temporary directory for state sync snapshot chunks, defaults to the OS tempdir (typically /tmp).\n# Will create a new, randomly named directory within, and remove it when done.\ntemp_dir = \"\"\n\n# The timeout duration before re-requesting a chunk, possibly from a different\n# peer (default: 1 minute).\nchunk_request_timeout = \"10s\"\n\n# The number of concurrent chunk fetchers to run (default: 1).\nchunk_fetchers = \"4\"\n\n#######################################################\n###       Block Sync Configuration Options          ###\n#######################################################\n[blocksync]\n\n# Block Sync version to use:\n#\n# In v0.37, v1 and v2 of the block sync protocols were deprecated.\n# Please use v0 instead.\n#\n#   1) \"v0\" - the default block sync implementation\nversion = \"v0\"\n\n#######################################################\n###         Consensus Configuration Options         ###\n#######################################################\n[consensus]\n\nwal_file = \"data/cs.wal/wal\"\n\n# How long we wait for a proposal block before prevoting nil\ntimeout_propose = \"2s\"\n# How much timeout_propose increases with each round\ntimeout_propose_delta = \"500ms\"\n# How long we wait after receiving +2/3 prevotes for “anything” (ie. not a single block or nil)\ntimeout_prevote = \"2s\"\n# How much the timeout_prevote increases with each round\ntimeout_prevote_delta = \"500ms\"\n# How long we wait after receiving +2/3 precommits for “anything” (ie. not a single block or nil)\ntimeout_precommit = \"2s\"\n# How much the timeout_precommit increases with each round\ntimeout_precommit_delta = \"500ms\"\n# How long we wait after committing a block, before starting on the new\n# height (this gives us a chance to receive some more precommits, even\n# though we already have +2/3).\n# Set to 0 if you want to make progress as soon as the node has all the precommits.\ntimeout_commit = \"500ms\"\n\n# Make progress as soon as we have all the precommits (as if TimeoutCommit = 0)\nskip_timeout_commit = false\n\n# How many blocks to look back to check existence of the node's consensus votes before joining consensus\n# When non-zero, the node will panic upon restart\n# if the same consensus key was used to sign {double_sign_check_height} last blocks.\n# So, validators should stop the state machine, wait for some blocks, and then restart the state machine to avoid panic.\ndouble_sign_check_height = 0\n\n# EmptyBlocks mode and possible interval between empty blocks\ncreate_empty_blocks = true\ncreate_empty_blocks_interval = \"0s\"\n\n# Reactor sleep duration parameters\npeer_gossip_sleep_duration = \"300ms\"\npeer_gossip_intraloop_sleep_duration = \"0s\"\npeer_query_maj23_sleep_duration = \"2s\"\n\n#######################################################\n###         Storage Configuration Options           ###\n#######################################################\n[storage]\n\n# Set to true to discard ABCI responses from the state store, which can save a\n# considerable amount of disk space. Set to false to ensure ABCI responses are\n# persisted. ABCI responses are required for /block_results RPC queries, and to\n# reindex events in the command-line tool.\ndiscard_abci_responses = true\n\n# The representation of keys in the database.\n# The current representation of keys in Comet's stores is considered to be v1\n# Users can experiment with a different layout by setting this field to v2.\n# Note that this is an experimental feature and switching back from v2 to v1\n# is not supported by CometBFT.\n# If the database was initially created with v1, it is necessary to migrate the DB\n# before switching to v2. The migration is not done automatically.\n# v1 - the legacy layout existing in Comet prior to v1.\n# v2 - Order preserving representation ordering entries by height.\nexperimental_db_key_layout = \"v1\"\n\n# If set to true, CometBFT will force compaction to happen for databases that support this feature.\n# and save on storage space. Setting this to true is most benefits when used in combination\n# with pruning as it will physically delete the entries marked for deletion.\n# false by default (forcing compaction is disabled).\ncompact = false\n\n# To avoid forcing compaction every time, this parameter instructs CometBFT to wait\n# the given amount of blocks to be pruned before triggering compaction.\n# It should be tuned depending on the number of items. If your retain height is 1 block,\n# it is too much of an overhead to try compaction every block. But it should also not be a very\n# large multiple of your retain height as it might occur bigger overheads.\ncompaction_interval = \"1000\"\n\n[storage.pruning]\n\n# The time period between automated background pruning operations.\ninterval = \"10s\"\n\n#\n# Storage pruning configuration relating only to the data companion.\n#\n[storage.pruning.data_companion]\n\n# Whether automatic pruning respects values set by the data companion. Disabled\n# by default. All other parameters in this section are ignored when this is\n# disabled.\n#\n# If disabled, only the application retain height will influence block pruning\n# (but not block results pruning). Only enabling this at a later stage will\n# potentially mean that blocks below the application-set retain height at the\n# time will not be available to the data companion.\nenabled = false\n\n# The initial value for the data companion block retain height if the data\n# companion has not yet explicitly set one. If the data companion has already\n# set a block retain height, this is ignored.\ninitial_block_retain_height = 0\n\n# The initial value for the data companion block results retain height if the\n# data companion has not yet explicitly set one. If the data companion has\n# already set a block results retain height, this is ignored.\ninitial_block_results_retain_height = 0\n\n#######################################################\n###   Transaction Indexer Configuration Options     ###\n#######################################################\n[tx_index]\n\n# What indexer to use for transactions\n#\n# The application will set which txs to index. In some cases a node operator will be able\n# to decide which txs to index based on configuration set in the application.\n#\n# Options:\n#   1) \"null\"\n#   2) \"kv\" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend).\n# \t\t- When \"kv\" is chosen \"tx.height\" and \"tx.hash\" will always be indexed.\n#   3) \"psql\" - the indexer services backed by PostgreSQL.\n# When \"kv\" or \"psql\" is chosen \"tx.height\" and \"tx.hash\" will always be indexed.\nindexer = \"null\"\n\n# The PostgreSQL connection configuration, the connection format:\n#   postgresql://<user>:<password>@<host>:<port>/<db>?<opts>\npsql-conn = \"\"\n\n#######################################################\n###       Instrumentation Configuration Options     ###\n#######################################################\n[instrumentation]\n\n# When true, Prometheus metrics are served under /metrics on\n# PrometheusListenAddr.\n# Check out the documentation for the list of available metrics.\nprometheus = true\n\n# Address to listen for Prometheus collector(s) connections\nprometheus_listen_addr = \":26660\"\n\n# Maximum number of simultaneous connections.\n# If you want to accept a larger number than the default, make sure\n# you increase your OS limits.\n# 0 - unlimited.\nmax_open_connections = 800\n\n# Instrumentation namespace\nnamespace = \"cometbft\"\n"
  },
  {
    "path": "testing/networks/80069/el-bootnodes.txt",
    "content": "enode://5c0d582c19ea9f19928cfd6b7e156372d051b5720f67a444c38b671b8119bb097abfd1e4b868a389ab4a65bb9b405ef837df0ae195c0f32a33c61c39ca54e8ab@34.107.71.151:30303,enode://59aec227e87f4cd7c0a24c6cb0f870ef77abcc0c6d640f5a536c597a206b3505f7963f6459c265952b7bed3c3f260edf8a1412bbdb05f0e59d6bd612dc4bf077@34.141.48.88:30303,enode://47f41b9ab5a45e880a78330d2ae3f95a61f5cb41f203bbc9c9ff0e37778fc6c7fd46a6ee103e65ac36df8c024075a33f535a03cd8d800800c27fa2699fa0182b@34.47.28.251:30303,enode://fe6d2429b582de7daf387c6e5436f05d9185965267b72b8b6b4924125b50afdad765a820213d73d2afbfe64a721160a1a94750b4874ed97ccbe97c51443d1c42@34.95.21.165:30303,enode://869293789a1bbdcbdd0d8c2f1eed560d20e4b4b23b21abf575c87158aea59f0396781b54fcedd8db01a6db075de71dbd29e75cfdbb83cea9cea1a6bd31bec74c@67.213.122.179:30303,enode://e4b804a4fc7833f03b6033542d72d026727a651e8b4369b42b8e6f22a1ebbe649c22b646e7180cd05843c4992c477d1999cbec101d97f0f7edc950495b846eb5@206.223.224.23:30303"
  },
  {
    "path": "testing/networks/80069/el-peers.txt",
    "content": "enode://fe6d2429b582de7daf387c6e5436f05d9185965267b72b8b6b4924125b50afdad765a820213d73d2afbfe64a721160a1a94750b4874ed97ccbe97c51443d1c42@34.118.173.2:30303,enode://47f41b9ab5a45e880a78330d2ae3f95a61f5cb41f203bbc9c9ff0e37778fc6c7fd46a6ee103e65ac36df8c024075a33f535a03cd8d800800c27fa2699fa0182b@34.152.12.159:30303,enode://59aec227e87f4cd7c0a24c6cb0f870ef77abcc0c6d640f5a536c597a206b3505f7963f6459c265952b7bed3c3f260edf8a1412bbdb05f0e59d6bd612dc4bf077@34.141.116.135:30303,enode://5c0d582c19ea9f19928cfd6b7e156372d051b5720f67a444c38b671b8119bb097abfd1e4b868a389ab4a65bb9b405ef837df0ae195c0f32a33c61c39ca54e8ab@34.89.220.53:30303,enode://869293789a1bbdcbdd0d8c2f1eed560d20e4b4b23b21abf575c87158aea59f0396781b54fcedd8db01a6db075de71dbd29e75cfdbb83cea9cea1a6bd31bec74c@67.213.122.179:30303,enode://e4b804a4fc7833f03b6033542d72d026727a651e8b4369b42b8e6f22a1ebbe649c22b646e7180cd05843c4992c477d1999cbec101d97f0f7edc950495b846eb5@206.223.224.23:30303"
  },
  {
    "path": "testing/networks/80069/eth-genesis.json",
    "content": "{\n  \"alloc\": {\n    \"0x0000000000000000000000000000000000000000\": {\n      \"balance\": \"0x211654585005212800000\"\n    },\n    \"0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02\": {\n      \"balance\": \"0x0\",\n      \"code\": \"0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500\",\n      \"nonce\": \"0x1\"\n    },\n    \"0x0cF32C7C003Bd9Fdbd5Ba635DAEDCb1070E77dE0\": {\n      \"balance\": \"0x422ca8b0a00a425000000\"\n    },\n    \"0x4242424242424242424242424242424242424242\": {\n      \"code\": \"0x608060405260043610610093575f3560e01c8063577212fe11610066578063c53925d91161004c578063c53925d914610231578063e12cf4cb14610250578063fea7ab7714610263575f80fd5b8063577212fe146101cc5780639eaffa96146101ed575f80fd5b806301ffc9a7146100975780632dfdf0b5146100cb5780633523f9bd14610103578063560036ec14610126575b5f80fd5b3480156100a2575f80fd5b506100b66100b1366004610bb7565b610282565b60405190151581526020015b60405180910390f35b3480156100d6575f80fd5b505f546100ea9067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016100c2565b34801561010e575f80fd5b5061011860015481565b6040519081526020016100c2565b348015610131575f80fd5b50610193610140366004610c2a565b80516020818301810180516003825292820191909301209152546bffffffffffffffffffffffff8116906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1682565b604080516bffffffffffffffffffffffff909316835273ffffffffffffffffffffffffffffffffffffffff9091166020830152016100c2565b3480156101d7575f80fd5b506101eb6101e6366004610d5f565b61031a565b005b3480156101f8575f80fd5b5061020c610207366004610d5f565b6103e7565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c2565b34801561023c575f80fd5b506101eb61024b366004610d5f565b610428565b6101eb61025e366004610dc1565b61063d565b34801561026e575f80fd5b506101eb61027d366004610e70565b61095c565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f136f920d00000000000000000000000000000000000000000000000000000000145b92915050565b6002828260405161032c929190610ec0565b908152604051908190036020019020543373ffffffffffffffffffffffffffffffffffffffff90911614610383576103837f7c214f0400000000000000000000000000000000000000000000000000000000610afc565b60038282604051610395929190610ec0565b9081526040519081900360200181205f90556103b49083908390610ec0565b604051908190038120907f1c0a7e1bd09da292425c039309671a03de56b89a0858598aab6df6ce84b006db905f90a25050565b5f600283836040516103fa929190610ec0565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff16905092915050565b5f6003838360405161043b929190610ec0565b908152604051908190036020019020805490915073ffffffffffffffffffffffffffffffffffffffff6c01000000000000000000000000820416906bffffffffffffffffffffffff163382146104b4576104b47f819a0d0b00000000000000000000000000000000000000000000000000000000610afc565b6bffffffffffffffffffffffff42166104d06201518083610efc565b6bffffffffffffffffffffffff16111561050d5761050d7fe8966d7a00000000000000000000000000000000000000000000000000000000610afc565b5f60028686604051610520929190610ec0565b9081526040519081900360200181205473ffffffffffffffffffffffffffffffffffffffff169150839060029061055a9089908990610ec0565b908152604051908190036020018120805473ffffffffffffffffffffffffffffffffffffffff939093167fffffffffffffffffffffffff0000000000000000000000000000000000000000909316929092179091556003906105bf9088908890610ec0565b9081526040519081900360200181205f90556105de9087908790610ec0565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff808716845284166020840152917f0adffd98d3072c48341843974dffd7a910bb849ba6ca04163d43bb26feb17403910160405180910390a2505050505050565b6030861461066e5761066e7f9f10647200000000000000000000000000000000000000000000000000000000610afc565b6020841461069f5761069f7fb39bca1600000000000000000000000000000000000000000000000000000000610afc565b606082146106d0576106d07f4be6321b00000000000000000000000000000000000000000000000000000000610afc565b5f73ffffffffffffffffffffffffffffffffffffffff16600288886040516106f9929190610ec0565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff16036108375773ffffffffffffffffffffffffffffffffffffffff8116610768576107687f51969a7a00000000000000000000000000000000000000000000000000000000610afc565b806002888860405161077b929190610ec0565b908152604051908190036020018120805473ffffffffffffffffffffffffffffffffffffffff939093167fffffffffffffffffffffffff0000000000000000000000000000000000000000909316929092179091556107dd9088908890610ec0565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff841683525f6020840152917f0adffd98d3072c48341843974dffd7a910bb849ba6ca04163d43bb26feb17403910160405180910390a261087c565b73ffffffffffffffffffffffffffffffffffffffff81161561087c5761087c7fc4142b4100000000000000000000000000000000000000000000000000000000610afc565b5f610885610b04565b90506509184e72a00067ffffffffffffffff821610156108c8576108c87f0e1eddda00000000000000000000000000000000000000000000000000000000610afc565b5f80547f68af751683498a9f9be59fe8b0d52a64dd155255d85cdb29fea30b1e3f891d46918a918a918a918a9187918b918b9167ffffffffffffffff16908061091083610f20565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060405161094a989796959493929190610f93565b60405180910390a15050505050505050565b5f6002848460405161096f929190610ec0565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff1690503381146109c7576109c77f7c214f0400000000000000000000000000000000000000000000000000000000610afc565b73ffffffffffffffffffffffffffffffffffffffff8216610a0b57610a0b7fd92e233d00000000000000000000000000000000000000000000000000000000610afc565b5f60038585604051610a1e929190610ec0565b908152604051908190036020018120426bffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff86166c01000000000000000000000000027fffffffffffffffffffffffffffffffffffffffff000000000000000000000000161781559150610a969086908690610ec0565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff8681168452851660208401524283830152905190917f7640ec3c8c4695deadda414dd20400acf275297a7c38715f9237657e97ddba5f919081900360600190a25050505050565b805f5260045ffd5b5f610b13633b9aca003461102b565b15610b4157610b417f40567b3800000000000000000000000000000000000000000000000000000000610afc565b5f610b50633b9aca003461103e565b905067ffffffffffffffff811115610b8b57610b8b7f2aa6673400000000000000000000000000000000000000000000000000000000610afc565b610b955f34610b9a565b919050565b5f385f3884865af1610bb35763b12d13eb5f526004601cfd5b5050565b5f60208284031215610bc7575f80fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610bf6575f80fd5b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f60208284031215610c3a575f80fd5b813567ffffffffffffffff811115610c50575f80fd5b8201601f81018413610c60575f80fd5b803567ffffffffffffffff811115610c7a57610c7a610bfd565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160116810181811067ffffffffffffffff82111715610ce657610ce6610bfd565b604052818152828201602001861015610cfd575f80fd5b816020840160208301375f91810160200191909152949350505050565b5f8083601f840112610d2a575f80fd5b50813567ffffffffffffffff811115610d41575f80fd5b602083019150836020828501011115610d58575f80fd5b9250929050565b5f8060208385031215610d70575f80fd5b823567ffffffffffffffff811115610d86575f80fd5b610d9285828601610d1a565b90969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610b95575f80fd5b5f805f805f805f6080888a031215610dd7575f80fd5b873567ffffffffffffffff811115610ded575f80fd5b610df98a828b01610d1a565b909850965050602088013567ffffffffffffffff811115610e18575f80fd5b610e248a828b01610d1a565b909650945050604088013567ffffffffffffffff811115610e43575f80fd5b610e4f8a828b01610d1a565b9094509250610e62905060608901610d9e565b905092959891949750929550565b5f805f60408486031215610e82575f80fd5b833567ffffffffffffffff811115610e98575f80fd5b610ea486828701610d1a565b9094509250610eb7905060208501610d9e565b90509250925092565b818382375f9101908152919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b6bffffffffffffffffffffffff818116838216019081111561031457610314610ecf565b5f67ffffffffffffffff821667ffffffffffffffff8103610f4357610f43610ecf565b60010192915050565b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60a081525f610fa660a083018a8c610f4c565b8281036020840152610fb981898b610f4c565b905067ffffffffffffffff871660408401528281036060840152610fde818688610f4c565b91505067ffffffffffffffff831660808301529998505050505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f8261103957611039610ffe565b500690565b5f8261104c5761104c610ffe565b50049056fea164736f6c634300081a000a\",\n      \"storage\": {\n        \"0x0000000000000000000000000000000000000000000000000000000000000000\": \"0x000000000000000000000000000000000000000000000000000000000000000a\",\n        \"0x0000000000000000000000000000000000000000000000000000000000000001\": \"0x43f7a8e2d16cceb70835172a7790a4aace27d18d39e30c43649b84231268b548\",\n        \"0x03d552cd0b6a48aa44cf44494aea1dfc6c218f0e2aa352d0ca3ed7945bdb2c24\": \"0x000000000000000000000000e9ba99ef852936cdddcd9075df3bde410c36e0cf\",\n        \"0x0faaea70c953dcfe11ad8bc316a089e2eda60e529d0bcfc62c7b7dd86b261feb\": \"0x0000000000000000000000000b59c939e52643cde4ef15a508cacdee8119d34c\",\n        \"0x145af481a0810f44c87f9901947772fe668830e73092929093a4364c57f4ca70\": \"0x000000000000000000000000340d3d95c8470684ee21b8f6b64540a365b72f88\",\n        \"0x148fbbe12a67f02bf75ba94d9663ea96d5bcaf77abb308716dc7919adc1283b1\": \"0x00000000000000000000000041707b8012929f0625b87757ce8c4ddfdd8c6837\",\n        \"0x3210ca2c1c490b6cae9ec1bb36ce12596c577f8b06cb57b09eb3bd63816c6c4e\": \"0x000000000000000000000000f690240ad1865ab6fe8c06d7e956de7fd877cbf7\",\n        \"0x3f45de2d635a6b087c80603ec1416e699edba6b2cd8d1d1e05add3dc6a01f3d2\": \"0x0000000000000000000000000d283a8aff77f4fb7b7a9ec78b09b26e083da304\",\n        \"0x42745319680dbe6769545a89399626eedaa7c4d1d3d813b272158972cfd23e52\": \"0x000000000000000000000000d2b18fb965968a81e2f0dcc777775aaba5f036e8\",\n        \"0x8ded9e69a1060de4ccc5b83484dc51ded413205d63a57a22c5a31f3b285693e2\": \"0x00000000000000000000000087784c08716671b8dc3b942e682e692f92f73381\",\n        \"0xccf6e5a9e737c27836dfa6601e82b4296a23feb2775bfdf549aa2717b34a0849\": \"0x00000000000000000000000012e2c8eb371d43416dc9f3b92b8c84a8cce6ada0\",\n        \"0xdb0c62b2ec141f0a4bb5dd01b05cb06824d445ece3979c01002904dd00fafb6f\": \"0x000000000000000000000000eb4a898c0ba5d0cdc5886156408edaea5b0a188d\"\n      },\n      \"balance\": \"0x0\",\n      \"nonce\": \"0x1\"\n    },\n    \"0x4e59b44847b379578588920cA78FbF26c0B4956C\": {\n      \"balance\": \"0x0\",\n      \"code\": \"0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3\",\n      \"nonce\": \"0x1\"\n    },\n    \"0x6969696969696969696969696969696969696969\": {\n      \"balance\": \"0x0\",\n      \"code\": \"0x6080604052600436106100dc575f3560e01c806370a082311161007c578063a9059cbb11610057578063a9059cbb14610365578063d0e30db014610384578063d505accf1461038c578063dd62ed3e146103ab575f80fd5b806370a08231146102be5780637ecebe00146102ef57806395d89b4114610320575f80fd5b806323b872dd116100b757806323b872dd1461019b5780632e1a7d4d146101ba578063313ce567146101d95780633644e515146101f4575f80fd5b806306fdde03146100ef578063095ea7b31461014657806318160ddd14610175575f80fd5b366100eb576100e96103df565b005b5f80fd5b3480156100fa575f80fd5b5060408051808201909152600c81527f577261707065642042657261000000000000000000000000000000000000000060208201525b60405161013d9190610865565b60405180910390f35b348015610151575f80fd5b506101656101603660046108e0565b6103eb565b604051901515815260200161013d565b348015610180575f80fd5b506805345cdf77eb68f44c545b60405190815260200161013d565b3480156101a6575f80fd5b506101656101b5366004610908565b61043a565b3480156101c5575f80fd5b506100e96101d4366004610942565b6104f2565b3480156101e4575f80fd5b506040516012815260200161013d565b3480156101ff575f80fd5b50604080518082018252600c81527f577261707065642042657261000000000000000000000000000000000000000060209182015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81527fb6c9387dd48cdde7d71a807357f57f1fef05232a4af3ed7fdf1f050c8e1a69fe918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc69181019190915246606082015230608082015260a0902061018d565b3480156102c9575f80fd5b5061018d6102d8366004610959565b6387a211a2600c9081525f91909152602090205490565b3480156102fa575f80fd5b5061018d610309366004610959565b6338377508600c9081525f91909152602090205490565b34801561032b575f80fd5b5060408051808201909152600581527f57424552410000000000000000000000000000000000000000000000000000006020820152610130565b348015610370575f80fd5b5061016561037f3660046108e0565b610518565b6100e96103df565b348015610397575f80fd5b506100e96103a6366004610979565b61058f565b3480156103b6575f80fd5b5061018d6103c53660046109e6565b602052637f5e9f20600c9081525f91909152603490205490565b6103e93334610768565b565b5f82602052637f5e9f20600c52335f52816034600c2055815f52602c5160601c337f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560205fa350600192915050565b5f8360601b33602052637f5e9f208117600c526034600c2080548019156104765780851115610470576313be252b5f526004601cfd5b84810382555b50506387a211a28117600c526020600c2080548085111561049e5763f4d678b85f526004601cfd5b84810382555050835f526020600c208381540181555082602052600c5160601c8160601c7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef602080a3505060019392505050565b6104fc33826107e4565b5f385f3884335af16105155763b12d13eb5f526004601cfd5b50565b5f6387a211a2600c52335f526020600c208054808411156105405763f4d678b85f526004601cfd5b83810382555050825f526020600c208281540181555081602052600c5160601c337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef602080a350600192915050565b60408051808201909152600c81527f57726170706564204265726100000000000000000000000000000000000000006020909101527fb6c9387dd48cdde7d71a807357f57f1fef05232a4af3ed7fdf1f050c8e1a69fe7fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc64286101561061b57631a15a3cc5f526004601cfd5b6040518960601b60601c99508860601b60601c985065383775081901600e52895f526020600c2080547f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f835284602084015283604084015246606084015230608084015260a08320602e527f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c983528b60208401528a60408401528960608401528060808401528860a084015260c08320604e526042602c205f528760ff16602052866040528560605260208060805f60015afa8c3d51146107035763ddafbaef5f526004601cfd5b019055777f5e9f20000000000000000000000000000000000000000089176040526034602c20889055888a7f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925602060608501a360405250505f60605250505050505050565b6805345cdf77eb68f44c548181018181101561078b5763e5cfe9575f526004601cfd5b806805345cdf77eb68f44c5550506387a211a2600c52815f526020600c208181540181555080602052600c5160601c5f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef602080a35050565b6387a211a2600c52815f526020600c2080548083111561080b5763f4d678b85f526004601cfd5b82900390556805345cdf77eb68f44c805482900390555f81815273ffffffffffffffffffffffffffffffffffffffff83167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef602083a35050565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b803573ffffffffffffffffffffffffffffffffffffffff811681146108db575f80fd5b919050565b5f80604083850312156108f1575f80fd5b6108fa836108b8565b946020939093013593505050565b5f805f6060848603121561091a575f80fd5b610923846108b8565b9250610931602085016108b8565b929592945050506040919091013590565b5f60208284031215610952575f80fd5b5035919050565b5f60208284031215610969575f80fd5b610972826108b8565b9392505050565b5f805f805f805f60e0888a03121561098f575f80fd5b610998886108b8565b96506109a6602089016108b8565b95506040880135945060608801359350608088013560ff811681146109c9575f80fd5b9699959850939692959460a0840135945060c09093013592915050565b5f80604083850312156109f7575f80fd5b610a00836108b8565b9150610a0e602084016108b8565b9050925092905056fea164736f6c634300081a000a\",\n      \"nonce\": \"0x1\"\n    },\n    \"0x7d84185eed48c38eb4181ef4dd9b4321b3b67d94\": {\n      \"balance\": \"0x422ca8b0a00a425000000\"\n    },\n    \"0x8a73D1380345942F1cb32541F1b19C40D8e6C94B\": {\n      \"balance\": \"0x18afa8ede3b3d3bcd800000\"\n    },\n    \"0xB796D5cB6dC182Da6ca7EC2D2Fd0112f599A188A\": {\n      \"balance\": \"0x422ca8b0a00a425000000\"\n    },\n    \"0xb8dCdb8f043e8061e887A8BDD83eB2f0E242BF64\": {\n      \"balance\": \"0x422ca8b0a00a425000000\"\n    },\n    \"0xcA11bde05977b3631167028862bE2a173976CA11\": {\n      \"balance\": \"0x0\",\n      \"code\": \"0x6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461025a578063bce38bd714610275578063c3077fa914610288578063ee82ac5e1461029b57600080fd5b80634d2301cc146101ec57806372425d9d1461022157806382ad56cb1461023457806386d516e81461024757600080fd5b80633408e470116100c65780633408e47014610191578063399542e9146101a45780633e64a696146101c657806342cbb15c146101d957600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d610128366004610a85565b6102ba565b6040516101119190610bbe565b61014d610148366004610a85565b6104ef565b604051610111929190610bd8565b34801561016757600080fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610107565b34801561019d57600080fd5b5046610107565b6101b76101b2366004610c60565b610690565b60405161011193929190610cba565b3480156101d257600080fd5b5048610107565b3480156101e557600080fd5b5043610107565b3480156101f857600080fd5b50610107610207366004610ce2565b73ffffffffffffffffffffffffffffffffffffffff163190565b34801561022d57600080fd5b5044610107565b61012d610242366004610a85565b6106ab565b34801561025357600080fd5b5045610107565b34801561026657600080fd5b50604051418152602001610111565b61012d610283366004610c60565b61085a565b6101b7610296366004610a85565b610a1a565b3480156102a757600080fd5b506101076102b6366004610d18565b4090565b60606000828067ffffffffffffffff8111156102d8576102d8610d31565b60405190808252806020026020018201604052801561031e57816020015b6040805180820190915260008152606060208201528152602001906001900390816102f65790505b5092503660005b8281101561047757600085828151811061034157610341610d60565b6020026020010151905087878381811061035d5761035d610d60565b905060200281019061036f9190610d8f565b6040810135958601959093506103886020850185610ce2565b73ffffffffffffffffffffffffffffffffffffffff16816103ac6060870187610dcd565b6040516103ba929190610e32565b60006040518083038185875af1925050503d80600081146103f7576040519150601f19603f3d011682016040523d82523d6000602084013e6103fc565b606091505b50602080850191909152901515808452908501351761046d577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fd5b5050600101610325565b508234146104e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561050c5761050c610d31565b60405190808252806020026020018201604052801561053f57816020015b606081526020019060019003908161052a5790505b5091503660005b8281101561068657600087878381811061056257610562610d60565b90506020028101906105749190610e42565b92506105836020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166105a66020850185610dcd565b6040516105b4929190610e32565b6000604051808303816000865af19150503d80600081146105f1576040519150601f19603f3d011682016040523d82523d6000602084013e6105f6565b606091505b5086848151811061060957610609610d60565b602090810291909101015290508061067d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b50600101610546565b5050509250929050565b43804060606106a086868661085a565b905093509350939050565b6060818067ffffffffffffffff8111156106c7576106c7610d31565b60405190808252806020026020018201604052801561070d57816020015b6040805180820190915260008152606060208201528152602001906001900390816106e55790505b5091503660005b828110156104e657600084828151811061073057610730610d60565b6020026020010151905086868381811061074c5761074c610d60565b905060200281019061075e9190610e76565b925061076d6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166107906040850185610dcd565b60405161079e929190610e32565b6000604051808303816000865af19150503d80600081146107db576040519150601f19603f3d011682016040523d82523d6000602084013e6107e0565b606091505b506020808401919091529015158083529084013517610851577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b50600101610714565b6060818067ffffffffffffffff81111561087657610876610d31565b6040519080825280602002602001820160405280156108bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816108945790505b5091503660005b82811015610a105760008482815181106108df576108df610d60565b602002602001015190508686838181106108fb576108fb610d60565b905060200281019061090d9190610e42565b925061091c6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff1661093f6020850185610dcd565b60405161094d929190610e32565b6000604051808303816000865af19150503d806000811461098a576040519150601f19603f3d011682016040523d82523d6000602084013e61098f565b606091505b506020830152151581528715610a07578051610a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b506001016108c3565b5050509392505050565b6000806060610a2b60018686610690565b919790965090945092505050565b60008083601f840112610a4b57600080fd5b50813567ffffffffffffffff811115610a6357600080fd5b6020830191508360208260051b8501011115610a7e57600080fd5b9250929050565b60008060208385031215610a9857600080fd5b823567ffffffffffffffff811115610aaf57600080fd5b610abb85828601610a39565b90969095509350505050565b6000815180845260005b81811015610aed57602081850181015186830182015201610ad1565b81811115610aff576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b84811015610bb1578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b9d81860183610ac7565b9a86019a9450505090830190600101610b4f565b5090979650505050505050565b602081526000610bd16020830184610b32565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610c52577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610c40868351610ac7565b95509284019290840190600101610c06565b509398975050505050505050565b600080600060408486031215610c7557600080fd5b83358015158114610c8557600080fd5b9250602084013567ffffffffffffffff811115610ca157600080fd5b610cad86828701610a39565b9497909650939450505050565b838152826020820152606060408201526000610cd96060830184610b32565b95945050505050565b600060208284031215610cf457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610bd157600080fd5b600060208284031215610d2a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610dc357600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610e0257600080fd5b83018035915067ffffffffffffffff821115610e1d57600080fd5b602001915036819003821315610a7e57600080fd5b8183823760009101908152919050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610dc357600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610dc357600080fdfea2646970667358221220bb2b5c71a328032f97c676ae39a1ec2148d3e5d6f73d95e9b17910152d61f16264736f6c634300080c0033\",\n      \"nonce\": \"0x1\"\n    }\n  },\n  \"coinbase\": \"0x0000000000000000000000000000000000000000\",\n  \"config\": {\n    \"arrowGlacierBlock\": 0,\n    \"berlinBlock\": 0,\n    \"byzantiumBlock\": 0,\n    \"cancunTime\": 0,\n    \"chainId\": 80069,\n    \"constantinopleBlock\": 0,\n    \"daoForkBlock\": 0,\n    \"daoForkSupport\": true,\n    \"eip150Block\": 0,\n    \"eip155Block\": 0,\n    \"eip158Block\": 0,\n    \"ethash\": {},\n    \"grayGlacierBlock\": 0,\n    \"homesteadBlock\": 0,\n    \"istanbulBlock\": 0,\n    \"londonBlock\": 0,\n    \"mergeNetsplitBlock\": 0,\n    \"muirGlacierBlock\": 0,\n    \"petersburgBlock\": 0,\n    \"shanghaiTime\": 0,\n    \"pragueTime\": 1746633600,\n    \"osakaTime\": 9999999999999999,\n    \"terminalTotalDifficulty\": 0,\n    \"terminalTotalDifficultyPassed\": true,\n    \"blobSchedule\": {\n      \"cancun\": {\n        \"target\": 3,\n        \"max\": 6,\n        \"baseFeeUpdateFraction\": 3338477\n      },\n      \"prague\": {\n        \"target\": 3,\n        \"max\": 6,\n        \"baseFeeUpdateFraction\": 3338477\n      }\n    },\n    \"berachain\": {\n      \"prague1\": {\n        \"time\": 1754496000,\n        \"baseFeeChangeDenominator\": 48,\n        \"minimumBaseFeeWei\": 10000000000,\n        \"polDistributorAddress\": \"0xD2f19a79b026Fb636A7c300bF5947df113940761\"\n      },\n      \"prague2\": {\n        \"time\": 1758124800,\n        \"minimumBaseFeeWei\": 0\n      }\n    }\n  },\n  \"difficulty\": \"0x01\",\n  \"extraData\": \"\",\n  \"gasLimit\": \"0x1c9c380\",\n  \"mixhash\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n  \"nonce\": \"0x1234\",\n  \"parentHash\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n  \"timestamp\": \"1739976735\"\n}\n"
  },
  {
    "path": "testing/networks/80069/genesis.json",
    "content": "{\n  \"app_name\": \"beacond\",\n  \"app_version\": \"v1.1.2\",\n  \"genesis_time\": \"2025-02-20T20:18:20.017462Z\",\n  \"chain_id\": \"testnet-beacon-80069\",\n  \"initial_height\": 1,\n  \"app_hash\": null,\n  \"app_state\": {\n    \"beacon\": {\n      \"fork_version\": \"0x04000000\",\n      \"deposits\": [\n        {\n          \"pubkey\": \"0x957004733f0c4d7e51b4f1ac3f1c08247f9c5455d302b669c723eb80d8c286515b5623757a9053a5a7b8c17ee3feed4b\",\n          \"credentials\": \"0x0100000000000000000000008a73d1380345942f1cb32541f1b19c40d8e6c94b\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0x920fb9e596c9b11677476e40d0bcc0f97620417e9ac73b885f982860a2c092b8a59352e80c689e99e8906a2f68ad922209d8e23a00d46c290ddaf239127af1ff6f76239939984a9d972095eb16565112c2cda7caa659ceae25a16b52b96b6b7d\",\n          \"index\": 0\n        },\n        {\n          \"pubkey\": \"0x97b21253b17f4e814fe7505c15c18e68c85ab2477274ad370a762df50e3eb4cb1a48451e089bc22e158d7448549a8ab9\",\n          \"credentials\": \"0x0100000000000000000000008a73d1380345942f1cb32541f1b19c40d8e6c94b\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xaa2e572c1c3521118a1bb75c57ec0bedfba679dd32c175961c8fd2df4f8f13c70db2c798926d7b0c96c5d0f045b3cc58046989764865b06a6574f38436a30d5a5ab26dcd3768bfffc9f80a9d188edd8f876f3c15034e40b1d546d13702df8ea8\",\n          \"index\": 1\n        },\n        {\n          \"pubkey\": \"0x92203b1242e536e91159707c2a6bfb3ed1339b07eb35a724e5237b60a55919815505a82199a4a8aa63e4e1daafd37983\",\n          \"credentials\": \"0x0100000000000000000000008a73d1380345942f1cb32541f1b19c40d8e6c94b\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0x8827ffe0264c7bf7493b70406b6995f30ce791dc07727c2ea3bf0676c52686c74e02b0b5b620cd1ea66824fea8bfbfd303acfa3d88d1bb5c572567c46d9b74f740f24db0233fb80ade57406a1541bfae4f3578fb2cb266a684339dbe548285d8\",\n          \"index\": 2\n        },\n        {\n          \"pubkey\": \"0xa4e4b63514f54d61da5197359f11ff1fc2930788ba2ffdd30c2fc059cbe0221020197bf9446b16ac347f36c7517a8686\",\n          \"credentials\": \"0x0100000000000000000000008a73d1380345942f1cb32541f1b19c40d8e6c94b\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0x8ea8bc8b09b061b281b9d3825c9a5103812bc42b0d1e5dc6fa85bb77a843e58f7ac431f0623dbc41d5d059f0f1b3bc8e0f2bf64566bf98f38327096b19d65f27c49a569886daab06d5dafe3149d1f7a9b4775ffa0783681026cd4d31a245334c\",\n          \"index\": 3\n        },\n        {\n          \"pubkey\": \"0xa2705d6b27891f3f5651f26547d1bb79e256f95f249d1ad717cef087d77d38b037e5d6dbaa2538930fd0731ec9b02f3a\",\n          \"credentials\": \"0x0100000000000000000000008a73d1380345942f1cb32541f1b19c40d8e6c94b\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xaabf262608ce6f1551968e0fc062b478fdc1503c9bf68aba89e580e216d65b4ff41f1fbf575e546b10142db8480f710e014afa9ac1458c6ce7db697e635d1191ccea4c2559eae253aaee9a8a647cabc0d73a603548d0a4eacf2486a5cd12cb27\",\n          \"index\": 4\n        },\n        {\n          \"pubkey\": \"0x8f51e63d9921a461be29e73dca1c2385e1adc5943fbb36ded4ba96025ee8a783184d1118da08171f6ea831153c878a6d\",\n          \"credentials\": \"0x0100000000000000000000000cf32c7c003bd9fdbd5ba635daedcb1070e77de0\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xb8c4c14fcac6736ac1c9c94414a4e0f71d4a4b25367b2b76f0b6e5f8f3de25aea72b45c5d34e8f626ee57828995d2c6b006d164262f01209c1077b47f2b60d8cc2a5462b82ec3bd4447aa2cdc60fabf173ef7e8acf263fe9ba66eff39b99eac3\",\n          \"index\": 5\n        },\n        {\n          \"pubkey\": \"0xa9060589e595ea482ebd98d461c54a038e4a115ec747a448f975fd4b34e7555dcd7f3f6188b894743254999b02e4c896\",\n          \"credentials\": \"0x0100000000000000000000000cf32c7c003bd9fdbd5ba635daedcb1070e77de0\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xb79dd04f00a1568e12afc9186b5491fd1fd40c03e3c69e0aace4f71eef2e607254026b43dfcfa4ee4d63e2d65cd7e63c13d6a685bbdf8a0afe0baf9479229b9a8b8a49407cf04d3ed592b6d4a6f0b7d4ca75e39b28469e7f190363b683bbd197\",\n          \"index\": 6\n        },\n        {\n          \"pubkey\": \"0x94ee582f23b3873a9242b0a701cd30b1b62d800c1525059624085e06fc93dd93bc52da47228f25d7da8c7988802f05c7\",\n          \"credentials\": \"0x0100000000000000000000000cf32c7c003bd9fdbd5ba635daedcb1070e77de0\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xb95c4ad16d12967165d159b324fc9f78c22056dc6c0dda810047e656aecbbee48ab1047b4a62a155457927b21088aedd13408b685e18752e9c184ab3ec1e71b481f5eb495bc940e128533f1ecc29f79c7002783f7a05a417ca2ca41b7d9a60a3\",\n          \"index\": 7\n        },\n        {\n          \"pubkey\": \"0xb0511ec039591e98bd4e183ba70b85572214a7ad8ca1a43e96ad3495d3821054927bc542e5482ec9733e35b7ef0b1f03\",\n          \"credentials\": \"0x0100000000000000000000000cf32c7c003bd9fdbd5ba635daedcb1070e77de0\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xb71253ef7901a1e12f0816ae305587e0770ba4b488ed43559bc5faf58095368af7ce5f15e9ca4a26da6b7a5258e789a80038a6822d74cd4c6ecd910ac906c0555dc897952c941a787ede271c704b3df35d49731407be1421f2f62fb6a442fd5c\",\n          \"index\": 8\n        },\n        {\n          \"pubkey\": \"0x9747e5a9ed44cc89806c376cec553aa3a58f3679ea0a5f22d001aee770aea252134a18ea30d40e04595ae0b64d0c6444\",\n          \"credentials\": \"0x0100000000000000000000000cf32c7c003bd9fdbd5ba635daedcb1070e77de0\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0x98f93cf85ec2bba69fc99c296aa4711ca2bbfdd2b44aebb80e9edfeffa451e9979151d00299fbec23cecddedbef267ff0f7aed094d41e0e3c071a8fab6c8bbcd98707e319ce0d47ad7611e28ddb44605dd113932e0d2c2f2a7423eebde0209cd\",\n          \"index\": 9\n        }\n      ],\n      \"execution_payload_header\": {\n        \"parentHash\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        \"feeRecipient\": \"0x0000000000000000000000000000000000000000\",\n        \"stateRoot\": \"0xaf7ac45ece564c84ee2451776587c548aebb91ba04eb6040fd2b26055539c8e3\",\n        \"receiptsRoot\": \"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\n        \"logsBloom\": \"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n        \"prevRandao\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        \"blockNumber\": \"0x0\",\n        \"gasLimit\": \"0x1c9c380\",\n        \"gasUsed\": \"0x0\",\n        \"timestamp\": \"0x67b5f01f\",\n        \"extraData\": \"0x\",\n        \"baseFeePerGas\": \"1000000000\",\n        \"blockHash\": \"0x0207661de38f0e54ba91c8286096e72486784c79dc6a9681fc486b38335c042f\",\n        \"transactionsRoot\": \"0x7ffe241ea60187fdb0187bfa22de35d1f9bed7ab061d9401fd47e34a54fbede1\",\n        \"withdrawalsRoot\": \"0x792930bbd5baac43bcc798ee49aa8185ef76bb3b44ba62b91d86ae569e4bb535\",\n        \"blobGasUsed\": \"0x0\",\n        \"excessBlobGas\": \"0x0\"\n      }\n    }\n  },\n  \"consensus\": {\n    \"params\": {\n      \"block\": {\n        \"max_bytes\": \"104857600\",\n        \"max_gas\": \"10000000\"\n      },\n      \"evidence\": {\n        \"max_age_num_blocks\": \"100000\",\n        \"max_age_duration\": \"172800000000000\",\n        \"max_bytes\": \"1048576\"\n      },\n      \"validator\": {\n        \"pub_key_types\": [\n          \"bls12_381\"\n        ]\n      },\n      \"version\": {\n        \"app\": \"0\"\n      },\n      \"synchrony\": {\n        \"precision\": \"505000000\",\n        \"message_delay\": \"15000000000\"\n      },\n      \"feature\": {\n        \"vote_extensions_enable_height\": \"0\",\n        \"pbts_enable_height\": \"1\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "testing/networks/80069/kzg-trusted-setup.json",
    "content": "{\n  \"g1_lagrange\": [\n    \"0xa0413c0dcafec6dbc9f47d66785cf1e8c981044f7d13cfe3e4fcbb71b5408dfde6312493cb3c1d30516cb3ca88c03654\",\n    \"0x8b997fb25730d661918371bb41f2a6e899cac23f04fc5365800b75433c0a953250e15e7a98fb5ca5cc56a8cd34c20c57\",\n    \"0x83302852db89424d5699f3f157e79e91dc1380f8d5895c5a772bb4ea3a5928e7c26c07db6775203ce33e62a114adaa99\",\n    \"0xa759c48b7e4a685e735c01e5aa6ef9c248705001f470f9ad856cd87806983e917a8742a3bd5ee27db8d76080269b7c83\",\n    \"0x967f8dc45ebc3be14c8705f43249a30ff48e96205fb02ae28daeab47b72eb3f45df0625928582aa1eb4368381c33e127\",\n    \"0xa418eb1e9fb84cb32b370610f56f3cb470706a40ac5a47c411c464299c45c91f25b63ae3fcd623172aa0f273c0526c13\",\n    \"0x8f44e3f0387293bc7931e978165abbaed08f53acd72a0a23ac85f6da0091196b886233bcee5b4a194db02f3d5a9b3f78\",\n    \"0x97173434b336be73c89412a6d70d416e170ea355bf1956c32d464090b107c090ef2d4e1a467a5632fbc332eeb679bf2d\",\n    \"0xa24052ad8d55ad04bc5d951f78e14213435681594110fd18173482609d5019105b8045182d53ffce4fc29fc8810516c1\",\n    \"0xb950768136b260277590b5bec3f56bbc2f7a8bc383d44ce8600e85bf8cf19f479898bcc999d96dfbd2001ede01d94949\",\n    \"0x92ab8077871037bd3b57b95cbb9fb10eb11efde9191690dcac655356986fd02841d8fdb25396faa0feadfe3f50baf56d\",\n    \"0xa79b096dff98038ac30f91112dd14b78f8ad428268af36d20c292e2b3b6d9ed4fb28480bb04e465071cc67d05786b6d1\",\n    \"0xb9ff71461328f370ce68bf591aa7fb13027044f42a575517f3319e2be4aa4843fa281e756d0aa5645428d6dfa857cef2\",\n    \"0x8d765808c00b3543ff182e2d159c38ae174b12d1314da88ea08e13bd9d1c37184cb515e6bf6420531b5d41767987d7ce\",\n    \"0xb8c9a837d20c3b53e6f578e4a257bb7ef8fc43178614ec2a154915b267ad2be135981d01ed2ee1b5fbd9d9bb27f0800a\",\n    \"0xa9773d92cf23f65f98ef68f6cf95c72b53d0683af2f9bf886bb9036e4a38184b1131b26fd24397910b494fbef856f3aa\",\n    \"0xb41ebe38962d112da4a01bf101cb248d808fbd50aaf749fc7c151cf332032eb3e3bdbd716db899724b734d392f26c412\",\n    \"0x90fbb030167fb47dcc13d604a726c0339418567c1d287d1d87423fa0cb92eec3455fbb46bcbe2e697144a2d3972142e4\",\n    \"0xb11d298bd167464b35fb923520d14832bd9ed50ed841bf6d7618424fd6f3699190af21759e351b89142d355952149da1\",\n    \"0x8bc36066f69dc89f7c4d1e58d67497675050c6aa002244cebd9fc957ec5e364c46bab4735ea3db02b73b3ca43c96e019\",\n    \"0xab7ab92c5d4d773068e485aa5831941ebd63db7118674ca38089635f3b4186833af2455a6fb9ed2b745df53b3ce96727\",\n    \"0xaf191ca3089892cb943cd97cf11a51f38e38bd9be50844a4e8da99f27e305e876f9ed4ab0628e8ae3939066b7d34a15f\",\n    \"0xa3204c1747feabc2c11339a542195e7cb6628fd3964f846e71e2e3f2d6bb379a5e51700682ea1844eba12756adb13216\",\n    \"0x903a29883846b7c50c15968b20e30c471aeac07b872c40a4d19eb1a42da18b649d5bbfde4b4cf6225d215a461b0deb6d\",\n    \"0x8e6e9c15ffbf1e16e5865a5fef7ed751dc81957a9757b535cb38b649e1098cda25d42381dc4f776778573cdf90c3e6e0\",\n    \"0xa8f6dd26100b512a8c96c52e00715c4b2cb9ac457f17aed8ffe1cf1ea524068fe5a1ddf218149845fc1417b789ecfc98\",\n    \"0xa5b0ffc819451ea639cfd1c18cbc9365cc79368d3b2e736c0ae54eba2f0801e6eb0ee14a5f373f4a70ca463bdb696c09\",\n    \"0x879f91ccd56a1b9736fbfd20d8747354da743fb121f0e308a0d298ff0d9344431890e41da66b5009af3f442c636b4f43\",\n    \"0x81bf3a2d9755e206b515a508ac4d1109bf933c282a46a4ae4a1b4cb4a94e1d23642fad6bd452428845afa155742ade7e\",\n    \"0x8de778d4742f945df40004964e165592f9c6b1946263adcdd5a88b00244bda46c7bb49098c8eb6b3d97a0dd46148a8ca\",\n    \"0xb7a57b21d13121907ee28c5c1f80ee2e3e83a3135a8101e933cf57171209a96173ff5037f5af606e9fd6d066de6ed693\",\n    \"0xb0877d1963fd9200414a38753dffd9f23a10eb3198912790d7eddbc9f6b477019d52ddd4ebdcb9f60818db076938a5a9\",\n    \"0x88da2d7a6611bc16adc55fc1c377480c828aba4496c645e3efe0e1a67f333c05a0307f7f1d2df8ac013602c655c6e209\",\n    \"0x95719eb02e8a9dede1a888c656a778b1c69b7716fbe3d1538fe8afd4a1bc972183c7d32aa7d6073376f7701df80116d8\",\n    \"0x8e8a1ca971f2444b35af3376e85dccda3abb8e8e11d095d0a4c37628dfe5d3e043a377c3de68289ef142e4308e9941a0\",\n    \"0xb720caaff02f6d798ac84c4f527203e823ff685869e3943c979e388e1c34c3f77f5c242c6daa7e3b30e511aab917b866\",\n    \"0x86040d55809afeec10e315d1ad950d269d37cfee8c144cd8dd4126459e3b15a53b3e68df5981df3c2346d23c7b4baaf4\",\n    \"0x82d8cabf13ab853db0377504f0aec00dba3a5cd3119787e8ad378ddf2c40b022ecfc67c642b7acc8c1e3dd03ab50993e\",\n    \"0xb8d873927936719d2484cd03a6687d65697e17dcf4f0d5aed6f5e4750f52ef2133d4645894e7ebfc4ef6ce6788d404c8\",\n    \"0xb1235594dbb15b674a419ff2b2deb644ad2a93791ca05af402823f87114483d6aa1689b7a9bea0f547ad12fe270e4344\",\n    \"0xa53fda86571b0651f5affb74312551a082fffc0385cfd24c1d779985b72a5b1cf7c78b42b4f7e51e77055f8e5e915b00\",\n    \"0xb579adcfd9c6ef916a5a999e77a0cb21d378c4ea67e13b7c58709d5da23a56c2e54218691fc4ac39a4a3d74f88cc31f7\",\n    \"0xab79e584011713e8a2f583e483a91a0c2a40771b77d91475825b5acbea82db4262132901cb3e4a108c46d7c9ee217a4e\",\n    \"0xa0fe58ea9eb982d7654c8aaf9366230578fc1362f6faae0594f8b9e659bcb405dff4aac0c7888bbe07f614ecf0d800a6\",\n    \"0x867e50e74281f28ecd4925560e2e7a6f8911b135557b688254623acce0dbc41e23ac3e706a184a45d54c586edc416eb0\",\n    \"0x89f81b61adda20ea9d0b387a36d0ab073dc7c7cbff518501962038be19867042f11fcc7ff78096e5d3b68c6d8dc04d9b\",\n    \"0xa58ee91bb556d43cf01f1398c5811f76dc0f11efdd569eed9ef178b3b0715e122060ec8f945b4dbf6eebfa2b90af6fa6\",\n    \"0xac460be540f4c840def2eef19fc754a9af34608d107cbadb53334cf194cc91138d53b9538fcd0ec970b5d4aa455b224a\",\n    \"0xb09b91f929de52c09d48ca0893be6eb44e2f5210a6c394689dc1f7729d4be4e11d0474b178e80cea8c2ac0d081f0e811\",\n    \"0x8d37a442a76b06a02a4e64c2504aea72c8b9b020ab7bcc94580fe2b9603c7c50d7b1e9d70d2a7daea19c68667e8f8c31\",\n    \"0xa9838d4c4e3f3a0075a952cf7dd623307ec633fcc81a7cf9e52e66c31780de33dbb3d74c320dc7f0a4b72f7a49949515\",\n    \"0xa44766b6251af458fe4f5f9ed1e02950f35703520b8656f09fc42d9a2d38a700c11a7c8a0436ac2e5e9f053d0bb8ff91\",\n    \"0xad78d9481c840f5202546bea0d13c776826feb8b1b7c72e83d99a947622f0bf38a4208551c4c41beb1270d7792075457\",\n    \"0xb619ffa8733b470039451e224b777845021e8dc1125f247a4ff2476cc774657d0ff9c5279da841fc1236047de9d81c60\",\n    \"0xaf760b0a30a1d6af3bc5cd6686f396bd41779aeeb6e0d70a09349bd5da17ca2e7965afc5c8ec22744198fbe3f02fb331\",\n    \"0xa0cc209abdb768b589fcb7b376b6e1cac07743288c95a1cf1a0354b47f0cf91fca78a75c1fcafa6f5926d6c379116608\",\n    \"0x864add673c89c41c754eeb3cd8dcff5cdde1d739fce65c30e474a082bb5d813cba6412e61154ce88fdb6c12c5d9be35b\",\n    \"0xb091443b0ce279327dc37cb484e9a5b69b257a714ce21895d67539172f95ffa326903747b64a3649e99aea7bb10d03f7\",\n    \"0xa8c452b8c4ca8e0a61942a8e08e28f17fb0ef4c5b018b4e6d1a64038280afa2bf1169202f05f14af24a06ca72f448ccd\",\n    \"0xa23c24721d18bc48d5dcf70effcbef89a7ae24e67158d70ae1d8169ee75d9a051d34b14e9cf06488bac324fe58549f26\",\n    \"0x92a730e30eb5f3231feb85f6720489dbb1afd42c43f05a1610c6b3c67bb949ec8fde507e924498f4ffc646f7b07d9123\",\n    \"0x8dbe5abf4031ec9ba6bb06d1a47dd1121fb9e03b652804069250967fd5e9577d0039e233441b7f837a7c9d67ba18c28e\",\n    \"0xaa456bcfef6a21bb88181482b279df260297b3778e84594ebddbdf337e85d9e3d46ca1d0b516622fb0b103df8ec519b7\",\n    \"0xa3b31ae621bd210a2b767e0e6f22eb28fe3c4943498a7e91753225426168b9a26da0e02f1dc5264da53a5ad240d9f51b\",\n    \"0xaa8d66857127e6e71874ce2202923385a7d2818b84cb73a6c42d71afe70972a70c6bdd2aad1a6e8c5e4ca728382a8ea8\",\n    \"0xac7e8e7a82f439127a5e40558d90d17990f8229852d21c13d753c2e97facf077cf59582b603984c3dd3faebd80aff4f5\",\n    \"0x93a8bcf4159f455d1baa73d2ef2450dcd4100420de84169bbe28b8b7a5d1746273f870091a87a057e834f754f34204b1\",\n    \"0x89d0ebb287c3613cdcae7f5acc43f17f09c0213fc40c074660120b755d664109ffb9902ed981ede79e018ddb0c845698\",\n    \"0xa87ccbfad431406aadbee878d9cf7d91b13649d5f7e19938b7dfd32645a43b114eef64ff3a13201398bd9b0337832e5a\",\n    \"0x833c51d0d0048f70c3eefb4e70e4ff66d0809c41838e8d2c21c288dd3ae9d9dfaf26d1742bf4976dab83a2b381677011\",\n    \"0x8bcd6b1c3b02fffead432e8b1680bad0a1ac5a712d4225e220690ee18df3e7406e2769e1f309e2e803b850bc96f0e768\",\n    \"0xb61e3dbd88aaf4ff1401521781e2eea9ef8b66d1fac5387c83b1da9e65c2aa2a56c262dea9eceeb4ad86c90211672db0\",\n    \"0x866d3090db944ecf190dd0651abf67659caafd31ae861bab9992c1e3915cb0952da7c561cc7e203560a610f48fae633b\",\n    \"0xa5e8971543c14274a8dc892b0be188c1b4fbc75c692ed29f166e0ea80874bc5520c2791342b7c1d2fb5dd454b03b8a5b\",\n    \"0x8f2f9fc50471bae9ea87487ebd1bc8576ef844cc42d606af5c4c0969670fdf2189afd643e4de3145864e7773d215f37f\",\n    \"0xb1bb0f2527db6d51f42b9224383c0f96048bbc03d469bf01fe1383173ef8b1cc9455d9dd8ba04d46057f46949bfc92b5\",\n    \"0xaa7c99d906b4d7922296cfe2520473fc50137c03d68b7865c5bfb8adbc316b1034310ec4b5670c47295f4a80fb8d61e9\",\n    \"0xa5d1da4d6aba555919df44cbaa8ff79378a1c9e2cfdfbf9d39c63a4a00f284c5a5724e28ecbc2d9dba27fe4ee5018bd5\",\n    \"0xa8db53224f70af4d991b9aae4ffe92d2aa5b618ad9137784b55843e9f16cefbfd25ada355d308e9bbf55f6d2f7976fb3\",\n    \"0xb6536c4232bb20e22af1a8bb12de76d5fec2ad9a3b48af1f38fa67e0f8504ef60f305a73d19385095bb6a9603fe29889\",\n    \"0x87f7e371a1817a63d6838a8cf4ab3a8473d19ce0d4f40fd013c03d5ddd5f4985df2956531cc9f187928ef54c68f4f9a9\",\n    \"0xae13530b1dbc5e4dced9d909ea61286ec09e25c12f37a1ed2f309b0eb99863d236c3b25ed3484acc8c076ad2fa8cd430\",\n    \"0x98928d850247c6f7606190e687d5c94a627550198dbdbea0161ef9515eacdb1a0f195cae3bb293112179082daccf8b35\",\n    \"0x918528bb8e6a055ad4db6230d3a405e9e55866da15c4721f5ddd1f1f37962d4904aad7a419218fe6d906fe191a991806\",\n    \"0xb71e31a06afe065773dd3f4a6e9ef81c3292e27a3b7fdfdd452d03e05af3b6dd654c355f7516b2a93553360c6681a73a\",\n    \"0x8870b83ab78a98820866f91ac643af9f3ff792a2b7fda34185a9456a63abdce42bfe8ad4dc67f08a6392f250d4062df4\",\n    \"0x91eea1b668e52f7a7a5087fabf1cab803b0316f78d9fff469fbfde2162f660c250e4336a9eea4cb0450bd30ac067bc8b\",\n    \"0x8b74990946de7b72a92147ceac1bd9d55999a8b576e8df68639e40ed5dc2062cfcd727903133de482b6dca19d0aaed82\",\n    \"0x8ebad537fece090ebbab662bdf2618e21ca30cf6329c50935e8346d1217dcbe3c1fe1ea28efca369c6003ce0a94703c1\",\n    \"0xa8640479556fb59ebd1c40c5f368fbd960932fdbb782665e4a0e24e2bdb598fc0164ce8c0726d7759cfc59e60a62e182\",\n    \"0xa9a52a6bf98ee4d749f6d38be2c60a6d54b64d5cbe4e67266633dc096cf28c97fe998596707d31968cbe2064b72256bf\",\n    \"0x847953c48a4ce6032780e9b39d0ed4384e0be202c2bbe2dfda3910f5d87aa5cd3c2ffbfcfae4dddce16d6ab657599b95\",\n    \"0xb6f6e1485d3ec2a06abaecd23028b200b2e4a0096c16144d07403e1720ff8f9ba9d919016b5eb8dc5103880a7a77a1d3\",\n    \"0x98dfc2065b1622f596dbe27131ea60bef7a193b12922cecb27f8c571404f483014f8014572e86ae2e341ab738e4887ef\",\n    \"0xacb0d205566bacc87bbe2e25d10793f63f7a1f27fd9e58f4f653ceae3ffeba511eaf658e068fad289eeb28f9edbeb35b\",\n    \"0xae4411ed5b263673cee894c11fe4abc72a4bf642d94022a5c0f3369380fcdfc1c21e277f2902972252503f91ada3029a\",\n    \"0xac4a7a27ba390a75d0a247d93d4a8ef1f0485f8d373a4af4e1139369ec274b91b3464d9738eeaceb19cd6f509e2f8262\",\n    \"0x87379c3bf231fdafcf6472a79e9e55a938d851d4dd662ab6e0d95fd47a478ed99e2ad1e6e39be3c0fc4f6d996a7dd833\",\n    \"0x81316904b035a8bcc2041199a789a2e6879486ba9fddcba0a82c745cc8dd8374a39e523b91792170cd30be7aa3005b85\",\n    \"0xb8206809c6cd027ed019f472581b45f7e12288f89047928ba32b4856b6560ad30395830d71e5e30c556f6f182b1fe690\",\n    \"0x88d76c028f534a62e019b4a52967bb8642ede6becfa3807be68fdd36d366fc84a4ac8dc176e80a68bc59eb62caf5dff9\",\n    \"0x8c3b8be685b0f8aad131ee7544d0e12f223f08a6f8edaf464b385ac644e0ddc9eff7cc7cb5c1b50ab5d71ea0f41d2213\",\n    \"0x8d91410e004f76c50fdc05784157b4d839cb5090022c629c7c97a5e0c3536eeafee17a527b54b1165c3cd81774bb54ce\",\n    \"0xb25c2863bc28ec5281ce800ddf91a7e1a53f4c6d5da1e6c86ef4616e93bcf55ed49e297216d01379f5c6e7b3c1e46728\",\n    \"0x865f7b09ac3ca03f20be90c48f6975dd2588838c2536c7a3532a6aa5187ed0b709cd03d91ff4048061c10d0aa72b69ce\",\n    \"0xb3f7477c90c11596eb4f8bbf34adbcb832638c4ff3cdd090d4d477ee50472ac9ddaf5be9ad7eca3f148960d362bbd098\",\n    \"0x8db35fd53fca04faecd1c76a8227160b3ab46ac1af070f2492445a19d8ff7c25bbaef6c9fa0c8c088444561e9f7e4eb2\",\n    \"0xa478b6e9d058a2e01d2fc053b739092e113c23a6a2770a16afbef044a3709a9e32f425ace9ba7981325f02667c3f9609\",\n    \"0x98caa6bd38916c08cf221722a675a4f7577f33452623de801d2b3429595f988090907a7e99960fff7c076d6d8e877b31\",\n    \"0xb79aaaacefc49c3038a14d2ac468cfec8c2161e88bdae91798d63552cdbe39e0e02f9225717436b9b8a40a022c633c6e\",\n    \"0x845a31006c680ee6a0cc41d3dc6c0c95d833fcf426f2e7c573fa15b2c4c641fbd6fe5ebb0e23720cc3467d6ee1d80dc4\",\n    \"0xa1bc287e272cf8b74dbf6405b3a5190883195806aa351f1dc8e525aa342283f0a35ff687e3b434324dedee74946dd185\",\n    \"0xa4fd2dc8db75d3783a020856e2b3aa266dc6926e84f5c491ef739a3bddd46dc8e9e0fc1177937839ef1b18d062ffbb9e\",\n    \"0xacbf0d3c697f57c202bb8c5dc4f3fc341b8fc509a455d44bd86acc67cad2a04495d5537bcd3e98680185e8aa286f2587\",\n    \"0xa5caf423a917352e1b8e844f5968a6da4fdeae467d10c6f4bbd82b5eea46a660b82d2f5440d3641c717b2c3c9ed0be52\",\n    \"0x8a39d763c08b926599ab1233219c49c825368fad14d9afc7c0c039224d37c00d8743293fd21645bf0b91eaf579a99867\",\n    \"0xb2b53a496def0ba06e80b28f36530fbe0fb5d70a601a2f10722e59abee529369c1ae8fd0f2db9184dd4a2519bb832d94\",\n    \"0xa73980fcef053f1b60ebbb5d78ba6332a475e0b96a0c724741a3abf3b59dd344772527f07203cf4c9cb5155ebed81fa0\",\n    \"0xa070d20acce42518ece322c9db096f16aed620303a39d8d5735a0df6e70fbeceb940e8d9f5cc38f3314b2240394ec47b\",\n    \"0xa50cf591f522f19ca337b73089557f75929d9f645f3e57d4f241e14cdd1ea3fb48d84bcf05e4f0377afbb789fbdb5d20\",\n    \"0x82a5ffce451096aca8eeb0cd2ae9d83db3ed76da3f531a80d9a70a346359bf05d74863ce6a7c848522b526156a5e20cd\",\n    \"0x88e0e84d358cbb93755a906f329db1537c3894845f32b9b0b691c29cbb455373d9452fadd1e77e20a623f6eaf624de6f\",\n    \"0xaa07ac7b84a6d6838826e0b9e350d8ec75e398a52e9824e6b0da6ae4010e5943fec4f00239e96433f291fef9d1d1e609\",\n    \"0xac8887bf39366034bc63f6cc5db0c26fd27307cbc3d6cce47894a8a019c22dd51322fb5096edc018227edfafc053a8f6\",\n    \"0xb7d26c26c5b33f77422191dca94977588ab1d4b9ce7d0e19c4a3b4cd1c25211b78c328dbf81e755e78cd7d1d622ad23e\",\n    \"0x99a676d5af49f0ba44047009298d8474cabf2d5bca1a76ba21eff7ee3c4691a102fdefea27bc948ccad8894a658abd02\",\n    \"0xb0d09a91909ab3620c183bdf1d53d43d39eb750dc7a722c661c3de3a1a5d383ad221f71bae374f8a71867505958a3f76\",\n    \"0x84681a883de8e4b93d68ac10e91899c2bbb815ce2de74bb48a11a6113b2a3f4df8aceabda1f5f67bc5aacac8c9da7221\",\n    \"0x9470259957780fa9b43521fab3644f555f5343281c72582b56d2efd11991d897b3b481cafa48681c5aeb80c9663b68f7\",\n    \"0xab1b29f7ece686e6fa968a4815da1d64f3579fed3bc92e1f3e51cd13a3c076b6cf695ed269d373300a62463dc98a4234\",\n    \"0x8ab415bfcd5f1061f7687597024c96dd9c7cb4942b5989379a7a3b5742f7d394337886317659cbeacaf030234a24f972\",\n    \"0xb9b524aad924f9acc63d002d617488f31b0016e0f0548f050cada285ce7491b74a125621638f19e9c96eabb091d945be\",\n    \"0x8c4c373e79415061837dd0def4f28a2d5d74d21cb13a76c9049ad678ca40228405ab0c3941df49249847ecdefc1a5b78\",\n    \"0xa8edf4710b5ab2929d3db6c1c0e3e242261bbaa8bcec56908ddadd7d2dad2dca9d6eb9de630b960b122ebeea41040421\",\n    \"0x8d66bb3b50b9df8f373163629f9221b3d4b6980a05ea81dc3741bfe9519cf3ebba7ab98e98390bae475e8ede5821bd5c\",\n    \"0x8d3c21bae7f0cfb97c56952bb22084b58e7bb718890935b73103f33adf5e4d99cd262f929c6eeab96209814f0dbae50a\",\n    \"0xa5c66cfab3d9ebf733c4af24bebc97070e7989fe3c73e79ac85fb0e4d40ae44fb571e0fad4ad72560e13ed453900d14f\",\n    \"0x9362e6b50b43dbefbc3254471372297b5dcce809cd3b60bf74a1268ab68bdb50e46e462cbd78f0d6c056330e982846af\",\n    \"0x854630d08e3f0243d570cc2e856234cb4c1a158d9c1883bf028a76525aaa34be897fe918d5f6da9764a3735fa9ebd24a\",\n    \"0x8c7d246985469ff252c3f4df6c7c9196fc79f05c1c66a609d84725c78001d0837c7a7049394ba5cf7e863e2d58af8417\",\n    \"0xae050271e01b528925302e71903f785b782f7bf4e4e7a7f537140219bc352dc7540c657ed03d3a297ad36798ecdb98cd\",\n    \"0x8d2ae9179fcf2b0c69850554580b52c1f4a5bd865af5f3028f222f4acad9c1ad69a8ef6c7dc7b03715ee5c506b74325e\",\n    \"0xb8ef8de6ce6369a8851cd36db0ccf00a85077e816c14c4e601f533330af9e3acf0743a95d28962ed8bfcfc2520ef3cfe\",\n    \"0xa6ecad6fdfb851b40356a8b1060f38235407a0f2706e7b8bb4a13465ca3f81d4f5b99466ac2565c60af15f022d26732e\",\n    \"0x819ff14cdea3ab89d98e133cd2d0379361e2e2c67ad94eeddcdb9232efd509f51d12f4f03ebd4dd953bd262a886281f7\",\n    \"0x8561cd0f7a6dbcddd83fcd7f472d7dbcba95b2d4fb98276f48fccf69f76d284e626d7e41314b633352df8e6333fd52a1\",\n    \"0xb42557ccce32d9a894d538c48712cb3e212d06ac05cd5e0527ccd2db1078ee6ae399bf6a601ffdab1f5913d35fc0b20c\",\n    \"0x89b4008d767aad3c6f93c349d3b956e28307311a5b1cec237e8d74bb0dee7e972c24f347fd56afd915a2342bd7bc32f0\",\n    \"0x877487384b207e53f5492f4e36c832c2227f92d1bb60542cfeb35e025a4a7afc2b885fae2528b33b40ab09510398f83e\",\n    \"0x8c411050b63c9053dd0cd81dacb48753c3d7f162028098e024d17cd6348482703a69df31ad6256e3d25a8bbf7783de39\",\n    \"0xa8506b54a88d17ac10fb1b0d1fe4aa40eae7553a064863d7f6b52ccc4236dd4b82d01dca6ba87da9a239e3069ba879fb\",\n    \"0xb1a24caef9df64750c1350789bb8d8a0db0f39474a1c74ea9ba064b1516db6923f00af8d57c632d58844fb8786c3d47a\",\n    \"0x959d6e255f212b0708c58a2f75cb1fe932248c9d93424612c1b8d1e640149656059737e4db2139afd5556bcdacf3eda2\",\n    \"0x84525af21a8d78748680b6535bbc9dc2f0cf9a1d1740d12f382f6ecb2e73811d6c1da2ad9956070b1a617c61fcff9fe5\",\n    \"0xb74417d84597a485d0a8e1be07bf78f17ebb2e7b3521b748f73935b9afbbd82f34b710fb7749e7d4ab55b0c7f9de127d\",\n    \"0xa4a9aecb19a6bab167af96d8b9d9aa5308eab19e6bfb78f5a580f9bf89bdf250a7b52a09b75f715d651cb73febd08e84\",\n    \"0x9777b30be2c5ffe7d29cc2803a562a32fb43b59d8c3f05a707ab60ec05b28293716230a7d264d7cd9dd358fc031cc13e\",\n    \"0x95dce7a3d4f23ac0050c510999f5fbf8042f771e8f8f94192e17bcbfa213470802ebdbe33a876cb621cf42e275cbfc8b\",\n    \"0xb0b963ebcbbee847ab8ae740478544350b3ac7e86887e4dfb2299ee5096247cd2b03c1de74c774d9bde94ae2ee2dcd59\",\n    \"0xa4ab20bafa316030264e13f7ef5891a2c3b29ab62e1668fcb5881f50a9acac6adbe3d706c07e62f2539715db768f6c43\",\n    \"0x901478a297669d608e406fe4989be75264b6c8be12169aa9e0ad5234f459ca377f78484ffd2099a2fe2db5e457826427\",\n    \"0x88c76e5c250810c057004a03408b85cd918e0c8903dc55a0dd8bb9b4fc2b25c87f9b8cf5943eb19fbbe99d36490050c5\",\n    \"0x91607322bbad4a4f03fc0012d0821eff5f8c516fda45d1ec1133bface6f858bf04b25547be24159cab931a7aa08344d4\",\n    \"0x843203e07fce3c6c81f84bc6dc5fb5e9d1c50c8811ace522dc66e8658433a0ef9784c947e6a62c11bf705307ef05212e\",\n    \"0x91dd8813a5d6dddcda7b0f87f672b83198cd0959d8311b2b26fb1fae745185c01f796fbd03aad9db9b58482483fdadd8\",\n    \"0x8d15911aacf76c8bcd7136e958febd6963104addcd751ce5c06b6c37213f9c4fb0ffd4e0d12c8e40c36d658999724bfd\",\n    \"0x8a36c5732d3f1b497ebe9250610605ee62a78eaa9e1a45f329d09aaa1061131cf1d9df00f3a7d0fe8ad614a1ff9caaae\",\n    \"0xa407d06affae03660881ce20dab5e2d2d6cddc23cd09b95502a9181c465e57597841144cb34d22889902aff23a76d049\",\n    \"0xb5fd856d0578620a7e25674d9503be7d97a2222900e1b4738c1d81ff6483b144e19e46802e91161e246271f90270e6cf\",\n    \"0x91b7708869cdb5a7317f88c0312d103f8ce90be14fb4f219c2e074045a2a83636fdc3e69e862049fc7c1ef000e832541\",\n    \"0xb64719cc5480709d1dae958f1d3082b32a43376da446c8f9f64cb02a301effc9c34d9102051733315a8179aed94d53cc\",\n    \"0x94347a9542ff9d18f7d9eaa2f4d9b832d0e535fe49d52aa2de08aa8192400eddabdb6444a2a78883e27c779eed7fdf5a\",\n    \"0x840ef44a733ff1376466698cd26f82cf56bb44811e196340467f932efa3ae1ef9958a0701b3b032f50fd9c1d2aed9ab5\",\n    \"0x90ab3f6f67688888a31ffc2a882bb37adab32d1a4b278951a21646f90d03385fc976715fc639a785d015751171016f10\",\n    \"0xb56f35d164c24b557dbcbc8a4bfa681ec916f8741ffcb27fb389c164f4e3ed2be325210ef5bdaeae7a172ca9599ab442\",\n    \"0xa7921a5a80d7cf6ae81ba9ee05e0579b18c20cd2852762c89d6496aa4c8ca9d1ca2434a67b2c16d333ea8e382cdab1e3\",\n    \"0xa506bcfbd7e7e5a92f68a1bd87d07ad5fe3b97aeee40af2bf2cae4efcd77fff03f872732c5b7883aa6584bee65d6f8cb\",\n    \"0xa8c46cff58931a1ce9cbe1501e1da90b174cddd6d50f3dfdfb759d1d4ad4673c0a8feed6c1f24c7af32865a7d6c984e5\",\n    \"0xb45686265a83bff69e312c5149db7bb70ac3ec790dc92e392b54d9c85a656e2bf58596ce269f014a906eafc97461aa5f\",\n    \"0x8d4009a75ccb2f29f54a5f16684b93202c570d7a56ec1a8b20173269c5f7115894f210c26b41e8d54d4072de2d1c75d0\",\n    \"0xaef8810af4fc676bf84a0d57b189760ddc3375c64e982539107422e3de2580b89bd27aa6da44e827b56db1b5555e4ee8\",\n    \"0x888f0e1e4a34f48eb9a18ef4de334c27564d72f2cf8073e3d46d881853ac1424d79e88d8ddb251914890588937c8f711\",\n    \"0xb64b0aa7b3a8f6e0d4b3499fe54e751b8c3e946377c0d5a6dbb677be23736b86a7e8a6be022411601dd75012012c3555\",\n    \"0x8d57776f519f0dd912ea14f79fbab53a30624e102f9575c0bad08d2dc754e6be54f39b11278c290977d9b9c7c0e1e0ad\",\n    \"0xa018fc00d532ceb2e4de908a15606db9b6e0665dd77190e2338da7c87a1713e6b9b61554e7c1462f0f6d4934b960b15c\",\n    \"0x8c932be83ace46f65c78e145b384f58e41546dc0395270c1397874d88626fdeda395c8a289d602b4c312fe98c1311856\",\n    \"0x89174838e21639d6bdd91a0621f04dc056907b88e305dd66e46a08f6d65f731dea72ae87ca5e3042d609e8de8de9aa26\",\n    \"0xb7b7f508bb74f7a827ac8189daa855598ff1d96fa3a02394891fd105d8f0816224cd50ac4bf2ed1cf469ace516c48184\",\n    \"0xb31877ad682583283baadd68dc1bebd83f5748b165aadd7fe9ef61a343773b88bcd3a022f36d6c92f339b7bfd72820a9\",\n    \"0xb79d77260b25daf9126dab7a193df2d7d30542786fa1733ffaf6261734770275d3ca8bae1d9915d1181a78510b3439db\",\n    \"0x91894fb94cd4c1dd2ceaf9c53a7020c5799ba1217cf2d251ea5bc91ed26e1159dd758e98282ebe35a0395ef9f1ed15a0\",\n    \"0xab59895cdafd33934ceedfc3f0d5d89880482cba6c99a6db93245f9e41987efd76e0640e80aef31782c9a8c7a83fccec\",\n    \"0xaa22ea63654315e033e09d4d4432331904a6fc5fb1732557987846e3c564668ca67c60a324b4af01663a23af11a9ce4b\",\n    \"0xb53ba3ef342601467e1f71aa280e100fbabbd38518fa0193e0099505036ee517c1ac78e96e9baeb549bb6879bb698fb0\",\n    \"0x943fd69fd656f37487cca3605dc7e5a215fddd811caf228595ec428751fc1de484a0cb84c667fe4d7c35599bfa0e5e34\",\n    \"0x9353128b5ebe0dddc555093cf3e5942754f938173541033e8788d7331fafc56f68d9f97b4131e37963ab7f1c8946f5f1\",\n    \"0xa76cd3c566691f65cfb86453b5b31dbaf3cab8f84fe1f795dd1e570784b9b01bdd5f0b3c1e233942b1b5838290e00598\",\n    \"0x983d84b2e53ffa4ae7f3ba29ef2345247ea2377686b74a10479a0ef105ecf90427bf53b74c96dfa346d0f842b6ffb25b\",\n    \"0x92e0fe9063306894a2c6970c001781cff416c87e87cb5fbac927a3192655c3da4063e6fa93539f6ff58efac6adcc5514\",\n    \"0xb00a81f03c2b8703acd4e2e4c21e06973aba696415d0ea1a648ace2b0ea19b242fede10e4f9d7dcd61c546ab878bc8f9\",\n    \"0xb0d08d880f3b456a10bf65cff983f754f545c840c413aea90ce7101a66eb0a0b9b1549d6c4d57725315828607963f15a\",\n    \"0x90cb64d03534f913b411375cce88a9e8b1329ce67a9f89ca5df8a22b8c1c97707fec727dbcbb9737f20c4cf751359277\",\n    \"0x8327c2d42590dfcdb78477fc18dcf71608686ad66c49bce64d7ee874668be7e1c17cc1042a754bbc77c9daf50b2dae07\",\n    \"0x8532171ea13aa7e37178e51a6c775da469d2e26ec854eb16e60f3307db4acec110d2155832c202e9ba525fc99174e3b0\",\n    \"0x83ca44b15393d021de2a511fa5511c5bd4e0ac7d67259dce5a5328f38a3cce9c3a269405959a2486016bc27bb140f9ff\",\n    \"0xb1d36e8ca812be545505c8214943b36cabee48112cf0de369957afa796d37f86bf7249d9f36e8e990f26f1076f292b13\",\n    \"0x9803abf45be5271e2f3164c328d449efc4b8fc92dfc1225d38e09630909fe92e90a5c77618daa5f592d23fc3ad667094\",\n    \"0xb268ad68c7bf432a01039cd889afae815c3e120f57930d463aece10af4fd330b5bd7d8869ef1bcf6b2e78e4229922edc\",\n    \"0xa4c91a0d6f16b1553264592b4cbbbf3ca5da32ab053ffbdd3dbb1aed1afb650fb6e0dc5274f71a51d7160856477228db\",\n    \"0xad89d043c2f0f17806277ffdf3ecf007448e93968663f8a0b674254f36170447b7527d5906035e5e56f4146b89b5af56\",\n    \"0x8b6964f757a72a22a642e4d69102951897e20c21449184e44717bd0681d75f7c5bfa5ee5397f6e53febf85a1810d6ed1\",\n    \"0xb08f5cdaabec910856920cd6e836c830b863eb578423edf0b32529488f71fe8257d90aed4a127448204df498b6815d79\",\n    \"0xaf26bb3358be9d280d39b21d831bb53145c4527a642446073fee5a86215c4c89ff49a3877a7a549486262f6f57a0f476\",\n    \"0xb4010b37ec4d7c2af20800e272539200a6b623ae4636ecbd0e619484f4ab9240d02bc5541ace3a3fb955dc0a3d774212\",\n    \"0x82752ab52bdcc3cc2fc405cb05a2e694d3df4a3a68f2179ec0652536d067b43660b96f85f573f26fbd664a9ef899f650\",\n    \"0x96d392dde067473a81faf2d1fea55b6429126b88b160e39b4210d31d0a82833ffd3a80e07d24d495aea2d96be7251547\",\n    \"0xa76d8236d6671204d440c33ac5b8deb71fa389f6563d80e73be8b043ec77d4c9b06f9a586117c7f957f4af0331cbc871\",\n    \"0xb6c90961f68b5e385d85c9830ec765d22a425f506904c4d506b87d8944c2b2c09615e740ed351df0f9321a7b93979cae\",\n    \"0xa6ec5ea80c7558403485b3b1869cdc63bde239bafdf936d9b62a37031628402a36a2cfa5cfbb8e26ac922cb0a209b3ba\",\n    \"0x8c3195bbdbf9bc0fc95fa7e3d7f739353c947f7767d1e3cb24d8c8602d8ea0a1790ac30b815be2a2ba26caa5227891e2\",\n    \"0xa7f8a63d809f1155722c57f375ea00412b00147776ae4444f342550279ef4415450d6f400000a326bf11fea6c77bf941\",\n    \"0x97fa404df48433a00c85793440e89bb1af44c7267588ae937a1f5d53e01e1c4d4fc8e4a6d517f3978bfdd6c2dfde012f\",\n    \"0xa984a0a3836de3d8d909c4629a2636aacb85393f6f214a2ef68860081e9db05ad608024762db0dc35e895dc00e2d4cdd\",\n    \"0x9526cf088ab90335add1db4d3a4ac631b58cbfbe88fa0845a877d33247d1cfeb85994522e1eb8f8874651bfb1df03e2a\",\n    \"0xac83443fd0afe99ad49de9bf8230158c118e2814c9c89db5ac951c240d6c2ce45e7677221279d9e97848ec466b99aafe\",\n    \"0xaeeefdbaba612e971697798ceaf63b247949dc823a0ad771ae5b988a5e882b338a98d3d0796230f49d533ec5ba411b39\",\n    \"0xae3f248b5a7b0f92b7820a6c5ae21e5bd8f4265d4f6e21a22512079b8ee9be06393fd3133ce8ebac0faf23f4f8517e36\",\n    \"0xa64a831b908eee784b8388b45447d2885ec0551b26b0c2b15e5f417d0a12c79e867fb7bd3d008d0af98b44336f8ec1ad\",\n    \"0xb242238cd8362b6e440ba21806905714dd55172db25ec7195f3fc4937b2aba146d5cbf3cf691a1384b4752dc3b54d627\",\n    \"0x819f97f337eea1ffb2a678cc25f556f1aab751c6b048993a1d430fe1a3ddd8bb411c152e12ca60ec6e057c190cd1db9a\",\n    \"0xb9d7d187407380df54ee9fef224c54eec1bfabf17dc8abf60765b7951f538f59aa26fffd5846cfe05546c35f59b573f4\",\n    \"0xaa6e3c14efa6a5962812e3f94f8ce673a433f4a82d07a67577285ea0eaa07f8be7115853122d12d6d4e1fdf64c504be1\",\n    \"0x82268bee9c1662d3ddb5fb785abfae6fb8b774190f30267f1d47091d2cd4b3874db4372625aa36c32f27b0eee986269b\",\n    \"0xb236459565b7b966166c4a35b2fa71030b40321821b8e96879d95f0e83a0baf33fa25721f30af4a631df209e25b96061\",\n    \"0x8708d752632d2435d2d5b1db4ad1fa2558d776a013655f88e9a3556d86b71976e7dfe5b8834fdec97682cd94560d0d0d\",\n    \"0xae1424a68ae2dbfb0f01211f11773732a50510b5585c1fb005cb892b2c6a58f4a55490b5c5b4483c6fce40e9d3236a52\",\n    \"0xb3f5f722af9dddb07293c871ce97abbccba0093ca98c8d74b1318fa21396fc1b45b69c15084f63d728f9908442024506\",\n    \"0x9606f3ce5e63886853ca476dc0949e7f1051889d529365c0cb0296fdc02abd088f0f0318ecd2cf36740a3634132d36f6\",\n    \"0xb11a833a49fa138db46b25ff8cdda665295226595bc212c0931b4931d0a55c99da972c12b4ef753f7e37c6332356e350\",\n    \"0xafede34e7dab0a9e074bc19a7daddb27df65735581ca24ad70c891c98b1349fcebbcf3ba6b32c2617fe06a5818dabc2d\",\n    \"0x97993d456e459e66322d01f8eb13918979761c3e8590910453944bdff90b24091bb018ac6499792515c9923be289f99f\",\n    \"0x977e3e967eff19290a192cd11df3667d511b398fb3ac9a5114a0f3707e25a0edcb56105648b1b85a8b7519fc529fc6f6\",\n    \"0xb873a7c88bf58731fe1bf61ff6828bf114cf5228f254083304a4570e854e83748fc98683ddba62d978fff7909f2c5c47\",\n    \"0xad4b2691f6f19da1d123aaa23cca3e876247ed9a4ab23c599afdbc0d3aa49776442a7ceaa996ac550d0313d9b9a36cee\",\n    \"0xb9210713c78e19685608c6475bfa974b57ac276808a443f8b280945c5d5f9c39da43effa294bfb1a6c6f7b6b9f85bf6c\",\n    \"0xa65152f376113e61a0e468759de38d742caa260291b4753391ee408dea55927af08a4d4a9918600a3bdf1df462dffe76\",\n    \"0x8bf8c27ad5140dde7f3d2280fd4cc6b29ab76537e8d7aa7011a9d2796ee3e56e9a60c27b5c2da6c5e14fc866301dc195\",\n    \"0x92fde8effc9f61393a2771155812b863cff2a0c5423d7d40aa04d621d396b44af94ddd376c28e7d2f53c930aea947484\",\n    \"0x97a01d1dd9ee30553ce676011aea97fa93d55038ada95f0057d2362ae9437f3ed13de8290e2ff21e3167dd7ba10b9c3f\",\n    \"0x89affffaa63cb2df3490f76f0d1e1d6ca35c221dd34057176ba739fa18d492355e6d2a5a5ad93a136d3b1fed0bb8aa19\",\n    \"0x928b8e255a77e1f0495c86d3c63b83677b4561a5fcbbe5d3210f1e0fc947496e426d6bf3b49394a5df796c9f25673fc4\",\n    \"0x842a0af91799c9b533e79ee081efe2a634cac6c584c2f054fb7d1db67dde90ae36de36cbf712ec9cd1a0c7ee79e151ea\",\n    \"0xa65b946cf637e090baf2107c9a42f354b390e7316beb8913638130dbc67c918926eb87bec3b1fe92ef72bc77a170fa3b\",\n    \"0xaafc0f19bfd71ab5ae4a8510c7861458b70ad062a44107b1b1dbacbfa44ba3217028c2824bd7058e2fa32455f624040b\",\n    \"0x95269dc787653814e0be899c95dba8cfa384f575a25e671c0806fd80816ad6797dc819d30ae06e1d0ed9cb01c3950d47\",\n    \"0xa1e760f7fa5775a1b2964b719ff961a92083c5c617f637fc46e0c9c20ab233f8686f7f38c3cb27d825c54dd95e93a59b\",\n    \"0xac3b8a7c2317ea967f229eddc3e23e279427f665c4705c7532ed33443f1243d33453c1088f57088d2ab1e3df690a9cc9\",\n    \"0xb787beeddfbfe36dd51ec4efd9cf83e59e84d354c3353cc9c447be53ae53d366ed1c59b686e52a92f002142c8652bfe0\",\n    \"0xb7a64198300cb6716aa7ac6b25621f8bdec46ad5c07a27e165b3f774cdf65bcfdbf31e9bae0c16b44de4b00ada7a4244\",\n    \"0xb8ae9f1452909e0c412c7a7fe075027691ea8df1347f65a5507bc8848f1d2c833d69748076db1129e5b4fb912f65c86c\",\n    \"0x9682e41872456b9fa67def89e71f06d362d6c8ca85c9c48536615bc401442711e1c9803f10ab7f8ab5feaec0f9df20a6\",\n    \"0x88889ff4e271dc1c7e21989cc39f73cde2f0475acd98078281591ff6c944fadeb9954e72334319050205d745d4df73df\",\n    \"0x8f79b5b8159e7fd0d93b0645f3c416464f39aec353b57d99ecf24f96272df8a068ad67a6c90c78d82c63b40bb73989bb\",\n    \"0x838c01a009a3d8558a3f0bdd5e22de21af71ca1aefc8423c91dc577d50920e9516880e87dce3e6d086e11cd45c9052d9\",\n    \"0xb97f1c6eee8a78f137c840667cc288256e39294268a3009419298a04a1d0087c9c9077b33c917c65caf76637702dda8a\",\n    \"0x972284ce72f96a61c899260203dfa06fc3268981732bef74060641c1a5068ead723e3399431c247ca034b0dae861e8df\",\n    \"0x945a8d52d6d3db6663dbd3110c6587f9e9c44132045eeffba15621576d178315cb52870fa5861669f84f0bee646183fe\",\n    \"0xa0a547b5f0967b1c3e5ec6c6a9a99f0578521489180dfdfbb5561f4d166baac43a2f06f950f645ce991664e167537eed\",\n    \"0xa0592cda5cdddf1340033a745fd13a6eff2021f2e26587116c61c60edead067e0f217bc2bef4172a3c9839b0b978ab35\",\n    \"0xb9c223b65a3281587fa44ec829e609154b32f801fd1de6950e01eafb07a8324243b960d5735288d0f89f0078b2c42b5b\",\n    \"0x99ebfc3b8f9f98249f4d37a0023149ed85edd7a5abe062c8fb30c8c84555258b998bdcdd1d400bc0fa2a4aaa8b224466\",\n    \"0x955b68526e6cb3937b26843270f4e60f9c6c8ece2fa9308fe3e23afa433309c068c66a4bc16ee2cf04220f095e9afce4\",\n    \"0xb766caeafcc00378135ae53397f8a67ed586f5e30795462c4a35853de6681b1f17401a1c40958de32b197c083b7279c1\",\n    \"0x921bf87cad947c2c33fa596d819423c10337a76fe5a63813c0a9dc78a728207ae7b339407a402fc4d0f7cba3af6da6fc\",\n    \"0xa74ba1f3bc3e6c025db411308f49b347ec91da1c916bda9da61e510ec8d71d25e0ac0f124811b7860e5204f93099af27\",\n    \"0xa29b4d144e0bf17a7e8353f2824cef0ce85621396babe8a0b873ca1e8a5f8d508b87866cf86da348470649fceefd735c\",\n    \"0xa8040e12ffc3480dd83a349d06741d1572ef91932c46f5cf03aee8454254156ee95786fd013d5654725e674c920cec32\",\n    \"0x8c4cf34ca60afd33923f219ffed054f90cd3f253ffeb2204a3b61b0183417e366c16c07fae860e362b0f2bfe3e1a1d35\",\n    \"0x8195eede4ddb1c950459df6c396b2e99d83059f282b420acc34220cadeed16ab65c856f2c52568d86d3c682818ed7b37\",\n    \"0x91fff19e54c15932260aa990c7fcb3c3c3da94845cc5aa8740ef56cf9f58d19b4c3c55596f8d6c877f9f4d22921d93aa\",\n    \"0xa3e0bf7e5d02a80b75cf75f2db7e66cb625250c45436e3c136d86297d652590ec97c2311bafe407ad357c79ab29d107b\",\n    \"0x81917ff87e5ed2ae4656b481a63ced9e6e5ff653b8aa6b7986911b8bc1ee5b8ef4f4d7882c3f250f2238e141b227e510\",\n    \"0x915fdbe5e7de09c66c0416ae14a8750db9412e11dc576cf6158755fdcaf67abdbf0fa79b554cac4fe91c4ec245be073f\",\n    \"0x8df27eafb5c3996ba4dc5773c1a45ca77e626b52e454dc1c4058aa94c2067c18332280630cc3d364821ee53bf2b8c130\",\n    \"0x934f8a17c5cbb827d7868f5c8ca00cb027728a841000a16a3428ab16aa28733f16b52f58c9c4fbf75ccc45df72d9c4df\",\n    \"0xb83f4da811f9183c25de8958bc73b504cf790e0f357cbe74ef696efa7aca97ad3b7ead1faf76e9f982c65b6a4d888fc2\",\n    \"0x87188213c8b5c268dc2b6da413f0501c95749e953791b727450af3e43714149c115b596b33b63a2f006a1a271b87efd0\",\n    \"0x83e9e888ab9c3e30761de635d9aabd31248cdd92f7675fc43e4b21fd96a03ec1dc4ad2ec94fec857ffb52683ac98e360\",\n    \"0xb4b9a1823fe2d983dc4ec4e3aaea297e581c3fc5ab4b4af5fa1370caa37af2d1cc7fc6bfc5e7da60ad8fdce27dfe4b24\",\n    \"0x856388bc78aef465dbcdd1f559252e028c9e9a2225c37d645c138e78f008f764124522705822a61326a6d1c79781e189\",\n    \"0xa6431b36db93c3b47353ba22e7c9592c9cdfb9cbdd052ecf2cc3793f5b60c1e89bc96e6bae117bfd047f2308da00dd2f\",\n    \"0xb619972d48e7e4291542dcde08f7a9cdc883c892986ded2f23ccb216e245cd8d9ad1d285347b0f9d7611d63bf4cee2bc\",\n    \"0x8845cca6ff8595955f37440232f8e61d5351500bd016dfadd182b9d39544db77a62f4e0102ff74dd4173ae2c181d24ef\",\n    \"0xb2f5f7fa26dcd3b6550879520172db2d64ee6aaa213cbef1a12befbce03f0973a22eb4e5d7b977f466ac2bf8323dcedd\",\n    \"0x858b7f7e2d44bdf5235841164aa8b4f3d33934e8cb122794d90e0c1cac726417b220529e4f896d7b77902ab0ccd35b3a\",\n    \"0x80b0408a092dae2b287a5e32ea1ad52b78b10e9c12f49282976cd738f5d834e03d1ad59b09c5ccaccc39818b87d06092\",\n    \"0xb996b0a9c6a2d14d984edcd6ab56bc941674102980d65b3ad9733455f49473d3f587c8cbf661228a7e125ddbe07e3198\",\n    \"0x90224fcebb36865293bd63af786e0c5ade6b67c4938d77eb0cbae730d514fdd0fe2d6632788e858afd29d46310cf86df\",\n    \"0xb71351fdfff7168b0a5ec48397ecc27ac36657a8033d9981e97002dcca0303e3715ce6dd3f39423bc8ef286fa2e9e669\",\n    \"0xae2a3f078b89fb753ce4ed87e0c1a58bb19b4f0cfb6586dedb9fcab99d097d659a489fb40e14651741e1375cfc4b6c5f\",\n    \"0x8ef476b118e0b868caed297c161f4231bbeb863cdfa5e2eaa0fc6b6669425ce7af50dc374abceac154c287de50c22307\",\n    \"0x92e46ab472c56cfc6458955270d3c72b7bde563bb32f7d4ab4d959db6f885764a3d864e1aa19802fefaa5e16b0cb0b54\",\n    \"0x96a3f68323d1c94e73d5938a18a377af31b782f56212de3f489d22bc289cf24793a95b37f1d6776edf88114b5c1fa695\",\n    \"0x962cc068cfce6faaa27213c4e43e44eeff0dfbb6d25b814e82c7da981fb81d7d91868fa2344f05fb552362f98cfd4a72\",\n    \"0x895d4e4c4ad670abf66d43d59675b1add7afad7438ada8f42a0360c704cee2060f9ac15b4d27e9b9d0996bb801276fe3\",\n    \"0xb3ad18d7ece71f89f2ef749b853c45dc56bf1c796250024b39a1e91ed11ca32713864049c9aaaea60cde309b47486bbf\",\n    \"0x8f05404e0c0258fdbae50e97ccb9b72ee17e0bd2400d9102c0dad981dac8c4c71585f03e9b5d50086d0a2d3334cb55d1\",\n    \"0x8bd877e9d4591d02c63c6f9fc9976c109de2d0d2df2bfa5f6a3232bab5b0b8b46e255679520480c2d7a318545efa1245\",\n    \"0x8d4c16b5d98957c9da13d3f36c46f176e64e5be879f22be3179a2c0e624fe4758a82bf8c8027410002f973a3b84cd55a\",\n    \"0x86e2a8dea86427b424fa8eada881bdff896907084a495546e66556cbdf070b78ba312bf441eb1be6a80006d25d5097a3\",\n    \"0x8608b0c117fd8652fdab0495b08fadbeba95d9c37068e570de6fddfef1ba4a1773b42ac2be212836141d1bdcdef11a17\",\n    \"0xa13d6febf5fb993ae76cae08423ca28da8b818d6ef0fde32976a4db57839cd45b085026b28ee5795f10a9a8e3098c683\",\n    \"0x8e261967fa6de96f00bc94a199d7f72896a6ad8a7bbb1d6187cca8fad824e522880e20f766620f4f7e191c53321d70f9\",\n    \"0x8b8e8972ac0218d7e3d922c734302803878ad508ca19f5f012bc047babd8a5c5a53deb5fe7c15a4c00fd6d1cb9b1dbd0\",\n    \"0xb5616b233fb3574a2717d125a434a2682ff68546dccf116dd8a3b750a096982f185614b9fb6c7678107ff40a451f56fa\",\n    \"0xaa6adf9b0c3334b0d0663f583a4914523b2ac2e7adffdb026ab9109295ff6af003ef8357026dbcf789896d2afded8d73\",\n    \"0xacb72df56a0b65496cd534448ed4f62950bb1e11e50873b6ed349c088ee364441821294ce0f7c61bd7d38105bea3b442\",\n    \"0xabae12df83e01ec947249fedd0115dc501d2b03ff7232092979eda531dbbca29ace1d46923427c7dde4c17bdf3fd7708\",\n    \"0x820b4fc2b63a9fda7964acf5caf19a2fc4965007cb6d6b511fcafcb1f71c3f673a1c0791d3f86e3a9a1eb6955b191cc0\",\n    \"0xaf277259d78c6b0f4f030a10c53577555df5e83319ddbad91afbd7c30bc58e7671c56d00d66ec3ab5ef56470cd910cee\",\n    \"0xad4a861c59f1f5ca1beedd488fb3d131dea924fffd8e038741a1a7371fad7370ca5cf80dc01f177fbb9576713bb9a5b3\",\n    \"0xb67a5162982ce6a55ccfb2f177b1ec26b110043cf18abd6a6c451cf140b5af2d634591eb4f28ad92177d8c7e5cd0a5e8\",\n    \"0x96176d0a83816330187798072d449cbfccff682561e668faf6b1220c9a6535b32a6e4f852e8abb00f79abb87493df16b\",\n    \"0xb0afe6e7cb672e18f0206e4423f51f8bd0017bf464c4b186d46332c5a5847647f89ff7fa4801a41c1b0b42f6135bcc92\",\n    \"0x8fc5e7a95ef20c1278c645892811f6fe3f15c431ebc998a32ec0da44e7213ea934ed2be65239f3f49b8ec471e9914160\",\n    \"0xb7793e41adda6c82ba1f2a31f656f6205f65bf8a3d50d836ee631bc7ce77c153345a2d0fc5c60edf8b37457c3729c4ec\",\n    \"0xa504dd7e4d6b2f4379f22cc867c65535079c75ccc575955f961677fa63ecb9f74026fa2f60c9fb6323c1699259e5e9c8\",\n    \"0xab899d00ae693649cc1afdf30fb80d728973d2177c006e428bf61c7be01e183866614e05410041bc82cb14a33330e69c\",\n    \"0x8a3bd8b0b1be570b65c4432a0f6dc42f48a2000e30ab089cf781d38f4090467b54f79c0d472fcbf18ef6a00df69cc6f3\",\n    \"0xb4d7028f7f76a96a3d7803fca7f507ae11a77c5346e9cdfccb120a833a59bda1f4264e425aa588e7a16f8e7638061d84\",\n    \"0xb9c7511a76ea5fb105de905d44b02edb17008335766ee357ed386b7b3cf19640a98b38785cb14603c1192bee5886c9b6\",\n    \"0x8563afb12e53aed71ac7103ab8602bfa8371ae095207cb0d59e8fd389b6ad1aff0641147e53cb6a7ca16c7f37c9c5e6b\",\n    \"0x8e108be614604e09974a9ed90960c28c4ea330a3d9a0cb4af6dd6f193f84ab282b243ecdf549b3131036bebc8905690c\",\n    \"0xb794d127fbedb9c5b58e31822361706ffac55ce023fbfe55716c3c48c2fd2f2c7660a67346864dfe588812d369cb50b6\",\n    \"0xb797a3442fc3b44f41baefd30346f9ac7f96e770d010d53c146ce74ce424c10fb62758b7e108b8abfdc5fafd89d745cb\",\n    \"0x993bb71e031e8096442e6205625e1bfddfe6dd6a83a81f3e2f84fafa9e5082ab4cad80a099f21eff2e81c83457c725c3\",\n    \"0x8711ab833fc03e37acf2e1e74cfd9133b101ff4144fe30260654398ae48912ab46549d552eb9d15d2ea57760d35ac62e\",\n    \"0xb21321fd2a12083863a1576c5930e1aecb330391ef83326d9d92e1f6f0d066d1394519284ddab55b2cb77417d4b0292f\",\n    \"0x877d98f731ffe3ee94b0b5b72d127630fa8a96f6ca4f913d2aa581f67732df6709493693053b3e22b0181632ac6c1e3b\",\n    \"0xae391c12e0eb8c145103c62ea64f41345973311c3bf7281fa6bf9b7faafac87bcf0998e5649b9ef81e288c369c827e07\",\n    \"0xb83a2842f36998890492ab1cd5a088d9423d192681b9a3a90ec518d4c541bce63e6c5f4df0f734f31fbfdd87785a2463\",\n    \"0xa21b6a790011396e1569ec5b2a423857b9bec16f543e63af28024e116c1ea24a3b96e8e4c75c6537c3e4611fd265e896\",\n    \"0xb4251a9c4aab3a495da7a42e684ba4860dbcf940ad1da4b6d5ec46050cbe8dab0ab9ae6b63b5879de97b905723a41576\",\n    \"0x8222f70aebfe6ac037f8543a08498f4cadb3edaac00336fc00437eb09f2cba758f6c38e887cc634b4d5b7112b6334836\",\n    \"0x86f05038e060594c46b5d94621a1d9620aa8ba59a6995baf448734e21f58e23c1ea2993d3002ad5250d6edd5ba59b34f\",\n    \"0xa7c0c749baef811ab31b973c39ceb1d94750e2bc559c90dc5eeb20d8bb6b78586a2b363c599ba2107d6be65cd435f24e\",\n    \"0x861d46a5d70b38d6c1cd72817a2813803d9f34c00320c8b62f8b9deb67f5b5687bc0b37c16d28fd017367b92e05da9ca\",\n    \"0xb3365d3dab639bffbe38e35383686a435c8c88b397b717cd4aeced2772ea1053ceb670f811f883f4e02975e5f1c4ac58\",\n    \"0xa5750285f61ab8f64cd771f6466e2c0395e01b692fd878f2ef2d5c78bdd8212a73a3b1dfa5e4c8d9e1afda7c84857d3b\",\n    \"0x835a10809ccf939bc46cf950a33b36d71be418774f51861f1cd98a016ade30f289114a88225a2c11e771b8b346cbe6ef\",\n    \"0xa4f59473a037077181a0a62f1856ec271028546ca9452b45cedfcb229d0f4d1aabfc13062b07e536cc8a0d4b113156a2\",\n    \"0x95cd14802180b224d44a73cc1ed599d6c4ca62ddcaa503513ccdc80aaa8be050cc98bd4b4f3b639549beb4587ac6caf9\",\n    \"0x973b731992a3e69996253d7f36dd7a0af1982b5ed21624b77a7965d69e9a377b010d6dabf88a8a97eec2a476259859cc\",\n    \"0xaf8a1655d6f9c78c8eb9a95051aa3baaf9c811adf0ae8c944a8d3fcba87b15f61021f3baf6996fa0aa51c81b3cb69de1\",\n    \"0x835aad5c56872d2a2d6c252507b85dd742bf9b8c211ccb6b25b52d15c07245b6d89b2a40f722aeb5083a47cca159c947\",\n    \"0xabf4e970b02bef8a102df983e22e97e2541dd3650b46e26be9ee394a3ea8b577019331857241d3d12b41d4eacd29a3ac\",\n    \"0xa13c32449dbedf158721c13db9539ae076a6ce5aeaf68491e90e6ad4e20e20d1cdcc4a89ed9fd49cb8c0dd50c17633c1\",\n    \"0x8c8f78f88b7e22dd7e9150ab1c000f10c28e696e21d85d6469a6fe315254740f32e73d81ab1f3c1cf8f544c86df506e8\",\n    \"0xb4b77f2acfe945abf81f2605f906c10b88fb4d28628487fb4feb3a09f17f28e9780445dfcee4878349d4c6387a9d17d4\",\n    \"0x8d255c235f3812c6ecc646f855fa3832be5cb4dbb9c9e544989fafdf3f69f05bfd370732eaf954012f0044aa013fc9c6\",\n    \"0xb982efd3f34b47df37c910148ac56a84e8116647bea24145a49e34e0a6c0176e3284d838dae6230cb40d0be91c078b85\",\n    \"0x983f365aa09bd85df2a6a2ad8e4318996b1e27d02090755391d4486144e40d80b1fbfe1c798d626db92f52e33aa634da\",\n    \"0x95fd1981271f3ea3a41d654cf497e6696730d9ff7369f26bc4d7d15c7adb4823dd0c42e4a005a810af12d234065e5390\",\n    \"0xa9f5219bd4b913c186ef30c02f995a08f0f6f1462614ea5f236964e02bdaa33db9d9b816c4aee5829947840a9a07ba60\",\n    \"0x9210e6ceb05c09b46fd09d036287ca33c45124ab86315e5d6911ff89054f1101faaa3e83d123b7805056d388bcec6664\",\n    \"0x8ed9cbf69c6ff3a5c62dd9fe0d7264578c0f826a29e614bc2fb4d621d90c8c9992438accdd7a614b1dca5d1bb73dc315\",\n    \"0x85cf2a8cca93e00da459e3cecd22c342d697eee13c74d5851634844fc215f60053cf84b0e03c327cb395f48d1c71a8a4\",\n    \"0x8818a18e9a2ec90a271b784400c1903089ffb0e0b40bc5abbbe12fbebe0f731f91959d98c5519ef1694543e31e2016d4\",\n    \"0x8dabc130f296fa7a82870bf9a8405aaf542b222ed9276bba9bd3c3555a0f473acb97d655ee7280baff766a827a8993f0\",\n    \"0xac7952b84b0dc60c4d858f034093b4d322c35959605a3dad2b806af9813a4680cb038c6d7f4485b4d6b2ff502aaeca25\",\n    \"0xad65cb6d57b48a2602568d2ec8010baed0eb440eec7638c5ec8f02687d764e9de5b5d42ad5582934e592b48471c22d26\",\n    \"0xa02ab8bd4c3d114ea23aebdd880952f9495912817da8c0c08eabc4e6755439899d635034413d51134c72a6320f807f1c\",\n    \"0x8319567764b8295402ec1ebef4c2930a138480b37e6d7d01c8b4c9cd1f2fc3f6e9a44ae6e380a0c469b25b06db23305f\",\n    \"0xafec53b2301dc0caa8034cd9daef78c48905e6068d692ca23d589b84a6fa9ddc2ed24a39480597e19cb3e83eec213b3f\",\n    \"0xac0b4ffdb5ae08e586a9cdb98f9fe56f4712af3a97065e89e274feacfb52b53c839565aee93c4cfaaccfe51432c4fab0\",\n    \"0x8972cbf07a738549205b1094c5987818124144bf187bc0a85287c94fdb22ce038c0f11df1aa16ec5992e91b44d1af793\",\n    \"0xb7267aa6f9e3de864179b7da30319f1d4cb2a3560f2ea980254775963f1523b44c680f917095879bebfa3dc2b603efcf\",\n    \"0x80f68f4bfc337952e29504ee5149f15093824ea7ab02507efd1317a670f6cbc3611201848560312e3e52e9d9af72eccf\",\n    \"0x8897fee93ce8fc1e1122e46b6d640bba309384dbd92e46e185e6364aa8210ebf5f9ee7e5e604b6ffba99aa80a10dd7d0\",\n    \"0xb58ea6c02f2360be60595223d692e82ee64874fda41a9f75930f7d28586f89be34b1083e03bbc1575bbfdda2d30db1ea\",\n    \"0x85a523a33d903280d70ac5938770453a58293480170c84926457ac2df45c10d5ff34322ab130ef4a38c916e70d81af53\",\n    \"0xa2cbf045e1bed38937492c1f2f93a5ba41875f1f262291914bc1fc40c60bd0740fb3fea428faf6da38b7c180fe8ac109\",\n    \"0x8c09328770ed8eb17afc6ac7ddd87bb476de18ed63cab80027234a605806895959990c47bd10d259d7f3e2ecb50074c9\",\n    \"0xb4b9e19edb4a33bde8b7289956568a5b6b6557404e0a34584b5721fe6f564821091013fbb158e2858c6d398293bb4b59\",\n    \"0x8a47377df61733a2aa5a0e945fce00267f8e950f37e109d4487d92d878fb8b573317bb382d902de515b544e9e233458d\",\n    \"0xb5804c9d97efeff5ca94f3689b8088c62422d92a1506fd1d8d3b1b30e8a866ad0d6dad4abfa051dfc4471250cac4c5d9\",\n    \"0x9084a6ee8ec22d4881e9dcc8a9eb3c2513523d8bc141942370fd191ad2601bf9537a0b1e84316f3209b3d8a54368051e\",\n    \"0x85447eea2fa26656a649f8519fa67279183044791d61cf8563d0783d46d747d96af31d0a93507bbb2242666aa87d3720\",\n    \"0x97566a84481027b60116c751aec552adfff2d9038e68d48c4db9811fb0cbfdb3f1d91fc176a0b0d988a765f8a020bce1\",\n    \"0xae87e5c1b9e86c49a23dceda4ecfd1dcf08567f1db8e5b6ec752ebd45433c11e7da4988573cdaebbb6f4135814fc059e\",\n    \"0xabee05cf9abdbc52897ac1ce9ed157f5466ed6c383d6497de28616238d60409e5e92619e528af8b62cc552bf09970dc2\",\n    \"0xae6d31cd7bf9599e5ee0828bab00ceb4856d829bba967278a73706b5f388465367aa8a6c7da24b5e5f1fdd3256ef8e63\",\n    \"0xac33e7b1ee47e1ee4af472e37ab9e9175260e506a4e5ce449788075da1b53c44cb035f3792d1eea2aa24b1f688cc6ed3\",\n    \"0x80f65b205666b0e089bb62152251c48c380a831e5f277f11f3ef4f0d52533f0851c1b612267042802f019ec900dc0e8f\",\n    \"0x858520ad7aa1c9fed738e3b583c84168f2927837ad0e1d326afe9935c26e9b473d7f8c382e82ef1fe37d2b39bb40a1ee\",\n    \"0xb842dd4af8befe00a97c2d0f0c33c93974761e2cb9e5ab8331b25170318ddd5e4bdbc02d8f90cbfdd5f348f4f371c1f7\",\n    \"0x8bf2cb79bc783cb57088aae7363320cbeaabd078ffdec9d41bc74ff49e0043d0dad0086a30e5112b689fd2f5a606365d\",\n    \"0x982eb03bbe563e8850847cd37e6a3306d298ab08c4d63ab6334e6b8c1fa13fce80cf2693b09714c7621d74261a0ff306\",\n    \"0xb143edb113dec9f1e5105d4a93fbe502b859e587640d3db2f628c09a17060e6aec9e900e2c8c411cda99bc301ff96625\",\n    \"0xaf472d9befa750dcebc5428fe1a024f18ec1c07bca0f95643ce6b5f4189892a910285afb03fd7ed7068fbe614e80d33c\",\n    \"0xa97e3bc57ede73ecd1bbf02de8f51b4e7c1a067da68a3cd719f4ba26a0156cbf1cef2169fd35a18c5a4cced50d475998\",\n    \"0xa862253c937cf3d75d7183e5f5be6a4385d526aeda5171c1c60a8381fea79f88f5f52a4fab244ecc70765d5765e6dfd5\",\n    \"0x90cb776f8e5a108f1719df4a355bebb04bf023349356382cae55991b31720f0fd03206b895fa10c56c98f52453be8778\",\n    \"0xa7614e8d0769dccd520ea4b46f7646e12489951efaef5176bc889e9eb65f6e31758df136b5bf1e9107e68472fa9b46ec\",\n    \"0xac3a9b80a3254c42e5ed3a090a0dd7aee2352f480de96ad187027a3bb6c791eddfc3074b6ffd74eea825188f107cda4d\",\n    \"0x82a01d0168238ef04180d4b6e0a0e39024c02c2d75b065017c2928039e154d093e1af4503f4d1f3d8a948917abb5d09f\",\n    \"0x8fab000a2b0eef851a483aec8d2dd85fe60504794411a2f73ed82e116960547ac58766cb73df71aea71079302630258d\",\n    \"0x872451a35c6db61c63e9b8bb9f16b217f985c20be4451c14282c814adb29d7fb13f201367c664435c7f1d4d9375d7a58\",\n    \"0x887d9ff54cc96b35d562df4a537ff972d7c4b3fd91ab06354969a4cfede0b9fc68bbffb61d0dbf1a58948dc701e54f5a\",\n    \"0x8cb5c2a6bd956875d88f41ae24574434f1308514d44057b55c9c70f13a3366ed054150eed0955a38fda3f757be73d55f\",\n    \"0x89ad0163cad93e24129d63f8e38422b7674632a8d0a9016ee8636184cab177659a676c4ee7efba3abe1a68807c656d60\",\n    \"0xb9ec01c7cab6d00359b5a0b4a1573467d09476e05ca51a9227cd16b589a9943d161eef62dcc73f0de2ec504d81f4d252\",\n    \"0x8031d17635d39dfe9705c485d2c94830b6fc9bc67b91300d9d2591b51e36a782e77ab5904662effa9382d9cca201f525\",\n    \"0x8be5a5f6bc8d680e5092d6f9a6585acbaaaa2ddc671da560dcf5cfa4472f4f184b9597b5b539438accd40dda885687cc\",\n    \"0xb1fc0f052fae038a2e3de3b3a96b0a1024b009de8457b8b3adb2d315ae68a89af905720108a30038e5ab8d0d97087785\",\n    \"0x8b8bdc77bd3a6bc7ca5492b6f8c614852c39a70d6c8a74916eaca0aeb4533b11898b8820a4c2620a97bf35e275480029\",\n    \"0xaf35f4dc538d4ad5cdf710caa38fd1eb496c3fa890a047b6a659619c5ad3054158371d1e88e0894428282eed9f47f76b\",\n    \"0x8166454a7089cc07758ad78724654f4e7a1a13e305bbf88ddb86f1a4b2904c4fc8ab872d7da364cdd6a6c0365239e2ad\",\n    \"0xab287c7d3addce74ce40491871c768abe01daaa0833481276ff2e56926b38a7c6d2681ffe837d2cc323045ad1a4414f9\",\n    \"0xb90317f4505793094d89365beb35537f55a6b5618904236258dd04ca61f21476837624a2f45fef8168acf732cab65579\",\n    \"0x98ae5ea27448e236b6657ab5ef7b1cccb5372f92ab25f5fa651fbac97d08353a1dae1b280b1cd42b17d2c6a70a63ab9d\",\n    \"0xadcf54e752d32cbaa6cb98fbca48d8cd087b1db1d131d465705a0d8042c8393c8f4d26b59006eb50129b21e6240f0c06\",\n    \"0xb591a3e4db18a7345fa935a8dd7994bbac5cc270b8ebd84c8304c44484c7a74afb45471fdbe4ab22156a30fae1149b40\",\n    \"0x806b53ac049a42f1dcc1d6335505371da0bf27c614f441b03bbf2e356be7b2fb4eed7117eabcce9e427a542eaa2bf7d8\",\n    \"0x800482e7a772d49210b81c4a907f5ce97f270b959e745621ee293cf8c71e8989363d61f66a98f2d16914439544ca84c7\",\n    \"0x99de9eafdad3617445312341644f2bb888680ff01ce95ca9276b1d2e5ef83fa02dab5e948ebf66c17df0752f1bd37b70\",\n    \"0x961ee30810aa4c93ae157fbe9009b8e443c082192bd36a73a6764ff9b2ad8b0948fe9a73344556e01399dd77badb4257\",\n    \"0xae0a361067c52efbe56c8adf982c00432cd478929459fc7f74052c8ee9531cd031fe1335418fde53f7c2ef34254eb7ac\",\n    \"0xa3503d16b6b27eb20c1b177bcf90d13706169220523a6271b85b2ce35a9a2b9c5bed088540031c0a4ebfdae3a4c6ab04\",\n    \"0x909420122c3e723289ca4e7b81c2df5aff312972a2203f4c45821b176e7c862bf9cac7f7df3adf1d59278f02694d06e7\",\n    \"0x989f42380ae904b982f85d0c6186c1aef5d6bcba29bcfbb658e811b587eb2749c65c6e4a8cc6409c229a107499a4f5d7\",\n    \"0x8037a6337195c8e26a27ea4ef218c6e7d79a9720aaab43932d343192abc2320fe72955f5e431c109093bda074103330a\",\n    \"0xb312e168663842099b88445e940249cc508f080ab0c94331f672e7760258dbd86be5267e4cf25ea25facb80bff82a7e9\",\n    \"0xaaa3ff8639496864fcdbfdda1ac97edc4f08e3c9288b768f6c8073038c9fbbf7e1c4bea169b4d45c31935cdf0680d45e\",\n    \"0x97dbd3df37f0b481a311dfc5f40e59227720f367912200d71908ef6650f32cc985cb05b981e3eea38958f7e48d10a15d\",\n    \"0xa89d49d1e267bb452d6cb621b9a90826fe55e9b489c0427b94442d02a16f390eed758e209991687f73f6b5a032321f42\",\n    \"0x9530dea4e0e19d6496f536f2e75cf7d814d65fde567055eb20db48fd8d20d501cd2a22fb506db566b94c9ee10f413d43\",\n    \"0x81a7009b9e67f1965fa7da6a57591c307de91bf0cd35ab4348dc4a98a4961e096d004d7e7ad318000011dc4342c1b809\",\n    \"0x83440a9402b766045d7aca61a58bba2aa29cac1cf718199e472ba086f5d48093d9dda4d135292ba51d049a23964eceae\",\n    \"0xa06c9ce5e802df14f6b064a3d1a0735d429b452f0e2e276042800b0a4f16df988fd94cf3945921d5dd3802ab2636f867\",\n    \"0xb1359e358b89936dee9e678a187aad3e9ab14ac40e96a0a68f70ee2583cdcf467ae03bef4215e92893f4e12f902adec8\",\n    \"0x835304f8619188b4d14674d803103d5a3fa594d48e96d9699e653115dd05fdc2dda6ba3641cf7ad53994d448da155f02\",\n    \"0x8327cba5a9ff0d3f5cd0ae55e77167448926d5fcf76550c0ad978092a14122723090c51c415e88e42a2b62eb07cc3981\",\n    \"0xb373dcdaea85f85ce9978b1426a7ef4945f65f2d3467a9f1cc551a99766aac95df4a09e2251d3f89ca8c9d1a7cfd7b0e\",\n    \"0xab1422dc41af2a227b973a6fd124dfcb2367e2a11a21faa1d381d404f51b7257e5bc82e9cf20cd7fe37d7ae761a2ab37\",\n    \"0xa93774a03519d2f20fdf2ef46547b0a5b77c137d6a3434b48d56a2cbef9e77120d1b85d0092cf8842909213826699477\",\n    \"0x8eb967a495a38130ea28711580b7e61bcd1d051cd9e4f2dbf62f1380bd86e0d60e978d72f6f31e909eb97b3b9a2b867c\",\n    \"0xae8213378da1287ba1fe4242e1acaec19b877b6fe872400013c6eac1084b8d03156792fa3020201725b08228a1e80f49\",\n    \"0xb143daf6893d674d607772b3b02d8ac48f294237e2f2c87963c0d4e26d9227d94a2a13512457c3d5883544bbc259f0ef\",\n    \"0xb343bd2aca8973888e42542218924e2dda2e938fd1150d06878af76f777546213912b7c7a34a0f94186817d80ffa185c\",\n    \"0xb188ebc6a8c3007001aa347ae72cc0b15d09bc6c19a80e386ee4b334734ec0cc2fe8b493c2422f38d1e6d133cc3db6fe\",\n    \"0xb795f6a8b9b826aaeee18ccd6baf6c5adeeec85f95eb5b6d19450085ec7217e95a2d9e221d77f583b297d0872073ba0e\",\n    \"0xb1c7dbd998ad32ae57bfa95deafa147024afd57389e98992c36b6e52df915d3d5a39db585141ec2423173e85d212fed8\",\n    \"0x812bcdeb9fe5f12d0e1df9964798056e1f1c3de3b17b6bd2919b6356c4b86d8e763c01933efbe0224c86a96d5198a4be\",\n    \"0xb19ebeda61c23d255cbf472ef0b8a441f4c55b70f0d8ed47078c248b1d3c7c62e076b43b95c00a958ec8b16d5a7cb0d7\",\n    \"0xb02adc9aaa20e0368a989c2af14ff48b67233d28ebee44ff3418bb0473592e6b681af1cc45450bd4b175df9051df63d9\",\n    \"0x8d87f0714acee522eb58cec00360e762adc411901dba46adc9227124fa70ee679f9a47e91a6306d6030dd4eb8de2f3c1\",\n    \"0x8be54cec21e74bcc71de29dc621444263737db15f16d0bb13670f64e42f818154e04b484593d19ef95f2ee17e4b3fe21\",\n    \"0xab8e20546c1db38d31493b5d5f535758afb17e459645c1b70813b1cf7d242fd5d1f4354a7c929e8f7259f6a25302e351\",\n    \"0x89f035a1ed8a1e302ac893349ba8ddf967580fcb6e73d44af09e3929cde445e97ff60c87dafe489e2c0ab9c9986cfa00\",\n    \"0x8b2b0851a795c19191a692af55f7e72ad2474efdc5401bc3733cfdd910e34c918aaebe69d5ea951bdddf3c01cabbfc67\",\n    \"0xa4edb52c2b51495ccd1ee6450fc14b7b3ede8b3d106808929d02fb31475bacb403e112ba9c818d2857651e508b3a7dd1\",\n    \"0x9569341fded45d19f00bcf3cbf3f20eb2b4d82ef92aba3c8abd95866398438a2387437e580d8b646f17cf6fde8c5af23\",\n    \"0xaa4b671c6d20f72f2f18a939a6ff21cc37e0084b44b4a717f1be859a80b39fb1be026b3205adec2a66a608ec2bcd578f\",\n    \"0x94902e980de23c4de394ad8aec91b46f888d18f045753541492bfbb92c59d3daa8de37ae755a6853744af8472ba7b72b\",\n    \"0xaf651ef1b2a0d30a7884557edfad95b6b5d445a7561caebdc46a485aedd25932c62c0798465c340a76f6feaa196dd712\",\n    \"0xb7b669b8e5a763452128846dd46b530dca4893ace5cc5881c7ddcd3d45969d7e73fbebdb0e78aa81686e5f7b22ec5759\",\n    \"0x82507fd4ebe9fa656a7f2e084d64a1fa6777a2b0bc106d686e2d9d2edafc58997e58cb6bfd0453b2bf415704aa82ae62\",\n    \"0xb40bce2b42b88678400ecd52955bbdadd15f8b9e1b3751a1a3375dc0efb5ca3ee258cf201e1140b3c09ad41217d1d49e\",\n    \"0xb0210d0cbb3fbf3b8cdb39e862f036b0ff941cd838e7aaf3a8354e24246e64778d22f3de34572e6b2a580614fb6425be\",\n    \"0x876693cba4301b251523c7d034108831df3ce133d8be5a514e7a2ca494c268ca0556fa2ad8310a1d92a16b55bcd99ea9\",\n    \"0x8660281406d22a4950f5ef050bf71dd3090edb16eff27fa29ef600cdea628315e2054211ed2cc6eaf8f2a1771ef689fd\",\n    \"0xa610e7e41e41ab66955b809ba4ade0330b8e9057d8efc9144753caed81995edeb1a42a53f93ce93540feca1fae708dac\",\n    \"0xa49e2c176a350251daef1218efaccc07a1e06203386ede59c136699d25ca5cb2ac1b800c25b28dd05678f14e78e51891\",\n    \"0x83e0915aa2b09359604566080d411874af8c993beba97d4547782fdbe1a68e59324b800ff1f07b8db30c71adcbd102a8\",\n    \"0xa19e84e3541fb6498e9bb8a099c495cbfcad113330e0262a7e4c6544495bb8a754b2208d0c2d895c93463558013a5a32\",\n    \"0x87f2bd49859a364912023aca7b19a592c60214b8d6239e2be887ae80b69ebdeb59742bdebcfa73a586ab23b2c945586c\",\n    \"0xb8e8fdddae934a14b57bc274b8dcd0d45ebb95ddbaabef4454e0f6ce7d3a5a61c86181929546b3d60c447a15134d08e1\",\n    \"0x87e0c31dcb736ea4604727e92dc1d9a3cf00adcff79df3546e02108355260f3dd171531c3c0f57be78d8b28058fcc8c0\",\n    \"0x9617d74e8f808a4165a8ac2e30878c349e1c3d40972006f0787b31ea62d248c2d9f3fc3da83181c6e57e95feedfd0e8c\",\n    \"0x8949e2cee582a2f8db86e89785a6e46bc1565c2d8627d5b6bf43ba71ffadfab7e3c5710f88dcb5fb2fc6edf6f4fae216\",\n    \"0xad3fa7b0edceb83118972a2935a09f409d09a8db3869f30be3a76f67aa9fb379cabb3a3aff805ba023a331cad7d7eb64\",\n    \"0x8c95718a4112512c4efbd496be38bf3ca6cdcaad8a0d128f32a3f9aae57f3a57bdf295a3b372a8c549fda8f4707cffed\",\n    \"0x88f3261d1e28a58b2dee3fcc799777ad1c0eb68b3560f9b4410d134672d9533532a91ea7be28a041784872632d3c9d80\",\n    \"0xb47472a41d72dd2e8b72f5c4f8ad626737dde3717f63d6bc776639ab299e564cbad0a2ad5452a07f02ff49a359c437e5\",\n    \"0x9896d21dc2e8aad87b76d6df1654f10cd7bceed4884159d50a818bea391f8e473e01e14684814c7780235f28e69dca6e\",\n    \"0x82d47c332bbd31bbe83b5eb44a23da76d4a7a06c45d7f80f395035822bc27f62f59281d5174e6f8e77cc9b5c3193d6f0\",\n    \"0x95c74cd46206e7f70c9766117c34c0ec45c2b0f927a15ea167901a160e1530d8522943c29b61e03568aa0f9c55926c53\",\n    \"0xa89d7757825ae73a6e81829ff788ea7b3d7409857b378ebccd7df73fdbe62c8d9073741cf038314971b39af6c29c9030\",\n    \"0x8c1cd212d0b010905d560688cfc036ae6535bc334fa8b812519d810b7e7dcf1bb7c5f43deaa40f097158358987324a7f\",\n    \"0xb86993c383c015ed8d847c6b795164114dd3e9efd25143f509da318bfba89389ea72a420699e339423afd68b6512fafb\",\n    \"0x8d06bd379c6d87c6ed841d8c6e9d2d0de21653a073725ff74be1934301cc3a79b81ef6dd0aad4e7a9dc6eac9b73019bc\",\n    \"0x81af4d2d87219985b9b1202d724fe39ef988f14fef07dfe3c3b11714e90ffba2a97250838e8535eb63f107abfe645e96\",\n    \"0x8c5e0af6330a8becb787e4b502f34f528ef5756e298a77dc0c7467433454347f3a2e0bd2641fbc2a45b95e231c6e1c02\",\n    \"0x8e2a8f0f04562820dc8e7da681d5cad9fe2e85dd11c785fb6fba6786c57a857e0b3bd838fb849b0376c34ce1665e4837\",\n    \"0xa39be8269449bfdfc61b1f62077033649f18dae9bef7c6163b9314ca8923691fb832f42776f0160b9e8abd4d143aa4e1\",\n    \"0x8c154e665706355e1cc98e0a4cabf294ab019545ba9c4c399d666e6ec5c869ca9e1faf8fb06cd9c0a5c2f51a7d51b70a\",\n    \"0xa046a7d4de879d3ebd4284f08f24398e9e3bf006cd4e25b5c67273ade248689c69affff92ae810c07941e4904296a563\",\n    \"0xafd94c1cb48758e5917804df03fb38a6da0e48cd9b6262413ea13b26973f9e266690a1b7d9d24bbaf7e82718e0e594b0\",\n    \"0x859e21080310c8d6a38e12e2ac9f90a156578cdeb4bb2e324700e97d9a5511cd6045dc39d1d0de3f94aeed043a24119d\",\n    \"0xa219fb0303c379d0ab50893264919f598e753aac9065e1f23ef2949abc992577ab43c636a1d2c089203ec9ddb941e27d\",\n    \"0xb0fdb639d449588a2ca730afcba59334e7c387342d56defdfb7ef79c493f7fd0e5277eff18e7203e756c7bdda5803047\",\n    \"0x87f9c3b7ed01f54368aca6dbcf2f6e06bff96e183c4b2c65f8baa23b377988863a0a125d5cdd41a072da8462ced4c070\",\n    \"0x99ef7a5d5ac2f1c567160e1f8c95f2f38d41881850f30c461a205f7b1b9fb181277311333839b13fb3ae203447e17727\",\n    \"0xaeaca9b1c2afd24e443326cc68de67b4d9cedb22ad7b501a799d30d39c85bb2ea910d4672673e39e154d699e12d9b3dc\",\n    \"0xa11675a1721a4ba24dd3d0e4c3c33a6edf4cd1b9f6b471070b4386c61f77452266eae6e3f566a40cfc885eada9a29f23\",\n    \"0xb228334445e37b9b49cb4f2cc56b454575e92173ddb01370a553bba665adadd52df353ad74470d512561c2c3473c7bb9\",\n    \"0xa18177087c996572d76f81178d18ed1ceebc8362a396348ce289f1d8bd708b9e99539be6fccd4acb1112381cfc5749b4\",\n    \"0x8e7b8bf460f0d3c99abb19803b9e43422e91507a1c0c22b29ee8b2c52d1a384da4b87c292e28eff040db5be7b1f8641f\",\n    \"0xb03d038d813e29688b6e6f444eb56fec3abba64c3d6f890a6bcf2e916507091cdb2b9d2c7484617be6b26552ed1c56cb\",\n    \"0xa1c88ccd30e934adfc5494b72655f8afe1865a84196abfb376968f22ddc07761210b6a9fb7638f1413d1b4073d430290\",\n    \"0x961b714faebf172ad2dbc11902461e286e4f24a99a939152a53406117767682a571057044decbeb3d3feef81f4488497\",\n    \"0xa03dc4059b46effdd786a0a03cc17cfee8585683faa35bb07936ded3fa3f3a097f518c0b8e2db92fd700149db1937789\",\n    \"0xadf60180c99ca574191cbcc23e8d025b2f931f98ca7dfcebfc380226239b6329347100fcb8b0fcb12db108c6ad101c07\",\n    \"0x805d4f5ef24d46911cbf942f62cb84b0346e5e712284f82b0db223db26d51aabf43204755eb19519b00e665c7719fcaa\",\n    \"0x8dea7243e9c139662a7fe3526c6c601eee72fd8847c54c8e1f2ad93ef7f9e1826b170afe58817dac212427164a88e87f\",\n    \"0xa2ba42356606d651b077983de1ad643650997bb2babb188c9a3b27245bb65d2036e46667c37d4ce02cb1be5ae8547abe\",\n    \"0xaf2ae50b392bdc013db2d12ce2544883472d72424fc767d3f5cb0ca2d973fc7d1f425880101e61970e1a988d0670c81b\",\n    \"0x98e6bec0568d3939b31d00eb1040e9b8b2a35db46ddf4369bdaee41bbb63cc84423d29ee510a170fb5b0e2df434ba589\",\n    \"0x822ff3cd12fbef4f508f3ca813c04a2e0b9b799c99848e5ad3563265979e753ee61a48f6adc2984a850f1b46c1a43d35\",\n    \"0x891e8b8b92a394f36653d55725ef514bd2e2a46840a0a2975c76c2a935577f85289026aaa74384da0afe26775cbddfb9\",\n    \"0xb2a3131a5d2fe7c8967047aa66e4524babae941d90552171cc109527f345f42aa0df06dcbb2fa01b33d0043917bbed69\",\n    \"0x80c869469900431f3eeefafdbe07b8afd8cee7739e659e6d0109b397cacff85a88247698f87dc4e2fe39a592f250ac64\",\n    \"0x9091594f488b38f9d2bb5df49fd8b4f8829d9c2f11a197dd1431ed5abbc5c954bbde3387088f9ee3a5a834beb7619bce\",\n    \"0xb472e241e6956146cca57b97a8a204668d050423b4e76f857bad5b47f43b203a04c8391ba9d9c3e95093c071f9d376a1\",\n    \"0xb7dd2de0284844392f7dfb56fe7ca3ede41e27519753ffc579a0a8d2d65ceb8108d06b6b0d4c3c1a2588951297bd1a1e\",\n    \"0x902116ce70d0a079ac190321c1f48701318c05f8e69ee09694754885d33a835a849cafe56f499a2f49f6cda413ddf9a7\",\n    \"0xb18105cc736787fafaf7c3c11c448bce9466e683159dff52723b7951dff429565e466e4841d982e3aaa9ee2066838666\",\n    \"0x97ab9911f3f659691762d568ae0b7faa1047b0aed1009c319fa79d15d0db8db9f808fc385dc9a68fa388c10224985379\",\n    \"0xb2a2cba65f5b927e64d2904ba412e2bac1cf18c9c3eda9c72fb70262497ecf505b640827e2afebecf10eebbcf48ccd3e\",\n    \"0xb36a3fd677baa0d3ef0dac4f1548ff50a1730286b8c99d276a0a45d576e17b39b3cbadd2fe55e003796d370d4be43ce3\",\n    \"0xa5dfec96ca3c272566e89dc453a458909247e3895d3e44831528130bc47cc9d0a0dac78dd3cad680a4351d399d241967\",\n    \"0x8029382113909af6340959c3e61db27392531d62d90f92370a432aec3eb1e4c36ae1d4ef2ba8ec6edb4d7320c7a453f6\",\n    \"0x971d85121ea108e6769d54f9c51299b0381ece8b51d46d49c89f65bedc123bab4d5a8bc14d6f67f4f680077529cbae4c\",\n    \"0x98ff6afc01d0bec80a278f25912e1b1ebff80117adae72e31d5b9fa4d9624db4ba2065b444df49b489b0607c45e26c4c\",\n    \"0x8fa29be10fb3ab30ce25920fec0187e6e91e458947009dabb869aade7136c8ba23602682b71e390c251f3743164cbdaa\",\n    \"0xb3345c89eb1653418fe3940cf3e56a9a9c66526389b98f45ca02dd62bfb37baa69a4baaa7132d7320695f8ea6ad1fd94\",\n    \"0xb72c7f5541c9ac6b60a7ec9f5415e7fb14da03f7164ea529952a29399f3a071576608dbbcc0d45994f21f92ddbeb1e19\",\n    \"0xaa3450bb155a5f9043d0ef95f546a2e6ade167280bfb75c9f09c6f9cdb1fffb7ce8181436161a538433afa3681c7a141\",\n    \"0x92a18fecaded7854b349f441e7102b638ababa75b1b0281dd0bded6541abe7aa37d96693595be0b01fe0a2e2133d50f9\",\n    \"0x980756ddf9d2253cfe6c94960b516c94889d09e612810935150892627d2ecee9a2517e04968eea295d0106850c04ca44\",\n    \"0xae68c6ccc454318cdd92f32b11d89116a3b8350207a36d22a0f626718cad671d960090e054c0c77ac3162ae180ecfd4b\",\n    \"0x99f31f66eaaa551749ad91d48a0d4e3ff4d82ef0e8b28f3184c54e852422ba1bdafd53b1e753f3a070f3b55f3c23b6a2\",\n    \"0xa44eaeaa6589206069e9c0a45ff9fc51c68da38d4edff1d15529b7932e6f403d12b9387019c44a1488a5d5f27782a51f\",\n    \"0xb80b5d54d4b344840e45b79e621bd77a3f83fb4ce6d8796b7d6915107b3f3c34d2e7d95bdafd120f285669e5acf2437a\",\n    \"0xb36c069ec085a612b5908314d6b84c00a83031780261d1c77a0384c406867c9847d5b0845deddfa512cc04a8df2046fb\",\n    \"0xb09dbe501583220f640d201acea7ee3e39bf9eda8b91aa07b5c50b7641d86d71acb619b38d27835ce97c3759787f08e9\",\n    \"0x87403d46a2bf63170fff0b857acacf42ee801afe9ccba8e5b4aea967b68eac73a499a65ca46906c2eb4c8f27bc739faa\",\n    \"0x82b93669f42a0a2aa5e250ffe6097269da06a9c02fcd1801abbad415a7729a64f830754bafc702e64600ba47671c2208\",\n    \"0x8e3a3029be7edb8dd3ab1f8216664c8dc50d395f603736061d802cef77627db7b859ef287ed850382c13b4d22d6a2d80\",\n    \"0x968e9ec7194ff424409d182ce0259acd950c384c163c04463bc8700a40b79beba6146d22b7fa7016875a249b7b31c602\",\n    \"0x8b42c984bbe4996e0c20862059167c6bdc5164b1ffcd928f29512664459212d263e89f0f0e30eed4e672ffa5ed0b01b5\",\n    \"0x96bac54062110dada905363211133f1f15dc7e4fd80a4c6e4a83bc9a0bcbbaba11cd2c7a13debcf0985e1a954c1da66b\",\n    \"0xa16dc8a653d67a7cd7ae90b2fffac0bf1ca587005430fe5ba9403edd70ca33e38ba5661d2ed6e9d2864400d997626a62\",\n    \"0xa68ab11a570a27853c8d67e491591dcba746bfbee08a2e75ae0790399130d027ed387f41ef1d7de8df38b472df309161\",\n    \"0x92532b74886874447c0300d07eda9bbe4b41ed25349a3da2e072a93fe32c89d280f740d8ff70d5816793d7f2b97373cc\",\n    \"0x88e35711b471e89218fd5f4d0eadea8a29405af1cd81974427bc4a5fb26ed60798daaf94f726c96e779b403a2cd82820\",\n    \"0xb5c72aa4147c19f8c4f3a0a62d32315b0f4606e0a7025edc5445571eaf4daff64f4b7a585464821574dd50dbe1b49d08\",\n    \"0x9305d9b4095258e79744338683fd93f9e657367b3ab32d78080e51d54eec331edbc224fad5093ebf8ee4bd4286757eb8\",\n    \"0xb2a17abb3f6a05bcb14dc7b98321fa8b46d299626c73d7c6eb12140bf4c3f8e1795250870947af817834f033c88a59d6\",\n    \"0xb3477004837dbd8ba594e4296f960fc91ab3f13551458445e6c232eb04b326da803c4d93e2e8dcd268b4413305ff84da\",\n    \"0x924b4b2ebaafdcfdfedb2829a8bf46cd32e1407d8d725a5bd28bdc821f1bafb3614f030ea4352c671076a63494275a3f\",\n    \"0x8b81b9ef6125c82a9bece6fdcb9888a767ac16e70527753428cc87c56a1236e437da8be4f7ecfe57b9296dc3ae7ba807\",\n    \"0x906e19ec8b8edd58bdf9ae05610a86e4ea2282b1bbc1e8b00b7021d093194e0837d74cf27ac9916bdb8ec308b00da3da\",\n    \"0xb41c5185869071760ac786078a57a2ab4e2af60a890037ac0c0c28d6826f15c2cf028fddd42a9b6de632c3d550bfbc14\",\n    \"0xa646e5dec1b713ae9dfdf7bdc6cd474d5731a320403c7dfcfd666ffc9ae0cff4b5a79530e8df3f4aa9cb80568cb138e9\",\n    \"0xb0efad22827e562bd3c3e925acbd0d9425d19057868608d78c2209a531cccd0f2c43dc5673acf9822247428ffa2bb821\",\n    \"0xa94c19468d14b6f99002fc52ac06bbe59e5c472e4a0cdb225144a62f8870b3f10593749df7a2de0bd3c9476ce682e148\",\n    \"0x803864a91162f0273d49271dafaab632d93d494d1af935aefa522768af058fce52165018512e8d6774976d52bd797e22\",\n    \"0xa08711c2f7d45c68fb340ac23597332e1bcaec9198f72967b9921204b9d48a7843561ff318f87908c05a44fc35e3cc9d\",\n    \"0x91c3cad94a11a3197ae4f9461faab91a669e0dddb0371d3cab3ed9aeb1267badc797d8375181130e461eadd05099b2a2\",\n    \"0x81bdaaf48aae4f7b480fc13f1e7f4dd3023a41439ba231760409ce9292c11128ab2b0bdbbf28b98af4f97b3551f363af\",\n    \"0x8d60f9df9fd303f625af90e8272c4ecb95bb94e6efc5da17b8ab663ee3b3f673e9f6420d890ccc94acf4d2cae7a860d8\",\n    \"0xa7b75901520c06e9495ab983f70b61483504c7ff2a0980c51115d11e0744683ce022d76e3e09f4e99e698cbd21432a0d\",\n    \"0x82956072df0586562fda7e7738226f694e1c73518dd86e0799d2e820d7f79233667192c9236dcb27637e4c65ef19d493\",\n    \"0xa586beb9b6ffd06ad200957490803a7cd8c9bf76e782734e0f55e04a3dc38949de75dc607822ec405736c576cf83bca3\",\n    \"0xa179a30d00def9b34a7e85607a447eea0401e32ab5abeee1a281f2acd1cf6ec81a178020666f641d9492b1bdf66f05a3\",\n    \"0x83e129705c538787ed8e0fdc1275e6466a3f4ee21a1e6abedd239393b1df72244723b92f9d9d9339a0cab6ebf28f5a16\",\n    \"0x811bd8d1e3722b64cd2f5b431167e7f91456e8bba2cc669d3fbbce7d553e29c3c19f629fcedd2498bc26d33a24891d17\",\n    \"0xa243c030c858f1f60cccd26b45b024698cc6d9d9e6198c1ed4964a235d9f8d0baf9cde10c8e63dfaa47f8e74e51a6e85\",\n    \"0xab839eb82e23ca52663281f863b55b0a3d6d4425c33ffb4eeb1d7979488ab068bf99e2a60e82cea4dc42c56c26cbfebe\",\n    \"0x8b896f9bb21d49343e67aec6ad175b58c0c81a3ca73d44d113ae4354a0065d98eb1a5cafedaf232a2bb9cdc62152f309\",\n    \"0xaf6230340cc0b66f5bf845540ed4fc3e7d6077f361d60762e488d57834c3e7eb7eacc1b0ed73a7d134f174a01410e50c\",\n    \"0x88975e1b1af678d1b5179f72300a30900736af580dd748fd9461ef7afccc91ccd9bed33f9da55c8711a7635b800e831f\",\n    \"0xa97486bb9047391661718a54b8dd5a5e363964e495eae6c692730264478c927cf3e66dd3602413189a3699fbeae26e15\",\n    \"0xa5973c161ab38732885d1d2785fd74bf156ba34881980cba27fe239caef06b24a533ffe6dbbbeca5e6566682cc00300a\",\n    \"0xa24776e9a840afda0003fa73b415d5bd6ecd9b5c2cc842b643ee51b8c6087f4eead4d0bfbd987eb174c489a7b952ff2a\",\n    \"0xa8a6ee06e3af053b705a12b59777267c546f33ba8a0f49493af8e6df4e15cf8dd2d4fb4daf7e84c6b5d3a7363118ff03\",\n    \"0xa28e59ce6ad02c2ce725067c0123117e12ac5a52c8f5af13eec75f4a9efc4f696777db18a374fa33bcae82e0734ebd16\",\n    \"0x86dfc3b78e841c708aff677baa8ee654c808e5d257158715097c1025d46ece94993efe12c9d188252ad98a1e0e331fec\",\n    \"0xa88d0275510f242eab11fdb0410ff6e1b9d7a3cbd3658333539815f1b450a84816e6613d15aa8a8eb15d87cdad4b27a2\",\n    \"0x8440acea2931118a5b481268ff9f180ee4ede85d14a52c026adc882410825b8275caa44aff0b50c2b88d39f21b1a0696\",\n    \"0xa7c3182eab25bd6785bacf12079d0afb0a9b165d6ed327814e2177148539f249eb9b5b2554538f54f3c882d37c0a8abe\",\n    \"0x85291fbe10538d7da38efdd55a7acebf03b1848428a2f664c3ce55367aece60039f4f320b1771c9c89a35941797f717c\",\n    \"0xa2c6414eeb1234728ab0de94aa98fc06433a58efa646ca3fcbd97dbfb8d98ae59f7ce6d528f669c8149e1e13266f69c9\",\n    \"0x840c8462785591ee93aee2538d9f1ec44ba2ca61a569ab51d335ac873f5d48099ae8d7a7efa0725d9ff8f9475bfa4f56\",\n    \"0xa7065a9d02fb3673acf7702a488fbc01aa69580964932f6f40b6c2d1c386b19e50b0e104fcac24ea26c4e723611d0238\",\n    \"0xb72db6d141267438279e032c95e6106c2ccb3164b842ba857a2018f3a35f4b040da92680881eb17cd61d0920d5b8f006\",\n    \"0xa8005d6c5960e090374747307ef0be2871a7a43fa4e76a16c35d2baab808e9777b496e9f57a4218b23390887c33a0b55\",\n    \"0x8e152cea1e00a451ca47c20a1e8875873419700af15a5f38ee2268d3fbc974d4bd5f4be38008fa6f404dbdedd6e6e710\",\n    \"0xa3391aed1fcd68761f06a7d1008ec62a09b1cb3d0203cd04e300a0c91adfed1812d8bc1e4a3fd7976dc0aae0e99f52f1\",\n    \"0x967eb57bf2aa503ee0c6e67438098149eac305089c155f1762cf5e84e31f0fbf27c34a9af05621e34645c1ec96afaec8\",\n    \"0x88af97ddc4937a95ec0dcd25e4173127260f91c8db2f6eac84afb789b363705fb3196235af631c70cafd09411d233589\",\n    \"0xa32df75b3f2c921b8767638fd289bcfc61e08597170186637a7128ffedd52c798c434485ac2c7de07014f9e895c2c3d8\",\n    \"0xb0a783832153650aa0d766a3a73ec208b6ce5caeb40b87177ffc035ab03c7705ecdd1090b6456a29f5fb7e90e2fa8930\",\n    \"0xb59c8e803b4c3486777d15fc2311b97f9ded1602fa570c7b0200bada36a49ee9ef4d4c1474265af8e1c38a93eb66b18b\",\n    \"0x982f2c85f83e852022998ff91bafbb6ff093ef22cf9d5063e083a48b29175ccbd51b9c6557151409e439096300981a6c\",\n    \"0x939e3b5989fefebb9d272a954659a4eb125b98c9da6953f5e628d26266bd0525ec38304b8d56f08d65abc4d6da4a8dbb\",\n    \"0x8898212fe05bc8de7d18503cb84a1c1337cc2c09d1eeef2b475aa79185b7322bf1f8e065f1bf871c0c927dd19faf1f6d\",\n    \"0x94b0393a41cd00f724aee2d4bc72103d626a5aecb4b5486dd1ef8ac27528398edf56df9db5c3d238d8579af368afeb09\",\n    \"0x96ac564450d998e7445dd2ea8e3fc7974d575508fa19e1c60c308d83b645864c029f2f6b7396d4ff4c1b24e92e3bac37\",\n    \"0x8adf6638e18aff3eb3b47617da696eb6c4bdfbecbbc3c45d3d0ab0b12cbad00e462fdfbe0c35780d21aa973fc150285e\",\n    \"0xb53f94612f818571b5565bbb295e74bada9b5f9794b3b91125915e44d6ddcc4da25510eab718e251a09c99534d6042d9\",\n    \"0x8b96462508d77ee083c376cd90807aebad8de96bca43983c84a4a6f196d5faf6619a2351f43bfeec101864c3bf255519\",\n    \"0xaeadf34657083fc71df33bd44af73bf5281c9ca6d906b9c745536e1819ea90b56107c55e2178ebad08f3ba75b3f81c86\",\n    \"0x9784ba29b2f0057b5af1d3ab2796d439b8753f1f749c73e791037461bdfc3f7097394283105b8ab01788ea5255a96710\",\n    \"0x8756241bda159d4a33bf74faba0d4594d963c370fb6a18431f279b4a865b070b0547a6d1613cf45b8cfb5f9236bbf831\",\n    \"0xb03ebfd6b71421dfd49a30460f9f57063eebfe31b9ceaa2a05c37c61522b35bdc09d7db3ad75c76c253c00ba282d3cd2\",\n    \"0xb34e7e6341fa9d854b2d3153bdda0c4ae2b2f442ab7af6f99a0975d45725aa48e36ae5f7011edd249862e91f499687d4\",\n    \"0xb462ee09dc3963a14354244313e3444de5cc37ea5ccfbf14cd9aca8027b59c4cb2a949bc30474497cab8123e768460e6\",\n    \"0xaea753290e51e2f6a21a9a0ee67d3a2713f95c2a5c17fe41116c87d3aa77b1683761264d704df1ac34f8b873bc88ef7b\",\n    \"0x98430592afd414394f98ddfff9f280fcb1c322dbe3510f45e1e9c4bb8ee306b3e0cf0282c0ee73ebb8ba087d4d9e0858\",\n    \"0xb95d3b5aaf54ffca11f4be8d57f76e14afdb20afc859dc7c7471e0b42031e8f3d461b726ecb979bdb2f353498dfe95ea\",\n    \"0x984d17f9b11a683132e0b5a9ee5945e3ff7054c2d5c716be73b29078db1d36f54c6e652fd2f52a19da313112e97ade07\",\n    \"0xab232f756b3fff3262be418a1af61a7e0c95ceebbc775389622a8e10610508cd6784ab7960441917a83cc191c58829ea\",\n    \"0xa28f41678d6e60de76b0e36ab10e4516e53e02e9c77d2b5af3cfeee3ce94cfa30c5797bd1daab20c98e1cad83ad0f633\",\n    \"0xb55395fca84dd3ccc05dd480cb9b430bf8631ff06e24cb51d54519703d667268c2f8afcde4ba4ed16bece8cc7bc8c6e0\",\n    \"0x8a8a5392a0e2ea3c7a8c51328fab11156004e84a9c63483b64e8f8ebf18a58b6ffa8fe8b9d95af0a2f655f601d096396\",\n    \"0xab480000fe194d23f08a7a9ec1c392334e9c687e06851f083845121ce502c06b54dda8c43092bcc1035df45cc752fe9b\",\n    \"0xb265644c29f628d1c7e8e25a5e845cabb21799371814730a41a363e1bda8a7be50fee7c3996a365b7fcba4642add10db\",\n    \"0xb8a915a3c685c2d4728f6931c4d29487cad764c5ce23c25e64b1a3259ac27235e41b23bfe7ae982921b4cb84463097df\",\n    \"0x8efa7338442a4b6318145a5440fc213b97869647eeae41b9aa3c0a27ee51285b73e3ae3b4a9423df255e6add58864aa9\",\n    \"0x9106d65444f74d217f4187dfc8fcf3810b916d1e4275f94f6a86d1c4f3565b131fd6cde1fa708bc05fe183c49f14941a\",\n    \"0x948252dac8026bbbdb0a06b3c9d66ec4cf9532163bab68076fda1bd2357b69e4b514729c15aaa83b5618b1977bbc60c4\",\n    \"0xae6596ccfdf5cbbc5782efe3bb0b101bb132dbe1d568854ca24cacc0b2e0e9fabcb2ca7ab42aecec412efd15cf8cb7a2\",\n    \"0x84a0b6c198ff64fd7958dfd1b40eac9638e8e0b2c4cd8cf5d8cdf80419baee76a05184bce6c5b635f6bf2d30055476a7\",\n    \"0x8893118be4a055c2b3da593dbca51b1ae2ea2469911acfb27ee42faf3e6c3ad0693d3914c508c0b05b36a88c8b312b76\",\n    \"0xb097479e967504deb6734785db7e60d1d8034d6ca5ba9552887e937f5e17bb413fccac2c1d1082154ed76609127860ad\",\n    \"0xa0294e6b9958f244d29943debf24b00b538b3da1116269b6e452bb12dc742226712fd1a15b9c88195afeb5d2415f505c\",\n    \"0xb3cc15f635080bc038f61b615f62b5b5c6f2870586191f59476e8368a73641d6ac2f7d0c1f54621982defdb318020230\",\n    \"0x99856f49b9fe1604d917c94d09cc0ed753d13d015d30587a94e6631ffd964b214e607deb8a69a8b5e349a7edf4309206\",\n    \"0xa8571e113ea22b4b4fce41a094da8c70de37830ae32e62c65c2fa5ad06a9bc29e884b945e73d448c72b176d6ecebfb58\",\n    \"0xa9e9c6e52beb0013273c29844956b3ce291023678107cdc785f7b44eff5003462841ad8780761b86aefc6b734adde7cf\",\n    \"0x80a784b0b27edb51ef2bad3aee80e51778dcaa0f3f5d3dcb5dc5d4f4b2cf7ae35b08de6680ea9dac53f8438b92eb09ef\",\n    \"0x827b543e609ea328e97e373f70ad72d4915a2d1daae0c60d44ac637231070e164c43a2a58db80a64df1c624a042b38f9\",\n    \"0xb449c65e8195202efdcb9bdb4e869a437313b118fef8b510cbbf8b79a4e99376adb749b37e9c20b51b31ed3310169e27\",\n    \"0x8ea3028f4548a79a94c717e1ed28ad4d8725b8d6ab18b021063ce46f665c79da3c49440c6577319dab2d036b7e08f387\",\n    \"0x897798431cfb17fe39f08f5f854005dc37b1c1ec1edba6c24bc8acb3b88838d0534a75475325a5ea98b326ad47dbad75\",\n    \"0x89cf232e6303b0751561960fd4dea5754a28c594daf930326b4541274ffb03c7dd75938e411eb9a375006a70ce38097f\",\n    \"0x9727c6ae7f0840f0b6c8bfb3a1a5582ceee705e0b5c59b97def7a7a2283edd4d3f47b7971e902a3a2079e40b53ff69b8\",\n    \"0xb76ed72b122c48679d221072efc0eeea063cb205cbf5f9ef0101fd10cb1075b8628166c83577cced654e1c001c7882f7\",\n    \"0xae908c42d208759da5ee9b405df85a6532ea35c6f0f6a1288d22870f59d98edc896841b8ac890a538e6c8d1e8b02d359\",\n    \"0x809d12fe4039a0ec80dc9be6a89acaab7797e5f7f9b163378f52f9a75a1d73b2e9ae6e3dd49e32ced439783c1cabbef5\",\n    \"0xa4149530b7f85d1098ba534d69548c6c612c416e8d35992fc1f64f4deeb41e09e49c6cf7aadbed7e846b91299358fe2d\",\n    \"0xa49342eacd1ec1148b8df1e253b1c015f603c39de11fa0a364ccb86ea32d69c34fd7aa6980a1fadcd8e785a57fa46f60\",\n    \"0x87d43eff5a006dc4dddcf76cc96c656a1f3a68f19f124181feab86c6cc9a52cb9189cdbb423414defdd9bb0ca8ff1ddc\",\n    \"0x861367e87a9aa2f0f68296ba50aa5dbc5713008d260cc2c7e62d407c2063064749324c4e8156dc21b749656cfebce26b\",\n    \"0xb5303c2f72e84e170e66ae1b0fbd51b8c7a6f27476eaf5694b64e8737d5c84b51fe90100b256465a4c4156dd873cddb0\",\n    \"0xb62849a4f891415d74f434cdc1d23c4a69074487659ca96e1762466b2b7a5d8525b056b891d0feea6fe6845cba8bc7fb\",\n    \"0x923dd9e0d6590a9307e8c4c23f13bae3306b580e297a937711a8b13e8de85e41a61462f25b7d352b682e8437bf2b4ab3\",\n    \"0x9147379860cd713cd46c94b8cdf75125d36c37517fbecf81ace9680b98ce6291cd1c3e472f84249cc3b2b445e314b1b6\",\n    \"0xa808a4f17ac21e3fb5cfef404e61fae3693ca3e688d375f99b6116779696059a146c27b06de3ac36da349b0649befd56\",\n    \"0x87787e9322e1b75e66c1f0d9ea0915722a232770930c2d2a95e9478c4b950d15ab767e30cea128f9ed65893bfc2d0743\",\n    \"0x9036a6ee2577223be105defe1081c48ea7319e112fff9110eb9f61110c319da25a6cea0464ce65e858635b079691ef1f\",\n    \"0xaf5548c7c24e1088c23b57ee14d26c12a83484c9fd9296edf1012d8dcf88243f20039b43c8c548c265ef9a1ffe9c1c88\",\n    \"0xa0fff520045e14065965fb8accd17e878d3fcaf9e0af2962c8954e50be6683d31fa0bf4816ab68f08630dbac6bfce52a\",\n    \"0xb4c1b249e079f6ae1781af1d97a60b15855f49864c50496c09c91fe1946266915b799f0406084d7783f5b1039116dd8b\",\n    \"0x8b0ffa5e7c498cb3879dddca34743b41eee8e2dea3d4317a6e961b58adb699ef0c92400c068d5228881a2b08121226bf\",\n    \"0x852ae8b19a1d80aa8ae5382e7ee5c8e7670ceb16640871c56b20b96b66b3b60e00015a3dde039446972e57b49a999ddd\",\n    \"0xa49942f04234a7d8492169da232cfff8051df86e8e1ba3db46aede02422c689c87dc1d99699c25f96cb763f5ca0983e5\",\n    \"0xb04b597b7760cf5dcf411ef896d1661e6d5b0db3257ac2cf64b20b60c6cc18fa10523bb958a48d010b55bac7b02ab3b1\",\n    \"0xa494591b51ea8285daecc194b5e5bd45ae35767d0246ac94fae204d674ee180c8e97ff15f71f28b7aeb175b8aea59710\",\n    \"0x97d2624919e78406e7460730680dea8e71c8571cf988e11441aeea54512b95bd820e78562c99372d535d96f7e200d20d\",\n    \"0xac693ddb00e48f76e667243b9b6a7008424043fb779e4f2252330285232c3fccac4da25cbd6d95fe9ad959ff305a91f6\",\n    \"0x8d20ca0a71a64a3f702a0825bb46bd810d03bebfb227683680d474a52f965716ff99e19a165ebaf6567987f4f9ee3c94\",\n    \"0xa5c516a438f916d1d68ca76996404792e0a66e97b7f18fc54c917bf10cf3211b62387932756e39e67e47b0bd6e88385a\",\n    \"0xb089614d830abc0afa435034cec7f851f2f095d479cacf1a3fb57272da826c499a52e7dcbc0eb85f4166fb94778e18e9\",\n    \"0xa8dacc943765d930848288192f4c69e2461c4b9bc6e79e30eeef9a543318cf9ae9569d6986c65c5668a89d49993f8e07\",\n    \"0xab5a9361fa339eec8c621bdad0a58078983abd8942d4282b22835d7a3a47e132d42414b7c359694986f7db39386c2e19\",\n    \"0x94230517fb57bd8eb26c6f64129b8b2abd0282323bf7b94b8bac7fab27b4ecc2c4290c294275e1a759de19f2216134f3\",\n    \"0xb8f158ea5006bc3b90b285246625faaa6ac9b5f5030dc69701b12f3b79a53ec7e92eeb5a63bbd1f9509a0a3469ff3ffc\",\n    \"0x8b6944fd8cb8540957a91a142fdcda827762aa777a31e8810ca6d026e50370ee1636fc351724767e817ca38804ebe005\",\n    \"0x82d1ee40fe1569c29644f79fa6c4033b7ed45cd2c3b343881f6eb0de2e79548fded4787fae19bed6ee76ed76ff9f2f11\",\n    \"0xa8924c7035e99eaed244ca165607e7e568b6c8085510dcdbaf6ebdbed405af2e6c14ee27d94ffef10d30aa52a60bf66d\",\n    \"0x956f82a6c2ae044635e85812581e4866c5fa2f427b01942047d81f6d79a14192f66fbbe77c9ffeaef4e6147097fdd2b5\",\n    \"0xb1100255a1bcf5e05b6aff1dfeb6e1d55b5d68d43a7457ba10cc76b61885f67f4d0d5179abda786e037ae95deb8eea45\",\n    \"0x99510799025e3e5e8fbf06dedb14c060c6548ba2bda824f687d3999dc395e794b1fb6514b9013f3892b6cf65cb0d65aa\",\n    \"0x8f9091cebf5e9c809aab415942172258f894e66e625d7388a05289183f01b8d994d52e05a8e69f784fba41db9ea357f0\",\n    \"0xa13d2eeb0776bdee9820ecb6693536720232848c51936bb4ef4fe65588d3f920d08a21907e1fdb881c1ad70b3725e726\",\n    \"0xa68b8f18922d550284c5e5dc2dda771f24c21965a6a4d5e7a71678178f46df4d8a421497aad8fcb4c7e241aba26378a0\",\n    \"0x8b7601f0a3c6ad27f03f2d23e785c81c1460d60100f91ea9d1cab978aa03b523150206c6d52ce7c7769c71d2c8228e9e\",\n    \"0xa8e02926430813caa851bb2b46de7f0420f0a64eb5f6b805401c11c9091d3b6d67d841b5674fa2b1dce0867714124cd8\",\n    \"0xb7968ecba568b8193b3058400af02c183f0a6df995a744450b3f7e0af7a772454677c3857f99c140bbdb2a09e832e8e0\",\n    \"0x8f20b1e9ba87d0a3f35309b985f3c18d2e8800f1ca7f0c52cadef773f1496b6070c936eea48c4a1cae83fd2524e9d233\",\n    \"0x88aef260042db0d641a51f40639dbeeefa9e9811df30bee695f3791f88a2f84d318f04e8926b7f47bf25956cb9e3754f\",\n    \"0x9725345893b647e9ba4e6a29e12f96751f1ae25fcaec2173e9a259921a1a7edb7a47159b3c8767e44d9e2689f5aa0f72\",\n    \"0x8c281e6f72752cb11e239e4df9341c45106eb7993c160e54423c2bffe10bc39d42624b45a1f673936ef2e1a02fc92f1a\",\n    \"0x90aba2f68bddb2fcce6c51430dacdfeec43ea8dc379660c99095df11017691ccf5faa27665cf4b9f0eea7728ae53c327\",\n    \"0xb7022695c16521c5704f49b7ddbdbec9b5f57ce0ceebe537bc0ebb0906d8196cc855a9afeb8950a1710f6a654464d93f\",\n    \"0x8fe1b9dd3c6a258116415d36e08374e094b22f0afb104385a5da48be17123e86fb8327baacc4f0d9ebae923d55d99bb5\",\n    \"0x817e85d8e3d19a4cbc1dec31597142c2daa4871bda89c2177fa719c00eda3344eb08b82eb92d4aa91a9eaacb3fc09783\",\n    \"0xb59053e1081d2603f1ca0ba553804d6fa696e1fd996631db8f62087b26a40dfef02098b0326bb75f99ec83b9267ca738\",\n    \"0x990a173d857d3ba81ff3789b931bfc9f5609cde0169b7f055fa3cb56451748d593d62d46ba33f80f9cafffe02b68dd14\",\n    \"0xb0c538dbba4954b809ab26f9f94a3cf1dcb77ce289eaec1d19f556c0ae4be1fa03af4a9b7057837541c3cc0a80538736\",\n    \"0xac3ba42f5f44f9e1fc453ce49c4ab79d0e1d5c42d3b30b1e098f3ab3f414c4c262fa12fb2be249f52d4aaf3c5224beb9\",\n    \"0xaf47467eb152e59870e21f0d4da2f43e093daf40180ab01438030684b114d025326928eaab12c41b81a066d94fce8436\",\n    \"0x98d1b58ba22e7289b1c45c79a24624f19b1d89e00f778eef327ec4856a9a897278e6f1a9a7e673844b31dde949153000\",\n    \"0x97ccb15dfadc7c59dca08cfe0d22df2e52c684cf97de1d94bc00d7ba24e020025130b0a39c0f4d46e4fc872771ee7875\",\n    \"0xb699e4ed9a000ff96ca296b2f09dce278832bc8ac96851ff3cff99ed3f6f752cfc0fea8571be28cd9b5a7ec36f1a08ee\",\n    \"0xb9f49f0edb7941cc296435ff0a912e3ad16848ee8765ab5f60a050b280d6ea585e5b34051b15f6b8934ef01ceb85f648\",\n    \"0xac3893df7b4ceab23c6b9054e48e8ba40d6e5beda8fbe90b814f992f52494186969b35d8c4cdc3c99890a222c9c09008\",\n    \"0xa41293ad22fae81dea94467bc1488c3707f3d4765059173980be93995fa4fcc3c9340796e3eed0beeb0ba0d9bb4fa3aa\",\n    \"0xa0543e77acd2aeecde13d18d258aeb2c7397b77f17c35a1992e8666ea7abcd8a38ec6c2741bd929abba2f766138618cc\",\n    \"0x92e79b22bc40e69f6527c969500ca543899105837b6b1075fa1796755c723462059b3d1b028e0b3df2559fa440e09175\",\n    \"0xa1fa1eac8f41a5197a6fb4aa1eae1a031c89f9c13ff9448338b222780cf9022e0b0925d930c37501a0ef7b2b00fdaf83\",\n    \"0xb3cb29ff73229f0637335f28a08ad8c5f166066f27c6c175164d0f26766a927f843b987ee9b309ed71cbf0a65d483831\",\n    \"0x84d4ab787f0ac00f104f4a734dc693d62d48c2aeb03913153da62c2ae2c27d11b1110dcef8980368dd84682ea2c1a308\",\n    \"0xab6a8e4bbc78d4a7b291ad3e9a8fe2d65f640524ba3181123b09d2d18a9e300e2509ccf7000fe47e75b65f3e992a2e7e\",\n    \"0xb7805ebe4f1a4df414003dc10bca805f2ab86ca75820012653e8f9b79c405196b0e2cab099f2ab953d67f0d60d31a0f9\",\n    \"0xb12c582454148338ea605d22bd00a754109063e22617f1f8ac8ddf5502c22a181c50c216c3617b9852aa5f26af56b323\",\n    \"0x86333ad9f898947e31ce747728dc8c887479e18d36ff3013f69ebef807d82c6981543b5c3788af93c4d912ba084d3cba\",\n    \"0xb514efa310dc4ad1258add138891e540d8c87142a881b5f46563cc58ecd1488e6d3a2fca54c0b72a929f3364ca8c333e\",\n    \"0xaa0a30f92843cf2f484066a783a1d75a7aa6f41f00b421d4baf20a6ac7886c468d0eea7ca8b17dd22f4f74631b62b640\",\n    \"0xb3b7dc63baec9a752e8433c0cdee4d0f9bc41f66f2b8d132faf925eef9cf89aae756fc132c45910f057122462605dc10\",\n    \"0xb9b8190dac5bfdeb59fd44f4da41a57e7f1e7d2c21faba9da91fa45cbeca06dcf299c9ae22f0c89ece11ac46352d619f\",\n    \"0x89f8cf36501ad8bdfeab863752a9090e3bfda57cf8fdeca2944864dc05925f501e252c048221bcc57136ab09a64b64b2\",\n    \"0xb0cbfaf317f05f97be47fc9d69eda2dd82500e00d42612f271a1fe24626408c28881f171e855bd5bd67409f9847502b4\",\n    \"0xa7c21a8fcede581bfd9847b6835eda62ba250bea81f1bb17372c800a19c732abe03064e64a2f865d974fb636cab4b859\",\n    \"0x95f9df524ba7a4667351696c4176b505d8ea3659f5ff2701173064acc624af69a0fad4970963736383b979830cb32260\",\n    \"0x856a74fe8b37a2e3afeac858c8632200485d438422a16ae3b29f359e470e8244995c63ad79c7e007ed063f178d0306fd\",\n    \"0xb37faa4d78fdc0bb9d403674dbea0176c2014a171c7be8527b54f7d1a32a76883d3422a3e7a5f5fcc5e9b31b57822eeb\",\n    \"0x8d37234d8594ec3fe75670b5c9cc1ec3537564d4739b2682a75b18b08401869a4264c0f264354219d8d896cded715db4\",\n    \"0xb5289ee5737f0e0bde485d32096d23387d68dab8f01f47821ab4f06cc79a967afe7355e72dc0c751d96b2747b26f6255\",\n    \"0x9085e1fdf9f813e9c3b8232d3c8863cd84ab30d45e8e0d3d6a0abd9ebc6fd70cdf749ff4d04390000e14c7d8c6655fc7\",\n    \"0x93a388c83630331eca4da37ea4a97b3b453238af474817cc0a0727fd3138dcb4a22de38c04783ec829c22cb459cb4e8e\",\n    \"0xa5377116027c5d061dbe24c240b891c08cdd8cd3f0899e848d682c873aff5b8132c1e7cfe76d2e5ed97ee0eb1d42cb68\",\n    \"0xa274c84b04338ed28d74683e2a7519c2591a3ce37c294d6f6e678f7d628be2db8eff253ede21823e2df7183e6552f622\",\n    \"0x8bc201147a842453a50bec3ac97671397bc086d6dfc9377fa38c2124cdc286abda69b7324f47d64da094ae011d98d9d9\",\n    \"0x9842d0c066c524592b76fbec5132bc628e5e1d21c424bec4555efca8619cc1fd8ea3161febcb8b9e8ab54702f4e815e2\",\n    \"0xa19191b713a07efe85c266f839d14e25660ee74452e6c691cd9997d85ae4f732052d802d3deb018bdd847caa298a894b\",\n    \"0xa24f71fc0db504da4e287dd118a4a74301cbcd16033937ba2abc8417956fcb4ae19b8e63b931795544a978137eff51cb\",\n    \"0xa90eec4a6a3a4b8f9a5b93d978b5026fcf812fe65585b008d7e08c4aaf21195a1d0699f12fc16f79b6a18a369af45771\",\n    \"0x8b551cf89737d7d06d9b3b9c4c1c73b41f2ea0af4540999c70b82dabff8580797cf0a3caf34c86c59a7069eb2e38f087\",\n    \"0xb8d312e6c635e7a216a1cda075ae77ba3e1d2fd501dc31e83496e6e81ed5d9c7799f8e578869c2e0e256fb29f5de10a7\",\n    \"0x8d144bdb8cae0b2cdb5b33d44bbc96984a5925202506a8cc65eb67ac904b466f5a7fe3e1cbf04aa785bbb7348c4bb73c\",\n    \"0xa101b3d58b7a98659244b88de0b478b3fb87dc5fc6031f6e689b99edf498abd43e151fd32bd4bbd240e0b3e59c440359\",\n    \"0x907453abca7d8e7151a05cc3d506c988007692fe7401395dc93177d0d07d114ab6cca0cc658eb94c0223fe8658295cad\",\n    \"0x825329ffbe2147ddb68f63a0a67f32d7f309657b8e5d9ab5bb34b3730bfa2c77a23eaaadb05def7d9f94a9e08fdc1e96\",\n    \"0x88ee923c95c1dac99ae7ed6067906d734d793c5dc5d26339c1bb3314abe201c5dccb33b9007351885eb2754e9a8ea06c\",\n    \"0x98bc9798543f5f1adc9f2cfcfa72331989420e9c3f6598c45269f0dc9b7c8607bbeaf03faa0aea2ddde2b8f17fdceff5\",\n    \"0x8ee87877702a79aef923ab970db6fa81561b3c07d5bf1a072af0a7bad765b4cbaec910afe1a91703feacc7822fa38a94\",\n    \"0x8060b9584aa294fe8adc2b22f67e988bc6da768eae91e429dcc43ddc53cfcc5d6753fdc1b420b268c7eb2fb50736a970\",\n    \"0xb344a5524d80a2f051870c7001f74fcf348a70fcf78dbd20c6ff9ca85d81567d2318c8b8089f2c4f195d6aec9fc15fa6\",\n    \"0x8f5a5d893e1936ed062149d20eb73d98b62b7f50ab5d93a6429c03656b36688d1c80cb5010e4977491e51fa0d7dd35d5\",\n    \"0x86fa32ebbf97328c5f5f15564e1238297e289ec3219b9a741724e9f3ae8d5c15277008f555863a478b247ba5dc601d44\",\n    \"0x9557e55377e279f4b6b5e0ffe01eca037cc13aac242d67dfcd0374a1e775c5ed5cb30c25fe21143fee54e3302d34a3ea\",\n    \"0x8cb6bcbc39372d23464a416ea7039f57ba8413cf3f00d9a7a5b356ab20dcb8ed11b3561f7bce372b8534d2870c7ee270\",\n    \"0xb5d59075cb5abde5391f64b6c3b8b50adc6e1f654e2a580b6d6d6eff3f4fbdd8fffc92e06809c393f5c8eab37f774c4b\",\n    \"0xafcfb6903ef13e493a1f7308675582f15af0403b6553e8c37afb8b2808ad21b88b347dc139464367dc260df075fea1ad\",\n    \"0x810fbbe808375735dd22d5bc7fc3828dc49fdd22cc2d7661604e7ac9c4535c1df578780affb3b895a0831640a945bcad\",\n    \"0x8056b0c678803b416f924e09a6299a33cf9ad7da6fe1ad7accefe95c179e0077da36815fde3716711c394e2c5ea7127f\",\n    \"0x8b67403702d06979be19f1d6dc3ec73cc2e81254d6b7d0cc49cd4fdda8cd51ab0835c1d2d26fc0ecab5df90585c2f351\",\n    \"0x87f97f9e6d4be07e8db250e5dd2bffdf1390665bc5709f2b631a6fa69a7fca958f19bd7cc617183da1f50ee63e9352b5\",\n    \"0xae151310985940471e6803fcf37600d7fa98830613e381e00dab943aec32c14162d51c4598e8847148148000d6e5af5c\",\n    \"0x81eb537b35b7602c45441cfc61b27fa9a30d3998fad35a064e05bc9479e9f10b62eba2b234b348219eea3cadcaac64bb\",\n    \"0x8a441434934180ab6f5bc541f86ebd06eadbee01f438836d797e930fa803a51510e005c9248cecc231a775b74d12b5e9\",\n    \"0x81f3c250a27ba14d8496a5092b145629eb2c2e6a5298438670375363f57e2798207832c8027c3e9238ad94ecdadfc4df\",\n    \"0xa6217c311f2f3db02ceaa5b6096849fe92b6f4b6f1491535ef8525f6ccee6130bed2809e625073ecbaddd4a3eb3df186\",\n    \"0x82d1c396f0388b942cf22b119d7ef1ad03d3dad49a74d9d01649ee284f377c8daddd095d596871669e16160299a210db\",\n    \"0xa40ddf7043c5d72a7246bd727b07f7fff1549f0e443d611de6f9976c37448b21664c5089c57f20105102d935ab82f27b\",\n    \"0xb6c03c1c97adf0c4bf4447ec71366c6c1bff401ba46236cd4a33d39291e7a1f0bb34bd078ba3a18d15c98993b153a279\",\n    \"0x8a94f5f632068399c359c4b3a3653cb6df2b207379b3d0cdace51afdf70d6d5cce6b89a2b0fee66744eba86c98fb21c2\",\n    \"0xb2f19e78ee85073f680c3bba1f07fd31b057c00b97040357d97855b54a0b5accb0d3b05b2a294568fcd6a4be6f266950\",\n    \"0xa74632d13bbe2d64b51d7a9c3ae0a5a971c19f51cf7596a807cea053e6a0f3719700976d4e394b356c0329a2dced9aa2\",\n    \"0xafef616d341a9bc94393b8dfba68ff0581436aa3a3adb7c26a1bbf2cf19fa877066191681f71f17f3cd6f9cf6bf70b5a\",\n    \"0x8ce96d93ae217408acf7eb0f9cbb9563363e5c7002e19bbe1e80760bc9d449daee2118f3878b955163ed664516b97294\",\n    \"0x8414f79b496176bc8b8e25f8e4cfee28f4f1c2ddab099d63d2aca1b6403d26a571152fc3edb97794767a7c4686ad557c\",\n    \"0xb6c61d01fd8ce087ef9f079bf25bf10090db483dd4f88c4a786d31c1bdf52065651c1f5523f20c21e75cea17df69ab73\",\n    \"0xa5790fd629be70545093631efadddc136661f63b65ec682609c38ef7d3d7fa4e56bdf94f06e263bc055b90cb1c6bcefe\",\n    \"0xb515a767e95704fb7597bca9e46f1753abacdc0e56e867ee3c6f4cd382643c2a28e65312c05ad040eaa3a8cbe7217a65\",\n    \"0x8135806a02ead6aa92e9adb6fefb91349837ab73105aaa7be488ef966aa8dfaafdfa64bbae30fcbfa55dd135a036a863\",\n    \"0x8f22435702716d76b1369750694540742d909d5e72b54d0878245fab7c269953b1c6f2b29c66f08d5e0263ca3a731771\",\n    \"0x8e0f8a8e8753e077dac95848212aeffd51c23d9b6d611df8b102f654089401954413ecbedc6367561ca599512ae5dda7\",\n    \"0x815a9084e3e2345f24c5fa559deec21ee1352fb60f4025c0779be65057f2d528a3d91593bd30d3a185f5ec53a9950676\",\n    \"0x967e6555ccba395b2cc1605f8484c5112c7b263f41ce8439a99fd1c71c5ed14ad02684d6f636364199ca48afbbde13be\",\n    \"0x8cd0ccf17682950b34c796a41e2ea7dd5367aba5e80a907e01f4cdc611e4a411918215e5aebf4292f8b24765d73314a6\",\n    \"0xa58bf1bbb377e4b3915df6f058a0f53b8fb8130fdec8c391f6bc82065694d0be59bb67ffb540e6c42cc8b380c6e36359\",\n    \"0x92af3151d9e6bfb3383d85433e953c0160859f759b0988431ec5893542ba40288f65db43c78a904325ef8d324988f09d\",\n    \"0x8011bbb05705167afb47d4425065630f54cb86cd462095e83b81dfebf348f846e4d8fbcf1c13208f5de1931f81da40b9\",\n    \"0x81c743c104fc3cb047885c9fa0fb9705c3a83ee24f690f539f4985509c3dafd507af3f6a2128276f45d5939ef70c167f\",\n    \"0xa2c9679b151c041aaf5efeac5a737a8f70d1631d931609fca16be1905682f35e291292874cb3b03f14994f98573c6f44\",\n    \"0xa4949b86c4e5b1d5c82a337e5ce6b2718b1f7c215148c8bfb7e7c44ec86c5c9476048fc5c01f57cb0920876478c41ad6\",\n    \"0x86c2495088bd1772152e527a1da0ef473f924ea9ab0e5b8077df859c28078f73c4e22e3a906b507fdf217c3c80808b5c\",\n    \"0x892e0a910dcf162bcea379763c3e2349349e4cda9402949255ac4a78dd5a47e0bf42f5bd0913951576b1d206dc1e536a\",\n    \"0xa7009b2c6b396138afe4754b7cc10dee557c51c7f1a357a11486b3253818531f781ea8107360c8d4c3b1cd96282353c0\",\n    \"0x911763ef439c086065cc7b4e57484ed6d693ea44acee4b18c9fd998116da55fbe7dcb8d2a0f0f9b32132fca82d73dff6\",\n    \"0xa722000b95a4a2d40bed81870793f15ba2af633f9892df507f2842e52452e02b5ea8dea6a043c2b2611d82376e33742a\",\n    \"0x9387ac49477bd719c2f92240d0bdfcf9767aad247ca93dc51e56106463206bc343a8ec855eb803471629a66fffb565d6\",\n    \"0x92819a1fa48ab4902939bb72a0a4e6143c058ea42b42f9bc6cea5df45f49724e2530daf3fc4f097cceefa2a8b9db0076\",\n    \"0x98eac7b04537653bc0f4941aae732e4b1f84bd276c992c64a219b8715eb1fb829b5cbd997d57feb15c7694c468f95f70\",\n    \"0xb275e7ba848ce21bf7996e12dbeb8dadb5d0e4f1cb5a0248a4f8f9c9fe6c74e3c93f4b61edbcb0a51af5a141e1c14bc7\",\n    \"0x97243189285aba4d49c53770c242f2faf5fd3914451da4931472e3290164f7663c726cf86020f8f181e568c72fd172d1\",\n    \"0x839b0b3c25dd412bee3dc24653b873cc65454f8f16186bb707bcd58259c0b6765fa4c195403209179192a4455c95f3b8\",\n    \"0x8689d1a870514568a074a38232e2ceb4d7df30fabeb76cff0aed5b42bf7f02baea12c5fadf69f4713464dbd52aafa55f\",\n    \"0x8958ae7b290f0b00d17c3e9fdb4dbf168432b457c7676829299dd428984aba892de1966fc106cfc58a772862ecce3976\",\n    \"0xa422bc6bd68b8870cfa5bc4ce71781fd7f4368b564d7f1e0917f6013c8bbb5b240a257f89ecfdbecb40fe0f3aa31d310\",\n    \"0xaa61f78130cebe09bc9a2c0a37f0dd57ed2d702962e37d38b1df7f17dc554b1d4b7a39a44182a452ce4c5eb31fa4cfcc\",\n    \"0xb7918bd114f37869bf1a459023386825821bfadce545201929d13ac3256d92a431e34f690a55d944f77d0b652cefeffc\",\n    \"0x819bba35fb6ace1510920d4dcff30aa682a3c9af9022e287751a6a6649b00c5402f14b6309f0aeef8fce312a0402915e\",\n    \"0x8b7c9ad446c6f63c11e1c24e24014bd570862b65d53684e107ba9ad381e81a2eaa96731b4b33536efd55e0f055071274\",\n    \"0x8fe79b53f06d33386c0ec7d6d521183c13199498594a46d44a8a716932c3ec480c60be398650bbfa044fa791c4e99b65\",\n    \"0x9558e10fb81250b9844c99648cf38fa05ec1e65d0ccbb18aa17f2d1f503144baf59d802c25be8cc0879fff82ed5034ad\",\n    \"0xb538a7b97fbd702ba84645ca0a63725be1e2891c784b1d599e54e3480e4670d0025526674ef5cf2f87dddf2290ba09f0\",\n    \"0x92eafe2e869a3dd8519bbbceb630585c6eb21712b2f31e1b63067c0acb5f9bdbbcbdb612db4ea7f9cc4e7be83d31973f\",\n    \"0xb40d21390bb813ab7b70a010dff64c57178418c62685761784e37d327ba3cb9ef62df87ecb84277c325a637fe3709732\",\n    \"0xb349e6fbf778c4af35fbed33130bd8a7216ed3ba0a79163ebb556e8eb8e1a7dad3456ddd700dad9d08d202491c51b939\",\n    \"0xa8fdaedecb251f892b66c669e34137f2650509ade5d38fbe8a05d9b9184bb3b2d416186a3640429bd1f3e4b903c159dd\",\n    \"0xac6167ebfee1dbab338eff7642f5e785fc21ef0b4ddd6660333fe398068cbd6c42585f62e81e4edbb72161ce852a1a4f\",\n    \"0x874b1fbf2ebe140c683bd7e4e0ab017afa5d4ad38055aaa83ee6bbef77dbc88a6ce8eb0dcc48f0155244af6f86f34c2d\",\n    \"0x903c58e57ddd9c446afab8256a6bb6c911121e6ccfb4f9b4ed3e2ed922a0e500a5cb7fa379d5285bc16e11dac90d1fda\",\n    \"0x8dae7a0cffa2fd166859cd1bf10ff82dd1932e488af377366b7efc0d5dec85f85fe5e8150ff86a79a39cefc29631733a\",\n    \"0xaa047857a47cc4dfc08585f28640420fcf105b881fd59a6cf7890a36516af0644d143b73f3515ab48faaa621168f8c31\",\n    \"0x864508f7077c266cc0cb3f7f001cb6e27125ebfe79ab57a123a8195f2e27d3799ff98413e8483c533b46a816a3557f1f\",\n    \"0x8bcd45ab1f9cbab36937a27e724af819838f66dfeb15923f8113654ff877bd8667c54f6307aaf0c35027ca11b6229bfd\",\n    \"0xb21aa34da9ab0a48fcfdd291df224697ce0c1ebc0e9b022fdee8750a1a4b5ba421c419541ed5c98b461eecf363047471\",\n    \"0xa9a18a2ab2fae14542dc336269fe612e9c1af6cf0c9ac933679a2f2cb77d3c304114f4d219ca66fe288adde30716775b\",\n    \"0xb5205989b92c58bdda71817f9a897e84100b5c4e708de1fced5c286f7a6f01ae96b1c8d845f3a320d77c8e2703c0e8b1\",\n    \"0xa364059412bbcc17b8907d43ac8e5df90bc87fd1724b5f99832d0d24559fae6fa76a74cff1d1eac8cbac6ec80b44af20\",\n    \"0xae709f2c339886b31450834cf29a38b26eb3b0779bd77c9ac269a8a925d1d78ea3837876c654b61a8fe834b3b6940808\",\n    \"0x8802581bba66e1952ac4dab36af371f66778958f4612901d95e5cac17f59165e6064371d02de8fb6fccf89c6dc8bd118\",\n    \"0xa313252df653e29c672cbcfd2d4f775089cb77be1077381cf4dc9533790e88af6cedc8a119158e7da5bf6806ad9b91a1\",\n    \"0x992a065b4152c7ef11515cd54ba9d191fda44032a01aed954acff3443377ee16680c7248d530b746b8c6dee2d634e68c\",\n    \"0xb627b683ee2b32c1ab4ccd27b9f6cce2fe097d96386fa0e5c182ad997c4c422ab8dfc03870cd830b8c774feb66537282\",\n    \"0xb823cf8a9aee03dadd013eb9efe40a201b4b57ef67efaae9f99683005f5d1bf55e950bf4af0774f50859d743642d3fea\",\n    \"0xb8a7449ffac0a3f206677097baf7ce00ca07a4d2bd9b5356fbcb83f3649b0fda07cfebad220c1066afba89e5a52abf4b\",\n    \"0xb2dd1a2f986395bb4e3e960fbbe823dbb154f823284ebc9068502c19a7609790ec0073d08bfa63f71e30c7161b6ef966\",\n    \"0x98e5236de4281245234f5d40a25b503505af140b503a035fc25a26159a9074ec81512b28f324c56ea2c9a5aa7ce90805\",\n    \"0x89070847dc8bbf5bc4ed073aa2e2a1f699cf0c2ca226f185a0671cecc54e7d3e14cd475c7752314a7a8e7476829da4bc\",\n    \"0xa9402dc9117fdb39c4734c0688254f23aed3dce94f5f53f5b7ef2b4bf1b71a67f85ab1a38ec224a59691f3bee050aeb3\",\n    \"0x957288f9866a4bf56a4204218ccc583f717d7ce45c01ea27142a7e245ad04a07f289cc044f8cf1f21d35e67e39299e9c\",\n    \"0xb2fb31ccb4e69113763d7247d0fc8edaae69b550c5c56aecacfd780c7217dc672f9fb7496edf4aba65dacf3361268e5b\",\n    \"0xb44a4526b2f1d6eb2aa8dba23bfa385ff7634572ab2afddd0546c3beb630fbfe85a32f42dd287a7fec069041411537f7\",\n    \"0x8db5a6660c3ac7fd7a093573940f068ee79a82bc17312af900b51c8c439336bc86ca646c6b7ab13aaaa008a24ca508ab\",\n    \"0x8f9899a6d7e8eb4367beb5c060a1f8e94d8a21099033ae582118477265155ba9e72176a67f7f25d7bad75a152b56e21a\",\n    \"0xa67de0e91ade8d69a0e00c9ff33ee2909b8a609357095fa12319e6158570c232e5b6f4647522efb7345ce0052aa9d489\",\n    \"0x82eb2414898e9c3023d57907a2b17de8e7eea5269029d05a94bfd7bf5685ac4a799110fbb375eb5e0e2bd16acf6458ae\",\n    \"0x94451fc7fea3c5a89ba701004a9693bab555cb622caf0896b678faba040409fdfd14a978979038b2a81e8f0abc4994d2\",\n    \"0xac879a5bb433998e289809a4a966bd02b4bf6a9c1cc276454e39c886efcf4fc68baebed575826bde577ab5aa71d735a9\",\n    \"0x880c0f8f49c875dfd62b4ddedde0f5c8b19f5687e693717f7e5c031bc580e58e13ab497d48b4874130a18743c59fdce3\",\n    \"0xb582af8d8ff0bf76f0a3934775e0b54c0e8fed893245d7d89cae65b03c8125b7237edc29dc45b4fe1a3fe6db45d280ee\",\n    \"0x89f337882ed3ae060aaee98efa20d79b6822bde9708c1c5fcee365d0ec9297f694cae37d38fd8e3d49717c1e86f078e7\",\n    \"0x826d2c1faea54061848b484e288a5f4de0d221258178cf87f72e14baaa4acc21322f8c9eab5dde612ef497f2d2e1d60b\",\n    \"0xa5333d4f227543e9cd741ccf3b81db79f2f03ca9e649e40d6a6e8ff9073e06da83683566d3b3c8d7b258c62970fb24d1\",\n    \"0xa28f08c473db06aaf4c043a2fae82b3c8cfaa160bce793a4c208e4e168fb1c65115ff8139dea06453c5963d95e922b94\",\n    \"0x8162546135cc5e124e9683bdfaa45833c18553ff06a0861c887dc84a5b12ae8cd4697f6794c7ef6230492c32faba7014\",\n    \"0xb23f0d05b74c08d6a7df1760792be83a761b36e3f8ae360f3c363fb196e2a9dd2de2e492e49d36561366e14daa77155c\",\n    \"0xb6f70d6c546722d3907c708d630dbe289771d2c8bf059c2e32b77f224696d750b4dda9b3a014debda38e7d02c9a77585\",\n    \"0x83bf4c4a9f3ca022c631017e7a30ea205ba97f7f5927cba8fc8489a4646eac6712cb821c5668c9ffe94d69d524374a27\",\n    \"0xb0371475425a8076d0dd5f733f55aabbe42d20a7c8ea7da352e736d4d35a327b2beb370dfcb05284e22cfd69c5f6c4cc\",\n    \"0xa0031ba7522c79211416c2cca3aa5450f96f8fee711552a30889910970ba13608646538781a2c08b834b140aadd7166f\",\n    \"0x99d273c80c7f2dc6045d4ed355d9fc6f74e93549d961f4a3b73cd38683f905934d359058cd1fc4da8083c7d75070487f\",\n    \"0xb0e4b0efa3237793e9dcce86d75aafe9879c5fa23f0d628649aef2130454dcf72578f9bf227b9d2b9e05617468e82588\",\n    \"0xa5ab076fa2e1c5c51f3ae101afdd596ad9d106bba7882b359c43d8548b64f528af19afa76cd6f40da1e6c5fca4def3fa\",\n    \"0x8ce2299e570331d60f6a6eff1b271097cd5f1c0e1113fc69b89c6a0f685dabea3e5bc2ac6bd789aa492ab189f89be494\",\n    \"0x91b829068874d911a310a5f9dee001021f97471307b5a3de9ec336870ec597413e1d92010ce320b619f38bed7c4f7910\",\n    \"0xb14fe91f4b07bf33b046e9285b66cb07927f3a8da0af548ac2569b4c4fb1309d3ced76d733051a20814e90dd5b75ffd1\",\n    \"0xabaab92ea6152d40f82940277c725aa768a631ee0b37f5961667f82fb990fc11e6d3a6a2752b0c6f94563ed9bb28265c\",\n    \"0xb7fe28543eca2a716859a76ab9092f135337e28109544f6bd2727728d0a7650428af5713171ea60bfc273d1c821d992c\",\n    \"0x8a4917b2ab749fc7343fc64bdf51b6c0698ff15d740cc7baf248c030475c097097d5a473bcc00d8c25817563fe0447b4\",\n    \"0xaa96156d1379553256350a0a3250166add75948fb9cde62aa555a0a9dc0a9cb7f2f7b8428aff66097bf6bfedaf14bbe2\",\n    \"0xae4ffeb9bdc76830d3eca2b705f30c1bdede6412fa064260a21562c8850c7fb611ec62bc68479fe48f692833e6f66d8d\",\n    \"0xb96543caaba9d051600a14997765d49e4ab10b07c7a92cccf0c90b309e6da334fdd6d18c96806cbb67a7801024fbd3c7\",\n    \"0x97b2b9ad76f19f500fcc94ca8e434176249f542ac66e5881a3dccd07354bdab6a2157018b19f8459437a68d8b86ba8e0\",\n    \"0xa8d206f6c5a14c80005849474fde44b1e7bcf0b2d52068f5f97504c3c035b09e65e56d1cf4b5322791ae2c2fdbd61859\",\n    \"0x936bad397ad577a70cf99bf9056584a61bd7f02d2d5a6cf219c05d770ae30a5cd902ba38366ce636067fc1dd10108d31\",\n    \"0xa77e30195ee402b84f3882e2286bf5380c0ed374a112dbd11e16cef6b6b61ab209d4635e6f35cdaaa72c1a1981d5dabe\",\n    \"0xa46ba4d3947188590a43c180757886a453a0503f79cc435322d92490446f37419c7b999fdf868a023601078070e03346\",\n    \"0x80d8d4c5542f223d48240b445d4d8cf6a75d120b060bc08c45e99a13028b809d910b534d2ac47fb7068930c54efd8da9\",\n    \"0x803be9c68c91b42b68e1f55e58917a477a9a6265e679ca44ee30d3eb92453f8c89c64eafc04c970d6831edd33d066902\",\n    \"0xb14b2b3d0dfe2bb57cee4cd72765b60ac33c1056580950be005790176543826c1d4fbd737f6cfeada6c735543244ab57\",\n    \"0xa9e480188bba1b8fb7105ff12215706665fd35bf1117bacfb6ab6985f4dbc181229873b82e5e18323c2b8f5de03258e0\",\n    \"0xa66a0f0779436a9a3999996d1e6d3000f22c2cac8e0b29cddef9636393c7f1457fb188a293b6c875b05d68d138a7cc4a\",\n    \"0x848397366300ab40c52d0dbbdafbafef6cd3dadf1503bb14b430f52bb9724188928ac26f6292a2412bc7d7aa620763c8\",\n    \"0x95466cc1a78c9f33a9aaa3829a4c8a690af074916b56f43ae46a67a12bb537a5ac6dbe61590344a25b44e8512355a4a7\",\n    \"0x8b5f7a959f818e3baf0887f140f4575cac093d0aece27e23b823cf421f34d6e4ff4bb8384426e33e8ec7b5eed51f6b5c\",\n    \"0x8d5e1368ec7e3c65640d216bcc5d076f3d9845924c734a34f3558ac0f16e40597c1a775a25bf38b187213fbdba17c93b\",\n    \"0xb4647c1b823516880f60d20c5cc38c7f80b363c19d191e8992226799718ee26b522a12ecb66556ed3d483aa4824f3326\",\n    \"0xac3abaea9cd283eb347efda4ed9086ea3acf495043e08d0d19945876329e8675224b685612a6badf8fd72fb6274902b1\",\n    \"0x8eae1ce292d317aaa71bcf6e77e654914edd5090e2e1ebab78b18bb41b9b1bc2e697439f54a44c0c8aa0d436ebe6e1a9\",\n    \"0x94dc7d1aec2c28eb43d93b111fa59aaa0d77d5a09501220bd411768c3e52208806abf973c6a452fd8292ff6490e0c9e2\",\n    \"0x8fd8967f8e506fef27d17b435d6b86b232ec71c1036351f12e6fb8a2e12daf01d0ee04451fb944d0f1bf7fd20e714d02\",\n    \"0x824e6865be55d43032f0fec65b3480ea89b0a2bf860872237a19a54bc186a85d2f8f9989cc837fbb325b7c72d9babe2c\",\n    \"0x8bd361f5adb27fd6f4e3f5de866e2befda6a8454efeb704aacc606f528c03f0faae888f60310e49440496abd84083ce2\",\n    \"0xb098a3c49f2aaa28b6b3e85bc40ce6a9cdd02134ee522ae73771e667ad7629c8d82c393fba9f27f5416986af4c261438\",\n    \"0xb385f5ca285ff2cfe64dcaa32dcde869c28996ed091542600a0b46f65f3f5a38428cca46029ede72b6cf43e12279e3d3\",\n    \"0x8196b03d011e5be5288196ef7d47137d6f9237a635ab913acdf9c595fa521d9e2df722090ec7eb0203544ee88178fc5f\",\n    \"0x8ed1270211ef928db18e502271b7edf24d0bbd11d97f2786aee772d70c2029e28095cf8f650b0328cc8a4c38d045316d\",\n    \"0xa52ab60e28d69b333d597a445884d44fd2a7e1923dd60f763951e1e45f83e27a4dac745f3b9eff75977b3280e132c15d\",\n    \"0x91e9fe78cdac578f4a4687f71b800b35da54b824b1886dafec073a3c977ce7a25038a2f3a5b1e35c2c8c9d1a7312417c\",\n    \"0xa42832173f9d9491c7bd93b21497fbfa4121687cd4d2ab572e80753d7edcbb42cfa49f460026fbde52f420786751a138\",\n    \"0x97b947126d84dcc70c97be3c04b3de3f239b1c4914342fa643b1a4bb8c4fe45c0fcb585700d13a7ed50784790c54bef9\",\n    \"0x860e407d353eac070e2418ef6cb80b96fc5f6661d6333e634f6f306779651588037be4c2419562c89c61f9aa2c4947f5\",\n    \"0xb2c9d93c3ba4e511b0560b55d3501bf28a510745fd666b3cb532db051e6a8617841ea2f071dda6c9f15619c7bfd2737f\",\n    \"0x8596f4d239aeeac78311207904d1bd863ef68e769629cc379db60e019aaf05a9d5cd31dc8e630b31e106a3a93e47cbc5\",\n    \"0x8b26e14e2e136b65c5e9e5c2022cee8c255834ea427552f780a6ca130a6446102f2a6f334c3f9a0308c53df09e3dba7e\",\n    \"0xb54724354eb515a3c8bed0d0677ff1db94ac0a07043459b4358cb90e3e1aa38ac23f2caa3072cf9647275d7cd61d0e80\",\n    \"0xb7ce9fe0e515e7a6b2d7ddcb92bc0196416ff04199326aea57996eef8c5b1548bd8569012210da317f7c0074691d01b7\",\n    \"0xa1a13549c82c877253ddefa36a29ea6a23695ee401fdd48e65f6f61e5ebd956d5e0edeff99484e9075cb35071fec41e2\",\n    \"0x838ba0c1e5bd1a6da05611ff1822b8622457ebd019cb065ece36a2d176bd2d889511328120b8a357e44569e7f640c1e6\",\n    \"0xb916eccff2a95519400bbf76b5f576cbe53cf200410370a19d77734dc04c05b585cfe382e8864e67142d548cd3c4c2f4\",\n    \"0xa610447cb7ca6eea53a6ff1f5fe562377dcb7f4aaa7300f755a4f5e8eba61e863c51dc2aa9a29b35525b550fbc32a0fe\",\n    \"0x9620e8f0f0ee9a4719aa9685eeb1049c5c77659ba6149ec4c158f999cfd09514794b23388879931fe26fea03fa471fd3\",\n    \"0xa9dcf8b679e276583cf5b9360702a185470d09aea463dc474ee9c8aee91ef089dacb073e334e47fbc78ec5417c90465c\",\n    \"0x8c9adee8410bdd99e5b285744cee61e2593b6300ff31a8a83b0ec28da59475a5c6fb9346fe43aadea2e6c3dad2a8e30a\",\n    \"0x97d5afe9b3897d7b8bb628b7220cf02d8ee4e9d0b78f5000d500aaf4c1df9251aaaabfd1601626519f9d66f00a821d4e\",\n    \"0x8a382418157b601ce4c3501d3b8409ca98136a4ef6abcbf62885e16e215b76b035c94d149cc41ff92e42ccd7c43b9b3d\",\n    \"0xb64b8d11fb3b01abb2646ac99fdb9c02b804ce15d98f9fe0fbf1c9df8440c71417487feb6cdf51e3e81d37104b19e012\",\n    \"0x849d7d044f9d8f0aab346a9374f0b3a5d14a9d1faa83dbacccbdc629ad1ef903a990940255564770537f8567521d17f0\",\n    \"0x829dbb0c76b996c2a91b4cbbe93ba455ca0d5729755e5f0c92aaee37dff7f36fcdc06f33aca41f1b609c784127b67d88\",\n    \"0x85a7c0069047b978422d264d831ab816435f63938015d2e977222b6b5746066c0071b7f89267027f8a975206ed25c1b0\",\n    \"0x84b9fbc1cfb302df1acdcf3dc5d66fd1edfe7839f7a3b2fb3a0d5548656249dd556104d7c32b73967bccf0f5bdcf9e3b\",\n    \"0x972220ac5b807f53eac37dccfc2ad355d8b21ea6a9c9b011c09fe440ddcdf7513e0b43d7692c09ded80d7040e26aa28f\",\n    \"0x855885ed0b21350baeca890811f344c553cf9c21024649c722453138ba29193c6b02c4b4994cd414035486f923472e28\",\n    \"0x841874783ae6d9d0e59daea03e96a01cbbe4ecaced91ae4f2c8386e0d87b3128e6d893c98d17c59e4de1098e1ad519dd\",\n    \"0x827e50fc9ce56f97a4c3f2f4cbaf0b22f1c3ce6f844ff0ef93a9c57a09b8bf91ebfbd2ba9c7f83c442920bffdaf288cc\",\n    \"0xa441f9136c7aa4c08d5b3534921b730e41ee91ab506313e1ba5f7c6f19fd2d2e1594e88c219834e92e6fb95356385aa7\",\n    \"0x97d75b144471bf580099dd6842b823ec0e6c1fb86dd0da0db195e65524129ea8b6fd4a7a9bbf37146269e938a6956596\",\n    \"0xa4b6fa87f09d5a29252efb2b3aaab6b3b6ea9fab343132a651630206254a25378e3e9d6c96c3d14c150d01817d375a8e\",\n    \"0xa31a671876d5d1e95fe2b8858dc69967231190880529d57d3cab7f9f4a2b9b458ac9ee5bdaa3289158141bf18f559efb\",\n    \"0x90bee6fff4338ba825974021b3b2a84e36d617e53857321f13d2b3d4a28954e6de3b3c0e629d61823d18a9763313b3bf\",\n    \"0x96b622a63153f393bb419bfcf88272ea8b3560dbd46b0aa07ada3a6223990d0abdd6c2adb356ef4be5641688c8d83941\",\n    \"0x84c202adeaff9293698022bc0381adba2cd959f9a35a4e8472288fd68f96f6de8be9da314c526d88e291c96b1f3d6db9\",\n    \"0x8ca01a143b8d13809e5a8024d03e6bc9492e22226073ef6e327edf1328ef4aff82d0bcccee92cb8e212831fa35fe1204\",\n    \"0xb2f970dbad15bfbefb38903c9bcc043d1367055c55dc1100a850f5eb816a4252c8c194b3132c929105511e14ea10a67d\",\n    \"0xa5e36556472a95ad57eb90c3b6623671b03eafd842238f01a081997ffc6e2401f76e781d049bb4aa94d899313577a9cf\",\n    \"0x8d1057071051772f7c8bedce53a862af6fd530dd56ae6321eaf2b9fc6a68beff5ed745e1c429ad09d5a118650bfd420a\",\n    \"0x8aadc4f70ace4fcb8d93a78610779748dcffc36182d45b932c226dc90e48238ea5daa91f137c65ed532352c4c4d57416\",\n    \"0xa2ea05ae37e673b4343232ae685ee14e6b88b867aef6dfac35db3589cbcd76f99540fed5c2641d5bb5a4a9f808e9bf0d\",\n    \"0x947f1abad982d65648ae4978e094332b4ecb90f482c9be5741d5d1cf5a28acf4680f1977bf6e49dd2174c37f11e01296\",\n    \"0xa27b144f1565e4047ba0e3f4840ef19b5095d1e281eaa463c5358f932114cbd018aa6dcf97546465cf2946d014d8e6d6\",\n    \"0x8574e1fc3acade47cd4539df578ce9205e745e161b91e59e4d088711a7ab5aa3b410d517d7304b92109924d9e2af8895\",\n    \"0xa48ee6b86b88015d6f0d282c1ae01d2a5b9e8c7aa3d0c18b35943dceb1af580d08a65f54dc6903cde82fd0d73ce94722\",\n    \"0x8875650cec543a7bf02ea4f2848a61d167a66c91ffaefe31a9e38dc8511c6a25bde431007eefe27a62af3655aca208dc\",\n    \"0x999b0a6e040372e61937bf0d68374e230346b654b5a0f591a59d33a4f95bdb2f3581db7c7ccb420cd7699ed709c50713\",\n    \"0x878c9e56c7100c5e47bbe77dc8da5c5fe706cec94d37fa729633bca63cace7c40102eee780fcdabb655f5fa47a99600e\",\n    \"0x865006fb5b475ada5e935f27b96f9425fc2d5449a3c106aa366e55ebed3b4ee42adc3c3f0ac19fd129b40bc7d6bc4f63\",\n    \"0xb7a7da847f1202e7bc1672553e68904715e84fd897d529243e3ecda59faa4e17ba99c649a802d53f6b8dfdd51f01fb74\",\n    \"0x8b2fb4432c05653303d8c8436473682933a5cb604da10c118ecfcd2c8a0e3132e125afef562bdbcc3df936164e5ce4f2\",\n    \"0x808d95762d33ddfa5d0ee3d7d9f327de21a994d681a5f372e2e3632963ea974da7f1f9e5bac8ccce24293509d1f54d27\",\n    \"0x932946532e3c397990a1df0e94c90e1e45133e347a39b6714c695be21aeb2d309504cb6b1dde7228ff6f6353f73e1ca2\",\n    \"0x9705e7c93f0cdfaa3fa96821f830fe53402ad0806036cd1b48adc2f022d8e781c1fbdab60215ce85c653203d98426da3\",\n    \"0xaa180819531c3ec1feb829d789cb2092964c069974ae4faad60e04a6afcce5c3a59aec9f11291e6d110a788d22532bc6\",\n    \"0x88f755097f7e25cb7dd3c449520c89b83ae9e119778efabb54fbd5c5714b6f37c5f9e0346c58c6ab09c1aef2483f895d\",\n    \"0x99fc03ab7810e94104c494f7e40b900f475fde65bdec853e60807ffd3f531d74de43335c3b2646b5b8c26804a7448898\",\n    \"0xaf2dea9683086bed1a179110efb227c9c00e76cd00a2015b089ccbcee46d1134aa18bda5d6cab6f82ae4c5cd2461ac21\",\n    \"0xa500f87ba9744787fdbb8e750702a3fd229de6b8817594348dec9a723b3c4240ddfa066262d002844b9e38240ce55658\",\n    \"0x924d0e45c780f5bc1c1f35d15dfc3da28036bdb59e4c5440606750ecc991b85be18bc9a240b6c983bc5430baa4c68287\",\n    \"0x865b11e0157b8bf4c5f336024b016a0162fc093069d44ac494723f56648bc4ded13dfb3896e924959ea11c96321afefc\",\n    \"0x93672d8607d4143a8f7894f1dcca83fb84906dc8d6dd7dd063bb0049cfc20c1efd933e06ca7bd03ea4cb5a5037990bfe\",\n    \"0x826891efbdff0360446825a61cd1fa04326dd90dae8c33dfb1ed97b045e165766dd070bd7105560994d0b2044bdea418\",\n    \"0x93c4a4a8bcbc8b190485cc3bc04175b7c0ed002c28c98a540919effd6ed908e540e6594f6db95cd65823017258fb3b1c\",\n    \"0xaeb2a0af2d2239fda9aa6b8234b019708e8f792834ff0dd9c487fa09d29800ddceddd6d7929faa9a3edcb9e1b3aa0d6b\",\n    \"0x87f11de7236d387863ec660d2b04db9ac08143a9a2c4dfff87727c95b4b1477e3bc473a91e5797313c58754905079643\",\n    \"0x80dc1db20067a844fe8baceca77f80db171a5ca967acb24e2d480eae9ceb91a3343c31ad1c95b721f390829084f0eae6\",\n    \"0x9825c31f1c18da0de3fa84399c8b40f8002c3cae211fb6a0623c76b097b4d39f5c50058f57a16362f7a575909d0a44a2\",\n    \"0xa99fc8de0c38dbf7b9e946de83943a6b46a762167bafe2a603fb9b86f094da30d6de7ed55d639aafc91936923ee414b3\",\n    \"0xad594678b407db5d6ea2e90528121f84f2b96a4113a252a30d359a721429857c204c1c1c4ff71d8bb5768c833f82e80e\",\n    \"0xb33d985e847b54510b9b007e31053732c8a495e43be158bd2ffcea25c6765bcbc7ca815f7c60b36ad088b955dd6e9350\",\n    \"0x815f8dfc6f90b3342ca3fbd968c67f324dae8f74245cbf8bc3bef10e9440c65d3a2151f951e8d18959ba01c1b50b0ec1\",\n    \"0x94c608a362dd732a1abc56e338637c900d59013db8668e49398b3c7a0cae3f7e2f1d1bf94c0299eeafe6af7f76c88618\",\n    \"0x8ebd8446b23e5adfcc393adc5c52fe172f030a73e63cd2d515245ca0dd02782ceed5bcdd9ccd9c1b4c5953dfac9c340c\",\n    \"0x820437f3f6f9ad0f5d7502815b221b83755eb8dc56cd92c29e9535eb0b48fb8d08c9e4fcc26945f9c8cca60d89c44710\",\n    \"0x8910e4e8a56bf4be9cc3bbf0bf6b1182a2f48837a2ed3c2aaec7099bfd7f0c83e14e608876b17893a98021ff4ab2f20d\",\n    \"0x9633918fde348573eec15ce0ad53ac7e1823aac86429710a376ad661002ae6d049ded879383faaa139435122f64047c6\",\n    \"0xa1f5e3fa558a9e89318ca87978492f0fb4f6e54a9735c1b8d2ecfb1d1c57194ded6e0dd82d077b2d54251f3bee1279e1\",\n    \"0xb208e22d04896abfd515a95c429ff318e87ff81a5d534c8ac2c33c052d6ffb73ef1dccd39c0bbe0734b596c384014766\",\n    \"0x986d5d7d2b5bde6d16336f378bd13d0e671ad23a8ec8a10b3fc09036faeeb069f60662138d7a6df3dfb8e0d36180f770\",\n    \"0xa2d4e6c5f5569e9cef1cddb569515d4b6ace38c8aed594f06da7434ba6b24477392cc67ba867c2b079545ca0c625c457\",\n    \"0xb5ac32b1d231957d91c8b7fc43115ce3c5c0d8c13ca633374402fa8000b6d9fb19499f9181844f0c10b47357f3f757ce\",\n    \"0x96b8bf2504b4d28fa34a4ec378e0e0b684890c5f44b7a6bb6e19d7b3db2ab27b1e2686389d1de9fbd981962833a313ea\",\n    \"0x953bfd7f6c3a0469ad432072b9679a25486f5f4828092401eff494cfb46656c958641a4e6d0d97d400bc59d92dba0030\",\n    \"0x876ab3cea7484bbfd0db621ec085b9ac885d94ab55c4bb671168d82b92e609754b86aaf472c55df3d81421d768fd108a\",\n    \"0x885ff4e67d9ece646d02dd425aa5a087e485c3f280c3471b77532b0db6145b69b0fbefb18aa2e3fa5b64928b43a94e57\",\n    \"0xb91931d93f806d0b0e6cc62a53c718c099526140f50f45d94b8bbb57d71e78647e06ee7b42aa5714aed9a5c05ac8533f\",\n    \"0xa0313eeadd39c720c9c27b3d671215331ab8d0a794e71e7e690f06bcd87722b531d6525060c358f35f5705dbb7109ccb\",\n    \"0x874c0944b7fedc6701e53344100612ddcb495351e29305c00ec40a7276ea5455465ffb7bded898886c1853139dfb1fc7\",\n    \"0x8dc31701a01ee8137059ca1874a015130d3024823c0576aa9243e6942ec99d377e7715ed1444cd9b750a64b85dcaa3e5\",\n    \"0x836d2a757405e922ec9a2dfdcf489a58bd48b5f9683dd46bf6047688f778c8dee9bc456de806f70464df0b25f3f3d238\",\n    \"0xb30b0a1e454a503ea3e2efdec7483eaf20b0a5c3cefc42069e891952b35d4b2c955cf615f3066285ed8fafd9fcfbb8f6\",\n    \"0x8e6d4044b55ab747e83ec8762ea86845f1785cc7be0279c075dadf08aca3ccc5a096c015bb3c3f738f647a4eadea3ba5\",\n    \"0xad7735d16ab03cbe09c029610aa625133a6daecfc990b297205b6da98eda8c136a7c50db90f426d35069708510d5ae9c\",\n    \"0x8d62d858bbb59ec3c8cc9acda002e08addab4d3ad143b3812098f3d9087a1b4a1bb255dcb1635da2402487d8d0249161\",\n    \"0x805beec33238b832e8530645a3254aeef957e8f7ea24bcfc1054f8b9c69421145ebb8f9d893237e8a001c857fedfc77e\",\n    \"0xb1005644be4b085e3f5775aa9bd3e09a283e87ddada3082c04e7a62d303dcef3b8cf8f92944c200c7ae6bb6bdf63f832\",\n    \"0xb4ba0e0790dc29063e577474ffe3b61f5ea2508169f5adc1e394934ebb473e356239413a17962bc3e5d3762d72cce8c2\",\n    \"0xa157ba9169c9e3e6748d9f1dd67fbe08b9114ade4c5d8fc475f87a764fb7e6f1d21f66d7905cd730f28a1c2d8378682a\",\n    \"0x913e52b5c93989b5d15e0d91aa0f19f78d592bc28bcfdfddc885a9980c732b1f4debb8166a7c4083c42aeda93a702898\",\n    \"0x90fbfc1567e7cd4e096a38433704d3f96a2de2f6ed3371515ccc30bc4dd0721a704487d25a97f3c3d7e4344472702d8d\",\n    \"0x89646043028ffee4b69d346907586fd12c2c0730f024acb1481abea478e61031966e72072ff1d5e65cb8c64a69ad4eb1\",\n    \"0xb125a45e86117ee11d2fb42f680ab4a7894edd67ff927ae2c808920c66c3e55f6a9d4588eee906f33a05d592e5ec3c04\",\n    \"0xaad47f5b41eae9be55fb4f67674ff1e4ae2482897676f964a4d2dcb6982252ee4ff56aac49578b23f72d1fced707525e\",\n    \"0xb9ddff8986145e33851b4de54d3e81faa3352e8385895f357734085a1616ef61c692d925fe62a5ed3be8ca49f5d66306\",\n    \"0xb3cb0963387ed28c0c0adf7fe645f02606e6e1780a24d6cecef5b7c642499109974c81a7c2a198b19862eedcea2c2d8c\",\n    \"0xac9c53c885457aaf5cb36c717a6f4077af701e0098eebd7aa600f5e4b14e6c1067255b3a0bc40e4a552025231be7de60\",\n    \"0x8e1a8d823c4603f6648ec21d064101094f2a762a4ed37dd2f0a2d9aa97b2d850ce1e76f4a4b8cae58819b058180f7031\",\n    \"0xb268b73bf7a179b6d22bd37e5e8cb514e9f5f8968c78e14e4f6d5700ca0d0ca5081d0344bb73b028970eebde3cb4124e\",\n    \"0xa7f57d71940f0edbd29ed8473d0149cae71d921dd15d1ff589774003e816b54b24de2620871108cec1ab9fa956ad6ce6\",\n    \"0x8053e6416c8b120e2b999cc2fc420a6a55094c61ac7f2a6c6f0a2c108a320890e389af96cbe378936132363c0d551277\",\n    \"0xb3823f4511125e5aa0f4269e991b435a0d6ceb523ebd91c04d7add5534e3df5fc951c504b4fd412a309fd3726b7f940b\",\n    \"0xae6eb04674d04e982ca9a6add30370ab90e303c71486f43ed3efbe431af1b0e43e9d06c11c3412651f304c473e7dbf39\",\n    \"0x96ab55e641ed2e677591f7379a3cd126449614181fce403e93e89b1645d82c4af524381ff986cae7f9cebe676878646d\",\n    \"0xb52423b4a8c37d3c3e2eca8f0ddbf7abe0938855f33a0af50f117fab26415fb0a3da5405908ec5fdc22a2c1f2ca64892\",\n    \"0x82a69ce1ee92a09cc709d0e3cd22116c9f69d28ea507fe5901f5676000b5179b9abe4c1875d052b0dd42d39925e186bb\",\n    \"0xa84c8cb84b9d5cfb69a5414f0a5283a5f2e90739e9362a1e8c784b96381b59ac6c18723a4aa45988ee8ef5c1f45cc97d\",\n    \"0xafd7efce6b36813082eb98257aae22a4c1ae97d51cac7ea9c852d4a66d05ef2732116137d8432e3f117119725a817d24\",\n    \"0xa0f5fe25af3ce021b706fcff05f3d825384a272284d04735574ce5fb256bf27100fad0b1f1ba0e54ae9dcbb9570ecad3\",\n    \"0x8751786cb80e2e1ff819fc7fa31c2833d25086534eb12b373d31f826382430acfd87023d2a688c65b5e983927e146336\",\n    \"0x8cf5c4b17fa4f3d35c78ce41e1dc86988fd1135cd5e6b2bb0c108ee13538d0d09ae7102609c6070f39f937b439b31e33\",\n    \"0xa9108967a2fedd7c322711eca8159c533dd561bedcb181b646de98bf5c3079449478eab579731bee8d215ae8852c7e21\",\n    \"0xb54c5171704f42a6f0f4e70767cdb3d96ffc4888c842eece343a01557da405961d53ffdc34d2f902ea25d3e1ed867cad\",\n    \"0xae8d4b764a7a25330ba205bf77e9f46182cd60f94a336bbd96773cf8064e3d39caf04c310680943dc89ed1fbad2c6e0d\",\n    \"0xaa5150e911a8e1346868e1b71c5a01e2a4bb8632c195861fb6c3038a0e9b85f0e09b3822e9283654a4d7bb17db2fc5f4\",\n    \"0x9685d3756ce9069bf8bb716cf7d5063ebfafe37e15b137fc8c3159633c4e006ff4887ddd0ae90360767a25c3f90cba7f\",\n    \"0x82155fd70f107ab3c8e414eadf226c797e07b65911508c76c554445422325e71af8c9a8e77fd52d94412a6fc29417cd3\",\n    \"0xabfae52f53a4b6e00760468d973a267f29321997c3dbb5aee36dc1f20619551229c0c45b9d9749f410e7f531b73378e8\",\n    \"0x81a76d921f8ef88e774fd985e786a4a330d779b93fad7def718c014685ca0247379e2e2a007ad63ee7f729cd9ed6ce1b\",\n    \"0x81947c84bc5e28e26e2e533af5ae8fe10407a7b77436dbf8f1d5b0bbe86fc659eae10f974659dc7c826c6dabd03e3a4b\",\n    \"0x92b8c07050d635b8dd4fd09df9054efe4edae6b86a63c292e73cc819a12a21dd7d104ce51fa56af6539dedf6dbe6f7b6\",\n    \"0xb44c579e3881f32b32d20c82c207307eca08e44995dd2aac3b2692d2c8eb2a325626c80ac81c26eeb38c4137ff95add5\",\n    \"0x97efab8941c90c30860926dea69a841f2dcd02980bf5413b9fd78d85904588bf0c1021798dbc16c8bbb32cce66c82621\",\n    \"0x913363012528b50698e904de0588bf55c8ec5cf6f0367cfd42095c4468fcc64954fbf784508073e542fee242d0743867\",\n    \"0x8ed203cf215148296454012bd10fddaf119203db1919a7b3d2cdc9f80e66729464fdfae42f1f2fc5af1ed53a42b40024\",\n    \"0xab84312db7b87d711e9a60824f4fe50e7a6190bf92e1628688dfcb38930fe87b2d53f9e14dd4de509b2216856d8d9188\",\n    \"0x880726def069c160278b12d2258eac8fa63f729cd351a710d28b7e601c6712903c3ac1e7bbd0d21e4a15f13ca49db5aa\",\n    \"0x980699cd51bac6283959765f5174e543ed1e5f5584b5127980cbc2ef18d984ecabba45042c6773b447b8e694db066028\",\n    \"0xaeb019cb80dc4cb4207430d0f2cd24c9888998b6f21d9bf286cc638449668d2eec0018a4cf3fe6448673cd6729335e2b\",\n    \"0xb29852f6aa6c60effdffe96ae88590c88abae732561d35cc19e82d3a51e26cb35ea00986193e07f90060756240f5346e\",\n    \"0xa0fa855adc5ba469f35800c48414b8921455950a5c0a49945d1ef6e8f2a1881f2e2dfae47de6417270a6bf49deeb091d\",\n    \"0xb6c7332e3b14813641e7272d4f69ecc7e09081df0037d6dab97ce13a9e58510f5c930d300633f208181d9205c5534001\",\n    \"0x85a6c050f42fce560b5a8d54a11c3bbb8407abbadd859647a7b0c21c4b579ec65671098b74f10a16245dc779dff7838e\",\n    \"0x8f3eb34bb68759d53c6677de4de78a6c24dd32c8962a7fb355ed362572ef8253733e6b52bc21c9f92ecd875020a9b8de\",\n    \"0xa17dd44181e5dab4dbc128e1af93ec22624b57a448ca65d2d9e246797e4af7d079e09c6e0dfb62db3a9957ce92f098d5\",\n    \"0xa56a1b854c3183082543a8685bb34cae1289f86cfa8123a579049dbd059e77982886bfeb61bf6e05b4b1fe4e620932e7\",\n    \"0xaedae3033cb2fb7628cb4803435bdd7757370a86f808ae4cecb9a268ad0e875f308c048c80cbcac523de16b609683887\",\n    \"0x9344905376aa3982b1179497fac5a1d74b14b7038fd15e3b002db4c11c8bfc7c39430db492cdaf58b9c47996c9901f28\",\n    \"0xa3bfafdae011a19f030c749c3b071f83580dee97dd6f949e790366f95618ca9f828f1daaeabad6dcd664fcef81b6556d\",\n    \"0x81c03d8429129e7e04434dee2c529194ddb01b414feda3adee2271eb680f6c85ec872a55c9fa9d2096f517e13ed5abcc\",\n    \"0x98205ef3a72dff54c5a9c82d293c3e45d908946fa74bb749c3aabe1ab994ea93c269bcce1a266d2fe67a8f02133c5985\",\n    \"0x85a70aeed09fda24412fadbafbbbf5ba1e00ac92885df329e147bfafa97b57629a3582115b780d8549d07d19b7867715\",\n    \"0xb0fbe81c719f89a57d9ea3397705f898175808c5f75f8eb81c2193a0b555869ba7bd2e6bc54ee8a60cea11735e21c68c\",\n    \"0xb03a0bd160495ee626ff3a5c7d95bc79d7da7e5a96f6d10116600c8fa20bedd1132f5170f25a22371a34a2d763f2d6d0\",\n    \"0xa90ab04091fbca9f433b885e6c1d60ab45f6f1daf4b35ec22b09909d493a6aab65ce41a6f30c98239cbca27022f61a8b\",\n    \"0xb66f92aa3bf2549f9b60b86f99a0bd19cbdd97036d4ae71ca4b83d669607f275260a497208f6476cde1931d9712c2402\",\n    \"0xb08e1fdf20e6a9b0b4942f14fa339551c3175c1ffc5d0ab5b226b6e6a322e9eb0ba96adc5c8d59ca4259e2bdd04a7eb0\",\n    \"0xa2812231e92c1ce74d4f5ac3ab6698520288db6a38398bb38a914ac9326519580af17ae3e27cde26607e698294022c81\",\n    \"0xabfcbbcf1d3b9e84c02499003e490a1d5d9a2841a9e50c7babbef0b2dd20d7483371d4dc629ba07faf46db659459d296\",\n    \"0xb0fe9f98c3da70927c23f2975a9dc4789194d81932d2ad0f3b00843dd9cbd7fb60747a1da8fe5a79f136a601becf279d\",\n    \"0xb130a6dba7645165348cb90f023713bed0eefbd90a976b313521c60a36d34f02032e69a2bdcf5361e343ed46911297ec\",\n    \"0x862f0cffe3020cea7a5fd4703353aa1eb1be335e3b712b29d079ff9f7090d1d8b12013011e1bdcbaa80c44641fd37c9f\",\n    \"0x8c6f11123b26633e1abb9ed857e0bce845b2b3df91cc7b013b2fc77b477eee445da0285fc6fc793e29d5912977f40916\",\n    \"0x91381846126ea819d40f84d3005e9fb233dc80071d1f9bb07f102bf015f813f61e5884ffffb4f5cd333c1b1e38a05a58\",\n    \"0x8add7d908de6e1775adbd39c29a391f06692b936518db1f8fde74eb4f533fc510673a59afb86e3a9b52ade96e3004c57\",\n    \"0x8780e086a244a092206edcde625cafb87c9ab1f89cc3e0d378bc9ee776313836160960a82ec397bc3800c0a0ec3da283\",\n    \"0xa6cb4cd9481e22870fdd757fae0785edf4635e7aacb18072fe8dc5876d0bab53fb99ce40964a7d3e8bcfff6f0ab1332f\",\n    \"0xaf30ff47ecc5b543efba1ba4706921066ca8bb625f40e530fb668aea0551c7647a9d126e8aba282fbcce168c3e7e0130\",\n    \"0x91b0bcf408ce3c11555dcb80c4410b5bc2386d3c05caec0b653352377efdcb6bab4827f2018671fc8e4a0e90d772acc1\",\n    \"0xa9430b975ef138b6b2944c7baded8fe102d31da4cfe3bd3d8778bda79189c99d38176a19c848a19e2d1ee0bddd9a13c1\",\n    \"0xaa5a4eef849d7c9d2f4b018bd01271c1dd83f771de860c4261f385d3bdcc130218495860a1de298f14b703ec32fa235f\",\n    \"0xb0ce79e7f9ae57abe4ff366146c3b9bfb38b0dee09c28c28f5981a5d234c6810ad4d582751948affb480d6ae1c8c31c4\",\n    \"0xb75122748560f73d15c01a8907d36d06dc068e82ce22b84b322ac1f727034493572f7907dec34ebc3ddcc976f2f89ed7\",\n    \"0xb0fc7836369a3e4411d34792d6bd5617c14f61d9bba023dda64e89dc5fb0f423244e9b48ee64869258931daa9753a56f\",\n    \"0x8956d7455ae9009d70c6e4a0bcd7610e55f37494cf9897a8f9e1b904cc8febc3fd2d642ebd09025cfff4609ad7e3bc52\",\n    \"0xad741efe9e472026aa49ae3d9914cb9c1a6f37a54f1a6fe6419bebd8c7d68dca105a751c7859f4389505ede40a0de786\",\n    \"0xb52f418797d719f0d0d0ffb0846788b5cba5d0454a69a2925de4b0b80fa4dd7e8c445e5eac40afd92897ed28ca650566\",\n    \"0xa0ab65fb9d42dd966cd93b1de01d7c822694669dd2b7a0c04d99cd0f3c3de795f387b9c92da11353412f33af5c950e9a\",\n    \"0xa0052f44a31e5741a331f7cac515a08b3325666d388880162d9a7b97598fde8b61f9ff35ff220df224eb5c4e40ef0567\",\n    \"0xa0101cfdc94e42b2b976c0d89612a720e55d145a5ef6ef6f1f78cf6de084a49973d9b5d45915349c34ce712512191e3c\",\n    \"0xa0dd99fcf3f5cead5aaf08e82212df3a8bb543c407a4d6fab88dc5130c1769df3f147e934a46f291d6c1a55d92b86917\",\n    \"0xa5939153f0d1931bbda5cf6bdf20562519ea55fbfa978d6dbc6828d298260c0da7a50c37c34f386e59431301a96c2232\",\n    \"0x9568269f3f5257200f9ca44afe1174a5d3cf92950a7f553e50e279c239e156a9faaa2a67f288e3d5100b4142efe64856\",\n    \"0xb746b0832866c23288e07f24991bbf687cad794e7b794d3d3b79367566ca617d38af586cdc8d6f4a85a34835be41d54f\",\n    \"0xa871ce28e39ab467706e32fec1669fda5a4abba2f8c209c6745df9f7a0fa36bbf1919cf14cb89ea26fa214c4c907ae03\",\n    \"0xa08dacdd758e523cb8484f6bd070642c0c20e184abdf8e2a601f61507e93952d5b8b0c723c34fcbdd70a8485eec29db2\",\n    \"0x85bdb78d501382bb95f1166b8d032941005661aefd17a5ac32df9a3a18e9df2fc5dc2c1f07075f9641af10353cecc0c9\",\n    \"0x98d730c28f6fa692a389e97e368b58f4d95382fad8f0baa58e71a3d7baaea1988ead47b13742ce587456f083636fa98e\",\n    \"0xa557198c6f3d5382be9fb363feb02e2e243b0c3c61337b3f1801c4a0943f18e38ce1a1c36b5c289c8fa2aa9d58742bab\",\n    \"0x89174f79201742220ac689c403fc7b243eed4f8e3f2f8aba0bf183e6f5d4907cb55ade3e238e3623d9885f03155c4d2b\",\n    \"0xb891d600132a86709e06f3381158db300975f73ea4c1f7c100358e14e98c5fbe792a9af666b85c4e402707c3f2db321e\",\n    \"0xb9e5b2529ef1043278c939373fc0dbafe446def52ddd0a8edecd3e4b736de87e63e187df853c54c28d865de18a358bb6\",\n    \"0x8589b2e9770340c64679062c5badb7bbef68f55476289b19511a158a9a721f197da03ece3309e059fc4468b15ac33aa3\",\n    \"0xaad8c6cd01d785a881b446f06f1e9cd71bca74ba98674c2dcddc8af01c40aa7a6d469037498b5602e76e9c91a58d3dbd\",\n    \"0xabaccb1bd918a8465f1bf8dbe2c9ad4775c620b055550b949a399f30cf0d9eb909f3851f5b55e38f9e461e762f88f499\",\n    \"0xae62339d26db46e85f157c0151bd29916d5cc619bd4b832814b3fd2f00af8f38e7f0f09932ffe5bba692005dab2d9a74\",\n    \"0x93a6ff30a5c0edf8058c89aba8c3259e0f1b1be1b80e67682de651e5346f7e1b4b4ac3d87cbaebf198cf779524aff6bf\",\n    \"0x8980a2b1d8f574af45b459193c952400b10a86122b71fca2acb75ee0dbd492e7e1ef5b959baf609a5172115e371f3177\",\n    \"0x8c2f49f3666faee6940c75e8c7f6f8edc3f704cca7a858bbb7ee5e96bba3b0cf0993996f781ba6be3b0821ef4cb75039\",\n    \"0xb14b9e348215b278696018330f63c38db100b0542cfc5be11dc33046e3bca6a13034c4ae40d9cef9ea8b34fef0910c4e\",\n    \"0xb59bc3d0a30d66c16e6a411cb641f348cb1135186d5f69fda8b0a0934a5a2e7f6199095ba319ec87d3fe8f1ec4a06368\",\n    \"0x8874aca2a3767aa198e4c3fec2d9c62d496bc41ff71ce242e9e082b7f38cdf356089295f80a301a3cf1182bde5308c97\",\n    \"0xb1820ebd61376d91232423fc20bf008b2ba37e761199f4ef0648ea2bd70282766799b4de814846d2f4d516d525c8daa7\",\n    \"0xa6b202e5dedc16a4073e04a11af3a8509b23dfe5a1952f899adeb240e75c3f5bde0c424f811a81ea48d343591faffe46\",\n    \"0xa69becee9c93734805523b92150a59a62eed4934f66056b645728740d42223f2925a1ad38359ba644da24d9414f4cdda\",\n    \"0xad72f0f1305e37c7e6b48c272323ee883320994cb2e0d850905d6655fafc9f361389bcb9c66b3ff8d2051dbb58c8aa96\",\n    \"0xb563600bd56fad7c8853af21c6a02a16ed9d8a8bbeea2c31731d63b976d83cb05b9779372d898233e8fd597a75424797\",\n    \"0xb0abb78ce465bf7051f563c62e8be9c57a2cc997f47c82819300f36e301fefd908894bb2053a9d27ce2d0f8c46d88b5b\",\n    \"0xa071a85fb8274bac2202e0cb8e0e2028a5e138a82d6e0374d39ca1884a549c7c401312f00071b91f455c3a2afcfe0cda\",\n    \"0xb931c271513a0f267b9f41444a5650b1918100b8f1a64959c552aff4e2193cc1b9927906c6fa7b8a8c68ef13d79aaa52\",\n    \"0xa6a1bb9c7d32cb0ca44d8b75af7e40479fbce67d216b48a2bb680d3f3a772003a49d3cd675fc64e9e0f8fabeb86d6d61\",\n    \"0xb98d609858671543e1c3b8564162ad828808bb50ded261a9f8690ded5b665ed8368c58f947365ed6e84e5a12e27b423d\",\n    \"0xb3dca58cd69ec855e2701a1d66cad86717ff103ef862c490399c771ad28f675680f9500cb97be48de34bcdc1e4503ffd\",\n    \"0xb34867c6735d3c49865e246ddf6c3b33baf8e6f164db3406a64ebce4768cb46b0309635e11be985fee09ab7a31d81402\",\n    \"0xacb966c554188c5b266624208f31fab250b3aa197adbdd14aee5ab27d7fb886eb4350985c553b20fdf66d5d332bfd3fe\",\n    \"0x943c36a18223d6c870d54c3b051ef08d802b85e9dd6de37a51c932f90191890656c06adfa883c87b906557ae32d09da0\",\n    \"0x81bca7954d0b9b6c3d4528aadf83e4bc2ef9ea143d6209bc45ae9e7ae9787dbcd8333c41f12c0b6deee8dcb6805e826a\",\n    \"0xaba176b92256efb68f574e543479e5cf0376889fb48e3db4ebfb7cba91e4d9bcf19dcfec444c6622d9398f06de29e2b9\",\n    \"0xb9f743691448053216f6ece7cd699871fff4217a1409ceb8ab7bdf3312d11696d62c74b0664ba0a631b1e0237a8a0361\",\n    \"0xa383c2b6276fa9af346b21609326b53fb14fdf6f61676683076e80f375b603645f2051985706d0401e6fbed7eb0666b6\",\n    \"0xa9ef2f63ec6d9beb8f3d04e36807d84bda87bdd6b351a3e4a9bf7edcb5618c46c1f58cfbf89e64b40f550915c6988447\",\n    \"0xa141b2d7a82f5005eaea7ae7d112c6788b9b95121e5b70b7168d971812f3381de8b0082ac1f0a82c7d365922ebd2d26a\",\n    \"0xb1b76ef8120e66e1535c17038b75255a07849935d3128e3e99e56567b842fb1e8d56ef932d508d2fb18b82f7868fe1a9\",\n    \"0x8e2e234684c81f21099f5c54f6bbe2dd01e3b172623836c77668a0c49ce1fe218786c3827e4d9ae2ea25c50a8924fb3c\",\n    \"0xa5caf5ff948bfd3c4ca3ffbdfcd91eec83214a6c6017235f309a0bbf7061d3b0b466307c00b44a1009cf575163898b43\",\n    \"0x986415a82ca16ebb107b4c50b0c023c28714281db0bcdab589f6cb13d80e473a3034b7081b3c358e725833f6d845cb14\",\n    \"0xb94836bf406ac2cbacb10e6df5bcdfcc9d9124ae1062767ca4e322d287fd5e353fdcebd0e52407cb3cd68571258a8900\",\n    \"0x83c6d70a640b33087454a4788dfd9ef3ed00272da084a8d36be817296f71c086b23b576f98178ab8ca6a74f04524b46b\",\n    \"0xad4115182ad784cfe11bcfc5ce21fd56229cc2ce77ac82746e91a2f0aa53ca6593a22efd2dc4ed8d00f84542643d9c58\",\n    \"0xab1434c5e5065da826d10c2a2dba0facccab0e52b506ce0ce42fbe47ced5a741797151d9ecc99dc7d6373cfa1779bbf6\",\n    \"0x8a8b591d82358d55e6938f67ea87a89097ab5f5496f7260adb9f649abb289da12b498c5b2539c2f9614fb4e21b1f66b0\",\n    \"0x964f355d603264bc1f44c64d6d64debca66f37dff39c971d9fc924f2bc68e6c187b48564a6dc82660a98b035f8addb5d\",\n    \"0xb66235eaaf47456bc1dc4bde454a028e2ce494ece6b713a94cd6bf27cf18c717fd0c57a5681caaa2ad73a473593cdd7a\",\n    \"0x9103e3bb74304186fa4e3e355a02da77da4aca9b7e702982fc2082af67127ebb23a455098313c88465bc9b7d26820dd5\",\n    \"0xb6a42ff407c9dd132670cdb83cbad4b20871716e44133b59a932cd1c3f97c7ac8ff7f61acfaf8628372508d8dc8cad7c\",\n    \"0x883a9c21c16a167a4171b0f084565c13b6f28ba7c4977a0de69f0a25911f64099e7bbb4da8858f2e93068f4155d04e18\",\n    \"0x8dbb3220abc6a43220adf0331e3903d3bfd1d5213aadfbd8dfcdf4b2864ce2e96a71f35ecfb7a07c3bbabf0372b50271\",\n    \"0xb4ad08aee48e176bda390b7d9acf2f8d5eb008f30d20994707b757dc6a3974b2902d29cd9b4d85e032810ad25ac49e97\",\n    \"0x865bb0f33f7636ec501bb634e5b65751c8a230ae1fa807a961a8289bbf9c7fe8c59e01fbc4c04f8d59b7f539cf79ddd5\",\n    \"0x86a54d4c12ad1e3605b9f93d4a37082fd26e888d2329847d89afa7802e815f33f38185c5b7292293d788ad7d7da1df97\",\n    \"0xb26c8615c5e47691c9ff3deca3021714662d236c4d8401c5d27b50152ce7e566266b9d512d14eb63e65bc1d38a16f914\",\n    \"0x827639d5ce7db43ba40152c8a0eaad443af21dc92636cc8cc2b35f10647da7d475a1e408901cd220552fddad79db74df\",\n    \"0xa2b79a582191a85dbe22dc384c9ca3de345e69f6aa370aa6d3ff1e1c3de513e30b72df9555b15a46586bd27ea2854d9d\",\n    \"0xae0d74644aba9a49521d3e9553813bcb9e18f0b43515e4c74366e503c52f47236be92dfbd99c7285b3248c267b1de5a0\",\n    \"0x80fb0c116e0fd6822a04b9c25f456bdca704e2be7bdc5d141dbf5d1c5eeb0a2c4f5d80db583b03ef3e47517e4f9a1b10\",\n    \"0xac3a1fa3b4a2f30ea7e0a114cdc479eb51773573804c2a158d603ad9902ae8e39ffe95df09c0d871725a5d7f9ba71a57\",\n    \"0xb56b2b0d601cba7f817fa76102c68c2e518c6f20ff693aad3ff2e07d6c4c76203753f7f91686b1801e8c4659e4d45c48\",\n    \"0x89d50c1fc56e656fb9d3915964ebce703cb723fe411ab3c9eaa88ccc5d2b155a9b2e515363d9c600d3c0cee782c43f41\",\n    \"0xb24207e61462f6230f3cd8ccf6828357d03e725769f7d1de35099ef9ee4dca57dbce699bb49ed994462bee17059d25ce\",\n    \"0xb886f17fcbcbfcd08ac07f04bb9543ef58510189decaccea4b4158c9174a067cb67d14b6be3c934e6e2a18c77efa9c9c\",\n    \"0xb9c050ad9cafd41c6e2e192b70d080076eed59ed38ea19a12bd92fa17b5d8947d58d5546aaf5e8e27e1d3b5481a6ce51\",\n    \"0xaaf7a34d3267e3b1ddbc54c641e3922e89303f7c86ebebc7347ebca4cffad5b76117dac0cbae1a133053492799cd936f\",\n    \"0xa9ee604ada50adef82e29e893070649d2d4b7136cc24fa20e281ce1a07bd736bf0de7c420369676bcbcecff26fb6e900\",\n    \"0x9855315a12a4b4cf80ab90b8bd13003223ba25206e52fd4fe6a409232fbed938f30120a3db23eab9c53f308bd8b9db81\",\n    \"0x8cd488dd7a24f548a3cf03c54dec7ff61d0685cb0f6e5c46c2d728e3500d8c7bd6bba0156f4bf600466fda53e5b20444\",\n    \"0x890ad4942ebac8f5b16c777701ab80c68f56fa542002b0786f8fea0fb073154369920ac3dbfc07ea598b82f4985b8ced\",\n    \"0x8de0cf9ddc84c9b92c59b9b044387597799246b30b9f4d7626fc12c51f6e423e08ee4cbfe9289984983c1f9521c3e19d\",\n    \"0xb474dfb5b5f4231d7775b3c3a8744956b3f0c7a871d835d7e4fd9cc895222c7b868d6c6ce250de568a65851151fac860\",\n    \"0x86433b6135d9ed9b5ee8cb7a6c40e5c9d30a68774cec04988117302b8a02a11a71a1e03fd8e0264ef6611d219f103007\",\n    \"0x80b9ed4adbe9538fb1ef69dd44ec0ec5b57cbfea820054d8d445b4261962624b4c70ac330480594bc5168184378379c3\",\n    \"0x8b2e83562ccd23b7ad2d17f55b1ab7ef5fbef64b3a284e6725b800f3222b8bdf49937f4a873917ada9c4ddfb090938c2\",\n    \"0xabe78cebc0f5a45d754140d1f685e387489acbfa46d297a8592aaa0d676a470654f417a4f7d666fc0b2508fab37d908e\",\n    \"0xa9c5f8ff1f8568e252b06d10e1558326db9901840e6b3c26bbd0cd5e850cb5fb3af3f117dbb0f282740276f6fd84126f\",\n    \"0x975f8dc4fb55032a5df3b42b96c8c0ffecb75456f01d4aef66f973cb7270d4eff32c71520ceefc1adcf38d77b6b80c67\",\n    \"0xb043306ed2c3d8a5b9a056565afd8b5e354c8c4569fda66b0d797a50a3ce2c08cffbae9bbe292da69f39e89d5dc7911e\",\n    \"0x8d2afc36b1e44386ba350c14a6c1bb31ff6ea77128a0c5287584ac3584282d18516901ce402b4644a53db1ed8e7fa581\",\n    \"0x8c294058bed53d7290325c363fe243f6ec4f4ea2343692f4bac8f0cb86f115c069ccb8334b53d2e42c067691ad110dba\",\n    \"0xb92157b926751aaf7ef82c1aa8c654907dccab6376187ee8b3e8c0c82811eae01242832de953faa13ebaff7da8698b3e\",\n    \"0xa780c4bdd9e4ba57254b09d745075cecab87feda78c88ffee489625c5a3cf96aa6b3c9503a374a37927d9b78de9bd22b\",\n    \"0x811f548ef3a2e6a654f7dcb28ac9378de9515ed61e5a428515d9594a83e80b35c60f96a5cf743e6fab0d3cb526149f49\",\n    \"0x85a4dccf6d90ee8e094731eec53bd00b3887aec6bd81a0740efddf812fd35e3e4fe4f983afb49a8588691c202dabf942\",\n    \"0xb152c2da6f2e01c8913079ae2b40a09b1f361a80f5408a0237a8131b429677c3157295e11b365b1b1841924b9efb922e\",\n    \"0x849b9efee8742502ffd981c4517c88ed33e4dd518a330802caff168abae3cd09956a5ee5eda15900243bc2e829016b74\",\n    \"0x955a933f3c18ec0f1c0e38fa931e4427a5372c46a3906ebe95082bcf878c35246523c23f0266644ace1fa590ffa6d119\",\n    \"0x911989e9f43e580c886656377c6f856cdd4ff1bd001b6db3bbd86e590a821d34a5c6688a29b8d90f28680e9fdf03ba69\",\n    \"0xb73b8b4f1fd6049fb68d47cd96a18fcba3f716e0a1061aa5a2596302795354e0c39dea04d91d232aec86b0bf2ba10522\",\n    \"0x90f87456d9156e6a1f029a833bf3c7dbed98ca2f2f147a8564922c25ae197a55f7ea9b2ee1f81bf7383197c4bad2e20c\",\n    \"0x903cba8b1e088574cb04a05ca1899ab00d8960580c884bd3c8a4c98d680c2ad11410f2b75739d6050f91d7208cac33a5\",\n    \"0x9329987d42529c261bd15ecedd360be0ea8966e7838f32896522c965adfc4febf187db392bd441fb43bbd10c38fdf68b\",\n    \"0x8178ee93acf5353baa349285067b20e9bb41aa32d77b5aeb7384fe5220c1fe64a2461bd7a83142694fe673e8bbf61b7c\",\n    \"0xa06a8e53abcff271b1394bcc647440f81fb1c1a5f29c27a226e08f961c3353f4891620f2d59b9d1902bf2f5cc07a4553\",\n    \"0xaaf5fe493b337810889e777980e6bbea6cac39ac66bc0875c680c4208807ac866e9fda9b5952aa1d04539b9f4a4bec57\",\n    \"0xaa058abb1953eceac14ccfa7c0cc482a146e1232905dcecc86dd27f75575285f06bbae16a8c9fe8e35d8713717f5f19f\",\n    \"0x8f15dd732799c879ca46d2763453b359ff483ca33adb1d0e0a57262352e0476c235987dc3a8a243c74bc768f93d3014c\",\n    \"0xa61cc8263e9bc03cce985f1663b8a72928a607121005a301b28a278e9654727fd1b22bc8a949af73929c56d9d3d4a273\",\n    \"0x98d6dc78502d19eb9f921225475a6ebcc7b44f01a2df6f55ccf6908d65b27af1891be2a37735f0315b6e0f1576c1f8d8\",\n    \"0x8bd258b883f3b3793ec5be9472ad1ff3dc4b51bc5a58e9f944acfb927349ead8231a523cc2175c1f98e7e1e2b9f363b8\",\n    \"0xaeacc2ecb6e807ad09bedd99654b097a6f39840e932873ace02eabd64ccfbb475abdcb62939a698abf17572d2034c51e\",\n    \"0xb8ccf78c08ccd8df59fd6eda2e01de328bc6d8a65824d6f1fc0537654e9bc6bf6f89c422dd3a295cce628749da85c864\",\n    \"0x8f91fd8cb253ba2e71cc6f13da5e05f62c2c3b485c24f5d68397d04665673167fce1fc1aec6085c69e87e66ec555d3fd\",\n    \"0xa254baa10cb26d04136886073bb4c159af8a8532e3fd36b1e9c3a2e41b5b2b6a86c4ebc14dbe624ee07b7ccdaf59f9ab\",\n    \"0x94e3286fe5cd68c4c7b9a7d33ae3d714a7f265cf77cd0e9bc19fc51015b1d1c34ad7e3a5221c459e89f5a043ee84e3a9\",\n    \"0xa279da8878af8d449a9539bec4b17cea94f0242911f66fab275b5143ab040825f78c89cb32a793930609415cfa3a1078\",\n    \"0xac846ceb89c9e5d43a2991c8443079dc32298cd63e370e64149cec98cf48a6351c09c856f2632fd2f2b3d685a18bbf8b\",\n    \"0xa847b27995c8a2e2454aaeb983879fb5d3a23105c33175839f7300b7e1e8ec3efd6450e9fa3f10323609dee7b98c6fd5\",\n    \"0xa2f432d147d904d185ff4b2de8c6b82fbea278a2956bc406855b44c18041854c4f0ecccd472d1d0dff1d8aa8e281cb1d\",\n    \"0x94a48ad40326f95bd63dff4755f863a1b79e1df771a1173b17937f9baba57b39e651e7695be9f66a472f098b339364fc\",\n    \"0xa12a0ccd8f96e96e1bc6494341f7ebce959899341b3a084aa1aa87d1c0d489ac908552b7770b887bb47e7b8cbc3d8e66\",\n    \"0x81a1f1681bda923bd274bfe0fbb9181d6d164fe738e54e25e8d4849193d311e2c4253614ed673c98af2c798f19a93468\",\n    \"0xabf71106a05d501e84cc54610d349d7d5eae21a70bd0250f1bebbf412a130414d1c8dbe673ffdb80208fd72f1defa4d4\",\n    \"0x96266dc2e0df18d8136d79f5b59e489978eee0e6b04926687fe389d4293c14f36f055c550657a8e27be4118b64254901\",\n    \"0x8df5dcbefbfb4810ae3a413ca6b4bf08619ca53cd50eb1dde2a1c035efffc7b7ac7dff18d403253fd80104bd83dc029e\",\n    \"0x9610b87ff02e391a43324a7122736876d5b3af2a137d749c52f75d07b17f19900b151b7f439d564f4529e77aa057ad12\",\n    \"0xa90a5572198b40fe2fcf47c422274ff36c9624df7db7a89c0eb47eb48a73a03c985f4ac5016161c76ca317f64339bce1\",\n    \"0x98e5e61a6ab6462ba692124dba7794b6c6bde4249ab4fcc98c9edd631592d5bc2fb5e38466691a0970a38e48d87c2e43\",\n    \"0x918cefb8f292f78d4db81462c633daf73b395e772f47b3a7d2cea598025b1d8c3ec0cbff46cdb23597e74929981cde40\",\n    \"0xa98918a5dc7cf610fe55f725e4fd24ce581d594cb957bb9b4e888672e9c0137003e1041f83e3f1d7b9caab06462c87d4\",\n    \"0xb92b74ac015262ca66c33f2d950221e19d940ba3bf4cf17845f961dc1729ae227aa9e1f2017829f2135b489064565c29\",\n    \"0xa053ee339f359665feb178b4e7ee30a85df37debd17cacc5a27d6b3369d170b0114e67ad1712ed26d828f1df641bcd99\",\n    \"0x8c3c8bad510b35da5ce5bd84b35c958797fbea024ad1c97091d2ff71d9b962e9222f65a9b776e5b3cc29c36e1063d2ee\",\n    \"0xaf99dc7330fe7c37e850283eb47cc3257888e7c197cb0d102edf94439e1e02267b6a56306d246c326c4c79f9dc8c6986\",\n    \"0xafecb2dc34d57a725efbd7eb93d61eb29dbe8409b668ab9ea040791f5b796d9be6d4fc10d7f627bf693452f330cf0435\",\n    \"0x93334fedf19a3727a81a6b6f2459db859186227b96fe7a391263f69f1a0884e4235de64d29edebc7b99c44d19e7c7d7a\",\n    \"0x89579c51ac405ad7e9df13c904061670ce4b38372492764170e4d3d667ed52e5d15c7cd5c5991bbfa3a5e4e3fa16363e\",\n    \"0x9778f3e8639030f7ef1c344014f124e375acb8045bd13d8e97a92c5265c52de9d1ffebaa5bc3e1ad2719da0083222991\",\n    \"0x88f77f34ee92b3d36791bdf3326532524a67d544297dcf1a47ff00b47c1b8219ff11e34034eab7d23b507caa2fd3c6b9\",\n    \"0xa699c1e654e7c484431d81d90657892efeb4adcf72c43618e71ca7bd7c7a7ebbb1db7e06e75b75dc4c74efd306b5df3f\",\n    \"0x81d13153baebb2ef672b5bdb069d3cd669ce0be96b742c94e04038f689ff92a61376341366b286eee6bf3ae85156f694\",\n    \"0x81efb17de94400fdacc1deec2550cbe3eecb27c7af99d8207e2f9be397e26be24a40446d2a09536bb5172c28959318d9\",\n    \"0x989b21ebe9ceab02488992673dc071d4d5edec24bff0e17a4306c8cb4b3c83df53a2063d1827edd8ed16d6e837f0d222\",\n    \"0x8d6005d6536825661b13c5fdce177cb37c04e8b109b7eb2b6d82ea1cb70efecf6a0022b64f84d753d165edc2bba784a3\",\n    \"0xa32607360a71d5e34af2271211652d73d7756d393161f4cf0da000c2d66a84c6826e09e759bd787d4fd0305e2439d342\",\n    \"0xaaad8d6f6e260db45d51b2da723be6fa832e76f5fbcb77a9a31e7f090dd38446d3b631b96230d78208cae408c288ac4e\",\n    \"0xabcfe425255fd3c5cffd3a818af7650190c957b6b07b632443f9e33e970a8a4c3bf79ac9b71f4d45f238a04d1c049857\",\n    \"0xaeabf026d4c783adc4414b5923dbd0be4b039cc7201219f7260d321f55e9a5b166d7b5875af6129c034d0108fdc5d666\",\n    \"0xaf49e740c752d7b6f17048014851f437ffd17413c59797e5078eaaa36f73f0017c3e7da020310cfe7d3c85f94a99f203\",\n    \"0x8854ca600d842566e3090040cd66bb0b3c46dae6962a13946f0024c4a8aca447e2ccf6f240045f1ceee799a88cb9210c\",\n    \"0xb6c03b93b1ab1b88ded8edfa1b487a1ed8bdce8535244dddb558ffb78f89b1c74058f80f4db2320ad060d0c2a9c351cc\",\n    \"0xb5bd7d17372faff4898a7517009b61a7c8f6f0e7ed4192c555db264618e3f6e57fb30a472d169fea01bf2bf0362a19a8\",\n    \"0x96eb1d38319dc74afe7e7eb076fcd230d19983f645abd14a71e6103545c01301b31c47ae931e025f3ecc01fb3d2f31fa\",\n    \"0xb55a8d30d4403067def9b65e16f867299f8f64c9b391d0846d4780bc196569622e7e5b64ce799b5aefac8f965b2a7a7b\",\n    \"0x8356d199a991e5cbbff608752b6291731b6b6771aed292f8948b1f41c6543e4ab1bedc82dd26d10206c907c03508df06\",\n    \"0x97f4137445c2d98b0d1d478049de952610ad698c91c9d0f0e7227d2aae690e9935e914ec4a2ea1fbf3fc1dddfeeacebb\",\n    \"0xaf5621707e0938320b15ddfc87584ab325fbdfd85c30efea36f8f9bd0707d7ec12c344eff3ec21761189518d192df035\",\n    \"0x8ac7817e71ea0825b292687928e349da7140285d035e1e1abff0c3704fa8453faaae343a441b7143a74ec56539687cc4\",\n    \"0x8a5e0a9e4758449489df10f3386029ada828d1762e4fb0a8ffe6b79e5b6d5d713cb64ed95960e126398b0cdb89002bc9\",\n    \"0x81324be4a71208bbb9bca74b77177f8f1abb9d3d5d9db195d1854651f2cf333cd618d35400da0f060f3e1b025124e4b2\",\n    \"0x849971d9d095ae067525b3cbc4a7dfae81f739537ade6d6cec1b42fb692d923176197a8770907c58069754b8882822d6\",\n    \"0x89f830825416802477cc81fdf11084885865ee6607aa15aa4eb28e351c569c49b8a1b9b5e95ddc04fa0ebafe20071313\",\n    \"0x9240aeeaff37a91af55f860b9badd466e8243af9e8c96a7aa8cf348cd270685ab6301bc135b246dca9eda696f8b0e350\",\n    \"0xacf74db78cc33138273127599eba35b0fb4e7b9a69fe02dae18fc6692d748ca332bd00b22afa8e654ed587aab11833f3\",\n    \"0xb091e6d37b157b50d76bd297ad752220cd5c9390fac16dc838f8557aed6d9833fc920b61519df21265406216315e883f\",\n    \"0xa6446c429ebf1c7793c622250e23594c836b2fbcaf6c5b3d0995e1595a37f50ea643f3e549b0be8bbdadd69044d72ab9\",\n    \"0x93e675353bd60e996bf1c914d5267eeaa8a52fc3077987ccc796710ef9becc6b7a00e3d82671a6bdfb8145ee3c80245a\",\n    \"0xa2f731e43251d04ed3364aa2f072d05355f299626f2d71a8a38b6f76cf08c544133f7d72dd0ab4162814b674b9fc7fa6\",\n    \"0x97a8b791a5a8f6e1d0de192d78615d73d0c38f1e557e4e15d15adc663d649e655bc8da3bcc499ef70112eafe7fb45c7a\",\n    \"0x98cd624cbbd6c53a94469be4643c13130916b91143425bcb7d7028adbbfede38eff7a21092af43b12d4fab703c116359\",\n    \"0x995783ce38fd5f6f9433027f122d4cf1e1ff3caf2d196ce591877f4a544ce9113ead60de2de1827eaff4dd31a20d79a8\",\n    \"0x8cf251d6f5229183b7f3fe2f607a90b4e4b6f020fb4ba2459d28eb8872426e7be8761a93d5413640a661d73e34a5b81f\",\n    \"0xb9232d99620652a3aa7880cad0876f153ff881c4ed4c0c2e7b4ea81d5d42b70daf1a56b869d752c3743c6d4c947e6641\",\n    \"0x849716f938f9d37250cccb1bf77f5f9fde53096cdfc6f2a25536a6187029a8f1331cdbed08909184b201f8d9f04b792f\",\n    \"0x80c7c4de098cbf9c6d17b14eba1805e433b5bc905f6096f8f63d34b94734f2e4ebf4bce8a177efd1186842a61204a062\",\n    \"0xb790f410cf06b9b8daadceeb4fd5ff40a2deda820c8df2537e0a7554613ae3948e149504e3e79aa84889df50c8678eeb\",\n    \"0x813aab8bd000299cd37485b73cd7cba06e205f8efb87f1efc0bae8b70f6db2bc7702eb39510ad734854fb65515fe9d0f\",\n    \"0x94f0ab7388ac71cdb67f6b85dfd5945748afb2e5abb622f0b5ad104be1d4d0062b651f134ba22385c9e32c2dfdcccce1\",\n    \"0xab6223dca8bd6a4f969e21ccd9f8106fc5251d321f9e90cc42cea2424b3a9c4e5060a47eeef6b23c7976109b548498e8\",\n    \"0x859c56b71343fce4d5c5b87814c47bf55d581c50fd1871a17e77b5e1742f5af639d0e94d19d909ec7dfe27919e954e0c\",\n    \"0xaae0d632b6191b8ad71b027791735f1578e1b89890b6c22e37de0e4a6074886126988fe8319ae228ac9ef3b3bcccb730\",\n    \"0x8ca9f32a27a024c3d595ecfaf96b0461de57befa3b331ab71dc110ec3be5824fed783d9516597537683e77a11d334338\",\n    \"0xa061df379fb3f4b24816c9f6cd8a94ecb89b4c6dc6cd81e4b8096fa9784b7f97ab3540259d1de9c02eb91d9945af4823\",\n    \"0x998603102ac63001d63eb7347a4bb2bf4cf33b28079bb48a169076a65c20d511ccd3ef696d159e54cc8e772fb5d65d50\",\n    \"0x94444d96d39450872ac69e44088c252c71f46be8333a608a475147752dbb99db0e36acfc5198f158509401959c12b709\",\n    \"0xac1b51b6c09fe055c1d7c9176eea9adc33f710818c83a1fbfa073c8dc3a7eb3513cbdd3f5960b7845e31e3e83181e6ba\",\n    \"0x803d530523fc9e1e0f11040d2412d02baef3f07eeb9b177fa9bfa396af42eea898a4276d56e1db998dc96ae47b644cb2\",\n    \"0x85a3c9fc7638f5bf2c3e15ba8c2fa1ae87eb1ceb44c6598c67a2948667a9dfa41e61f66d535b4e7fda62f013a5a8b885\",\n    \"0xa961cf5654c46a1a22c29baf7a4e77837a26b7f138f410e9d1883480ed5fa42411d522aba32040b577046c11f007388e\",\n    \"0xad1154142344f494e3061ef45a34fab1aaacf5fdf7d1b26adbb5fbc3d795655fa743444e39d9a4119b4a4f82a6f30441\",\n    \"0xb1d6c30771130c77806e7ab893b73d4deb590b2ff8f2f8b5e54c2040c1f3e060e2bd99afc668cf706a2df666a508bbf6\",\n    \"0xa00361fd440f9decabd98d96c575cd251dc94c60611025095d1201ef2dedde51cb4de7c2ece47732e5ed9b3526c2012c\",\n    \"0xa85c5ab4d17d328bda5e6d839a9a6adcc92ff844ec25f84981e4f44a0e8419247c081530f8d9aa629c7eb4ca21affba6\",\n    \"0xa4ddd3eab4527a2672cf9463db38bc29f61460e2a162f426b7852b7a7645fbd62084fd39a8e4d60e1958cce436dd8f57\",\n    \"0x811648140080fe55b8618f4cf17f3c5a250adb0cd53d885f2ddba835d2b4433188e41fc0661faac88e4ff910b16278c0\",\n    \"0xb85c7f1cfb0ed29addccf7546023a79249e8f15ac2d14a20accbfef4dd9dc11355d599815fa09d2b6b4e966e6ea8cff1\",\n    \"0xa10b5d8c260b159043b020d5dd62b3467df2671afea6d480ca9087b7e60ed170c82b121819d088315902842d66c8fb45\",\n    \"0x917e191df1bcf3f5715419c1e2191da6b8680543b1ba41fe84ed07ef570376e072c081beb67b375fca3565a2565bcabb\",\n    \"0x881fd967407390bfd7badc9ab494e8a287559a01eb07861f527207c127eadea626e9bcc5aa9cca2c5112fbac3b3f0e9c\",\n    \"0x959fd71149af82cc733619e0e5bf71760ca2650448c82984b3db74030d0e10f8ab1ce1609a6de6f470fe8b5bd90df5b3\",\n    \"0xa3370898a1c5f33d15adb4238df9a6c945f18b9ada4ce2624fc32a844f9ece4c916a64e9442225b6592afa06d2e015f2\",\n    \"0x817efb8a791435e4236f7d7b278181a5fa34587578c629dbc14fbf9a5c26772290611395eecd20222a4c58649fc256d8\",\n    \"0xa04c9876acf2cfdc8ef96de4879742709270fa1d03fe4c8511fbef2d59eb0aaf0336fa2c7dfe41a651157377fa217813\",\n    \"0x81e15875d7ea7f123e418edf14099f2e109d4f3a6ce0eb65f67fe9fb10d2f809a864a29f60ad3fc949f89e2596b21783\",\n    \"0xb49f529975c09e436e6bc202fdc16e3fdcbe056db45178016ad6fdece9faad4446343e83aed096209690b21a6910724f\",\n    \"0x879e8eda589e1a279f7f49f6dd0580788c040d973748ec4942dbe51ea8fbd05983cc919b78f0c6b92ef3292ae29db875\",\n    \"0x81a2b74b2118923f34139a102f3d95e7eee11c4c2929c2576dee200a5abfd364606158535a6c9e4178a6a83dbb65f3c4\",\n    \"0x8913f281d8927f2b45fc815d0f7104631cb7f5f7278a316f1327d670d15868daadd2a64e3eb98e1f53fe7e300338cc80\",\n    \"0xa6f815fba7ef9af7fbf45f93bc952e8b351f5de6568a27c7c47a00cb39a254c6b31753794f67940fc7d2e9cc581529f4\",\n    \"0xb3722a15c66a0014ce4d082de118def8d39190c15678a472b846225585f3a83756ae1b255b2e3f86a26168878e4773b2\",\n    \"0x817ae61ab3d0dd5b6e24846b5a5364b1a7dc2e77432d9fed587727520ae2f307264ea0948c91ad29f0aea3a11ff38624\",\n    \"0xb3db467464415fcad36dc1de2d6ba7686772a577cc2619242ac040d6734881a45d3b40ed4588db124e4289cfeec4bbf6\",\n    \"0xad66a14f5a54ac69603b16e5f1529851183da77d3cc60867f10aea41339dd5e06a5257982e9e90a352cdd32750f42ee4\",\n    \"0xadafa3681ef45d685555601a25a55cf23358319a17f61e2179e704f63df83a73bdd298d12cf6cef86db89bd17119e11d\",\n    \"0xa379dc44cb6dd3b9d378c07b2ec654fec7ca2f272de6ba895e3d00d20c9e4c5550498a843c8ac67e4221db2115bedc1c\",\n    \"0xb7bf81c267a78efc6b9e5a904574445a6487678d7ef70054e3e93ea6a23f966c2b68787f9164918e3b16d2175459ed92\",\n    \"0xb41d66a13a4afafd5760062b77f79de7e6ab8ccacde9c6c5116a6d886912fb491dc027af435b1b44aacc6af7b3c887f2\",\n    \"0x9904d23a7c1c1d2e4bab85d69f283eb0a8e26d46e8b7b30224438015c936729b2f0af7c7c54c03509bb0500acb42d8a4\",\n    \"0xae30d65e9e20c3bfd603994ae2b175ff691d51f3e24b2d058b3b8556d12ca4c75087809062dddd4aaac81c94d15d8a17\",\n    \"0x9245162fab42ac01527424f6013310c3eb462982518debef6c127f46ba8a06c705d7dc9f0a41e796ba8d35d60ae6cc64\",\n    \"0x87fab853638d7a29a20f3ba2b1a7919d023e9415bfa78ebb27973d8cbc7626f584dc5665d2e7ad71f1d760eba9700d88\",\n    \"0x85aac46ecd330608e5272430970e6081ff02a571e8ea444f1e11785ea798769634a22a142d0237f67b75369d3c484a8a\",\n    \"0x938c85ab14894cc5dfce3d80456f189a2e98eddbc8828f4ff6b1df1dcb7b42b17ca2ff40226a8a1390a95d63dca698dd\",\n    \"0xa18ce1f846e3e3c4d846822f60271eecf0f5d7d9f986385ac53c5ace9589dc7c0188910448c19b91341a1ef556652fa9\",\n    \"0x8611608a9d844f0e9d7584ad6ccf62a5087a64f764caf108db648a776b5390feb51e5120f0ef0e9e11301af3987dd7dc\",\n    \"0x8106333ba4b4de8d1ae43bc9735d3fea047392e88efd6a2fa6f7b924a18a7a265ca6123c3edc0f36307dd7fb7fe89257\",\n    \"0xa91426fa500951ff1b051a248c050b7139ca30dde8768690432d597d2b3c4357b11a577be6b455a1c5d145264dcf81fc\",\n    \"0xb7f9f90e0e450f37b081297f7f651bad0496a8b9afd2a4cf4120a2671aaaa8536dce1af301258bfbfdb122afa44c5048\",\n    \"0x84126da6435699b0c09fa4032dec73d1fca21d2d19f5214e8b0bea43267e9a8dd1fc44f8132d8315e734c8e2e04d7291\",\n    \"0xaff064708103884cb4f1a3c1718b3fc40a238d35cf0a7dc24bdf9823693b407c70da50df585bf5bc4e9c07d1c2d203e8\",\n    \"0xa8b40fc6533752983a5329c31d376c7a5c13ce6879cc7faee648200075d9cd273537001fb4c86e8576350eaac6ba60c2\",\n    \"0xa02db682bdc117a84dcb9312eb28fcbde12d49f4ce915cc92c610bb6965ec3cc38290f8c5b5ec70afe153956692cda95\",\n    \"0x86decd22b25d300508472c9ce75d3e465b737e7ce13bc0fcce32835e54646fe12322ba5bc457be18bfd926a1a6ca4a38\",\n    \"0xa18666ef65b8c2904fd598791f5627207165315a85ee01d5fb0e6b2e10bdd9b00babc447da5bd63445e3337de33b9b89\",\n    \"0x89bb0c06effadefdaf34ffe4b123e1678a90d4451ee856c863df1e752eef41fd984689ded8f0f878bf8916d5dd8e8024\",\n    \"0x97cfcba08ebec05d0073992a66b1d7d6fb9d95871f2cdc36db301f78bf8069294d1c259efef5c93d20dc937eedae3a1a\",\n    \"0xac2643b14ece79dcb2e289c96776a47e2bebd40dd6dc74fd035df5bb727b5596f40e3dd2d2202141e69b0993717ede09\",\n    \"0xa5e6fd88a2f9174d9bd4c6a55d9c30974be414992f22aa852f552c7648f722ed8077acf5aba030abd47939bb451b2c60\",\n    \"0x8ad40a612824a7994487731a40b311b7349038c841145865539c6ada75c56de6ac547a1c23df190e0caaafecddd80ccc\",\n    \"0x953a7cea1d857e09202c438c6108060961f195f88c32f0e012236d7a4b39d840c61b162ec86436e8c38567328bea0246\",\n    \"0x80d8b47a46dae1868a7b8ccfe7029445bbe1009dad4a6c31f9ef081be32e8e1ac1178c3c8fb68d3e536c84990cc035b1\",\n    \"0x81ecd99f22b3766ce0aca08a0a9191793f68c754fdec78b82a4c3bdc2db122bbb9ebfd02fc2dcc6e1567a7d42d0cc16a\",\n    \"0xb1dd0446bccc25846fb95d08c1c9cc52fb51c72c4c5d169ffde56ecfe800f108dc1106d65d5c5bd1087c656de3940b63\",\n    \"0xb87547f0931e164e96de5c550ca5aa81273648fe34f6e193cd9d69cf729cb432e17aa02e25b1c27a8a0d20a3b795e94e\",\n    \"0x820a94e69a927e077082aae66f6b292cfbe4589d932edf9e68e268c9bd3d71ef76cf7d169dd445b93967c25db11f58f1\",\n    \"0xb0d07ddf2595270c39adfa0c8cf2ab1322979b0546aa4d918f641be53cd97f36c879bb75d205e457c011aca3bbd9f731\",\n    \"0x8700b876b35b4b10a8a9372c5230acecd39539c1bb87515640293ad4464a9e02929d7d6a6a11112e8a29564815ac0de4\",\n    \"0xa61a601c5bb27dcb97e37c8e2b9ce479c6b192a5e04d9ed5e065833c5a1017ee5f237b77d1a17be5d48f8e7cc0bcacf6\",\n    \"0x92fb88fe774c1ba1d4a08cae3c0e05467ad610e7a3f1d2423fd47751759235fe0a3036db4095bd6404716aa03820f484\",\n    \"0xb274f140d77a3ce0796f5e09094b516537ccaf27ae1907099bff172e6368ba85e7c3ef8ea2a07457cac48ae334da95b3\",\n    \"0xb2292d9181f16581a9a9142490b2bdcdfb218ca6315d1effc8592100d792eb89d5356996c890441f04f2b4a95763503e\",\n    \"0x8897e73f576d86bc354baa3bd96e553107c48cf5889dcc23c5ba68ab8bcd4e81f27767be2233fdfa13d39f885087e668\",\n    \"0xa29eac6f0829791c728d71abc49569df95a4446ecbfc534b39f24f56c88fe70301838dfc1c19751e7f3c5c1b8c6af6a0\",\n    \"0x9346dc3720adc5df500a8df27fd9c75ef38dc5c8f4e8ed66983304750e66d502c3c59b8e955be781b670a0afc70a2167\",\n    \"0x9566d534e0e30a5c5f1428665590617e95fd05d45f573715f58157854ad596ece3a3cfec61356aee342308d623e029d5\",\n    \"0xa464fb8bffe6bd65f71938c1715c6e296cc6d0311a83858e4e7eb5873b7f2cf0c584d2101e3407b85b64ca78b2ac93ce\",\n    \"0xb54088f7217987c87e9498a747569ac5b2f8afd5348f9c45bf3fd9fbf713a20f495f49c8572d087efe778ac7313ad6d3\",\n    \"0x91fa9f5f8000fe050f5b224d90b59fcce13c77e903cbf98ded752e5b3db16adb2bc1f8c94be48b69f65f1f1ad81d6264\",\n    \"0x92d04a5b0ac5d8c8e313709b432c9434ecd3e73231f01e9b4e7952b87df60cbfa97b5dedd2200bd033b4b9ea8ba45cc1\",\n    \"0xa94b90ad3c3d6c4bbe169f8661a790c40645b40f0a9d1c7220f01cf7fc176e04d80bab0ced9323fcafb93643f12b2760\",\n    \"0x94d86149b9c8443b46196f7e5a3738206dd6f3be7762df488bcbb9f9ee285a64c997ed875b7b16b26604fa59020a8199\",\n    \"0x82efe4ae2c50a2d7645240c173a047f238536598c04a2c0b69c96e96bd18e075a99110f1206bc213f39edca42ba00cc1\",\n    \"0xab8667685f831bc14d4610f84a5da27b4ea5b133b4d991741a9e64dceb22cb64a3ce8f1b6e101d52af6296df7127c9ad\",\n    \"0x83ba433661c05dcc5d562f4a9a261c8110dac44b8d833ae1514b1fc60d8b4ee395b18804baea04cb10adb428faf713c3\",\n    \"0xb5748f6f660cc5277f1211d2b8649493ed8a11085b871cd33a5aea630abd960a740f08c08be5f9c21574600ac9bf5737\",\n    \"0xa5c8dd12af48fb710642ad65ebb97ca489e8206741807f7acfc334f8035d3c80593b1ff2090c9bb7bd138f0c48714ca8\",\n    \"0xa2b382fd5744e3babf454b1d806cc8783efeb4761bc42b6914ea48a46a2eae835efbe0a18262b6bc034379e03cf1262b\",\n    \"0xb3145ffaf603f69f15a64936d32e3219eea5ed49fdfd2f5bf40ea0dfd974b36fb6ff12164d4c2282d892db4cf3ff3ce1\",\n    \"0x87a316fb213f4c5e30c5e3face049db66be4f28821bd96034714ec23d3e97849d7b301930f90a4323c7ccf53de23050c\",\n    \"0xb9de09a919455070fed6220fc179c8b7a4c753062bcd27acf28f5b9947a659c0b364298daf7c85c4ca6fca7f945add1f\",\n    \"0x806fbd98d411b76979464c40ad88bc07a151628a27fcc1012ba1dfbaf5b5cc9d962fb9b3386008978a12515edce934bc\",\n    \"0xa15268877fae0d21610ae6a31061ed7c20814723385955fac09fdc9693a94c33dea11db98bb89fdfe68f933490f5c381\",\n    \"0x8d633fb0c4da86b2e0b37d8fad5972d62bff2ac663c5ec815d095cd4b7e1fe66ebef2a2590995b57eaf941983c7ad7a4\",\n    \"0x8139e5dd9cf405e8ef65f11164f0440827d98389ce1b418b0c9628be983a9ddd6cf4863036ccb1483b40b8a527acd9ed\",\n    \"0x88b15fa94a08eac291d2b94a2b30eb851ff24addf2cc30b678e72e32cfcb3424cf4b33aa395d741803f3e578ddf524de\",\n    \"0xb5eaf0c8506e101f1646bcf049ee38d99ea1c60169730da893fd6020fd00a289eb2f415947e44677af49e43454a7b1be\",\n    \"0x8489822ad0647a7e06aa2aa5595960811858ddd4542acca419dd2308a8c5477648f4dd969a6740bb78aa26db9bfcc555\",\n    \"0xb1e9a7b9f3423c220330d45f69e45fa03d7671897cf077f913c252e3e99c7b1b1cf6d30caad65e4228d5d7b80eb86e5e\",\n    \"0xb28fe9629592b9e6a55a1406903be76250b1c50c65296c10c5e48c64b539fb08fe11f68cf462a6edcbba71b0cee3feb2\",\n    \"0xa41acf96a02c96cd8744ff6577c244fc923810d17ade133587e4c223beb7b4d99fa56eae311a500d7151979267d0895c\",\n    \"0x880798938fe4ba70721be90e666dfb62fcab4f3556fdb7b0dc8ec5bc34f6b4513df965eae78527136eb391889fe2caf9\",\n    \"0x98d4d89d358e0fb7e212498c73447d94a83c1b66e98fc81427ab13acddb17a20f52308983f3a5a8e0aaacec432359604\",\n    \"0x81430b6d2998fc78ba937a1639c6020199c52da499f68109da227882dc26d005b73d54c5bdcac1a04e8356a8ca0f7017\",\n    \"0xa8d906a4786455eb74613aba4ce1c963c60095ffb8658d368df9266fdd01e30269ce10bf984e7465f34b4fd83beba26a\",\n    \"0xaf54167ac1f954d10131d44a8e0045df00d581dd9e93596a28d157543fbe5fb25d213806ed7fb3cba6b8f5b5423562db\",\n    \"0x8511e373a978a12d81266b9afbd55035d7bc736835cfa921903a92969eeba3624437d1346b55382e61415726ab84a448\",\n    \"0x8cf43eea93508ae586fa9a0f1354a1e16af659782479c2040874a46317f9e8d572a23238efa318fdfb87cc63932602b7\",\n    \"0xb0bdd3bacff077173d302e3a9678d1d37936188c7ecc34950185af6b462b7c679815176f3cce5db19aac8b282f2d60ad\",\n    \"0xa355e9b87f2f2672052f5d4d65b8c1c827d24d89b0d8594641fccfb69aef1b94009105f3242058bb31c8bf51caae5a41\",\n    \"0xb8baa9e4b950b72ff6b88a6509e8ed1304bc6fd955748b2e59a523a1e0c5e99f52aec3da7fa9ff407a7adf259652466c\",\n    \"0x840bc3dbb300ea6f27d1d6dd861f15680bd098be5174f45d6b75b094d0635aced539fa03ddbccb453879de77fb5d1fe9\",\n    \"0xb4bc7e7e30686303856472bae07e581a0c0bfc815657c479f9f5931cff208d5c12930d2fd1ff413ebd8424bcd7a9b571\",\n    \"0x89b5d514155d7999408334a50822508b9d689add55d44a240ff2bdde2eee419d117031f85e924e2a2c1ca77db9b91eea\",\n    \"0xa8604b6196f87a04e1350302e8aa745bba8dc162115d22657b37a1d1a98cb14876ddf7f65840b5dbd77e80cd22b4256c\",\n    \"0x83cb7acdb9e03247515bb2ce0227486ccf803426717a14510f0d59d45e998b245797d356f10abca94f7a14e1a2f0d552\",\n    \"0xaeb3266a9f16649210ab2df0e1908ac259f34ce1f01162c22b56cf1019096ee4ea5854c36e30bb2feb06c21a71e8a45c\",\n    \"0x89e72e86edf2aa032a0fc9acf4d876a40865fbb2c8f87cb7e4d88856295c4ac14583e874142fd0c314a49aba68c0aa3c\",\n    \"0x8c3576eba0583c2a7884976b4ed11fe1fda4f6c32f6385d96c47b0e776afa287503b397fa516a455b4b8c3afeedc76db\",\n    \"0xa31e5b633bda9ffa174654fee98b5d5930a691c3c42fcf55673d927dbc8d91c58c4e42e615353145431baa646e8bbb30\",\n    \"0x89f2f3f7a8da1544f24682f41c68114a8f78c86bd36b066e27da13acb70f18d9f548773a16bd8e24789420e17183f137\",\n    \"0xada27fa4e90a086240c9164544d2528621a415a5497badb79f8019dc3dce4d12eb6b599597e47ec6ac39c81efda43520\",\n    \"0x90dc1eb21bf21c0187f359566fc4bf5386abea52799306a0e5a1151c0817c5f5bc60c86e76b1929c092c0f3ff48cedd2\",\n    \"0xb702a53ebcc17ae35d2e735a347d2c700e9cbef8eadbece33cac83df483b2054c126593e1f462cfc00a3ce9d737e2af5\",\n    \"0x9891b06455ec925a6f8eafffba05af6a38cc5e193acaaf74ffbf199df912c5197106c5e06d72942bbb032ce277b6417f\",\n    \"0x8c0ee71eb01197b019275bcf96cae94e81d2cdc3115dbf2d8e3080074260318bc9303597e8f72b18f965ad601d31ec43\",\n    \"0x8aaf580aaf75c1b7a5f99ccf60503506e62058ef43b28b02f79b8536a96be3f019c9f71caf327b4e6730134730d1bef5\",\n    \"0xae6f9fc21dd7dfa672b25a87eb0a41644f7609fab5026d5cedb6e43a06dbbfd6d6e30322a2598c8dedde88c52eaed626\",\n    \"0x8159b953ffece5693edadb2e906ebf76ff080ee1ad22698950d2d3bfc36ac5ea78f58284b2ca180664452d55bd54716c\",\n    \"0xab7647c32ca5e9856ac283a2f86768d68de75ceeba9e58b74c5324f8298319e52183739aba4340be901699d66ac9eb3f\",\n    \"0xa4d85a5701d89bcfaf1572db83258d86a1a0717603d6f24ac2963ffcf80f1265e5ab376a4529ca504f4396498791253c\",\n    \"0x816080c0cdbfe61b4d726c305747a9eb58ac26d9a35f501dd32ba43c098082d20faf3ccd41aad24600aa73bfa453dfac\",\n    \"0x84f3afac024f576b0fd9acc6f2349c2fcefc3f77dbe5a2d4964d14b861b88e9b1810334b908cf3427d9b67a8aee74b18\",\n    \"0x94b390655557b1a09110018e9b5a14490681ade275bdc83510b6465a1218465260d9a7e2a6e4ec700f58c31dc3659962\",\n    \"0xa8c66826b1c04a2dd4c682543242e7a57acae37278bd09888a3d17747c5b5fec43548101e6f46d703638337e2fd3277b\",\n    \"0x86e6f4608a00007fa533c36a5b054c5768ccafe41ad52521d772dcae4c8a4bcaff8f7609be30d8fab62c5988cbbb6830\",\n    \"0x837da4cf09ae8aa0bceb16f8b3bfcc3b3367aecac9eed6b4b56d7b65f55981ef066490764fb4c108792623ecf8cad383\",\n    \"0x941ff3011462f9b5bf97d8cbdb0b6f5d37a1b1295b622f5485b7d69f2cb2bcabc83630dae427f0259d0d9539a77d8424\",\n    \"0xb99e5d6d82aa9cf7d5970e7f710f4039ac32c2077530e4c2779250c6b9b373bc380adb0a03b892b652f649720672fc8c\",\n    \"0xa791c78464b2d65a15440b699e1e30ebd08501d6f2720adbc8255d989a82fcded2f79819b5f8f201bed84a255211b141\",\n    \"0x84af7ad4a0e31fcbb3276ab1ad6171429cf39adcf78dc03750dc5deaa46536d15591e26d53e953dfb31e1622bc0743ab\",\n    \"0xa833e62fe97e1086fae1d4917fbaf09c345feb6bf1975b5cb863d8b66e8d621c7989ab3dbecda36bc9eaffc5eaa6fa66\",\n    \"0xb4ef79a46a2126f53e2ebe62770feb57fd94600be29459d70a77c5e9cc260fa892be06cd60f886bf48459e48eb50d063\",\n    \"0xb43b8f61919ea380bf151c294e54d3a3ff98e20d1ee5efbfe38aa2b66fafbc6a49739793bd5cb1c809f8b30466277c3a\",\n    \"0xab37735af2412d2550e62df9d8b3b5e6f467f20de3890bf56faf1abf2bf3bd1d98dc3fa0ad5e7ab3fce0fa20409eb392\",\n    \"0x82416b74b1551d484250d85bb151fabb67e29cce93d516125533df585bc80779ab057ea6992801a3d7d5c6dcff87a018\",\n    \"0x8145d0787f0e3b5325190ae10c1d6bee713e6765fb6a0e9214132c6f78f4582bb2771aaeae40d3dad4bafb56bf7e36d8\",\n    \"0xb6935886349ecbdd5774e12196f4275c97ec8279fdf28ccf940f6a022ebb6de8e97d6d2173c3fe402cbe9643bed3883b\",\n    \"0x87ef9b4d3dc71ac86369f8ed17e0dd3b91d16d14ae694bc21a35b5ae37211b043d0e36d8ff07dcc513fb9e6481a1f37f\",\n    \"0xae1d0ded32f7e6f1dc8fef495879c1d9e01826f449f903c1e5034aeeabc5479a9e323b162b688317d46d35a42d570d86\",\n    \"0xa40d16497004db4104c6794e2f4428d75bdf70352685944f3fbe17526df333e46a4ca6de55a4a48c02ecf0bde8ba03c0\",\n    \"0x8d45121efba8cc308a498e8ee39ea6fa5cae9fb2e4aab1c2ff9d448aa8494ccbec9a078f978a86fcd97b5d5e7be7522a\",\n    \"0xa8173865c64634ba4ac2fa432740f5c05056a9deaf6427cb9b4b8da94ca5ddbc8c0c5d3185a89b8b28878194de9cdfcd\",\n    \"0xb6ec06a74d690f6545f0f0efba236e63d1fdfba54639ca2617408e185177ece28901c457d02b849fd00f1a53ae319d0a\",\n    \"0xb69a12df293c014a40070e3e760169b6f3c627caf9e50b35a93f11ecf8df98b2bc481b410eecb7ab210bf213bbe944de\",\n    \"0x97e7dc121795a533d4224803e591eef3e9008bab16f12472210b73aaf77890cf6e3877e0139403a0d3003c12c8f45636\",\n    \"0xacdfa6fdd4a5acb7738cc8768f7cba84dbb95c639399b291ae8e4e63df37d2d4096900a84d2f0606bf534a9ccaa4993f\",\n    \"0x86ee253f3a9446a33e4d1169719b7d513c6b50730988415382faaf751988c10a421020609f7bcdef91be136704b906e2\",\n    \"0xaac9438382a856caf84c5a8a234282f71b5fc5f65219103b147e7e6cf565522285fbfd7417b513bdad8277a00f652ca1\",\n    \"0x83f3799d8e5772527930f5dc071a2e0a65471618993ec8990a96ccdeee65270e490bda9d26bb877612475268711ffd80\",\n    \"0x93f28a81ac8c0ec9450b9d762fae9c7f8feaace87a6ee6bd141ef1d2d0697ef1bbd159fe6e1de640dbdab2b0361fca8a\",\n    \"0xa0825c95ba69999b90eac3a31a3fd830ea4f4b2b7409bde5f202b61d741d6326852ce790f41de5cb0eccec7af4db30c1\",\n    \"0x83924b0e66233edd603c3b813d698daa05751fc34367120e3cf384ea7432e256ccee4d4daf13858950549d75a377107d\",\n    \"0x956fd9fa58345277e06ba2ec72f49ed230b8d3d4ff658555c52d6cddeb84dd4e36f1a614f5242d5ca0192e8daf0543c2\",\n    \"0x944869912476baae0b114cced4ff65c0e4c90136f73ece5656460626599051b78802df67d7201c55d52725a97f5f29fe\",\n    \"0x865cb25b64b4531fb6fe4814d7c8cd26b017a6c6b72232ff53defc18a80fe3b39511b23f9e4c6c7249d06e03b2282ed2\",\n    \"0x81e09ff55214960775e1e7f2758b9a6c4e4cd39edf7ec1adfaad51c52141182b79fe2176b23ddc7df9fd153e5f82d668\",\n    \"0xb31006896f02bc90641121083f43c3172b1039334501fbaf1672f7bf5d174ddd185f945adf1a9c6cf77be34c5501483d\",\n    \"0x88b92f6f42ae45e9f05b16e52852826e933efd0c68b0f2418ac90957fd018df661bc47c8d43c2a7d7bfcf669dab98c3c\",\n    \"0x92fc68f595853ee8683930751789b799f397135d002eda244fe63ecef2754e15849edde3ba2f0cc8b865c9777230b712\",\n    \"0x99ca06a49c5cd0bb097c447793fcdd809869b216a34c66c78c7e41e8c22f05d09168d46b8b1f3390db9452d91bc96dea\",\n    \"0xb48b9490a5d65296802431852d548d81047bbefc74fa7dc1d4e2a2878faacdfcb365ae59209cb0ade01901a283cbd15d\",\n    \"0xaff0fdbef7c188b120a02bc9085d7b808e88f73973773fef54707bf2cd772cd066740b1b6f4127b5c349f657bd97e738\",\n    \"0x966fd4463b4f43dd8ccba7ad50baa42292f9f8b2e70da23bb6780e14155d9346e275ef03ddaf79e47020dcf43f3738bd\",\n    \"0x9330c3e1fadd9e08ac85f4839121ae20bbeb0a5103d84fa5aadbd1213805bdcda67bf2fb75fc301349cbc851b5559d20\",\n    \"0x993bb99867bd9041a71a55ad5d397755cfa7ab6a4618fc526179bfc10b7dc8b26e4372fe9a9b4a15d64f2b63c1052dda\",\n    \"0xa29b59bcfab51f9b3c490a3b96f0bf1934265c315349b236012adbd64a56d7f6941b2c8cc272b412044bc7731f71e1dc\",\n    \"0xa65c9cefe1fc35d089fe8580c2e7671ebefdb43014ac291528ff4deefd4883fd4df274af83711dad610dad0d615f9d65\",\n    \"0x944c78c56fb227ae632805d448ca3884cd3d2a89181cead3d2b7835e63297e6d740aa79a112edb1d4727824991636df5\",\n    \"0xa73d782da1db7e4e65d7b26717a76e16dd9fab4df65063310b8e917dc0bc24e0d6755df5546c58504d04d9e68c3b474a\",\n    \"0xaf80f0b87811ae3124f68108b4ca1937009403f87928bbc53480e7c5408d072053ace5eeaf5a5aba814dab8a45502085\",\n    \"0x88aaf1acfc6e2e19b8387c97da707cb171c69812fefdd4650468e9b2c627bd5ccfb459f4d8e56bdfd84b09ddf87e128f\",\n    \"0x92c97276ff6f72bab6e9423d02ad6dc127962dbce15a0dd1e4a393b4510c555df6aa27be0f697c0d847033a9ca8b8dfd\",\n    \"0xa0e07d43d96e2d85b6276b3c60aadb48f0aedf2de8c415756dc597249ea64d2093731d8735231dadc961e5682ac59479\",\n    \"0xadc9e6718a8f9298957d1da3842a7751c5399bbdf56f8de6c1c4bc39428f4aee6f1ba6613d37bf46b9403345e9d6fc81\",\n    \"0x951da434da4b20d949b509ceeba02e24da7ed2da964c2fcdf426ec787779c696b385822c7dbea4df3e4a35921f1e912c\",\n    \"0xa04cbce0d2b2e87bbf038c798a12ec828423ca6aca08dc8d481cf6466e3c9c73d4d4a7fa47df9a7e2e15aae9e9f67208\",\n    \"0x8f855cca2e440d248121c0469de1f94c2a71b8ee2682bbad3a78243a9e03da31d1925e6760dbc48a1957e040fae9abe8\",\n    \"0xb642e5b17c1df4a4e101772d73851180b3a92e9e8b26c918050f51e6dd3592f102d20b0a1e96f0e25752c292f4c903ff\",\n    \"0xa92454c300781f8ae1766dbbb50a96192da7d48ef4cbdd72dd8cbb44c6eb5913c112cc38e9144615fdc03684deb99420\",\n    \"0x8b74f7e6c2304f8e780df4649ef8221795dfe85fdbdaa477a1542d135b75c8be45bf89adbbb6f3ddf54ca40f02e733e9\",\n    \"0x85cf66292cbb30cec5fd835ab10c9fcb3aea95e093aebf123e9a83c26f322d76ebc89c4e914524f6c5f6ee7d74fc917d\",\n    \"0xae0bfe0cdc97c09542a7431820015f2d16067b30dca56288013876025e81daa8c519e5e347268e19aa1a85fa1dc28793\",\n    \"0x921322fc6a47dc091afa0ad6df18ed14cde38e48c6e71550aa513918b056044983aee402de21051235eecf4ce8040fbe\",\n    \"0x96c030381e97050a45a318d307dcb3c8377b79b4dd5daf6337cded114de26eb725c14171b9b8e1b3c08fe1f5ea6b49e0\",\n    \"0x90c23b86b6111818c8baaf53a13eaee1c89203b50e7f9a994bf0edf851919b48edbac7ceef14ac9414cf70c486174a77\",\n    \"0x8bf6c301240d2d1c8d84c71d33a6dfc6d9e8f1cfae66d4d0f7a256d98ae12b0bcebfa94a667735ee89f810bcd7170cff\",\n    \"0xa41a4ffbbea0e36874d65c009ee4c3feffff322f6fc0e30d26ee4dbc1f46040d05e25d9d0ecb378cef0d24a7c2c4b850\",\n    \"0xa8d4cdd423986bb392a0a92c12a8bd4da3437eec6ef6af34cf5310944899287452a2eb92eb5386086d5063381189d10e\",\n    \"0xa81dd26ec057c4032a4ed7ad54d926165273ed51d09a1267b2e477535cf6966835a257c209e4e92d165d74fa75695fa3\",\n    \"0x8d7f708c3ee8449515d94fc26b547303b53d8dd55f177bc3b25d3da2768accd9bc8e9f09546090ebb7f15c66e6c9c723\",\n    \"0x839ba65cffcd24cfffa7ab3b21faabe3c66d4c06324f07b2729c92f15cad34e474b0f0ddb16cd652870b26a756b731d3\",\n    \"0x87f1a3968afec354d92d77e2726b702847c6afcabb8438634f9c6f7766de4c1504317dc4fa9a4a735acdbf985e119564\",\n    \"0x91a8a7fd6542f3e0673f07f510d850864b34ac087eb7eef8845a1d14b2b1b651cbdc27fa4049bdbf3fea54221c5c8549\",\n    \"0xaef3cf5f5e3a2385ead115728d7059e622146c3457d266c612e778324b6e06fbfb8f98e076624d2f3ce1035d65389a07\",\n    \"0x819915d6232e95ccd7693fdd78d00492299b1983bc8f96a08dcb50f9c0a813ed93ae53c0238345d5bea0beda2855a913\",\n    \"0x8e9ba68ded0e94935131b392b28218315a185f63bf5e3c1a9a9dd470944509ca0ba8f6122265f8da851b5cc2abce68f1\",\n    \"0xb28468e9b04ee9d69003399a3cf4457c9bf9d59f36ab6ceeb8e964672433d06b58beeea198fedc7edbaa1948577e9fa2\",\n    \"0xa633005e2c9f2fd94c8bce2dd5bb708fe946b25f1ec561ae65e54e15cdd88dc339f1a083e01f0d39610c8fe24151aaf0\",\n    \"0x841d0031e22723f9328dd993805abd13e0c99b0f59435d2426246996b08d00ce73ab906f66c4eab423473b409e972ce0\",\n    \"0x85758d1b084263992070ec8943f33073a2d9b86a8606672550c17545507a5b3c88d87382b41916a87ee96ff55a7aa535\",\n    \"0x8581b06b0fc41466ef94a76a1d9fb8ae0edca6d018063acf6a8ca5f4b02d76021902feba58972415691b4bdbc33ae3b4\",\n    \"0x83539597ff5e327357ee62bc6bf8c0bcaec2f227c55c7c385a4806f0d37fb461f1690bad5066b8a5370950af32fafbef\",\n    \"0xaee3557290d2dc10827e4791d00e0259006911f3f3fce4179ed3c514b779160613eca70f720bff7804752715a1266ffa\",\n    \"0xb48d2f0c4e90fc307d5995464e3f611a9b0ef5fe426a289071f4168ed5cc4f8770c9332960c2ca5c8c427f40e6bb389f\",\n    \"0x847af8973b4e300bb06be69b71b96183fd1a0b9d51b91701bef6fcfde465068f1eb2b1503b07afda380f18d69de5c9e1\",\n    \"0xa70a6a80ce407f07804c0051ac21dc24d794b387be94eb24e1db94b58a78e1bcfb48cd0006db8fc1f9bedaece7a44fbe\",\n    \"0xb40e942b8fa5336910ff0098347df716bff9d1fa236a1950c16eeb966b3bc1a50b8f7b0980469d42e75ae13ced53cead\",\n    \"0xb208fabaa742d7db3148515330eb7a3577487845abdb7bd9ed169d0e081db0a5816595c33d375e56aeac5b51e60e49d3\",\n    \"0xb7c8194b30d3d6ef5ab66ec88ad7ebbc732a3b8a41731b153e6f63759a93f3f4a537eab9ad369705bd730184bdbbdc34\",\n    \"0x9280096445fe7394d04aa1bc4620c8f9296e991cc4d6c131bd703cb1cc317510e6e5855ac763f4d958c5edfe7eebeed7\",\n    \"0xabc2aa4616a521400af1a12440dc544e3c821313d0ab936c86af28468ef8bbe534837e364598396a81cf8d06274ed5a6\",\n    \"0xb18ca8a3325adb0c8c18a666d4859535397a1c3fe08f95eebfac916a7a99bbd40b3c37b919e8a8ae91da38bc00fa56c0\",\n    \"0x8a40c33109ecea2a8b3558565877082f79121a432c45ec2c5a5e0ec4d1c203a6788e6b69cb37f1fd5b8c9a661bc5476d\",\n    \"0x88c47301dd30998e903c84e0b0f2c9af2e1ce6b9f187dab03528d44f834dc991e4c86d0c474a2c63468cf4020a1e24a0\",\n    \"0x920c832853e6ab4c851eecfa9c11d3acc7da37c823be7aa1ab15e14dfd8beb5d0b91d62a30cec94763bd8e4594b66600\",\n    \"0x98e1addbe2a6b8edc7f12ecb9be81c3250aeeca54a1c6a7225772ca66549827c15f3950d01b8eb44aecb56fe0fff901a\",\n    \"0x8cfb0fa1068be0ec088402f5950c4679a2eb9218c729da67050b0d1b2d7079f3ddf4bf0f57d95fe2a8db04bc6bcdb20c\",\n    \"0xb70f381aafe336b024120453813aeab70baac85b9c4c0f86918797b6aee206e6ed93244a49950f3d8ec9f81f4ac15808\",\n    \"0xa4c8edf4aa33b709a91e1062939512419711c1757084e46f8f4b7ed64f8e682f4e78b7135920c12f0eb0422fe9f87a6a\",\n    \"0xb4817e85fd0752d7ebb662d3a51a03367a84bac74ebddfba0e5af5e636a979500f72b148052d333b3dedf9edd2b4031b\",\n    \"0xa87430169c6195f5d3e314ff2d1c2f050e766fd5d2de88f5207d72dba4a7745bb86d0baca6e9ae156582d0d89e5838c7\",\n    \"0x991b00f8b104566b63a12af4826b61ce7aa40f4e5b8fff3085e7a99815bdb4471b6214da1e480214fac83f86a0b93cc5\",\n    \"0xb39966e3076482079de0678477df98578377a094054960ee518ef99504d6851f8bcd3203e8da5e1d4f6f96776e1fe6eb\",\n    \"0xa448846d9dc2ab7a0995fa44b8527e27f6b3b74c6e03e95edb64e6baa4f1b866103f0addb97c84bef1d72487b2e21796\",\n    \"0x894bec21a453ae84b592286e696c35bc30e820e9c2fd3e63dd4fbe629e07df16439c891056070faa490155f255bf7187\",\n    \"0xa9ec652a491b11f6a692064e955f3f3287e7d2764527e58938571469a1e29b5225b9415bd602a45074dfbfe9c131d6ca\",\n    \"0xb39d37822e6cbe28244b5f42ce467c65a23765bd16eb6447c5b3e942278069793763483dafd8c4dd864f8917aad357fe\",\n    \"0x88dba51133f2019cb266641c56101e3e5987d3b77647a2e608b5ff9113dfc5f85e2b7c365118723131fbc0c9ca833c9c\",\n    \"0xb566579d904b54ecf798018efcb824dccbebfc6753a0fd2128ac3b4bd3b038c2284a7c782b5ca6f310eb7ea4d26a3f0a\",\n    \"0xa97a55c0a492e53c047e7d6f9d5f3e86fb96f3dddc68389c0561515343b66b4bc02a9c0d5722dff1e3445308240b27f7\",\n    \"0xa044028ab4bcb9e1a2b9b4ca4efbf04c5da9e4bf2fff0e8bd57aa1fc12a71e897999c25d9117413faf2f45395dee0f13\",\n    \"0xa78dc461decbeaeed8ebd0909369b491a5e764d6a5645a7dac61d3140d7dc0062526f777b0eb866bff27608429ebbdde\",\n    \"0xb2c2a8991f94c39ca35fea59f01a92cb3393e0eccb2476dfbf57261d406a68bd34a6cff33ed80209991688c183609ef4\",\n    \"0x84189eefb521aff730a4fd3fd5b10ddfd29f0d365664caef63bb015d07e689989e54c33c2141dd64427805d37a7e546e\",\n    \"0x85ac80bd734a52235da288ff042dea9a62e085928954e8eacd2c751013f61904ed110e5b3afe1ab770a7e6485efb7b5e\",\n    \"0x9183a560393dcb22d0d5063e71182020d0fbabb39e32493eeffeb808df084aa243eb397027f150b55a247d1ed0c8513e\",\n    \"0x81c940944df7ecc58d3c43c34996852c3c7915ed185d7654627f7af62abae7e0048dd444a6c09961756455000bd96d09\",\n    \"0xaa8c34e164019743fd8284b84f06c3b449aae7996e892f419ee55d82ad548cb300fd651de329da0384243954c0ef6a60\",\n    \"0x89a7b7bdfc7e300d06a14d463e573d6296d8e66197491900cc9ae49504c4809ff6e61b758579e9091c61085ba1237b83\",\n    \"0x878d21809ba540f50bd11f4c4d9590fb6f3ab9de5692606e6e2ef4ed9d18520119e385be5e1f4b3f2e2b09c319f0e8fc\",\n    \"0x8eb248390193189cf0355365e630b782cd15751e672dc478b39d75dc681234dcd9309df0d11f4610dbb249c1e6be7ef9\",\n    \"0xa1d7fb3aecb896df3a52d6bd0943838b13f1bd039c936d76d03de2044c371d48865694b6f532393b27fd10a4cf642061\",\n    \"0xa34bca58a24979be442238cbb5ece5bee51ae8c0794dd3efb3983d4db713bc6f28a96e976ac3bd9a551d3ed9ba6b3e22\",\n    \"0x817c608fc8cacdd178665320b5a7587ca21df8bdd761833c3018b967575d25e3951cf3d498a63619a3cd2ad4406f5f28\",\n    \"0x86c95707db0495689afd0c2e39e97f445f7ca0edffad5c8b4cacd1421f2f3cc55049dfd504f728f91534e20383955582\",\n    \"0x99c3b0bb15942c301137765d4e19502f65806f3b126dc01a5b7820c87e8979bce6a37289a8f6a4c1e4637227ad5bf3bf\",\n    \"0x8aa1518a80ea8b074505a9b3f96829f5d4afa55a30efe7b4de4e5dbf666897fdd2cf31728ca45921e21a78a80f0e0f10\",\n    \"0x8d74f46361c79e15128ac399e958a91067ef4cec8983408775a87eca1eed5b7dcbf0ddf30e66f51780457413496c7f07\",\n    \"0xa41cde4a786b55387458a1db95171aca4fd146507b81c4da1e6d6e495527c3ec83fc42fad1dfe3d92744084a664fd431\",\n    \"0x8c352852c906fae99413a84ad11701f93f292fbf7bd14738814f4c4ceab32db02feb5eb70bc73898b0bc724a39d5d017\",\n    \"0xa5993046e8f23b71ba87b7caa7ace2d9023fb48ce4c51838813174880d918e9b4d2b0dc21a2b9c6f612338c31a289df8\",\n    \"0x83576d3324bf2d8afbfb6eaecdc5d767c8e22e7d25160414924f0645491df60541948a05e1f4202e612368e78675de8a\",\n    \"0xb43749b8df4b15bc9a3697e0f1c518e6b04114171739ef1a0c9c65185d8ec18e40e6954d125cbc14ebc652cf41ad3109\",\n    \"0xb4eebd5d80a7327a040cafb9ccdb12b2dfe1aa86e6bc6d3ac8a57fadfb95a5b1a7332c66318ff72ba459f525668af056\",\n    \"0x9198be7f1d413c5029b0e1c617bcbc082d21abe2c60ec8ce9b54ca1a85d3dba637b72fda39dae0c0ae40d047eab9f55a\",\n    \"0x8d96a0232832e24d45092653e781e7a9c9520766c3989e67bbe86b3a820c4bf621ea911e7cd5270a4bfea78b618411f6\",\n    \"0x8d7160d0ea98161a2d14d46ef01dff72d566c330cd4fabd27654d300e1bc7644c68dc8eabf2a20a59bfe7ba276545f9b\",\n    \"0xabb60fce29dec7ba37e3056e412e0ec3e05538a1fc0e2c68877378c867605966108bc5742585ab6a405ce0c962b285b6\",\n    \"0x8fabffa3ed792f05e414f5839386f6449fd9f7b41a47595c5d71074bd1bb3784cc7a1a7e1ad6b041b455035957e5b2dc\",\n    \"0x90ff017b4804c2d0533b72461436b10603ab13a55f86fd4ec11b06a70ef8166f958c110519ca1b4cc7beba440729fe2d\",\n    \"0xb340cfd120f6a4623e3a74cf8c32bfd7cd61a280b59dfd17b15ca8fae4d82f64a6f15fbde4c02f424debc72b7db5fe67\",\n    \"0x871311c9c7220c932e738d59f0ecc67a34356d1429fe570ca503d340c9996cb5ee2cd188fad0e3bd16e4c468ec1dbebd\",\n    \"0xa772470262186e7b94239ba921b29f2412c148d6f97c4412e96d21e55f3be73f992f1ad53c71008f0558ec3f84e2b5a7\",\n    \"0xb2a897dcb7ffd6257f3f2947ec966f2077d57d5191a88840b1d4f67effebe8c436641be85524d0a21be734c63ab5965d\",\n    \"0xa044f6eacc48a4a061fa149500d96b48cbf14853469aa4d045faf3dca973be1bd4b4ce01646d83e2f24f7c486d03205d\",\n    \"0x981af5dc2daa73f7fa9eae35a93d81eb6edba4a7f673b55d41f6ecd87a37685d31bb40ef4f1c469b3d72f2f18b925a17\",\n    \"0x912d2597a07864de9020ac77083eff2f15ceb07600f15755aba61251e8ce3c905a758453b417f04d9c38db040954eb65\",\n    \"0x9642b7f6f09394ba5e0805734ef6702c3eddf9eea187ba98c676d5bbaec0e360e3e51dc58433aaa1e2da6060c8659cb7\",\n    \"0x8ab3836e0a8ac492d5e707d056310c4c8e0489ca85eb771bff35ba1d658360084e836a6f51bb990f9e3d2d9aeb18fbb5\",\n    \"0x879e058e72b73bb1f4642c21ffdb90544b846868139c6511f299aafe59c2d0f0b944dffc7990491b7c4edcd6a9889250\",\n    \"0xb9e60b737023f61479a4a8fd253ed0d2a944ea6ba0439bbc0a0d3abf09b0ad1f18d75555e4a50405470ae4990626f390\",\n    \"0xb9c2535d362796dcd673640a9fa2ebdaec274e6f8b850b023153b0a7a30fffc87f96e0b72696f647ebe7ab63099a6963\",\n    \"0x94aeff145386a087b0e91e68a84a5ede01f978f9dd9fe7bebca78941938469495dc30a96bba9508c0d017873aeea9610\",\n    \"0x98b179f8a3d9f0d0a983c30682dd425a2ddc7803be59bd626c623c8951a5179117d1d2a68254c95c9952989877d0ee55\",\n    \"0x889ecf5f0ee56938273f74eb3e9ecfb5617f04fb58e83fe4c0e4aef51615cf345bc56f3f61b17f6eed3249d4afd54451\",\n    \"0xa0f2b2c39bcea4b50883e2587d16559e246248a66ecb4a4b7d9ab3b51fb39fe98d83765e087eee37a0f86b0ba4144c02\",\n    \"0xb2a61e247ed595e8a3830f7973b07079cbda510f28ad8c78c220b26cb6acde4fbb5ee90c14a665f329168ee951b08cf0\",\n    \"0x95bd0fcfb42f0d6d8a8e73d7458498a85bcddd2fb132fd7989265648d82ac2707d6d203fac045504977af4f0a2aca4b7\",\n    \"0x843e5a537c298666e6cf50fcc044f13506499ef83c802e719ff2c90e85003c132024e04711be7234c04d4b0125512d5d\",\n    \"0xa46d1797c5959dcd3a5cfc857488f4d96f74277c3d13b98b133620192f79944abcb3a361d939a100187f1b0856eae875\",\n    \"0xa1c7786736d6707a48515c38660615fcec67eb8a2598f46657855215f804fd72ab122d17f94fcffad8893f3be658dca7\",\n    \"0xb23dc9e610abc7d8bd21d147e22509a0fa49db5be6ea7057b51aae38e31654b3aa044df05b94b718153361371ba2f622\",\n    \"0xb00cc8f257d659c22d30e6d641f79166b1e752ea8606f558e4cad6fc01532e8319ea4ee12265ba4140ac45aa4613c004\",\n    \"0xac7019af65221b0cc736287b32d7f1a3561405715ba9a6a122342e04e51637ba911c41573de53e4781f2230fdcb2475f\",\n    \"0x81a630bc41b3da8b3eb4bf56cba10cd9f93153c3667f009dc332287baeb707d505fb537e6233c8e53d299ec0f013290c\",\n    \"0xa6b7aea5c545bb76df0f230548539db92bc26642572cb7dd3d5a30edca2b4c386f44fc8466f056b42de2a452b81aff5b\",\n    \"0x8271624ff736b7b238e43943c81de80a1612207d32036d820c11fc830c737972ccc9c60d3c2359922b06652311e3c994\",\n    \"0x8a684106458cb6f4db478170b9ad595d4b54c18bf63b9058f095a2fa1b928c15101472c70c648873d5887880059ed402\",\n    \"0xa5cc3c35228122f410184e4326cf61a37637206e589fcd245cb5d0cec91031f8f7586b80503070840fdfd8ce75d3c88b\",\n    \"0x9443fc631aed8866a7ed220890911057a1f56b0afe0ba15f0a0e295ab97f604b134b1ed9a4245e46ee5f9a93aa74f731\",\n    \"0x984b6f7d79835dffde9558c6bb912d992ca1180a2361757bdba4a7b69dc74b056e303adc69fe67414495dd9c2dd91e64\",\n    \"0xb15a5c8cba5de080224c274d31c68ed72d2a7126d347796569aef0c4e97ed084afe3da4d4b590b9dda1a07f0c2ff3dfb\",\n    \"0x991708fe9650a1f9a4e43938b91d45dc68c230e05ee999c95dbff3bf79b1c1b2bb0e7977de454237c355a73b8438b1d9\",\n    \"0xb4f7edc7468b176a4a7c0273700c444fa95c726af6697028bed4f77eee887e3400f9c42ee15b782c0ca861c4c3b8c98a\",\n    \"0x8c60dcc16c51087eb477c13e837031d6c6a3dc2b8bf8cb43c23f48006bc7173151807e866ead2234b460c2de93b31956\",\n    \"0x83ad63e9c910d1fc44bc114accfb0d4d333b7ebe032f73f62d25d3e172c029d5e34a1c9d547273bf6c0fead5c8801007\",\n    \"0x85de73213cc236f00777560756bdbf2b16841ba4b55902cf2cad9742ecaf5d28209b012ceb41f337456dfeca93010cd7\",\n    \"0xa7561f8827ccd75b6686ba5398bb8fc3083351c55a589b18984e186820af7e275af04bcd4c28e1dc11be1e8617a0610b\",\n    \"0x88c0a4febd4068850557f497ea888035c7fc9f404f6cc7794e7cc8722f048ad2f249e7dc62743e7a339eb7473ad3b0cd\",\n    \"0x932b22b1d3e6d5a6409c34980d176feb85ada1bf94332ef5c9fc4d42b907dabea608ceef9b5595ef3feee195151f18d8\",\n    \"0xa2867bb3f5ab88fbdae3a16c9143ab8a8f4f476a2643c505bb9f37e5b1fd34d216cab2204c9a017a5a67b7ad2dda10e8\",\n    \"0xb573d5f38e4e9e8a3a6fd82f0880dc049efa492a946d00283019bf1d5e5516464cf87039e80aef667cb86fdea5075904\",\n    \"0xb948f1b5ab755f3f5f36af27d94f503b070696d793b1240c1bdfd2e8e56890d69e6904688b5f8ff5a4bdf5a6abfe195f\",\n    \"0x917eae95ebc4109a2e99ddd8fec7881d2f7aaa0e25fda44dec7ce37458c2ee832f1829db7d2dcfa4ca0f06381c7fe91d\",\n    \"0x95751d17ed00a3030bce909333799bb7f4ab641acf585807f355b51d6976dceee410798026a1a004ef4dcdff7ec0f5b8\",\n    \"0xb9b7bd266f449a79bbfe075e429613e76c5a42ac61f01c8f0bbbd34669650682efe01ff9dbbc400a1e995616af6aa278\",\n    \"0xac1722d097ce9cd7617161f8ec8c23d68f1fb1c9ca533e2a8b4f78516c2fd8fb38f23f834e2b9a03bb06a9d655693ca9\",\n    \"0xa7ad9e96ffd98db2ecdb6340c5d592614f3c159abfd832fe27ee9293519d213a578e6246aae51672ee353e3296858873\",\n    \"0x989b8814d5de7937c4acafd000eec2b4cd58ba395d7b25f98cafd021e8efa37029b29ad8303a1f6867923f5852a220eb\",\n    \"0xa5bfe6282c771bc9e453e964042d44eff4098decacb89aecd3be662ea5b74506e1357ab26f3527110ba377711f3c9f41\",\n    \"0x8900a7470b656639721d2abbb7b06af0ac4222ab85a1976386e2a62eb4b88bfb5b72cf7921ddb3cf3a395d7eeb192a2e\",\n    \"0x95a71b55cd1f35a438cf5e75f8ff11c5ec6a2ebf2e4dba172f50bfad7d6d5dca5de1b1afc541662c81c858f7604c1163\",\n    \"0x82b5d62fea8db8d85c5bc3a76d68dedd25794cf14d4a7bc368938ffca9e09f7e598fdad2a5aac614e0e52f8112ae62b9\",\n    \"0x997173f07c729202afcde3028fa7f52cefc90fda2d0c8ac2b58154a5073140683e54c49ed1f254481070d119ce0ce02a\",\n    \"0xaeffb91ccc7a72bbd6ffe0f9b99c9e66e67d59cec2e02440465e9636a613ab3017278cfa72ea8bc4aba9a8dc728cb367\",\n    \"0x952743b06e8645894aeb6440fc7a5f62dd3acf96dab70a51e20176762c9751ea5f2ba0b9497ccf0114dc4892dc606031\",\n    \"0x874c63baeddc56fbbca2ff6031f8634b745f6e34ea6791d7c439201aee8f08ef5ee75f7778700a647f3b21068513fce6\",\n    \"0x85128fec9c750c1071edfb15586435cc2f317e3e9a175bb8a9697bcda1eb9375478cf25d01e7fed113483b28f625122d\",\n    \"0x85522c9576fd9763e32af8495ae3928ed7116fb70d4378448926bc9790e8a8d08f98cf47648d7da1b6e40d6a210c7924\",\n    \"0x97d0f37a13cfb723b848099ca1c14d83e9aaf2f7aeb71829180e664b7968632a08f6a85f557d74b55afe6242f2a36e7c\",\n    \"0xabaa472d6ad61a5fccd1a57c01aa1bc081253f95abbcba7f73923f1f11c4e79b904263890eeb66926de3e2652f5d1c70\",\n    \"0xb3c04945ba727a141e5e8aec2bf9aa3772b64d8fd0e2a2b07f3a91106a95cbcb249adcd074cbe498caf76fffac20d4ef\",\n    \"0x82c46781a3d730d9931bcabd7434a9171372dde57171b6180e5516d4e68db8b23495c8ac3ab96994c17ddb1cf249b9fb\",\n    \"0xa202d8b65613c42d01738ccd68ed8c2dbc021631f602d53f751966e04182743ebc8e0747d600b8a8676b1da9ae7f11ab\",\n    \"0xae73e7256e9459db04667a899e0d3ea5255211fb486d084e6550b6dd64ca44af6c6b2d59d7aa152de9f96ce9b58d940d\",\n    \"0xb67d87b176a9722945ec7593777ee461809861c6cfd1b945dde9ee4ff009ca4f19cf88f4bbb5c80c9cbab2fe25b23ac8\",\n    \"0x8f0b7a317a076758b0dac79959ee4a06c08b07d0f10538a4b53d3da2eda16e2af26922feb32c090330dc4d969cf69bd3\",\n    \"0x90b36bf56adbd8c4b6cb32febc3a8d5f714370c2ac3305c10fa6d168dffb2a026804517215f9a2d4ec8310cdb6bb459b\",\n    \"0xaa80c19b0682ead69934bf18cf476291a0beddd8ef4ed75975d0a472e2ab5c70f119722a8574ae4973aceb733d312e57\",\n    \"0xa3fc9abb12574e5c28dcb51750b4339b794b8e558675eef7d26126edf1de920c35e992333bcbffcbf6a5f5c0d383ce62\",\n    \"0xa1573ff23ab972acdcd08818853b111fc757fdd35aa070186d3e11e56b172fb49d840bf297ac0dd222e072fc09f26a81\",\n    \"0x98306f2be4caa92c2b4392212d0cbf430b409b19ff7d5b899986613bd0e762c909fc01999aa94be3bd529d67f0113d7f\",\n    \"0x8c1fc42482a0819074241746d17dc89c0304a2acdae8ed91b5009e9e3e70ff725ba063b4a3e68fdce05b74f5180c545e\",\n    \"0xa6c6113ebf72d8cf3163b2b8d7f3fa24303b13f55752522c660a98cd834d85d8c79214d900fa649499365e2e7641f77a\",\n    \"0xab95eea424f8a2cfd9fb1c78bb724e5b1d71a0d0d1e4217c5d0f98b0d8bbd3f8400a2002abc0a0e4576d1f93f46fefad\",\n    \"0x823c5a4fd8cf4a75fdc71d5f2dd511b6c0f189b82affeacd2b7cfcad8ad1a5551227dcc9bfdb2e34b2097eaa00efbb51\",\n    \"0xb97314dfff36d80c46b53d87a61b0e124dc94018a0bb680c32765b9a2d457f833a7c42bbc90b3b1520c33a182580398d\",\n    \"0xb17566ee3dcc6bb3b004afe4c0136dfe7dd27df9045ae896dca49fb36987501ae069eb745af81ba3fc19ff037e7b1406\",\n    \"0xb0bdc0f55cfd98d331e3a0c4fbb776a131936c3c47c6bffdc3aaf7d8c9fa6803fbc122c2fefbb532e634228687d52174\",\n    \"0xaa5d9e60cc9f0598559c28bb9bdd52aa46605ab4ffe3d192ba982398e72cec9a2a44c0d0d938ce69935693cabc0887ea\",\n    \"0x802b6459d2354fa1d56c592ac1346c428dadea6b6c0a87bf7d309bab55c94e1cf31dd98a7a86bd92a840dd51f218b91b\",\n    \"0xa526914efdc190381bf1a73dd33f392ecf01350b9d3f4ae96b1b1c3d1d064721c7d6eec5788162c933245a3943f5ee51\",\n    \"0xb3b8fcf637d8d6628620a1a99dbe619eabb3e5c7ce930d6efd2197e261bf394b74d4e5c26b96c4b8009c7e523ccfd082\",\n    \"0x8f7510c732502a93e095aba744535f3928f893f188adc5b16008385fb9e80f695d0435bfc5b91cdad4537e87e9d2551c\",\n    \"0x97b90beaa56aa936c3ca45698f79273a68dd3ccd0076eab48d2a4db01782665e63f33c25751c1f2e070f4d1a8525bf96\",\n    \"0xb9fb798324b1d1283fdc3e48288e3861a5449b2ab5e884b34ebb8f740225324af86e4711da6b5cc8361c1db15466602f\",\n    \"0xb6d52b53cea98f1d1d4c9a759c25bf9d8a50b604b144e4912acbdbdc32aab8b9dbb10d64a29aa33a4f502121a6fb481c\",\n    \"0x9174ffff0f2930fc228f0e539f5cfd82c9368d26b074467f39c07a774367ff6cccb5039ac63f107677d77706cd431680\",\n    \"0xa33b6250d4ac9e66ec51c063d1a6a31f253eb29bbaed12a0d67e2eccfffb0f3a52750fbf52a1c2aaba8c7692346426e7\",\n    \"0xa97025fd5cbcebe8ef865afc39cd3ea707b89d4e765ec817fd021d6438e02fa51e3544b1fd45470c58007a08efac6edd\",\n    \"0xb32a78480edd9ff6ba2f1eec4088db5d6ceb2d62d7e59e904ecaef7bb4a2e983a4588e51692b3be76e6ffbc0b5f911a5\",\n    \"0xb5ab590ef0bb77191f00495b33d11c53c65a819f7d0c1f9dc4a2caa147a69c77a4fff7366a602d743ee1f395ce934c1e\",\n    \"0xb3fb0842f9441fb1d0ee0293b6efbc70a8f58d12d6f769b12872db726b19e16f0f65efbc891cf27a28a248b0ef9c7e75\",\n    \"0x9372ad12856fefb928ccb0d34e198df99e2f8973b07e9d417a3134d5f69e12e79ff572c4e03ccd65415d70639bc7c73e\",\n    \"0xaa8d6e83d09ce216bfe2009a6b07d0110d98cf305364d5529c170a23e693aabb768b2016befb5ada8dabdd92b4d012bb\",\n    \"0xa954a75791eeb0ce41c85200c3763a508ed8214b5945a42c79bfdcfb1ec4f86ad1dd7b2862474a368d4ac31911a2b718\",\n    \"0x8e2081cfd1d062fe3ab4dab01f68062bac802795545fede9a188f6c9f802cb5f884e60dbe866710baadbf55dc77c11a4\",\n    \"0xa2f06003b9713e7dd5929501ed485436b49d43de80ea5b15170763fd6346badf8da6de8261828913ee0dacd8ff23c0e1\",\n    \"0x98eecc34b838e6ffd1931ca65eec27bcdb2fdcb61f33e7e5673a93028c5865e0d1bf6d3bec040c5e96f9bd08089a53a4\",\n    \"0x88cc16019741b341060b95498747db4377100d2a5bf0a5f516f7dec71b62bcb6e779de2c269c946d39040e03b3ae12b7\",\n    \"0xad1135ccbc3019d5b2faf59a688eef2500697642be8cfbdf211a1ab59abcc1f24483e50d653b55ff1834675ac7b4978f\",\n    \"0xa946f05ed9972f71dfde0020bbb086020fa35b482cce8a4cc36dd94355b2d10497d7f2580541bb3e81b71ac8bba3c49f\",\n    \"0xa83aeed488f9a19d8cfd743aa9aa1982ab3723560b1cd337fc2f91ad82f07afa412b3993afb845f68d47e91ba4869840\",\n    \"0x95eebe006bfc316810cb71da919e5d62c2cebb4ac99d8e8ef67be420302320465f8b69873470982de13a7c2e23516be9\",\n    \"0xa55f8961295a11e91d1e5deadc0c06c15dacbfc67f04ccba1d069cba89d72aa3b3d64045579c3ea8991b150ac29366ae\",\n    \"0xb321991d12f6ac07a5de3c492841d1a27b0d3446082fbce93e7e1f9e8d8fe3b45d41253556261c21b70f5e189e1a7a6f\",\n    \"0xa0b0822f15f652ce7962a4f130104b97bf9529797c13d6bd8e24701c213cc37f18157bd07f3d0f3eae6b7cd1cb40401f\",\n    \"0x96e2fa4da378aa782cc2d5e6e465fc9e49b5c805ed01d560e9b98abb5c0de8b74a2e7bec3aa5e2887d25cccb12c66f0c\",\n    \"0x97e4ab610d414f9210ed6f35300285eb3ccff5b0b6a95ed33425100d7725e159708ea78704497624ca0a2dcabce3a2f9\",\n    \"0x960a375b17bdb325761e01e88a3ea57026b2393e1d887b34b8fa5d2532928079ce88dc9fd06a728b26d2bb41b12b9032\",\n    \"0x8328a1647398e832aadc05bd717487a2b6fcdaa0d4850d2c4da230c6a2ed44c3e78ec4837b6094f3813f1ee99414713f\",\n    \"0xaa283834ebd18e6c99229ce4b401eda83f01d904f250fedd4e24f1006f8fa0712a6a89a7296a9bf2ce8de30e28d1408e\",\n    \"0xb29e097f2caadae3e0f0ae3473c072b0cd0206cf6d2e9b22c1a5ad3e07d433e32bd09ed1f4e4276a2da4268633357b7f\",\n    \"0x9539c5cbba14538b2fe077ecf67694ef240da5249950baaabea0340718b882a966f66d97f08556b08a4320ceb2cc2629\",\n    \"0xb4529f25e9b42ae8cf8338d2eface6ba5cd4b4d8da73af502d081388135c654c0b3afb3aa779ffc80b8c4c8f4425dd2b\",\n    \"0x95be0739c4330619fbe7ee2249c133c91d6c07eab846c18c5d6c85fc21ac5528c5d56dcb0145af68ed0c6a79f68f2ccd\",\n    \"0xac0c83ea802227bfc23814a24655c9ff13f729619bcffdb487ccbbf029b8eaee709f8bddb98232ef33cd70e30e45ca47\",\n    \"0xb503becb90acc93b1901e939059f93e671900ca52c6f64ae701d11ac891d3a050b505d89324ce267bc43ab8275da6ffe\",\n    \"0x98e3811b55b1bacb70aa409100abb1b870f67e6d059475d9f278c751b6e1e2e2d6f2e586c81a9fb6597fda06e7923274\",\n    \"0xb0b0f61a44053fa6c715dbb0731e35d48dba257d134f851ee1b81fd49a5c51a90ebf5459ec6e489fce25da4f184fbdb1\",\n    \"0xb1d2117fe811720bb997c7c93fe9e4260dc50fca8881b245b5e34f724aaf37ed970cdad4e8fcb68e05ac8cf55a274a53\",\n    \"0xa10f502051968f14b02895393271776dee7a06db9de14effa0b3471825ba94c3f805302bdddac4d397d08456f620999d\",\n    \"0xa3dbad2ef060ae0bb7b02eaa4a13594f3f900450faa1854fc09620b01ac94ab896321dfb1157cf2374c27e5718e8026a\",\n    \"0xb550fdec503195ecb9e079dcdf0cad559d64d3c30818ef369b4907e813e689da316a74ad2422e391b4a8c2a2bef25fc0\",\n    \"0xa25ba865e2ac8f28186cea497294c8649a201732ecb4620c4e77b8e887403119910423df061117e5f03fc5ba39042db1\",\n    \"0xb3f88174e03fdb443dd6addd01303cf88a4369352520187c739fc5ae6b22fa99629c63c985b4383219dab6acc5f6f532\",\n    \"0x97a7503248e31e81b10eb621ba8f5210c537ad11b539c96dfb7cf72b846c7fe81bd7532c5136095652a9618000b7f8d3\",\n    \"0xa8bcdc1ce5aa8bfa683a2fc65c1e79de8ff5446695dcb8620f7350c26d2972a23da22889f9e2b1cacb3f688c6a2953dc\",\n    \"0x8458c111df2a37f5dd91a9bee6c6f4b79f4f161c93fe78075b24a35f9817da8dde71763218d627917a9f1f0c4709c1ed\",\n    \"0xac5f061a0541152b876cbc10640f26f1cc923c9d4ae1b6621e4bb3bf2cec59bbf87363a4eb72fb0e5b6d4e1c269b52d5\",\n    \"0xa9a25ca87006e8a9203cbb78a93f50a36694aa4aad468b8d80d3feff9194455ca559fcc63838128a0ab75ad78c07c13a\",\n    \"0xa450b85f5dfffa8b34dfd8bc985f921318efacf8857cf7948f93884ba09fb831482ee90a44224b1a41e859e19b74962f\",\n    \"0x8ed91e7f92f5c6d7a71708b6132f157ac226ecaf8662af7d7468a4fa25627302efe31e4620ad28719318923e3a59bf82\",\n    \"0xab524165fd4c71b1fd395467a14272bd2b568592deafa039d8492e9ef36c6d3f96927c95c72d410a768dc0b6d1fbbc9b\",\n    \"0xb662144505aa8432c75ffb8d10318526b6d5777ac7af9ebfad87d9b0866c364f7905a6352743bd8fd79ffd9d5dd4f3e6\",\n    \"0xa48f1677550a5cd40663bb3ba8f84caaf8454f332d0ceb1d94dbea52d0412fe69c94997f7749929712fd3995298572f7\",\n    \"0x8391cd6e2f6b0c242de1117a612be99776c3dc95cb800b187685ea5bf7e2722275eddb79fd7dfc8be8e389c4524cdf70\",\n    \"0x875d3acb9af47833b72900bc0a2448999d638f153c5e97e8a14ec02d0c76f6264353a7e275e1f1a5855daced523d243b\",\n    \"0x91f1823657d30b59b2f627880a9a9cb530f5aca28a9fd217fe6f2f5133690dfe7ad5a897872e400512db2e788b3f7628\",\n    \"0xad3564332aa56cea84123fc7ca79ea70bb4fef2009fa131cb44e4b15e8613bd11ca1d83b9d9bf456e4b7fee9f2e8b017\",\n    \"0x8c530b84001936d5ab366c84c0b105241a26d1fb163669f17c8f2e94776895c2870edf3e1bc8ccd04d5e65531471f695\",\n    \"0x932d01fa174fdb0c366f1230cffde2571cc47485f37f23ba5a1825532190cc3b722aeb1f15aed62cf83ccae9403ba713\",\n    \"0x88b28c20585aca50d10752e84b901b5c2d58efef5131479fbbe53de7bce2029e1423a494c0298e1497669bd55be97a5d\",\n    \"0xb914148ca717721144ebb3d3bf3fcea2cd44c30c5f7051b89d8001502f3856fef30ec167174d5b76265b55d70f8716b5\",\n    \"0x81d0173821c6ddd2a068d70766d9103d1ee961c475156e0cbd67d54e668a796310474ef698c7ab55abe6f2cf76c14679\",\n    \"0x8f28e8d78e2fe7fa66340c53718e0db4b84823c8cfb159c76eac032a62fb53da0a5d7e24ca656cf9d2a890cb2a216542\",\n    \"0x8a26360335c73d1ab51cec3166c3cf23b9ea51e44a0ad631b0b0329ef55aaae555420348a544e18d5760969281759b61\",\n    \"0x94f326a32ed287545b0515be9e08149eb0a565025074796d72387cc3a237e87979776410d78339e23ef3172ca43b2544\",\n    \"0xa785d2961a2fa5e70bffa137858a92c48fe749fee91b02599a252b0cd50d311991a08efd7fa5e96b78d07e6e66ffe746\",\n    \"0x94af9030b5ac792dd1ce517eaadcec1482206848bea4e09e55cc7f40fd64d4c2b3e9197027c5636b70d6122c51d2235d\",\n    \"0x9722869f7d1a3992850fe7be405ec93aa17dc4d35e9e257d2e469f46d2c5a59dbd504056c85ab83d541ad8c13e8bcd54\",\n    \"0xb13c4088b61a06e2c03ac9813a75ff1f68ffdfee9df6a8f65095179a475e29cc49119cad2ce05862c3b1ac217f3aace9\",\n    \"0x8c64d51774753623666b10ca1b0fe63ae42f82ed6aa26b81dc1d48c86937c5772eb1402624c52a154b86031854e1fb9f\",\n    \"0xb47e4df18002b7dac3fee945bf9c0503159e1b8aafcce2138818e140753011b6d09ef1b20894e08ba3006b093559061b\",\n    \"0x93cb5970076522c5a0483693f6a35ffd4ea2aa7aaf3730c4eccd6af6d1bebfc1122fc4c67d53898ae13eb6db647be7e2\",\n    \"0xa68873ef80986795ea5ed1a597d1cd99ed978ec25e0abb57fdcc96e89ef0f50aeb779ff46e3dce21dc83ada3157a8498\",\n    \"0x8cab67f50949cc8eee6710e27358aea373aae3c92849f8f0b5531c080a6300cdf2c2094fe6fecfef6148de0d28446919\",\n    \"0x993e932bcb616dbaa7ad18a4439e0565211d31071ef1b85a0627db74a05d978c60d507695eaeea5c7bd9868a21d06923\",\n    \"0xacdadff26e3132d9478a818ef770e9fa0d2b56c6f5f48bd3bd674436ccce9bdfc34db884a73a30c04c5f5e9764cb2218\",\n    \"0xa0d3e64c9c71f84c0eef9d7a9cb4fa184224b969db5514d678e93e00f98b41595588ca802643ea225512a4a272f5f534\",\n    \"0x91c9140c9e1ba6e330cb08f6b2ce4809cd0d5a0f0516f70032bf30e912b0ed684d07b413b326ab531ee7e5b4668c799b\",\n    \"0x87bc2ee7a0c21ba8334cd098e35cb703f9af57f35e091b8151b9b63c3a5b0f89bd7701dbd44f644ea475901fa6d9ef08\",\n    \"0x9325ccbf64bf5d71b303e31ee85d486298f9802c5e55b2c3d75427097bf8f60fa2ab4fcaffa9b60bf922c3e24fbd4b19\",\n    \"0x95d0506e898318f3dc8d28d16dfd9f0038b54798838b3c9be2a2ae3c2bf204eb496166353fc042220b0bd4f6673b9285\",\n    \"0x811de529416331fe9c416726d45df9434c29dcd7e949045eb15740f47e97dde8f31489242200e19922cac2a8b7c6fd1f\",\n    \"0xade632d04a4c8bbab6ca7df370b2213cb9225023e7973f0e29f4f5e52e8aeaabc65171306bbdd12a67b195dfbb96d48f\",\n    \"0x88b7f029e079b6ae956042c0ea75d53088c5d0efd750dd018adaeacf46be21bf990897c58578c491f41afd3978d08073\",\n    \"0x91f477802de507ffd2be3f4319903119225b277ad24f74eb50f28b66c14d32fae53c7edb8c7590704741af7f7f3e3654\",\n    \"0x809838b32bb4f4d0237e98108320d4b079ee16ed80c567e7548bd37e4d7915b1192880f4812ac0e00476d246aec1dbc8\",\n    \"0x84183b5fc4a7997a8ae5afedb4d21dce69c480d5966b5cbdafd6dd10d29a9a6377f3b90ce44da0eb8b176ac3af0253bb\",\n    \"0x8508abbf6d3739a16b9165caf0f95afb3b3ac1b8c38d6d374cf0c91296e2c1809a99772492b539cda184510bce8a0271\",\n    \"0x8722054e59bab2062e6419a6e45fc803af77fde912ef2cd23055ad0484963de65a816a2debe1693d93c18218d2b8e81a\",\n    \"0x8e895f80e485a7c4f56827bf53d34b956281cdc74856c21eb3b51f6288c01cc3d08565a11cc6f3e2604775885490e8c5\",\n    \"0xafc92714771b7aa6e60f3aee12efd9c2595e9659797452f0c1e99519f67c8bc3ac567119c1ddfe82a3e961ee9defea9a\",\n    \"0x818ff0fd9cefd32db87b259e5fa32967201016fc02ef44116cdca3c63ce5e637756f60477a408709928444a8ad69c471\",\n    \"0x8251e29af4c61ae806fc5d032347fb332a94d472038149225298389495139ce5678fae739d02dfe53a231598a992e728\",\n    \"0xa0ea39574b26643f6f1f48f99f276a8a64b5481989cfb2936f9432a3f8ef5075abfe5c067dc5512143ce8bf933984097\",\n    \"0xaf67a73911b372bf04e57e21f289fc6c3dfac366c6a01409b6e76fea4769bdb07a6940e52e8d7d3078f235c6d2f632c6\",\n    \"0xb5291484ef336024dd2b9b4cf4d3a6b751133a40656d0a0825bcc6d41c21b1c79cb50b0e8f4693f90c29c8f4358641f9\",\n    \"0x8bc0d9754d70f2cb9c63f991902165a87c6535a763d5eece43143b5064ae0bcdce7c7a8f398f2c1c29167b2d5a3e6867\",\n    \"0x8d7faff53579ec8f6c92f661c399614cc35276971752ce0623270f88be937c414eddcb0997e14724a783905a026c8883\",\n    \"0x9310b5f6e675fdf60796f814dbaa5a6e7e9029a61c395761e330d9348a7efab992e4e115c8be3a43d08e90d21290c892\",\n    \"0xb5eb4f3eb646038ad2a020f0a42202532d4932e766da82b2c1002bf9c9c2e5336b54c8c0ffcc0e02d19dde2e6a35b6cc\",\n    \"0x91dabfd30a66710f1f37a891136c9be1e23af4abf8cb751f512a40c022a35f8e0a4fb05b17ec36d4208de02d56f0d53a\",\n    \"0xb3ded14e82d62ac7a5a036122a62f00ff8308498f3feae57d861babaff5a6628d43f0a0c5fc903f10936bcf4e2758ceb\",\n    \"0xa88e8348fed2b26acca6784d19ef27c75963450d99651d11a950ea81d4b93acd2c43e0ecce100eaf7e78508263d5baf3\",\n    \"0xb1f5bbf7c4756877b87bb42163ac570e08c6667c4528bf68b5976680e19beeff7c5effd17009b0718797077e2955457a\",\n    \"0xad2e7b516243f915d4d1415326e98b1a7390ae88897d0b03b66c2d9bd8c3fba283d7e8fe44ed3333296a736454cef6d8\",\n    \"0x8f82eae096d5b11f995de6724a9af895f5e1c58d593845ad16ce8fcae8507e0d8e2b2348a0f50a1f66a17fd6fac51a5c\",\n    \"0x890e4404d0657c6c1ee14e1aac132ecf7a568bb3e04137b85ac0f84f1d333bd94993e8750f88eee033a33fb00f85dcc7\",\n    \"0x82ac7d3385e035115f1d39a99fc73e5919de44f5e6424579776d118d711c8120b8e5916372c6f27bed4cc64cac170b6c\",\n    \"0x85ee16d8901c272cfbbe966e724b7a891c1bd5e68efd5d863043ad8520fc409080af61fd726adc680b3f1186fe0ac8b8\",\n    \"0x86dc564c9b545567483b43a38f24c41c6551a49cabeebb58ce86404662a12dbfafd0778d30d26e1c93ce222e547e3898\",\n    \"0xa29f5b4522db26d88f5f95f18d459f8feefab02e380c2edb65aa0617a82a3c1a89474727a951cef5f15050bcf7b380fb\",\n    \"0xa1ce039c8f6cac53352899edb0e3a72c76da143564ad1a44858bd7ee88552e2fe6858d1593bbd74aeee5a6f8034b9b9d\",\n    \"0x97f10d77983f088286bd7ef3e7fdd8fa275a56bec19919adf33cf939a90c8f2967d2b1b6fc51195cb45ad561202a3ed7\",\n    \"0xa25e2772e8c911aaf8712bdac1dd40ee061c84d3d224c466cfaae8e5c99604053f940cde259bd1c3b8b69595781dbfec\",\n    \"0xb31bb95a0388595149409c48781174c340960d59032ab2b47689911d03c68f77a2273576fbe0c2bf4553e330656058c7\",\n    \"0xb8b2e9287ad803fb185a13f0d7456b397d4e3c8ad5078f57f49e8beb2e85f661356a3392dbd7bcf6a900baa5582b86a1\",\n    \"0xa3d0893923455eb6e96cc414341cac33d2dbc88fba821ac672708cce131761d85a0e08286663a32828244febfcae6451\",\n    \"0x82310cb42f647d99a136014a9f881eb0b9791efd2e01fc1841907ad3fc8a9654d3d1dab6689c3607214b4dc2aca01cee\",\n    \"0x874022d99c16f60c22de1b094532a0bc6d4de700ad01a31798fac1d5088b9a42ad02bef8a7339af7ed9c0d4f16b186ee\",\n    \"0x94981369e120265aed40910eebc37eded481e90f4596b8d57c3bec790ab7f929784bd33ddd05b7870aad6c02e869603b\",\n    \"0xa4f1f50e1e2a73f07095e0dd31cb45154f24968dae967e38962341c1241bcd473102fff1ff668b20c6547e9732d11701\",\n    \"0xae2328f3b0ad79fcda807e69a1b5278145225083f150f67511dafc97e079f860c3392675f1752ae7e864c056e592205b\",\n    \"0x875d8c971e593ca79552c43d55c8c73b17cd20c81ff2c2fed1eb19b1b91e4a3a83d32df150dbfd5db1092d0aebde1e1f\",\n    \"0xadd2e80aa46aae95da73a11f130f4bda339db028e24c9b11e5316e75ba5e63bc991d2a1da172c7c8e8fee038baae3433\",\n    \"0xb46dbe1cb3424002aa7de51e82f600852248e251465c440695d52538d3f36828ff46c90ed77fc1d11534fe3c487df8ef\",\n    \"0xa5e5045d28b4e83d0055863c30c056628c58d4657e6176fd0536f5933f723d60e851bb726d5bf3c546b8ce4ac4a57ef8\",\n    \"0x91fec01e86dd1537e498fff7536ea3ca012058b145f29d9ada49370cd7b7193ac380e116989515df1b94b74a55c45df3\",\n    \"0xa7428176d6918cd916a310bdc75483c72de660df48cac4e6e7478eef03205f1827ea55afc0df5d5fa7567d14bbea7fc9\",\n    \"0x851d89bef45d9761fe5fdb62972209335193610015e16a675149519f9911373bac0919add226ef118d9f3669cfdf4734\",\n    \"0xb74acf5c149d0042021cb2422ea022be4c4f72a77855f42393e71ffd12ebb3eec16bdf16f812159b67b79a9706e7156d\",\n    \"0x99f35dce64ec99aa595e7894b55ce7b5a435851b396e79036ffb249c28206087db4c85379df666c4d95857db02e21ff9\",\n    \"0xb6b9a384f70db9e298415b8ab394ee625dafff04be2886476e59df8d052ca832d11ac68a9b93fba7ab055b7bc36948a4\",\n    \"0x898ee4aefa923ffec9e79f2219c7389663eb11eb5b49014e04ed4a336399f6ea1691051d86991f4c46ca65bcd4fdf359\",\n    \"0xb0f948217b0d65df7599a0ba4654a5e43c84db477936276e6f11c8981efc6eaf14c90d3650107ed4c09af4cc8ec11137\",\n    \"0xaa6286e27ac54f73e63dbf6f41865dd94d24bc0cf732262fcaff67319d162bb43af909f6f8ee27b1971939cfbba08141\",\n    \"0x8bca7cdf730cf56c7b2c8a2c4879d61361a6e1dba5a3681a1a16c17a56e168ace0e99cf0d15826a1f5e67e6b8a8a049a\",\n    \"0xa746d876e8b1ce225fcafca603b099b36504846961526589af977a88c60d31ba2cc56e66a3dec8a77b3f3531bf7524c9\",\n    \"0xa11e2e1927e6704cdb8874c75e4f1842cef84d7d43d7a38e339e61dc8ba90e61bbb20dd3c12e0b11d2471d58eed245be\",\n    \"0xa36395e22bc1d1ba8b0459a235203177737397da5643ce54ded3459d0869ff6d8d89f50c73cb62394bf66a959cde9b90\",\n    \"0x8b49f12ba2fdf9aca7e5f81d45c07d47f9302a2655610e7634d1e4bd16048381a45ef2c95a8dd5b0715e4b7cf42273af\",\n    \"0x91cffa2a17e64eb7f76bccbe4e87280ee1dd244e04a3c9eac12e15d2d04845d876eb24fe2ec6d6d266cce9efb281077f\",\n    \"0xa6b8afabf65f2dee01788114e33a2f3ce25376fb47a50b74da7c3c25ff1fdc8aa9f41307534abbf48acb6f7466068f69\",\n    \"0x8d13db896ccfea403bd6441191995c1a65365cab7d0b97fbe9526da3f45a877bd1f4ef2edef160e8a56838cd1586330e\",\n    \"0x98c717de9e01bef8842c162a5e757fe8552d53269c84862f4d451e7c656ae6f2ae473767b04290b134773f63be6fdb9d\",\n    \"0x8c2036ace1920bd13cf018e82848c49eb511fad65fd0ff51f4e4b50cf3bfc294afb63cba682c16f52fb595a98fa84970\",\n    \"0xa3520fdff05dbad9e12551b0896922e375f9e5589368bcb2cc303bde252743b74460cb5caf99629325d3620f13adc796\",\n    \"0x8d4f83a5bfec05caf5910e0ce538ee9816ee18d0bd44c1d0da2a87715a23cd2733ad4d47552c6dc0eb397687d611dd19\",\n    \"0xa7b39a0a6a02823452d376533f39d35029867b3c9a6ad6bca181f18c54132d675613a700f9db2440fb1b4fa13c8bf18a\",\n    \"0x80bcb114b2544b80f404a200fc36860ed5e1ad31fe551acd4661d09730c452831751baa9b19d7d311600d267086a70bc\",\n    \"0x90dcce03c6f88fc2b08f2b42771eedde90cc5330fe0336e46c1a7d1b5a6c1641e5fcc4e7b3d5db00bd8afca9ec66ed81\",\n    \"0xaec15f40805065c98e2965b1ae12a6c9020cfdb094c2d0549acfc7ea2401a5fb48d3ea7d41133cf37c4e096e7ff53eb9\",\n    \"0x80e129b735dba49fa627a615d6c273119acec8e219b2f2c4373a332b5f98d66cbbdd688dfbe72a8f8bfefaccc02c50c1\",\n    \"0xa9b596da3bdfe23e6799ece5f7975bf7a1979a75f4f546deeaf8b34dfe3e0d623217cb4cf4ccd504cfa3625b88cd53f1\",\n    \"0xabcbbb70b16f6e517c0ab4363ab76b46e4ff58576b5f8340e5c0e8cc0e02621b6e23d742d73b015822a238b17cfd7665\",\n    \"0xa046937cc6ea6a2e1adae543353a9fe929c1ae4ad655be1cc051378482cf88b041e28b1e9a577e6ccff2d3570f55e200\",\n    \"0x831279437282f315e65a60184ef158f0a3dddc15a648dc552bdc88b3e6fe8288d3cfe9f0031846d81350f5e7874b4b33\",\n    \"0x993d7916fa213c6d66e7c4cafafc1eaec9a2a86981f91c31eb8a69c5df076c789cbf498a24c84e0ee77af95b42145026\",\n    \"0x823907a3b6719f8d49b3a4b7c181bd9bb29fcf842d7c70660c4f351852a1e197ca46cf5e879b47fa55f616fa2b87ce5e\",\n    \"0x8d228244e26132b234930ee14c75d88df0943cdb9c276a8faf167d259b7efc1beec2a87c112a6c608ad1600a239e9aae\",\n    \"0xab6e55766e5bfb0cf0764ed909a8473ab5047d3388b4f46faeba2d1425c4754c55c6daf6ad4751e634c618b53e549529\",\n    \"0xab0cab6860e55a84c5ad2948a7e0989e2b4b1fd637605634b118361497332df32d9549cb854b2327ca54f2bcb85eed8f\",\n    \"0xb086b349ae03ef34f4b25a57bcaa5d1b29bd94f9ebf87e22be475adfe475c51a1230c1ebe13506cb72c4186192451658\",\n    \"0x8a0b49d8a254ca6d91500f449cbbfbb69bb516c6948ac06808c65595e46773e346f97a5ce0ef7e5a5e0de278af22709c\",\n    \"0xac49de11edaaf04302c73c578cc0824bdd165c0d6321be1c421c1950e68e4f3589aa3995448c9699e93c6ebae8803e27\",\n    \"0x884f02d841cb5d8f4c60d1402469216b114ab4e93550b5bc1431756e365c4f870a9853449285384a6fa49e12ce6dc654\",\n    \"0xb75f3a28fa2cc8d36b49130cb7448a23d73a7311d0185ba803ad55c8219741d451c110f48b786e96c728bc525903a54f\",\n    \"0x80ae04dbd41f4a35e33f9de413b6ad518af0919e5a30cb0fa1b061b260420780bb674f828d37fd3b52b5a31673cbd803\",\n    \"0xb9a8011eb5fcea766907029bf743b45262db3e49d24f84503687e838651ed11cb64c66281e20a0ae9f6aa51acc552263\",\n    \"0x90bfdd75e2dc9cf013e22a5d55d2d2b8a754c96103a17524488e01206e67f8b6d52b1be8c4e3d5307d4fe06d0e51f54c\",\n    \"0xb4af353a19b06203a815ec43e79a88578cc678c46f5a954b85bc5c53b84059dddba731f3d463c23bfd5273885c7c56a4\",\n    \"0xaa125e96d4553b64f7140e5453ff5d2330318b69d74d37d283e84c26ad672fa00e3f71e530eb7e28be1e94afb9c4612e\",\n    \"0xa18e060aee3d49cde2389b10888696436bb7949a79ca7d728be6456a356ea5541b55492b2138da90108bd1ce0e6f5524\",\n    \"0x93e55f92bdbccc2de655d14b1526836ea2e52dba65eb3f87823dd458a4cb5079bf22ce6ef625cb6d6bfdd0995ab9a874\",\n    \"0x89f5a683526b90c1c3ceebbb8dc824b21cff851ce3531b164f6626e326d98b27d3e1d50982e507d84a99b1e04e86a915\",\n    \"0x83d1c38800361633a3f742b1cb2bfc528129496e80232611682ddbe403e92c2ac5373aea0bca93ecb5128b0b2b7a719e\",\n    \"0x8ecba560ac94905e19ce8d9c7af217bf0a145d8c8bd38e2db82f5e94cc3f2f26f55819176376b51f154b4aab22056059\",\n    \"0xa7e2a4a002b60291924850642e703232994acb4cfb90f07c94d1e0ecd2257bb583443283c20fc6017c37e6bfe85b7366\",\n    \"0x93ed7316fa50b528f1636fc6507683a672f4f4403e55e94663f91221cc198199595bd02eef43d609f451acc9d9b36a24\",\n    \"0xa1220a8ebc5c50ceed76a74bc3b7e0aa77f6884c71b64b67c4310ac29ce5526cb8992d6abc13ef6c8413ce62486a6795\",\n    \"0xb2f6eac5c869ad7f4a25161d3347093e2f70e66cd925032747e901189355022fab3038bca4d610d2f68feb7e719c110b\",\n    \"0xb703fa11a4d511ca01c7462979a94acb40b5d933759199af42670eb48f83df202fa0c943f6ab3b4e1cc54673ea3aab1e\",\n    \"0xb5422912afbfcb901f84791b04f1ddb3c3fbdc76d961ee2a00c5c320e06d3cc5b5909c3bb805df66c5f10c47a292b13d\",\n    \"0xad0934368da823302e1ac08e3ede74b05dfdbfffca203e97ffb0282c226814b65c142e6e15ec1e754518f221f01b30f7\",\n    \"0xa1dd302a02e37df15bf2f1147efe0e3c06933a5a767d2d030e1132f5c3ce6b98e216b6145eb39e1e2f74e76a83165b8d\",\n    \"0xa346aab07564432f802ae44738049a36f7ca4056df2d8f110dbe7fef4a3e047684dea609b2d03dc6bf917c9c2a47608f\",\n    \"0xb96c5f682a5f5d02123568e50f5d0d186e4b2c4c9b956ec7aabac1b3e4a766d78d19bd111adb5176b898e916e49be2aa\",\n    \"0x8a96676d56876fc85538db2e806e1cba20fd01aeb9fa3cb43ca6ca94a2c102639f65660db330e5d74a029bb72d6a0b39\",\n    \"0xab0048336bd5c3def1a4064eadd49e66480c1f2abb4df46e03afbd8a3342c2c9d74ee35d79f08f4768c1646681440984\",\n    \"0x888427bdf76caec90814c57ee1c3210a97d107dd88f7256f14f883ad0f392334b82be11e36dd8bfec2b37935177c7831\",\n    \"0xb622b282becf0094a1916fa658429a5292ba30fb48a4c8066ce1ddcefb71037948262a01c95bab6929ed3a76ba5db9fe\",\n    \"0xb5b9e005c1f456b6a368a3097634fb455723abe95433a186e8278dceb79d4ca2fbe21f8002e80027b3c531e5bf494629\",\n    \"0xa3c6707117a1e48697ed41062897f55d8119403eea6c2ee88f60180f6526f45172664bfee96bf61d6ec0b7fbae6aa058\",\n    \"0xb02a9567386a4fbbdb772d8a27057b0be210447348efe6feb935ceec81f361ed2c0c211e54787dc617cdffed6b4a6652\",\n    \"0xa9b8364e40ef15c3b5902e5534998997b8493064fa2bea99600def58279bb0f64574c09ba11e9f6f669a8354dd79dc85\",\n    \"0x9998a2e553a9aa9a206518fae2bc8b90329ee59ab23005b10972712389f2ec0ee746033c733092ffe43d73d33abbb8ef\",\n    \"0x843a4b34d9039bf79df96d79f2d15e8d755affb4d83d61872daf540b68c0a3888cf8fc00d5b8b247b38524bcb3b5a856\",\n    \"0x84f7128920c1b0bb40eee95701d30e6fc3a83b7bb3709f16d97e72acbb6057004ee7ac8e8f575936ca9dcb7866ab45f7\",\n    \"0x918d3e2222e10e05edb34728162a899ad5ada0aaa491aeb7c81572a9c0d506e31d5390e1803a91ff3bd8e2bb15d47f31\",\n    \"0x9442d18e2489613a7d47bb1cb803c8d6f3259d088cd079460976d87f7905ee07dea8f371b2537f6e1d792d36d7e42723\",\n    \"0xb491976970fe091995b2ed86d629126523ccf3e9daf8145302faca71b5a71a5da92e0e05b62d7139d3efac5c4e367584\",\n    \"0xaa628006235dc77c14cef4c04a308d66b07ac92d377df3de1a2e6ecfe3144f2219ad6d7795e671e1cb37a3641910b940\",\n    \"0x99d386adaea5d4981d7306feecac9a555b74ffdc218c907c5aa7ac04abaead0ec2a8237300d42a3fbc464673e417ceed\",\n    \"0x8f78e8b1556f9d739648ea3cab9606f8328b52877fe72f9305545a73b74d49884044ba9c1f1c6db7d9b7c7b7c661caba\",\n    \"0x8fb357ae49932d0babdf74fc7aa7464a65d3b6a2b3acf4f550b99601d3c0215900cfd67f2b6651ef94cfc323bac79fae\",\n    \"0x9906f2fa25c0290775aa001fb6198113d53804262454ae8b83ef371b5271bde189c0460a645829cb6c59f9ee3a55ce4d\",\n    \"0x8f4379b3ebb50e052325b27655ca6a82e6f00b87bf0d2b680d205dd2c7afdc9ff32a9047ae71a1cdf0d0ce6b9474d878\",\n    \"0xa85534e88c2bd43c043792eaa75e50914b21741a566635e0e107ae857aed0412035f7576cf04488ade16fd3f35fdbb87\",\n    \"0xb4ce93199966d3c23251ca7f28ec5af7efea1763d376b0385352ffb2e0a462ef95c69940950278cf0e3dafd638b7bd36\",\n    \"0xb10cb3d0317dd570aa73129f4acf63c256816f007607c19b423fb42f65133ce21f2f517e0afb41a5378cccf893ae14d0\",\n    \"0xa9b231c9f739f7f914e5d943ed9bff7eba9e2c333fbd7c34eb1648a362ee01a01af6e2f7c35c9fe962b11152cddf35de\",\n    \"0x99ff6a899e156732937fb81c0cced80ae13d2d44c40ba99ac183aa246103b31ec084594b1b7feb96da58f4be2dd5c0ed\",\n    \"0x8748d15d18b75ff2596f50d6a9c4ce82f61ecbcee123a6ceae0e43cab3012a29b6f83cf67b48c22f6f9d757c6caf76b2\",\n    \"0xb88ab05e4248b7fb634cf640a4e6a945d13e331237410f7217d3d17e3e384ddd48897e7a91e4516f1b9cbd30f35f238b\",\n    \"0x8d826deaeeb84a3b2d2c04c2300ca592501f992810582d6ae993e0d52f6283a839dba66c6c72278cff5871802b71173b\",\n    \"0xb36fed027c2f05a5ef625ca00b0364b930901e9e4420975b111858d0941f60e205546474bb25d6bfa6928d37305ae95f\",\n    \"0xaf2fcfc6b87967567e8b8a13a4ed914478185705724e56ce68fb2df6d1576a0cf34a61e880997a0d35dc2c3276ff7501\",\n    \"0xac351b919cd1fbf106feb8af2c67692bfcddc84762d18cea681cfa7470a5644839caace27efee5f38c87d3df306f4211\",\n    \"0x8d6665fb1d4d8d1fa23bd9b8a86e043b8555663519caac214d1e3e3effbc6bee7f2bcf21e645f77de0ced279d69a8a8b\",\n    \"0xa9fc1c2061756b2a1a169c1b149f212ff7f0d2488acd1c5a0197eba793cffa593fc6d1d1b40718aa75ca3ec77eff10e1\",\n    \"0xaff64f0fa009c7a6cf0b8d7a22ddb2c8170c3cb3eec082e60d5aadb00b0040443be8936d728d99581e33c22178c41c87\",\n    \"0x82e0b181adc5e3b1c87ff8598447260e839d53debfae941ebea38265575546c3a74a14b4325a030833a62ff6c52d9365\",\n    \"0xb7ad43cbb22f6f892c2a1548a41dc120ab1f4e1b8dea0cb6272dd9cb02054c542ecabc582f7e16de709d48f5166cae86\",\n    \"0x985e0c61094281532c4afb788ecb2dfcba998e974b5d4257a22040a161883908cdd068fe80f8eb49b8953cfd11acf43a\",\n    \"0xae46895c6d67ea6d469b6c9c07b9e5d295d9ae73b22e30da4ba2c973ba83a130d7eef39717ec9d0f36e81d56bf742671\",\n    \"0x8600177ea1f7e7ef90514b38b219a37dedfc39cb83297e4c7a5b479817ef56479d48cf6314820960c751183f6edf8b0e\",\n    \"0xb9208ec1c1d7a1e99b59c62d3e4e61dfb706b0e940d09d3abfc3454c19749083260614d89cfd7e822596c3cdbcc6bb95\",\n    \"0xa1e94042c796c2b48bc724352d2e9f3a22291d9a34705993357ddb6adabd76da6fc25dac200a8cb0b5bbd99ecddb7af6\",\n    \"0xb29c3adedd0bcad8a930625bc4dfdc3552a9afd5ca6dd9c0d758f978068c7982b50b711aa0eb5b97f2b84ee784637835\",\n    \"0xaf0632a238bb1f413c7ea8e9b4c3d68f2827bd2e38cd56024391fba6446ac5d19a780d0cfd4a78fe497d537b766a591a\",\n    \"0xaaf6e7f7d54f8ef5e2e45dd59774ecbeecf8683aa70483b2a75be6a6071b5981bbaf1627512a65d212817acdfab2e428\",\n    \"0x8c751496065da2e927cf492aa5ca9013b24f861d5e6c24b30bbf52ec5aaf1905f40f9a28175faef283dd4ed4f2182a09\",\n    \"0x8952377d8e80a85cf67d6b45499f3bad5fd452ea7bcd99efc1b066c4720d8e5bff1214cea90fd1f972a7f0baac3d29be\",\n    \"0xa1946ee543d1a6e21f380453be4d446e4130950c5fc3d075794eb8260f6f52d0a795c1ff91d028a648dc1ce7d9ab6b47\",\n    \"0x89f3fefe37af31e0c17533d2ca1ce0884cc1dc97c15cbfab9c331b8debd94781c9396abef4bb2f163d09277a08d6adf0\",\n    \"0xa2753f1e6e1a154fb117100a5bd9052137add85961f8158830ac20541ab12227d83887d10acf7fd36dcaf7c2596d8d23\",\n    \"0x814955b4198933ee11c3883863b06ff98c7eceb21fc3e09df5f916107827ccf3323141983e74b025f46ae00284c9513b\",\n    \"0x8cc5c6bb429073bfef47cae7b3bfccb0ffa076514d91a1862c6bda4d581e0df87db53cc6c130bf8a7826304960f5a34e\",\n    \"0x909f22c1f1cdc87f7be7439c831a73484a49acbf8f23d47087d7cf867c64ef61da3bde85dc57d705682b4c3fc710d36e\",\n    \"0x8048fee7f276fcd504aed91284f28e73693615e0eb3858fa44bcf79d7285a9001c373b3ef71d9a3054817ba293ebe28c\",\n    \"0x94400e5cf5d2700ca608c5fe35ce14623f71cc24959f2bc27ca3684092850f76b67fb1f07ca9e5b2ca3062cf8ad17bd4\",\n    \"0x81c2ae7d4d1b17f8b6de6a0430acc0d58260993980fe48dc2129c4948269cdc74f9dbfbf9c26b19360823fd913083d48\",\n    \"0x8c41fe765128e63f6889d6a979f6a4342300327c8b245a8cfe3ecfbcac1e09c3da30e2a1045b24b78efc6d6d50c8c6ac\",\n    \"0xa5dd4ae51ae48c8be4b218c312ade226cffce671cf121cb77810f6c0990768d6dd767badecb5c69921d5574d5e8433d3\",\n    \"0xb7642e325f4ba97ae2a39c1c9d97b35aafd49d53dba36aed3f3cb0ca816480b3394079f46a48252d46596559c90f4d58\",\n    \"0xae87375b40f35519e7bd4b1b2f73cd0b329b0c2cb9d616629342a71c6c304338445eda069b78ea0fbe44087f3de91e09\",\n    \"0xb08918cb6f736855e11d3daca1ddfbdd61c9589b203b5493143227bf48e2c77c2e8c94b0d1aa2fab2226e0eae83f2681\",\n    \"0xac36b84a4ac2ebd4d6591923a449c564e3be8a664c46092c09e875c2998eba16b5d32bfd0882fd3851762868e669f0b1\",\n    \"0xa44800a3bb192066fa17a3f29029a23697240467053b5aa49b9839fb9b9b8b12bcdcbfc557f024b61f4f51a9aacdefcb\",\n    \"0x9064c688fec23441a274cdf2075e5a449caf5c7363cc5e8a5dc9747183d2e00a0c69f2e6b3f6a7057079c46014c93b3b\",\n    \"0xaa367b021469af9f5b764a79bb3afbe2d87fe1e51862221672d1a66f954b165778b7c27a705e0f93841fab4c8468344d\",\n    \"0xa1a8bfc593d4ab71f91640bc824de5c1380ab2591cfdafcbc78a14b32de3c0e15f9d1b461d85c504baa3d4232c16bb53\",\n    \"0x97df48da1799430f528184d30b6baa90c2a2f88f34cdfb342d715339c5ebd6d019aa693cea7c4993daafc9849063a3aa\",\n    \"0xabd923831fbb427e06e0dd335253178a9e5791395c84d0ab1433c07c53c1209161097e9582fb8736f8a60bde62d8693e\",\n    \"0x84cd1a43f1a438b43dc60ffc775f646937c4f6871438163905a3cebf1115f814ccd38a6ccb134130bff226306e412f32\",\n    \"0x91426065996b0743c5f689eb3ca68a9f7b9e4d01f6c5a2652b57fa9a03d8dc7cd4bdbdab0ca5a891fee1e97a7f00cf02\",\n    \"0xa4bee50249db3df7fd75162b28f04e57c678ba142ce4d3def2bc17bcb29e4670284a45f218dad3969af466c62a903757\",\n    \"0x83141ebcc94d4681404e8b67a12a46374fded6df92b506aff3490d875919631408b369823a08b271d006d5b93136f317\",\n    \"0xa0ea1c8883d58d5a784da3d8c8a880061adea796d7505c1f903d07c287c5467f71e4563fc0faafbc15b5a5538b0a7559\",\n    \"0x89d9d480574f201a87269d26fb114278ed2c446328df431dc3556e3500e80e4cd01fcac196a2459d8646361ebda840df\",\n    \"0x8bf302978973632dd464bec819bdb91304712a3ec859be071e662040620422c6e75eba6f864f764cffa2799272efec39\",\n    \"0x922f666bc0fd58b6d7d815c0ae4f66d193d32fc8382c631037f59eeaeae9a8ca6c72d08e72944cf9e800b8d639094e77\",\n    \"0x81ad8714f491cdff7fe4399f2eb20e32650cff2999dd45b9b3d996d54a4aba24cc6c451212e78c9e5550368a1a38fb3f\",\n    \"0xb58fcf4659d73edb73175bd9139d18254e94c3e32031b5d4b026f2ed37aa19dca17ec2eb54c14340231615277a9d347e\",\n    \"0xb365ac9c2bfe409b710928c646ea2fb15b28557e0f089d39878e365589b9d1c34baf5566d20bb28b33bb60fa133f6eff\",\n    \"0x8fcae1d75b53ab470be805f39630d204853ca1629a14158bac2f52632277d77458dec204ff84b7b2d77e641c2045be65\",\n    \"0xa03efa6bebe84f4f958a56e2d76b5ba4f95dd9ed7eb479edc7cc5e646c8d4792e5b0dfc66cc86aa4b4afe2f7a4850760\",\n    \"0xaf1c823930a3638975fb0cc5c59651771b2719119c3cd08404fbd4ce77a74d708cefbe3c56ea08c48f5f10e6907f338f\",\n    \"0x8260c8299b17898032c761c325ac9cabb4c5b7e735de81eacf244f647a45fb385012f4f8df743128888c29aefcaaad16\",\n    \"0xab2f37a573c82e96a8d46198691cd694dfa860615625f477e41f91b879bc58a745784fccd8ffa13065834ffd150d881d\",\n    \"0x986c746c9b4249352d8e5c629e8d7d05e716b3c7aab5e529ca969dd1e984a14b5be41528baef4c85d2369a42d7209216\",\n    \"0xb25e32da1a8adddf2a6080725818b75bc67240728ad1853d90738485d8924ea1e202df0a3034a60ffae6f965ec55cf63\",\n    \"0xa266e627afcebcefea6b6b44cbc50f5c508f7187e87d047b0450871c2a030042c9e376f3ede0afcf9d1952f089582f71\",\n    \"0x86c3bbca4c0300606071c0a80dbdec21ce1dd4d8d4309648151c420854032dff1241a1677d1cd5de4e4de4385efda986\",\n    \"0xb9a21a1fe2d1f3273a8e4a9185abf2ff86448cc98bfa435e3d68306a2b8b4a6a3ea33a155be3cb62a2170a86f77679a5\",\n    \"0xb117b1ea381adce87d8b342cba3a15d492ff2d644afa28f22424cb9cbc820d4f7693dfc1a4d1b3697046c300e1c9b4c8\",\n    \"0x9004c425a2e68870d6c69b658c344e3aa3a86a8914ee08d72b2f95c2e2d8a4c7bb0c6e7e271460c0e637cec11117bf8e\",\n    \"0x86a18aa4783b9ebd9131580c8b17994825f27f4ac427b0929a1e0236907732a1c8139e98112c605488ee95f48bbefbfc\",\n    \"0x84042243b955286482ab6f0b5df4c2d73571ada00716d2f737ca05a0d2e88c6349e8ee9e67934cfee4a1775dbf7f4800\",\n    \"0x92c2153a4733a62e4e1d5b60369f3c26777c7d01cd3c8679212660d572bd3bac9b8a8a64e1f10f7dbf5eaa7579c4e423\",\n    \"0x918454b6bb8e44a2afa144695ba8d48ae08d0cdfef4ad078f67709eddf3bb31191e8b006f04e82ea45a54715ef4d5817\",\n    \"0xacf0b54f6bf34cf6ed6c2b39cf43194a40d68de6bcf1e4b82c34c15a1343e9ac3737885e1a30b78d01fa3a5125463db8\",\n    \"0xa7d60dbe4b6a7b054f7afe9ee5cbbfeca0d05dc619e6041fa2296b549322529faddb8a11e949562309aecefb842ac380\",\n    \"0x91ffb53e6d7e5f11159eaf13e783d6dbdfdb1698ed1e6dbf3413c6ea23492bbb9e0932230a9e2caac8fe899a17682795\",\n    \"0xb6e8d7be5076ee3565d5765a710c5ecf17921dd3cf555c375d01e958a365ae087d4a88da492a5fb81838b7b92bf01143\",\n    \"0xa8c6b763de2d4b2ed42102ef64eccfef31e2fb2a8a2776241c82912fa50fc9f77f175b6d109a97ede331307c016a4b1a\",\n    \"0x99839f86cb700c297c58bc33e28d46b92931961548deac29ba8df91d3e11721b10ea956c8e16984f9e4acf1298a79b37\",\n    \"0x8c2e2c338f25ea5c25756b7131cde0d9a2b35abf5d90781180a00fe4b8e64e62590dc63fe10a57fba3a31c76d784eb01\",\n    \"0x9687d7df2f41319ca5469d91978fed0565a5f11f829ebadaa83db92b221755f76c6eacd7700735e75c91e257087512e3\",\n    \"0x8795fdfb7ff8439c58b9bf58ed53873d2780d3939b902b9ddaaa4c99447224ced9206c3039a23c2c44bcc461e2bb637f\",\n    \"0xa803697b744d2d087f4e2307218d48fa88620cf25529db9ce71e2e3bbcc65bac5e8bb9be04777ef7bfb5ed1a5b8e6170\",\n    \"0x80f3d3efbbb9346ddd413f0a8e36b269eb5d7ff6809d5525ff9a47c4bcab2c01b70018b117f6fe05253775612ff70c6b\",\n    \"0x9050e0e45bcc83930d4c505af35e5e4d7ca01cd8681cba92eb55821aececcebe32bb692ebe1a4daac4e7472975671067\",\n    \"0x8d206812aac42742dbaf233e0c080b3d1b30943b54b60283515da005de05ea5caa90f91fedcfcba72e922f64d7040189\",\n    \"0xa2d44faaeb2eff7915c83f32b13ca6f31a6847b1c1ce114ea240bac3595eded89f09b2313b7915ad882292e2b586d5b4\",\n    \"0x961776c8576030c39f214ea6e0a3e8b3d32f023d2600958c098c95c8a4e374deeb2b9dc522adfbd6bda5949bdc09e2a2\",\n    \"0x993fa7d8447407af0fbcd9e6d77f815fa5233ab00674efbcf74a1f51c37481445ae291cc7b76db7c178f9cb0e570e0fc\",\n    \"0xabd5b1c78e05f9d7c8cc99bdaef8b0b6a57f2daf0f02bf492bec48ea4a27a8f1e38b5854da96efff11973326ff980f92\",\n    \"0x8f15af4764bc275e6ccb892b3a4362cacb4e175b1526a9a99944e692fe6ccb1b4fc19abf312bb2a089cb1f344d91a779\",\n    \"0xa09b27ccd71855512aba1d0c30a79ffbe7f6707a55978f3ced50e674b511a79a446dbc6d7946add421ce111135a460af\",\n    \"0x94b2f98ce86a9271fbd4153e1fc37de48421fe3490fb3840c00f2d5a4d0ba8810c6a32880b002f6374b59e0a7952518b\",\n    \"0x8650ac644f93bbcb88a6a0f49fee2663297fd4bc6fd47b6a89b9d8038d32370438ab3a4775ec9b58cb10aea8a95ef7b6\",\n    \"0x95e5c2f2e84eed88c6980bbba5a1c0bb375d5a628bff006f7516d45bb7d723da676add4fdd45956f312e7bab0f052644\",\n    \"0xb3278a3fa377ac93af7cfc9453f8cb594aae04269bbc99d2e0e45472ff4b6a2f97a26c4c57bf675b9d86f5e77a5d55d1\",\n    \"0xb4bcbe6eb666a206e2ea2f877912c1d3b5bdbd08a989fc4490eb06013e1a69ad1ba08bcdac048bf29192312be399077b\",\n    \"0xa76d70b78c99fffcbf9bb9886eab40f1ea4f99a309710b660b64cbf86057cbcb644d243f6e341711bb7ef0fedf0435a7\",\n    \"0xb2093c1ee945dca7ac76ad5aed08eae23af31dd5a77c903fd7b6f051f4ab84425d33a03c3d45bf2907bc93c02d1f3ad8\",\n    \"0x904b1f7534e053a265b22d20be859912b9c9ccb303af9a8d6f1d8f6ccdc5c53eb4a45a1762b880d8444d9be0cd55e7f9\",\n    \"0x8f664a965d65bc730c9ef1ec7467be984d4b8eb46bd9b0d64e38e48f94e6e55dda19aeac82cbcf4e1473440e64c4ca18\",\n    \"0x8bcee65c4cc7a7799353d07b114c718a2aae0cd10a3f22b7eead5185d159dafd64852cb63924bf87627d176228878bce\",\n    \"0x8c78f2e3675096fef7ebaa898d2615cd50d39ca3d8f02b9bdfb07e67da648ae4be3da64838dffc5935fd72962c4b96c7\",\n    \"0x8c40afd3701629421fec1df1aac4e849384ef2e80472c0e28d36cb1327acdf2826f99b357f3d7afdbc58a6347fc40b3c\",\n    \"0xa197813b1c65a8ea5754ef782522a57d63433ef752215ecda1e7da76b0412ee619f58d904abd2e07e0c097048b6ae1dd\",\n    \"0xa670542629e4333884ad7410f9ea3bd6f988df4a8f8a424ca74b9add2312586900cf9ae8bd50411f9146e82626b4af56\",\n    \"0xa19875cc07ab84e569d98b8b67fb1dbbdfb59093c7b748fae008c8904a6fd931a63ca8d03ab5fea9bc8d263568125a9b\",\n    \"0xb57e7f68e4eb1bd04aafa917b1db1bdab759a02aa8a9cdb1cba34ba8852b5890f655645c9b4e15d5f19bf37e9f2ffe9f\",\n    \"0x8abe4e2a4f6462b6c64b3f10e45db2a53c2b0d3c5d5443d3f00a453e193df771eda635b098b6c8604ace3557514027af\",\n    \"0x8459e4fb378189b22b870a6ef20183deb816cefbf66eca1dc7e86d36a2e011537db893729f500dc154f14ce24633ba47\",\n    \"0x930851df4bc7913c0d8c0f7bd3b071a83668987ed7c397d3d042fdc0d9765945a39a3bae83da9c88cb6b686ed8aeeb26\",\n    \"0x8078c9e5cd05e1a8c932f8a1d835f61a248b6e7133fcbb3de406bf4ffc0e584f6f9f95062740ba6008d98348886cf76b\",\n    \"0xaddff62bb29430983fe578e3709b0949cdc0d47a13a29bc3f50371a2cb5c822ce53e2448cfaa01bcb6e0aa850d5a380e\",\n    \"0x9433add687b5a1e12066721789b1db2edf9b6558c3bdc0f452ba33b1da67426abe326e9a34d207bfb1c491c18811bde1\",\n    \"0x822beda3389963428cccc4a2918fa9a8a51cf0919640350293af70821967108cded5997adae86b33cb917780b097f1ca\",\n    \"0xa7a9f52bda45e4148ed56dd176df7bd672e9b5ed18888ccdb405f47920fdb0844355f8565cefb17010b38324edd8315f\",\n    \"0xb35c3a872e18e607b2555c51f9696a17fa18da1f924d503b163b4ec9fe22ed0c110925275cb6c93ce2d013e88f173d6a\",\n    \"0xadf34b002b2b26ab84fc1bf94e05bd8616a1d06664799ab149363c56a6e0c807fdc473327d25632416e952ea327fcd95\",\n    \"0xae4a6b9d22a4a3183fac29e2551e1124a8ce4a561a9a2afa9b23032b58d444e6155bb2b48f85c7b6d70393274e230db7\",\n    \"0xa2ea3be4fc17e9b7ce3110284038d46a09e88a247b6971167a7878d9dcf36925d613c382b400cfa4f37a3ebea3699897\",\n    \"0x8e5863786b641ce3140fbfe37124d7ad3925472e924f814ebfc45959aaf3f61dc554a597610b5defaecc85b59a99b50f\",\n    \"0xaefde3193d0f700d0f515ab2aaa43e2ef1d7831c4f7859f48e52693d57f97fa9e520090f3ed700e1c966f4b76048e57f\",\n    \"0x841a50f772956622798e5cd208dc7534d4e39eddee30d8ce133383d66e5f267e389254a0cdae01b770ecd0a9ca421929\",\n    \"0x8fbc2bfd28238c7d47d4c03b1b910946c0d94274a199575e5b23242619b1de3497784e646a92aa03e3e24123ae4fcaba\",\n    \"0x926999579c8eec1cc47d7330112586bdca20b4149c8b2d066f527c8b9f609e61ce27feb69db67eea382649c6905efcf9\",\n    \"0xb09f31f305efcc65589adf5d3690a76cf339efd67cd43a4e3ced7b839507466e4be72dd91f04e89e4bbef629d46e68c0\",\n    \"0xb917361f6b95f759642638e0b1d2b3a29c3bdef0b94faa30de562e6078c7e2d25976159df3edbacbf43614635c2640b4\",\n    \"0x8e7e8a1253bbda0e134d62bfe003a2669d471b47bd2b5cde0ff60d385d8e62279d54022f5ac12053b1e2d3aaa6910b4c\",\n    \"0xb69671a3c64e0a99d90b0ed108ce1912ff8ed983e4bddd75a370e9babde25ee1f5efb59ec707edddd46793207a8b1fe7\",\n    \"0x910b2f4ebd37b7ae94108922b233d0920b4aba0bd94202c70f1314418b548d11d8e9caa91f2cd95aff51b9432d122b7f\",\n    \"0x82f645c90dfb52d195c1020346287c43a80233d3538954548604d09fbab7421241cde8593dbc4acc4986e0ea39a27dd9\",\n    \"0x8fee895f0a140d88104ce442fed3966f58ff9d275e7373483f6b4249d64a25fb5374bbdc6bce6b5ab0270c2847066f83\",\n    \"0x84f5bd7aab27b2509397aeb86510dd5ac0a53f2c8f73799bf720f2f87a52277f8d6b0f77f17bc80739c6a7119b7eb062\",\n    \"0x9903ceced81099d7e146e661bcf01cbaccab5ba54366b85e2177f07e2d8621e19d9c9c3eee14b9266de6b3f9b6ea75ae\",\n    \"0xb9c16ea2a07afa32dd6c7c06df0dec39bca2067a9339e45475c98917f47e2320f6f235da353fd5e15b477de97ddc68dd\",\n    \"0x9820a9bbf8b826bec61ebf886de2c4f404c1ebdc8bab82ee1fea816d9de29127ce1852448ff717a3fe8bbfe9e92012e5\",\n    \"0x817224d9359f5da6f2158c2c7bf9165501424f063e67ba9859a07ab72ee2ee62eb00ca6da821cfa19065c3282ca72c74\",\n    \"0x94b95c465e6cb00da400558a3c60cfec4b79b27e602ca67cbc91aead08de4b6872d8ea096b0dc06dca4525c8992b8547\",\n    \"0xa2b539a5bccd43fa347ba9c15f249b417997c6a38c63517ca38394976baa08e20be384a360969ff54e7e721db536b3e5\",\n    \"0x96caf707e34f62811ee8d32ccf28d8d6ec579bc33e424d0473529af5315c456fd026aa910c1fed70c91982d51df7d3ca\",\n    \"0x8a77b73e890b644c6a142bdbac59b22d6a676f3b63ddafb52d914bb9d395b8bf5aedcbcc90429337df431ebd758a07a6\",\n    \"0x8857830a7351025617a08bc44caec28d2fae07ebf5ffc9f01d979ce2a53839a670e61ae2783e138313929129790a51a1\",\n    \"0xaa3e420321ed6f0aa326d28d1a10f13facec6f605b6218a6eb9cbc074801f3467bf013a456d1415a5536f12599efa3d3\",\n    \"0x824aed0951957b00ea2f3d423e30328a3527bf6714cf9abbae84cf27e58e5c35452ba89ccc011de7c68c75d6e021d8f1\",\n    \"0xa2e87cc06bf202e953fb1081933d8b4445527dde20e38ed1a4f440144fd8fa464a2b73e068b140562e9045e0f4bd3144\",\n    \"0xae3b8f06ad97d7ae3a5e5ca839efff3e4824dc238c0c03fc1a8d2fc8aa546cdfd165b784a31bb4dec7c77e9305b99a4b\",\n    \"0xb30c3e12395b1fb8b776f3ec9f87c70e35763a7b2ddc68f0f60a4982a84017f27c891a98561c830038deb033698ed7fc\",\n    \"0x874e507757cd1177d0dff0b0c62ce90130324442a33da3b2c8ee09dbca5d543e3ecfe707e9f1361e7c7db641c72794bb\",\n    \"0xb53012dd10b5e7460b57c092eaa06d6502720df9edbbe3e3f61a9998a272bf5baaac4a5a732ad4efe35d6fac6feca744\",\n    \"0x85e6509d711515534d394e6cacbed6c81da710074d16ef3f4950bf2f578d662a494d835674f79c4d6315bced4defc5f0\",\n    \"0xb6132b2a34b0905dcadc6119fd215419a7971fe545e52f48b768006944b4a9d7db1a74b149e2951ea48c083b752d0804\",\n    \"0x989867da6415036d19b4bacc926ce6f4df7a556f50a1ba5f3c48eea9cefbb1c09da81481c8009331ee83f0859185e164\",\n    \"0x960a6c36542876174d3fbc1505413e29f053ed87b8d38fef3af180491c7eff25200b45dd5fe5d4d8e63c7e8c9c00f4c8\",\n    \"0x9040b59bd739d9cc2e8f6e894683429e4e876a8106238689ff4c22770ae5fdae1f32d962b30301fa0634ee163b524f35\",\n    \"0xaf3fcd0a45fe9e8fe256dc7eab242ef7f582dd832d147444483c62787ac820fafc6ca55d639a73f76bfa5e7f5462ab8f\",\n    \"0xb934c799d0736953a73d91e761767fdb78454355c4b15c680ce08accb57ccf941b13a1236980001f9e6195801cffd692\",\n    \"0x8871e8e741157c2c326b22cf09551e78da3c1ec0fc0543136f581f1550f8bab03b0a7b80525c1e99812cdbf3a9698f96\",\n    \"0xa8a977f51473a91d178ee8cfa45ffef8d6fd93ab1d6e428f96a3c79816d9c6a93cd70f94d4deda0125fd6816e30f3bea\",\n    \"0xa7688b3b0a4fc1dd16e8ba6dc758d3cfe1b7cf401c31739484c7fa253cce0967df1b290769bcefc9d23d3e0cb19e6218\",\n    \"0x8ae84322662a57c6d729e6ff9d2737698cc2da2daeb1f39e506618750ed23442a6740955f299e4a15dda6db3e534d2c6\",\n    \"0xa04a961cdccfa4b7ef83ced17ab221d6a043b2c718a0d6cc8e6f798507a31f10bf70361f70a049bc8058303fa7f96864\",\n    \"0xb463e39732a7d9daec8a456fb58e54b30a6e160aa522a18b9a9e836488cce3342bcbb2e1deab0f5e6ec0a8796d77197d\",\n    \"0xb1434a11c6750f14018a2d3bcf94390e2948f4f187e93bb22070ca3e5393d339dc328cbfc3e48815f51929465ffe7d81\",\n    \"0x84ff81d73f3828340623d7e3345553610aa22a5432217ef0ebd193cbf4a24234b190c65ca0873c22d10ea7b63bd1fbed\",\n    \"0xb6fe2723f0c47757932c2ddde7a4f8434f665612f7b87b4009c2635d56b6e16b200859a8ade49276de0ef27a2b6c970a\",\n    \"0x9742884ed7cd52b4a4a068a43d3faa02551a424136c85a9313f7cb58ea54c04aa83b0728fd741d1fe39621e931e88f8f\",\n    \"0xb7d2d65ea4d1ad07a5dee39e40d6c03a61264a56b1585b4d76fc5b2a68d80a93a42a0181d432528582bf08d144c2d6a9\",\n    \"0x88c0f66bada89f8a43e5a6ead2915088173d106c76f724f4a97b0f6758aed6ae5c37c373c6b92cdd4aea8f6261f3a374\",\n    \"0x81f9c43582cb42db3900747eb49ec94edb2284999a499d1527f03315fd330e5a509afa3bff659853570e9886aab5b28b\",\n    \"0x821f9d27d6beb416abf9aa5c79afb65a50ed276dbda6060103bc808bcd34426b82da5f23e38e88a55e172f5c294b4d40\",\n    \"0x8ba307b9e7cb63a6c4f3851b321aebfdb6af34a5a4c3bd949ff7d96603e59b27ff4dc4970715d35f7758260ff942c9e9\",\n    \"0xb142eb6c5f846de33227d0bda61d445a7c33c98f0a8365fe6ab4c1fabdc130849be597ef734305894a424ea715372d08\",\n    \"0xa732730ae4512e86a741c8e4c87fee8a05ee840fec0e23b2e037d58dba8dde8d10a9bc5191d34d00598941becbbe467f\",\n    \"0xadce6f7c30fd221f6b10a0413cc76435c4bb36c2d60bca821e5c67409fe9dbb2f4c36ef85eb3d734695e4be4827e9fd3\",\n    \"0xa74f00e0f9b23aff7b2527ce69852f8906dab9d6abe62ecd497498ab21e57542e12af9918d4fd610bb09e10b0929c510\",\n    \"0xa593b6b0ef26448ce4eb3ab07e84238fc020b3cb10d542ff4b16d4e2be1bcde3797e45c9cf753b8dc3b0ffdb63984232\",\n    \"0xaed3913afccf1aa1ac0eb4980eb8426d0baccebd836d44651fd72af00d09fac488a870223c42aca3ceb39752070405ae\",\n    \"0xb2c44c66a5ea7fde626548ba4cef8c8710191343d3dadfd3bb653ce715c0e03056a5303a581d47dde66e70ea5a2d2779\",\n    \"0x8e5029b2ccf5128a12327b5103f7532db599846e422531869560ceaff392236434d87159f597937dbf4054f810c114f4\",\n    \"0x82beed1a2c4477e5eb39fc5b0e773b30cfec77ef2b1bf17eadaf60eb35b6d0dd9d8cf06315c48d3546badb3f21cd0cca\",\n    \"0x90077bd6cc0e4be5fff08e5d07a5a158d36cebd1d1363125bc4fae0866ffe825b26f933d4ee5427ba5cd0c33c19a7b06\",\n    \"0xa7ec0d8f079970e8e34f0ef3a53d3e0e45428ddcef9cc776ead5e542ef06f3c86981644f61c5a637e4faf001fb8c6b3e\",\n    \"0xae6d4add6d1a6f90b22792bc9d40723ee6850c27d0b97eefafd5b7fd98e424aa97868b5287cc41b4fbd7023bca6a322c\",\n    \"0x831aa917533d077da07c01417feaa1408846363ba2b8d22c6116bb858a95801547dd88b7d7fa1d2e3f0a02bdeb2e103d\",\n    \"0x96511b860b07c8a5ed773f36d4aa9d02fb5e7882753bf56303595bcb57e37ccc60288887eb83bef08c657ec261a021a2\",\n    \"0x921d2a3e7e9790f74068623de327443666b634c8443aba80120a45bba450df920b2374d96df1ce3fb1b06dd06f8cf6e3\",\n    \"0xaa74451d51fe82b4581ead8e506ec6cd881010f7e7dd51fc388eb9a557db5d3c6721f81c151d08ebd9c2591689fbc13e\",\n    \"0xa972bfbcf4033d5742d08716c927c442119bdae336bf5dff914523b285ccf31953da2733759aacaa246a9af9f698342c\",\n    \"0xad1fcd0cae0e76840194ce4150cb8a56ebed728ec9272035f52a799d480dfc85840a4d52d994a18b6edb31e79be6e8ad\",\n    \"0xa2c69fe1d36f235215432dad48d75887a44c99dfa0d78149acc74087da215a44bdb5f04e6eef88ff7eff80a5a7decc77\",\n    \"0xa94ab2af2b6ee1bc6e0d4e689ca45380d9fbd3c5a65b9bd249d266a4d4c07bf5d5f7ef2ae6000623aee64027892bf8fe\",\n    \"0x881ec1fc514e926cdc66480ac59e139148ff8a2a7895a49f0dff45910c90cdda97b66441a25f357d6dd2471cddd99bb3\",\n    \"0x884e6d3b894a914c8cef946a76d5a0c8351843b2bffa2d1e56c6b5b99c84104381dd1320c451d551c0b966f4086e60f9\",\n    \"0x817c6c10ce2677b9fc5223500322e2b880583254d0bb0d247d728f8716f5e05c9ff39f135854342a1afecd9fbdcf7c46\",\n    \"0xaaf4a9cb686a14619aa1fc1ac285dd3843ac3dd99f2b2331c711ec87b03491c02f49101046f3c5c538dc9f8dba2a0ac2\",\n    \"0x97ecea5ce53ca720b5d845227ae61d70269a2f53540089305c86af35f0898bfd57356e74a8a5e083fa6e1ea70080bd31\",\n    \"0xa22d811e1a20a75feac0157c418a4bfe745ccb5d29466ffa854dca03e395b6c3504a734341746b2846d76583a780b32e\",\n    \"0x940cbaa0d2b2db94ae96b6b9cf2deefbfd059e3e5745de9aec4a25f0991b9721e5cd37ef71c631575d1a0c280b01cd5b\",\n    \"0xae33cb4951191258a11044682de861bf8d92d90ce751b354932dd9f3913f542b6a0f8a4dc228b3cd9244ac32c4582832\",\n    \"0xa580df5e58c4274fe0f52ac2da1837e32f5c9db92be16c170187db4c358f43e5cfdda7c5911dcc79d77a5764e32325f5\",\n    \"0x81798178cb9d8affa424f8d3be67576ba94d108a28ccc01d330c51d5a63ca45bb8ca63a2f569b5c5fe1303cecd2d777f\",\n    \"0x89975b91b94c25c9c3660e4af4047a8bacf964783010820dbc91ff8281509379cb3b24c25080d5a01174dd9a049118d5\",\n    \"0xa7327fcb3710ed3273b048650bde40a32732ef40a7e58cf7f2f400979c177944c8bc54117ba6c80d5d4260801dddab79\",\n    \"0x92b475dc8cb5be4b90c482f122a51bcb3b6c70593817e7e2459c28ea54a7845c50272af38119406eaadb9bcb993368d0\",\n    \"0x9645173e9ecefc4f2eae8363504f7c0b81d85f8949a9f8a6c01f2d49e0a0764f4eacecf3e94016dd407fc14494fce9f9\",\n    \"0x9215fd8983d7de6ae94d35e6698226fc1454977ae58d42d294be9aad13ac821562ad37d5e7ee5cdfe6e87031d45cd197\",\n    \"0x810360a1c9b88a9e36f520ab5a1eb8bed93f52deefbe1312a69225c0a08edb10f87cc43b794aced9c74220cefcc57e7d\",\n    \"0xad7e810efd61ed4684aeda9ed8bb02fb9ae4b4b63fda8217d37012b94ff1b91c0087043bfa4e376f961fff030c729f3b\",\n    \"0x8b07c95c6a06db8738d10bb03ec11b89375c08e77f0cab7e672ce70b2685667ca19c7e1c8b092821d31108ea18dfd4c7\",\n    \"0x968825d025ded899ff7c57245250535c732836f7565eab1ae23ee7e513201d413c16e1ba3f5166e7ac6cf74de8ceef4f\",\n    \"0x908243370c5788200703ade8164943ad5f8c458219186432e74dbc9904a701ea307fd9b94976c866e6c58595fd891c4b\",\n    \"0x959969d16680bc535cdc6339e6186355d0d6c0d53d7bbfb411641b9bf4b770fd5f575beef5deec5c4fa4d192d455c350\",\n    \"0xad177f4f826a961adeac76da40e2d930748effff731756c797eddc4e5aa23c91f070fb69b19221748130b0961e68a6bb\",\n    \"0x82f8462bcc25448ef7e0739425378e9bb8a05e283ce54aae9dbebaf7a3469f57833c9171672ad43a79778366c72a5e37\",\n    \"0xa28fb275b1845706c2814d9638573e9bc32ff552ebaed761fe96fdbce70395891ca41c400ae438369264e31a2713b15f\",\n    \"0x8a9c613996b5e51dadb587a787253d6081ea446bf5c71096980bf6bd3c4b69905062a8e8a3792de2d2ece3b177a71089\",\n    \"0x8d5aefef9f60cb27c1db2c649221204dda48bb9bf8bf48f965741da051340e8e4cab88b9d15c69f3f84f4c854709f48a\",\n    \"0x93ebf2ca6ad85ab6deace6de1a458706285b31877b1b4d7dcb9d126b63047efaf8c06d580115ec9acee30c8a7212fa55\",\n    \"0xb3ee46ce189956ca298057fa8223b7fd1128cf52f39159a58bca03c71dd25161ac13f1472301f72aef3e1993fe1ab269\",\n    \"0xa24d7a8d066504fc3f5027ccb13120e2f22896860e02c45b5eba1dbd512d6a17c28f39155ea581619f9d33db43a96f92\",\n    \"0xae9ceacbfe12137db2c1a271e1b34b8f92e4816bad1b3b9b6feecc34df0f8b3b0f7ed0133acdf59c537d43d33fc8d429\",\n    \"0x83967e69bf2b361f86361bd705dce0e1ad26df06da6c52b48176fe8dfcbeb03c462c1a4c9e649eff8c654b18c876fdef\",\n    \"0x9148e6b814a7d779c19c31e33a068e97b597de1f8100513db3c581190513edc4d544801ce3dd2cf6b19e0cd6daedd28a\",\n    \"0x94ccdafc84920d320ed22de1e754adea072935d3c5f8c2d1378ebe53d140ea29853f056fb3fb1e375846061a038cc9bc\",\n    \"0xafb43348498c38b0fa5f971b8cdd3a62c844f0eb52bc33daf2f67850af0880fce84ecfb96201b308d9e6168a0d443ae3\",\n    \"0x86d5736520a83538d4cd058cc4b4e84213ed00ebd6e7af79ae787adc17a92ba5359e28ba6c91936d967b4b28d24c3070\",\n    \"0xb5210c1ff212c5b1e9ef9126e08fe120a41e386bb12c22266f7538c6d69c7fd8774f11c02b81fd4e88f9137b020801fe\",\n    \"0xb78cfd19f94d24e529d0f52e18ce6185cb238edc6bd43086270fd51dd99f664f43dd4c7d2fe506762fbd859028e13fcf\",\n    \"0xa6e7220598c554abdcc3fdc587b988617b32c7bb0f82c06205467dbedb58276cc07cae317a190f19d19078773f4c2bbb\",\n    \"0xb88862809487ee430368dccd85a5d72fa4d163ca4aad15c78800e19c1a95be2192719801e315d86cff7795e0544a77e4\",\n    \"0x87ecb13a03921296f8c42ceb252d04716f10e09c93962239fcaa0a7fef93f19ab3f2680bc406170108bc583e9ff2e721\",\n    \"0xa810cd473832b6581c36ec4cb403f2849357ba2d0b54df98ef3004b8a530c078032922a81d40158f5fb0043d56477f6e\",\n    \"0xa247b45dd85ca7fbb718b328f30a03f03c84aef2c583fbdc9fcc9eb8b52b34529e8c8f535505c10598b1b4dac3d7c647\",\n    \"0x96ee0b91313c68bac4aa9e065ce9e1d77e51ca4cff31d6a438718c58264dee87674bd97fc5c6b8008be709521e4fd008\",\n    \"0x837567ad073e42266951a9a54750919280a2ac835a73c158407c3a2b1904cf0d17b7195a393c71a18ad029cbd9cf79ee\",\n    \"0xa6a469c44b67ebf02196213e7a63ad0423aab9a6e54acc6fcbdbb915bc043586993454dc3cd9e4be8f27d67c1050879b\",\n    \"0x8712d380a843b08b7b294f1f06e2f11f4ad6bcc655fdde86a4d8bc739c23916f6fad2b902fe47d6212f03607907e9f0e\",\n    \"0x920adfb644b534789943cdae1bdd6e42828dda1696a440af2f54e6b97f4f97470a1c6ea9fa6a2705d8f04911d055acd1\",\n    \"0xa161c73adf584a0061e963b062f59d90faac65c9b3a936b837a10d817f02fcabfa748824607be45a183dd40f991fe83f\",\n    \"0x874f4ecd408c76e625ea50bc59c53c2d930ee25baf4b4eca2440bfbffb3b8bc294db579caa7c68629f4d9ec24187c1ba\",\n    \"0x8bff18087f112be7f4aa654e85c71fef70eee8ae480f61d0383ff6f5ab1a0508f966183bb3fc4d6f29cb7ca234aa50d3\",\n    \"0xb03b46a3ca3bc743a173cbc008f92ab1aedd7466b35a6d1ca11e894b9482ea9dc75f8d6db2ddd1add99bfbe7657518b7\",\n    \"0x8b4f3691403c3a8ad9e097f02d130769628feddfa8c2b3dfe8cff64e2bed7d6e5d192c1e2ba0ac348b8585e94acd5fa1\",\n    \"0xa0d9ca4a212301f97591bf65d5ef2b2664766b427c9dd342e23cb468426e6a56be66b1cb41fea1889ac5d11a8e3c50a5\",\n    \"0x8c93ed74188ca23b3df29e5396974b9cc135c91fdefdea6c0df694c8116410e93509559af55533a3776ac11b228d69b1\",\n    \"0x82dd331fb3f9e344ebdeeb557769b86a2cc8cc38f6c298d7572a33aea87c261afa9dbd898989139b9fc16bc1e880a099\",\n    \"0xa65faedf326bcfd8ef98a51410c78b021d39206704e8291cd1f09e096a66b9b0486be65ff185ca224c45918ac337ddeb\",\n    \"0xa188b37d363ac072a766fd5d6fa27df07363feff1342217b19e3c37385e42ffde55e4be8355aceaa2f267b6d66b4ac41\",\n    \"0x810fa3ba3e96d843e3bafd3f2995727f223d3567c8ba77d684c993ba1773c66551eb5009897c51b3fe9b37196984f5ec\",\n    \"0x87631537541852da323b4353af45a164f68b304d24c01183bf271782e11687f3fcf528394e1566c2a26cb527b3148e64\",\n    \"0xb721cb2b37b3c477a48e3cc0044167d51ff568a5fd2fb606e5aec7a267000f1ddc07d3db919926ae12761a8e017c767c\",\n    \"0x904dfad4ba2cc1f6e60d1b708438a70b1743b400164cd981f13c064b8328d5973987d4fb9cf894068f29d3deaf624dfb\",\n    \"0xa70491538893552c20939fae6be2f07bfa84d97e2534a6bbcc0f1729246b831103505e9f60e97a8fa7d2e6c1c2384579\",\n    \"0x8726cf1b26b41f443ff7485adcfddc39ace2e62f4d65dd0bb927d933e262b66f1a9b367ded5fbdd6f3b0932553ac1735\",\n    \"0xae8a11cfdf7aa54c08f80cb645e3339187ab3886babe9fae5239ba507bb3dd1c0d161ca474a2df081dcd3d63e8fe445e\",\n    \"0x92328719e97ce60e56110f30a00ac5d9c7a2baaf5f8d22355d53c1c77941e3a1fec7d1405e6fbf8959665fe2ba7a8cad\",\n    \"0x8d9d6255b65798d0018a8cccb0b6343efd41dc14ff2058d3eed9451ceaad681e4a0fa6af67b0a04318aa628024e5553d\",\n    \"0xb70209090055459296006742d946a513f0cba6d83a05249ee8e7a51052b29c0ca9722dc4af5f9816a1b7938a5dac7f79\",\n    \"0xaab7b766b9bf91786dfa801fcef6d575dc6f12b77ecc662eb4498f0312e54d0de9ea820e61508fc8aeee5ab5db529349\",\n    \"0xa8104b462337748b7f086a135d0c3f87f8e51b7165ca6611264b8fb639d9a2f519926cb311fa2055b5fadf03da70c678\",\n    \"0xb0d2460747d5d8b30fc6c6bd0a87cb343ddb05d90a51b465e8f67d499cfc5e3a9e365da05ae233bbee792cdf90ec67d5\",\n    \"0xaa55f5bf3815266b4a149f85ed18e451c93de9163575e3ec75dd610381cc0805bb0a4d7c4af5b1f94d10231255436d2c\",\n    \"0x8d4c6a1944ff94426151909eb5b99cfd92167b967dabe2bf3aa66bb3c26c449c13097de881b2cfc1bf052862c1ef7b03\",\n    \"0x8862296162451b9b6b77f03bf32e6df71325e8d7485cf3335d66fd48b74c2a8334c241db8263033724f26269ad95b395\",\n    \"0x901aa96deb26cda5d9321190ae6624d357a41729d72ef1abfd71bebf6139af6d690798daba53b7bc5923462115ff748a\",\n    \"0x96c195ec4992728a1eb38cdde42d89a7bce150db43adbc9e61e279ea839e538deec71326b618dd39c50d589f78fc0614\",\n    \"0xb6ff8b8aa0837b99a1a8b46fb37f20ad4aecc6a98381b1308697829a59b8442ffc748637a88cb30c9b1f0f28a926c4f6\",\n    \"0x8d807e3dca9e7bef277db1d2cfb372408dd587364e8048b304eff00eacde2c723bfc84be9b98553f83cba5c7b3cba248\",\n    \"0x8800c96adb0195c4fc5b24511450dee503c32bf47044f5e2e25bd6651f514d79a2dd9b01cd8c09f3c9d3859338490f57\",\n    \"0x89fe366096097e38ec28dd1148887112efa5306cc0c3da09562aafa56f4eb000bf46ff79bf0bdd270cbde6bf0e1c8957\",\n    \"0xaf409a90c2776e1e7e3760b2042507b8709e943424606e31e791d42f17873a2710797f5baaab4cc4a19998ef648556b0\",\n    \"0x8d761863c9b6edbd232d35ab853d944f5c950c2b643f84a1a1327ebb947290800710ff01dcfa26dc8e9828481240e8b1\",\n    \"0x90b95e9be1e55c463ed857c4e0617d6dc3674e99b6aa62ed33c8e79d6dfcf7d122f4f4cc2ee3e7c5a49170cb617d2e2e\",\n    \"0xb3ff381efefabc4db38cc4727432e0301949ae4f16f8d1dea9b4f4de611cf5a36d84290a0bef160dac4e1955e516b3b0\",\n    \"0xa8a84564b56a9003adcadb3565dc512239fc79572762cda7b5901a255bc82656bb9c01212ad33d6bef4fbbce18dacc87\",\n    \"0x90a081890364b222eef54bf0075417f85e340d2fec8b7375995f598aeb33f26b44143ebf56fca7d8b4ebb36b5747b0eb\",\n    \"0xade6ee49e1293224ddf2d8ab7f14bb5be6bc6284f60fd5b3a1e0cf147b73cff57cf19763b8a36c5083badc79c606b103\",\n    \"0xb2fa99806dd2fa3de09320b615a2570c416c9bcdb052e592b0aead748bbe407ec9475a3d932ae48b71c2627eb81986a6\",\n    \"0x91f3b7b73c8ccc9392542711c45fe6f236057e6efad587d661ad5cb4d6e88265f86b807bb1151736b1009ab74fd7acb4\",\n    \"0x8800e2a46af96696dfbdcbf2ca2918b3dcf28ad970170d2d1783b52b8d945a9167d052beeb55f56c126da7ffa7059baa\",\n    \"0x9862267a1311c385956b977c9aa08548c28d758d7ba82d43dbc3d0a0fd1b7a221d39e8399997fea9014ac509ff510ac4\",\n    \"0xb7d24f78886fd3e2d283e18d9ad5a25c1a904e7d9b9104bf47da469d74f34162e27e531380dbbe0a9d051e6ffd51d6e7\",\n    \"0xb0f445f9d143e28b9df36b0f2c052da87ee2ca374d9d0fbe2eff66ca6fe5fe0d2c1951b428d58f7314b7e74e45d445ea\",\n    \"0xb63fc4083eabb8437dafeb6a904120691dcb53ce2938b820bb553da0e1eecd476f72495aacb72600cf9cad18698fd3db\",\n    \"0xb9ffd8108eaebd582d665f8690fe8bb207fd85185e6dd9f0b355a09bac1bbff26e0fdb172bc0498df025414e88fe2eda\",\n    \"0x967ed453e1f1a4c5b7b6834cc9f75c13f6889edc0cc91dc445727e9f408487bbf05c337103f61397a10011dfbe25d61d\",\n    \"0x98ceb673aff36e1987d5521a3984a07079c3c6155974bb8b413e8ae1ce84095fe4f7862fba7aefa14753eb26f2a5805f\",\n    \"0x85f01d28603a8fdf6ce6a50cb5c44f8a36b95b91302e3f4cd95c108ce8f4d212e73aec1b8d936520d9226802a2bd9136\",\n    \"0x88118e9703200ca07910345fbb789e7a8f92bd80bbc79f0a9e040e8767d33df39f6eded403a9b636eabf9101e588482a\",\n    \"0x90833a51eef1b10ed74e8f9bbd6197e29c5292e469c854eed10b0da663e2bceb92539710b1858bbb21887bd538d28d89\",\n    \"0xb513b905ec19191167c6193067b5cfdf5a3d3828375360df1c7e2ced5815437dfd37f0c4c8f009d7fb29ff3c8793f560\",\n    \"0xb1b6d405d2d18f9554b8a358cc7e2d78a3b34269737d561992c8de83392ac9a2857be4bf15de5a6c74e0c9d0f31f393c\",\n    \"0xb828bd3e452b797323b798186607849f85d1fb20c616833c0619360dfd6b3e3aa000fd09dafe4b62d74abc41072ff1a9\",\n    \"0x8efde67d0cca56bb2c464731879c9ac46a52e75bac702a63200a5e192b4f81c641f855ca6747752b84fe469cb7113b6c\",\n    \"0xb2762ba1c89ac3c9a983c242e4d1c2610ff0528585ed5c0dfc8a2c0253551142af9b59f43158e8915a1da7cc26b9df67\",\n    \"0x8a3f1157fb820d1497ef6b25cd70b7e16bb8b961b0063ad340d82a79ee76eb2359ca9e15e6d42987ed7f154f5eeaa2da\",\n    \"0xa75e29f29d38f09c879f971c11beb5368affa084313474a5ecafa2896180b9e47ea1995c2733ec46f421e395a1d9cffe\",\n    \"0x8e8c3dd3e7196ef0b4996b531ec79e4a1f211db5d5635e48ceb80ff7568b2ff587e845f97ee703bb23a60945ad64314a\",\n    \"0x8e7f32f4a3e3c584af5e3d406924a0aa34024c42eca74ef6cc2a358fd3c9efaf25f1c03aa1e66bb94b023a2ee2a1cace\",\n    \"0xab7dce05d59c10a84feb524fcb62478906b3fa045135b23afbede3bb32e0c678d8ebe59feabccb5c8f3550ea76cae44b\",\n    \"0xb38bb4b44d827f6fd3bd34e31f9186c59e312dbfadd4a7a88e588da10146a78b1f8716c91ad8b806beb8da65cab80c4c\",\n    \"0x9490ce9442bbbd05438c7f5c4dea789f74a7e92b1886a730544b55ba377840740a3ae4f2f146ee73f47c9278b0e233bc\",\n    \"0x83c003fab22a7178eed1a668e0f65d4fe38ef3900044e9ec63070c23f2827d36a1e73e5c2b883ec6a2afe2450171b3b3\",\n    \"0x9982f02405978ddc4fca9063ebbdb152f524c84e79398955e66fe51bc7c1660ec1afc3a86ec49f58d7b7dde03505731c\",\n    \"0xab337bd83ccdd2322088ffa8d005f450ced6b35790f37ab4534313315ee84312adc25e99cce052863a8bedee991729ed\",\n    \"0x8312ce4bec94366d88f16127a17419ef64285cd5bf9e5eda010319b48085966ed1252ed2f5a9fd3e0259b91bb65f1827\",\n    \"0xa60d5a6327c4041b0c00a1aa2f0af056520f83c9ce9d9ccd03a0bd4d9e6a1511f26a422ea86bd858a1f77438adf07e6c\",\n    \"0xb84a0a0b030bdad83cf5202aa9afe58c9820e52483ab41f835f8c582c129ee3f34aa096d11c1cd922eda02ea1196a882\",\n    \"0x8077d105317f4a8a8f1aadeb05e0722bb55f11abcb490c36c0904401107eb3372875b0ac233144829e734f0c538d8c1d\",\n    \"0x9202503bd29a6ec198823a1e4e098f9cfe359ed51eb5174d1ca41368821bfeebcbd49debfd02952c41359d1c7c06d2b1\",\n    \"0xabc28c155e09365cb77ffead8dc8f602335ef93b2f44e4ef767ce8fc8ef9dd707400f3a722e92776c2e0b40192c06354\",\n    \"0xb0f6d1442533ca45c9399e0a63a11f85ff288d242cea6cb3b68c02e77bd7d158047cae2d25b3bcd9606f8f66d9b32855\",\n    \"0xb01c3d56a0db84dc94575f4b6ee2de4beca3230e86bed63e2066beb22768b0a8efb08ebaf8ac3dedb5fe46708b084807\",\n    \"0x8c8634b0432159f66feaabb165842d1c8ac378f79565b1b90c381aa8450eb4231c3dad11ec9317b9fc2b155c3a771e32\",\n    \"0x8e67f623d69ecd430c9ee0888520b6038f13a2b6140525b056dc0951f0cfed2822e62cf11d952a483107c5c5acac4826\",\n    \"0x9590bb1cba816dd6acd5ac5fba5142c0a19d53573e422c74005e0bcf34993a8138c83124cad35a3df65879dba6134edd\",\n    \"0x801cd96cde0749021a253027118d3ea135f3fcdbe895db08a6c145641f95ebd368dd6a1568d995e1d0084146aebe224a\",\n    \"0x848b5d196427f6fc1f762ee3d36e832b64a76ec1033cfedc8b985dea93932a7892b8ef1035c653fb9dcd9ab2d9a44ac8\",\n    \"0xa1017eb83d5c4e2477e7bd2241b2b98c4951a3b391081cae7d75965cadc1acaec755cf350f1f3d29741b0828e36fedea\",\n    \"0x8d6d2785e30f3c29aad17bd677914a752f831e96d46caf54446d967cb2432be2c849e26f0d193a60bee161ea5c6fe90a\",\n    \"0x935c0ba4290d4595428e034b5c8001cbd400040d89ab00861108e8f8f4af4258e41f34a7e6b93b04bc253d3b9ffc13bf\",\n    \"0xaac02257146246998477921cef2e9892228590d323b839f3e64ea893b991b463bc2f47e1e5092ddb47e70b2f5bce7622\",\n    \"0xb921fde9412970a5d4c9a908ae8ce65861d06c7679af577cf0ad0d5344c421166986bee471fd6a6cecb7d591f06ec985\",\n    \"0x8ef4c37487b139d6756003060600bb6ebac7ea810b9c4364fc978e842f13ac196d1264fbe5af60d76ff6d9203d8e7d3f\",\n    \"0x94b65e14022b5cf6a9b95f94be5ace2711957c96f4211c3f7bb36206bd39cfbd0ea82186cab5ad0577a23214a5c86e9e\",\n    \"0xa31c166d2a2ca1d5a75a5920fef7532681f62191a50d8555fdaa63ba4581c3391cc94a536fc09aac89f64eafceec3f90\",\n    \"0x919a8cc128de01e9e10f5d83b08b52293fdd41bde2b5ae070f3d95842d4a16e5331cf2f3d61c765570c8022403610fa4\",\n    \"0xb23d6f8331eef100152d60483cfa14232a85ee712c8538c9b6417a5a7c5b353c2ac401390c6c215cb101f5cee6b5f43e\",\n    \"0xab357160c08a18319510a571eafff154298ce1020de8e1dc6138a09fcb0fcbcdd8359f7e9386bda00b7b9cdea745ffdc\",\n    \"0xab55079aea34afa5c0bd1124b9cdfe01f325b402fdfa017301bf87812eaa811ea5798c3aaf818074d420d1c782b10ada\",\n    \"0xade616010dc5009e7fc4f8d8b00dc716686a5fa0a7816ad9e503e15839d3b909b69d9dd929b7575376434ffec0d2bea8\",\n    \"0x863997b97ed46898a8a014599508fa3079f414b1f4a0c4fdc6d74ae8b444afa350f327f8bfc2a85d27f9e2d049c50135\",\n    \"0x8d602ff596334efd4925549ed95f2aa762b0629189f0df6dbb162581657cf3ea6863cd2287b4d9c8ad52813d87fcd235\",\n    \"0xb70f68c596dcdeed92ad5c6c348578b26862a51eb5364237b1221e840c47a8702f0fbc56eb520a22c0eed99795d3903e\",\n    \"0x9628088f8e0853cefadee305a8bf47fa990c50fa96a82511bbe6e5dc81ef4b794e7918a109070f92fc8384d77ace226f\",\n    \"0x97e26a46e068b605ce96007197ecd943c9a23881862f4797a12a3e96ba2b8d07806ad9e2a0646796b1889c6b7d75188c\",\n    \"0xb1edf467c068cc163e2d6413cc22b16751e78b3312fe47b7ea82b08a1206d64415b2c8f2a677fa89171e82cc49797150\",\n    \"0xa44d15ef18745b251429703e3cab188420e2d974de07251501799b016617f9630643fcd06f895634d8ecdd579e1bf000\",\n    \"0xabd126df3917ba48c618ee4dbdf87df506193462f792874439043fa1b844466f6f4e0ff2e42516e63b5b23c0892b2695\",\n    \"0xa2a67f57c4aa3c2aa1eeddbfd5009a89c26c2ce8fa3c96a64626aba19514beb125f27df8559506f737de3eae0f1fc18f\",\n    \"0xa633e0132197e6038197304b296ab171f1d8e0d0f34dcf66fe9146ac385b0239232a8470b9205a4802ab432389f4836d\",\n    \"0xa914b3a28509a906c3821463b936455d58ff45dcbe158922f9efb2037f2eb0ce8e92532d29b5d5a3fcd0d23fa773f272\",\n    \"0xa0e1412ce4505daf1a2e59ce4f0fc0e0023e335b50d2b204422f57cd65744cc7a8ed35d5ef131a42c70b27111d3115b7\",\n    \"0xa2339e2f2b6072e88816224fdd612c04d64e7967a492b9f8829db15367f565745325d361fd0607b0def1be384d010d9e\",\n    \"0xa7309fc41203cb99382e8193a1dcf03ac190a7ce04835304eb7e341d78634e83ea47cb15b885601956736d04cdfcaa01\",\n    \"0x81f3ccd6c7f5b39e4e873365f8c37b214e8ab122d04a606fbb7339dc3298c427e922ec7418002561d4106505b5c399ee\",\n    \"0x92c121cf914ca549130e352eb297872a63200e99b148d88fbc9506ad882bec9d0203d65f280fb5b0ba92e336b7f932e8\",\n    \"0xa4b330cf3f064f5b131578626ad7043ce2a433b6f175feb0b52d36134a454ca219373fd30d5e5796410e005b69082e47\",\n    \"0x86fe5774112403ad83f9c55d58317eeb17ad8e1176d9f2f69c2afb7ed83bc718ed4e0245ceab4b377f5f062dcd4c00e7\",\n    \"0x809d152a7e2654c7fd175b57f7928365a521be92e1ed06c05188a95864ddb25f7cab4c71db7d61bbf4cae46f3a1d96ce\",\n    \"0xb82d663e55c2a5ada7e169e9b1a87bc1c0177baf1ec1c96559b4cb1c5214ce1ddf2ab8d345014cab6402f3774235cf5a\",\n    \"0x86580af86df1bd2c385adb8f9a079e925981b7184db66fc5fe5b14cddb82e7d836b06eaeef14924ac529487b23dae111\",\n    \"0xb5f5f4c5c94944ecc804df6ab8687d64e27d988cbfeae1ba7394e0f6adbf778c5881ead7cd8082dd7d68542b9bb4ecd5\",\n    \"0xa6016916146c2685c46e8fdd24186394e2d5496e77e08c0c6a709d4cd7dfa97f1efcef94922b89196819076a91ad37b5\",\n    \"0xb778e7367ded3b6eab53d5fc257f7a87e8faf74a593900f2f517220add2125be3f6142022660d8181df8d164ad9441ce\",\n    \"0x8581b2d36abe6f553add4d24be761bec1b8efaa2929519114346615380b3c55b59e6ad86990e312f7e234d0203bdf59b\",\n    \"0x9917e74fd45c3f71a829ff5498a7f6b5599b48c098dda2339bf04352bfc7f368ccf1a407f5835901240e76452ae807d7\",\n    \"0xafd196ce6f9335069138fd2e3d133134da253978b4ce373152c0f26affe77a336505787594022e610f8feb722f7cc1fb\",\n    \"0xa477491a1562e329764645e8f24d8e228e5ef28c9f74c6b5b3abc4b6a562c15ffb0f680d372aed04d9e1bf944dece7be\",\n    \"0x9767440d58c57d3077319d3a330e5322b9ba16981ec74a5a14d53462eab59ae7fd2b14025bfc63b268862094acb444e6\",\n    \"0x80986d921be3513ef69264423f351a61cb48390c1be8673aee0f089076086aaebea7ebe268fd0aa7182695606116f679\",\n    \"0xa9554c5c921c07b450ee04e34ec58e054ac1541b26ce2ce5a393367a97348ba0089f53db6660ad76b60278b66fd12e3e\",\n    \"0x95097e7d2999b3e84bf052c775581cf361325325f4a50192521d8f4693c830bed667d88f482dc1e3f833aa2bd22d2cbf\",\n    \"0x9014c91d0f85aefd28436b5228c12f6353c055a9326c7efbf5e071e089e2ee7c070fcbc84c5fafc336cbb8fa6fec1ca1\",\n    \"0x90f57ba36ee1066b55d37384942d8b57ae00f3cf9a3c1d6a3dfee1d1af42d4b5fa9baeb0cd7e46687d1d6d090ddb931d\",\n    \"0x8e4b1db12fd760a17214c9e47f1fce6e43c0dbb4589a827a13ac61aaae93759345697bb438a00edab92e0b7b62414683\",\n    \"0x8022a959a513cdc0e9c705e0fc04eafd05ff37c867ae0f31f6d01cddd5df86138a426cab2ff0ac8ff03a62e20f7e8f51\",\n    \"0x914e9a38829834c7360443b8ed86137e6f936389488eccf05b4b4db7c9425611705076ecb3f27105d24b85c852be7511\",\n    \"0x957fb10783e2bd0db1ba66b18e794df710bc3b2b05776be146fa5863c15b1ebdd39747b1a95d9564e1772cdfc4f37b8a\",\n    \"0xb6307028444daed8ed785ac9d0de76bc3fe23ff2cc7e48102553613bbfb5afe0ebe45e4212a27021c8eb870721e62a1f\",\n    \"0x8f76143597777d940b15a01b39c5e1b045464d146d9a30a6abe8b5d3907250e6c7f858ff2308f8591e8b0a7b3f3c568a\",\n    \"0x96163138ac0ce5fd00ae9a289648fd9300a0ca0f63a88481d703ecd281c06a52a3b5178e849e331f9c85ca4ba398f4cc\",\n    \"0xa63ef47c3e18245b0482596a09f488a716df3cbd0f9e5cfabed0d742843e65db8961c556f45f49762f3a6ac8b627b3ef\",\n    \"0x8cb595466552e7c4d42909f232d4063e0a663a8ef6f6c9b7ce3a0542b2459cde04e0e54c7623d404acb5b82775ac04f6\",\n    \"0xb47fe69960eb45f399368807cff16d941a5a4ebad1f5ec46e3dc8a2e4d598a7e6114d8f0ca791e9720fd786070524e2b\",\n    \"0x89eb5ff83eea9df490e5beca1a1fbbbbcf7184a37e2c8c91ede7a1e654c81e8cd41eceece4042ea7918a4f4646b67fd6\",\n    \"0xa84f5d155ed08b9054eecb15f689ba81e44589e6e7207a99790c598962837ca99ec12344105b16641ca91165672f7153\",\n    \"0xa6cc8f25c2d5b2d2f220ec359e6a37a52b95fa6af6e173c65e7cd55299eff4aa9e6d9e6f2769e6459313f1f2aecb0fab\",\n    \"0xafcde944411f017a9f7979755294981e941cc41f03df5e10522ef7c7505e5f1babdd67b3bf5258e8623150062eb41d9b\",\n    \"0x8fab39f39c0f40182fcd996ade2012643fe7731808afbc53f9b26900b4d4d1f0f5312d9d40b3df8baa4739970a49c732\",\n    \"0xae193af9726da0ebe7df1f9ee1c4846a5b2a7621403baf8e66c66b60f523e719c30c6b4f897bb14b27d3ff3da8392eeb\",\n    \"0x8ac5adb82d852eba255764029f42e6da92dcdd0e224d387d1ef94174038db9709ac558d90d7e7c57ad4ce7f89bbfc38c\",\n    \"0xa2066b3458fdf678ee487a55dd5bfb74fde03b54620cb0e25412a89ee28ad0d685e309a51e3e4694be2fa6f1593a344c\",\n    \"0x88d031745dd0ae07d61a15b594be5d4b2e2a29e715d081649ad63605e3404b0c3a5353f0fd9fad9c05c18e93ce674fa1\",\n    \"0x8283cfb0ef743a043f2b77ecaeba3005e2ca50435585b5dd24777ee6bce12332f85e21b446b536da38508807f0f07563\",\n    \"0xb376de22d5f6b0af0b59f7d9764561f4244cf8ffe22890ecd3dcf2ff1832130c9b821e068c9d8773136f4796721e5963\",\n    \"0xae3afc50c764f406353965363840bf28ee85e7064eb9d5f0bb3c31c64ab10f48c853e942ee2c9b51bae59651eaa08c2f\",\n    \"0x948b204d103917461a01a6c57a88f2d66b476eae5b00be20ec8c747650e864bc8a83aee0aff59cb7584b7a3387e0ee48\",\n    \"0x81ab098a082b07f896c5ffd1e4446cb7fb44804cbbf38d125208b233fc82f8ec9a6a8d8dd1c9a1162dc28ffeec0dde50\",\n    \"0xa149c6f1312821ced2969268789a3151bdda213451760b397139a028da609c4134ac083169feb0ee423a0acafd10eceb\",\n    \"0xb0ac9e27a5dadaf523010f730b28f0ebac01f460d3bbbe277dc9d44218abb5686f4fac89ae462682fef9edbba663520a\",\n    \"0x8d0e0073cca273daaaa61b6fc54bfe5a009bc3e20ae820f6c93ba77b19eca517d457e948a2de5e77678e4241807157cb\",\n    \"0xad61d3a2edf7c7533a04964b97499503fd8374ca64286dba80465e68fe932e96749b476f458c6fc57cb1a7ca85764d11\",\n    \"0x90eb5e121ae46bc01a30881eaa556f46bd8457a4e80787cf634aab355082de34ac57d7f497446468225f7721e68e2a47\",\n    \"0x8cdac557de7c42d1f3780e33dec1b81889f6352279be81c65566cdd4952d4c15d79e656cbd46035ab090b385e90245ef\",\n    \"0x82b67e61b88b84f4f4d4f65df37b3e3dcf8ec91ea1b5c008fdccd52da643adbe6468a1cfdb999e87d195afe2883a3b46\",\n    \"0x8503b467e8f5d6048a4a9b78496c58493a462852cab54a70594ae3fd064cfd0deb4b8f336a262155d9fedcaa67d2f6fd\",\n    \"0x8db56c5ac763a57b6ce6832930c57117058e3e5a81532b7d19346346205e2ec614eb1a2ee836ef621de50a7bc9b7f040\",\n    \"0xad344699198f3c6e8c0a3470f92aaffc805b76266734414c298e10b5b3797ca53578de7ccb2f458f5e0448203f55282b\",\n    \"0x80602032c43c9e2a09154cc88b83238343b7a139f566d64cb482d87436b288a98f1ea244fd3bff8da3c398686a900c14\",\n    \"0xa6385bd50ecd548cfb37174cdbb89e10025b5cadaf3cff164c95d7aef5a33e3d6a9bf0c681b9e11db9ef54ebeee2a0c1\",\n    \"0xabf2d95f4aa34b0581eb9257a0cc8462b2213941a5deb8ba014283293e8b36613951b61261cc67bbd09526a54cbbff76\",\n    \"0xa3d5de52f48df72c289ff713e445991f142390798cd42bd9d9dbefaee4af4f5faf09042d126b975cf6b98711c3072553\",\n    \"0x8e627302ff3d686cff8872a1b7c2a57b35f45bf2fc9aa42b049d8b4d6996a662b8e7cbac6597f0cb79b0cc4e29fbf133\",\n    \"0x8510702e101b39a1efbf4e504e6123540c34b5689645e70d0bac1ecc1baf47d86c05cef6c4317a4e99b4edaeb53f2d00\",\n    \"0xaa173f0ecbcc6088f878f8726d317748c81ebf501bba461f163b55d66099b191ec7c55f7702f351a9c8eb42cfa3280e2\",\n    \"0xb560a697eafab695bcef1416648a0a664a71e311ecbe5823ae903bd0ed2057b9d7574b9a86d3fe22aa3e6ddce38ea513\",\n    \"0x8df6304a3d9cf40100f3f687575419c998cd77e5cc27d579cf4f8e98642de3609af384a0337d145dd7c5635172d26a71\",\n    \"0x8105c7f3e4d30a29151849673853b457c1885c186c132d0a98e63096c3774bc9deb956cf957367e633d0913680bda307\",\n    \"0x95373fc22c0917c3c2044ac688c4f29a63ed858a45c0d6d2d0fe97afd6f532dcb648670594290c1c89010ecc69259bef\",\n    \"0x8c2fae9bcadab341f49b55230310df93cac46be42d4caa0d42e45104148a91e527af1b4209c0d972448162aed28fab64\",\n    \"0xb05a77baab70683f76209626eaefdda2d36a0b66c780a20142d23c55bd479ddd4ad95b24579384b6cf62c8eb4c92d021\",\n    \"0x8e6bc6a7ea2755b4aaa19c1c1dee93811fcde514f03485fdc3252f0ab7f032c315614f6336e57cea25dcfb8fb6084eeb\",\n    \"0xb656a27d06aade55eadae2ad2a1059198918ea6cc3fd22c0ed881294d34d5ac7b5e4700cc24350e27d76646263b223aa\",\n    \"0xa296469f24f6f56da92d713afcd4dd606e7da1f79dc4e434593c53695847eefc81c7c446486c4b3b8c8d00c90c166f14\",\n    \"0x87a326f57713ac2c9dffeb3af44b9f3c613a8f952676fc46343299122b47ee0f8d792abaa4b5db6451ced5dd153aabd0\",\n    \"0xb689e554ba9293b9c1f6344a3c8fcb6951d9f9eac4a2e2df13de021aade7c186be27500e81388e5b8bcab4c80f220a31\",\n    \"0x87ae0aa0aa48eac53d1ca5a7b93917de12db9e40ceabf8fdb40884ae771cfdf095411deef7c9f821af0b7070454a2608\",\n    \"0xa71ffa7eae8ace94e6c3581d4cb2ad25d48cbd27edc9ec45baa2c8eb932a4773c3272b2ffaf077b40f76942a1f3af7f2\",\n    \"0x94c218c91a9b73da6b7a495b3728f3028df8ad9133312fc0c03e8c5253b7ccb83ed14688fd4602e2fd41f29a0bc698bd\",\n    \"0xae1e77b90ca33728af07a4c03fb2ef71cd92e2618e7bf8ed4d785ce90097fc4866c29999eb84a6cf1819d75285a03af2\",\n    \"0xb7a5945b277dab9993cf761e838b0ac6eaa903d7111fca79f9fde3d4285af7a89bf6634a71909d095d7619d913972c9c\",\n    \"0x8c43b37be02f39b22029b20aca31bff661abce4471dca88aa3bddefd9c92304a088b2dfc8c4795acc301ca3160656af2\",\n    \"0xb32e5d0fba024554bd5fe8a793ebe8003335ddd7f585876df2048dcf759a01285fecb53daae4950ba57f3a282a4d8495\",\n    \"0x85ea7fd5e10c7b659df5289b2978b2c89e244f269e061b9a15fcab7983fc1962b63546e82d5731c97ec74b6804be63ef\",\n    \"0x96b89f39181141a7e32986ac02d7586088c5a9662cec39843f397f3178714d02f929af70630c12cbaba0268f8ba2d4fa\",\n    \"0x929ab1a2a009b1eb37a2817c89696a06426529ebe3f306c586ab717bd34c35a53eca2d7ddcdef36117872db660024af9\",\n    \"0xa696dccf439e9ca41511e16bf3042d7ec0e2f86c099e4fc8879d778a5ea79e33aa7ce96b23dc4332b7ba26859d8e674d\",\n    \"0xa8fe69a678f9a194b8670a41e941f0460f6e2dbc60470ab4d6ae2679cc9c6ce2c3a39df2303bee486dbfde6844e6b31a\",\n    \"0x95f58f5c82de2f2a927ca99bf63c9fc02e9030c7e46d0bf6b67fe83a448d0ae1c99541b59caf0e1ccab8326231af09a5\",\n    \"0xa57badb2c56ca2c45953bd569caf22968f76ed46b9bac389163d6fe22a715c83d5e94ae8759b0e6e8c2f27bff7748f3f\",\n    \"0x868726fd49963b24acb5333364dffea147e98f33aa19c7919dc9aca0fd26661cfaded74ede7418a5fadbe7f5ae67b67b\",\n    \"0xa8d8550dcc64d9f1dd7bcdab236c4122f2b65ea404bb483256d712c7518f08bb028ff8801f1da6aed6cbfc5c7062e33b\",\n    \"0x97e25a87dae23155809476232178538d4bc05d4ff0882916eb29ae515f2a62bfce73083466cc0010ca956aca200aeacc\",\n    \"0xb4ea26be3f4bd04aa82d7c4b0913b97bcdf5e88b76c57eb1a336cbd0a3eb29de751e1bc47c0e8258adec3f17426d0c71\",\n    \"0x99ee555a4d9b3cf2eb420b2af8e3bc99046880536116d0ce7193464ac40685ef14e0e3c442f604e32f8338cb0ef92558\",\n    \"0x8c64efa1da63cd08f319103c5c7a761221080e74227bbc58b8fb35d08aa42078810d7af3e60446cbaff160c319535648\",\n    \"0x8d9fd88040076c28420e3395cbdfea402e4077a3808a97b7939d49ecbcf1418fe50a0460e1c1b22ac3f6e7771d65169a\",\n    \"0xae3c19882d7a9875d439265a0c7003c8d410367627d21575a864b9cb4918de7dbdb58a364af40c5e045f3df40f95d337\",\n    \"0xb4f7bfacab7b2cafe393f1322d6dcc6f21ffe69cd31edc8db18c06f1a2b512c27bd0618091fd207ba8df1808e9d45914\",\n    \"0x94f134acd0007c623fb7934bcb65ef853313eb283a889a3ffa79a37a5c8f3665f3d5b4876bc66223610c21dc9b919d37\",\n    \"0xaa15f74051171daacdc1f1093d3f8e2d13da2833624b80a934afec86fc02208b8f55d24b7d66076444e7633f46375c6a\",\n    \"0xa32d6bb47ef9c836d9d2371807bafbbbbb1ae719530c19d6013f1d1f813c49a60e4fa51d83693586cba3a840b23c0404\",\n    \"0xb61b3599145ea8680011aa2366dc511a358b7d67672d5b0c5be6db03b0efb8ca5a8294cf220ea7409621f1664e00e631\",\n    \"0x859cafc3ee90b7ececa1ed8ef2b2fc17567126ff10ca712d5ffdd16aa411a5a7d8d32c9cab1fbf63e87dce1c6e2f5f53\",\n    \"0xa2fef1b0b2874387010e9ae425f3a9676d01a095d017493648bcdf3b31304b087ccddb5cf76abc4e1548b88919663b6b\",\n    \"0x939e18c73befc1ba2932a65ede34c70e4b91e74cc2129d57ace43ed2b3af2a9cc22a40fbf50d79a63681b6d98852866d\",\n    \"0xb3b4259d37b1b14aee5b676c9a0dd2d7f679ab95c120cb5f09f9fbf10b0a920cb613655ddb7b9e2ba5af4a221f31303c\",\n    \"0x997255fe51aaca6e5a9cb3359bcbf25b2bb9e30649bbd53a8a7c556df07e441c4e27328b38934f09c09d9500b5fabf66\",\n    \"0xabb91be2a2d860fd662ed4f1c6edeefd4da8dc10e79251cf87f06029906e7f0be9b486462718f0525d5e049472692cb7\",\n    \"0xb2398e593bf340a15f7801e1d1fbda69d93f2a32a889ec7c6ae5e8a37567ac3e5227213c1392ee86cfb3b56ec2787839\",\n    \"0x8ddf10ccdd72922bed36829a36073a460c2118fc7a56ff9c1ac72581c799b15c762cb56cb78e3d118bb9f6a7e56cb25e\",\n    \"0x93e6bc0a4708d16387cacd44cf59363b994dc67d7ada7b6d6dbd831c606d975247541b42b2a309f814c1bfe205681fc6\",\n    \"0xb93fc35c05998cffda2978e12e75812122831523041f10d52f810d34ff71944979054b04de0117e81ddf5b0b4b3e13c0\",\n    \"0x92221631c44d60d68c6bc7b287509f37ee44cbe5fdb6935cee36b58b17c7325098f98f7910d2c3ca5dc885ad1d6dabc7\",\n    \"0xa230124424a57fad3b1671f404a94d7c05f4c67b7a8fbacfccea28887b78d7c1ed40b92a58348e4d61328891cd2f6cee\",\n    \"0xa6a230edb8518a0f49d7231bc3e0bceb5c2ac427f045819f8584ba6f3ae3d63ed107a9a62aad543d7e1fcf1f20605706\",\n    \"0x845be1fe94223c7f1f97d74c49d682472585d8f772762baad8a9d341d9c3015534cc83d102113c51a9dea2ab10d8d27b\",\n    \"0xb44262515e34f2db597c8128c7614d33858740310a49cdbdf9c8677c5343884b42c1292759f55b8b4abc4c86e4728033\",\n    \"0x805592e4a3cd07c1844bc23783408310accfdb769cca882ad4d07d608e590a288b7370c2cb327f5336e72b7083a0e30f\",\n    \"0x95153e8b1140df34ee864f4ca601cb873cdd3efa634af0c4093fbaede36f51b55571ab271e6a133020cd34db8411241f\",\n    \"0x82878c1285cfa5ea1d32175c9401f3cc99f6bb224d622d3fd98cc7b0a27372f13f7ab463ce3a33ec96f9be38dbe2dfe3\",\n    \"0xb7588748f55783077c27fc47d33e20c5c0f5a53fc0ac10194c003aa09b9f055d08ec971effa4b7f760553997a56967b3\",\n    \"0xb36b4de6d1883b6951f59cfae381581f9c6352fcfcf1524fccdab1571a20f80441d9152dc6b48bcbbf00371337ca0bd5\",\n    \"0x89c5523f2574e1c340a955cbed9c2f7b5fbceb260cb1133160dabb7d41c2f613ec3f6e74bbfab3c4a0a6f0626dbe068f\",\n    \"0xa52f58cc39f968a9813b1a8ddc4e83f4219e4dd82c7aa1dd083bea7edf967151d635aa9597457f879771759b876774e4\",\n    \"0x8300a67c2e2e123f89704abfde095463045dbd97e20d4c1157bab35e9e1d3d18f1f4aaba9cbe6aa2d544e92578eaa1b6\",\n    \"0xac6a7f2918768eb6a43df9d3a8a04f8f72ee52f2e91c064c1c7d75cad1a3e83e5aba9fe55bb94f818099ac91ccf2e961\",\n    \"0x8d64a2b0991cf164e29835c8ddef6069993a71ec2a7de8157bbfa2e00f6367be646ed74cbaf524f0e9fe13fb09fa15fd\",\n    \"0x8b2ffe5a545f9f680b49d0a9797a4a11700a2e2e348c34a7a985fc278f0f12def6e06710f40f9d48e4b7fbb71e072229\",\n    \"0x8ab8f71cd337fa19178924e961958653abf7a598e3f022138b55c228440a2bac4176cea3aea393549c03cd38a13eb3fc\",\n    \"0x8419d28318c19ea4a179b7abb43669fe96347426ef3ac06b158d79c0acf777a09e8e770c2fb10e14b3a0421705990b23\",\n    \"0x8bacdac310e1e49660359d0a7a17fe3d334eb820e61ae25e84cb52f863a2f74cbe89c2e9fc3283745d93a99b79132354\",\n    \"0xb57ace3fa2b9f6b2db60c0d861ace7d7e657c5d35d992588aeed588c6ce3a80b6f0d49f8a26607f0b17167ab21b675e4\",\n    \"0x83e265cde477f2ecc164f49ddc7fb255bb05ff6adc347408353b7336dc3a14fdedc86d5a7fb23f36b8423248a7a67ed1\",\n    \"0xa60ada971f9f2d79d436de5d3d045f5ab05308cae3098acaf5521115134b2a40d664828bb89895840db7f7fb499edbc5\",\n    \"0xa63eea12efd89b62d3952bf0542a73890b104dd1d7ff360d4755ebfa148fd62de668edac9eeb20507967ea37fb220202\",\n    \"0xa0275767a270289adc991cc4571eff205b58ad6d3e93778ddbf95b75146d82517e8921bd0d0564e5b75fa0ccdab8e624\",\n    \"0xb9b03fd3bf07201ba3a039176a965d736b4ef7912dd9e9bf69fe1b57c330a6aa170e5521fe8be62505f3af81b41d7806\",\n    \"0xa95f640e26fb1106ced1729d6053e41a16e4896acac54992279ff873e5a969aad1dcfa10311e28b8f409ac1dab7f03bb\",\n    \"0xb144778921742418053cb3c70516c63162c187f00db2062193bb2c14031075dbe055d020cde761b26e8c58d0ea6df2c1\",\n    \"0x8432fbb799e0435ef428d4fefc309a05dd589bce74d7a87faf659823e8c9ed51d3e42603d878e80f439a38be4321c2fa\",\n    \"0xb08ddef14e42d4fd5d8bf39feb7485848f0060d43b51ed5bdda39c05fe154fb111d29719ee61a23c392141358c0cfcff\",\n    \"0x8ae3c5329a5e025b86b5370e06f5e61177df4bda075856fade20a17bfef79c92f54ed495f310130021ba94fb7c33632b\",\n    \"0x92b6d3c9444100b4d7391febfc1dddaa224651677c3695c47a289a40d7a96d200b83b64e6d9df51f534564f272a2c6c6\",\n    \"0xb432bc2a3f93d28b5e506d68527f1efeb2e2570f6be0794576e2a6ef9138926fdad8dd2eabfa979b79ab7266370e86bc\",\n    \"0x8bc315eacedbcfc462ece66a29662ca3dcd451f83de5c7626ef8712c196208fb3d8a0faf80b2e80384f0dd9772f61a23\",\n    \"0xa72375b797283f0f4266dec188678e2b2c060dfed5880fc6bb0c996b06e91a5343ea2b695adaab0a6fd183b040b46b56\",\n    \"0xa43445036fbaa414621918d6a897d3692fdae7b2961d87e2a03741360e45ebb19fcb1703d23f1e15bb1e2babcafc56ac\",\n    \"0xb9636b2ffe305e63a1a84bd44fb402442b1799bd5272638287aa87ca548649b23ce8ce7f67be077caed6aa2dbc454b78\",\n    \"0x99a30bf0921d854c282b83d438a79f615424f28c2f99d26a05201c93d10378ab2cd94a792b571ddae5d4e0c0013f4006\",\n    \"0x8648e3c2f93d70b392443be116b48a863e4b75991bab5db656a4ef3c1e7f645e8d536771dfe4e8d1ceda3be8d32978b0\",\n    \"0xab50dc9e6924c1d2e9d2e335b2d679fc7d1a7632e84964d3bac0c9fe57e85aa5906ec2e7b0399d98ddd022e9b19b5904\",\n    \"0xab729328d98d295f8f3272afaf5d8345ff54d58ff9884da14f17ecbdb7371857fdf2f3ef58080054e9874cc919b46224\",\n    \"0x83fa5da7592bd451cad3ad7702b4006332b3aae23beab4c4cb887fa6348317d234bf62a359e665b28818e5410c278a09\",\n    \"0x8bdbff566ae9d368f114858ef1f009439b3e9f4649f73efa946e678d6c781d52c69af195df0a68170f5f191b2eac286b\",\n    \"0x91245e59b4425fd4edb2a61d0d47c1ccc83d3ced8180de34887b9655b5dcda033d48cde0bdc3b7de846d246c053a02e8\",\n    \"0xa2cb00721e68f1cad8933947456f07144dc69653f96ceed845bd577d599521ba99cdc02421118971d56d7603ed118cbf\",\n    \"0xaf8cd66d303e808b22ec57860dd909ca64c27ec2c60e26ffecfdc1179d8762ffd2739d87b43959496e9fee4108df71df\",\n    \"0x9954136812dffcd5d3f167a500e7ab339c15cfc9b3398d83f64b0daa3dd5b9a851204f424a3493b4e326d3de81e50a62\",\n    \"0x93252254d12511955f1aa464883ad0da793f84d900fea83e1df8bca0f2f4cf5b5f9acbaec06a24160d33f908ab5fea38\",\n    \"0x997cb55c26996586ba436a95566bd535e9c22452ca5d2a0ded2bd175376557fa895f9f4def4519241ff386a063f2e526\",\n    \"0xa12c78ad451e0ac911260ade2927a768b50cb4125343025d43474e7f465cdc446e9f52a84609c5e7e87ae6c9b3f56cda\",\n    \"0xa789d4ca55cbba327086563831b34487d63d0980ba8cf55197c016702ed6da9b102b1f0709ce3da3c53ff925793a3d73\",\n    \"0xa5d76acbb76741ce85be0e655b99baa04f7f587347947c0a30d27f8a49ae78cce06e1cde770a8b618d3db402be1c0c4b\",\n    \"0x873c0366668c8faddb0eb7c86f485718d65f8c4734020f1a18efd5fa123d3ea8a990977fe13592cd01d17e60809cb5ff\",\n    \"0xb659b71fe70f37573ff7c5970cc095a1dc0da3973979778f80a71a347ef25ad5746b2b9608bad4ab9a4a53a4d7df42d7\",\n    \"0xa34cbe05888e5e5f024a2db14cb6dcdc401a9cbd13d73d3c37b348f68688f87c24ca790030b8f84fef9e74b4eab5e412\",\n    \"0x94ce8010f85875c045b0f014db93ef5ab9f1f6842e9a5743dce9e4cb872c94affd9e77c1f1d1ab8b8660b52345d9acb9\",\n    \"0xadefa9b27a62edc0c5b019ddd3ebf45e4de846165256cf6329331def2e088c5232456d3de470fdce3fa758bfdd387512\",\n    \"0xa6b83821ba7c1f83cc9e4529cf4903adb93b26108e3d1f20a753070db072ad5a3689643144bdd9c5ea06bb9a7a515cd0\",\n    \"0xa3a9ddedc2a1b183eb1d52de26718151744db6050f86f3580790c51d09226bf05f15111691926151ecdbef683baa992c\",\n    \"0xa64bac89e7686932cdc5670d07f0b50830e69bfb8c93791c87c7ffa4913f8da881a9d8a8ce8c1a9ce5b6079358c54136\",\n    \"0xa77b5a63452cb1320b61ab6c7c2ef9cfbcade5fd4727583751fb2bf3ea330b5ca67757ec1f517bf4d503ec924fe32fbd\",\n    \"0x8746fd8d8eb99639d8cd0ca34c0d9c3230ed5a312aab1d3d925953a17973ee5aeb66e68667e93caf9cb817c868ea8f3d\",\n    \"0x88a2462a26558fc1fbd6e31aa8abdc706190a17c27fdc4217ffd2297d1b1f3321016e5c4b2384c5454d5717dc732ed03\",\n    \"0xb78893a97e93d730c8201af2e0d3b31cb923d38dc594ffa98a714e627c473d42ea82e0c4d2eeb06862ee22a9b2c54588\",\n    \"0x920cc8b5f1297cf215a43f6fc843e379146b4229411c44c0231f6749793d40f07b9af7699fd5d21fd69400b97febe027\",\n    \"0xa0f0eafce1e098a6b58c7ad8945e297cd93aaf10bc55e32e2e32503f02e59fc1d5776936577d77c0b1162cb93b88518b\",\n    \"0x98480ba0064e97a2e7a6c4769b4d8c2a322cfc9a3b2ca2e67e9317e2ce04c6e1108169a20bd97692e1cb1f1423b14908\",\n    \"0x83dbbb2fda7e287288011764a00b8357753a6a44794cc8245a2275237f11affdc38977214e463ad67aec032f3dfa37e9\",\n    \"0x86442fff37598ce2b12015ff19b01bb8a780b40ad353d143a0f30a06f6d23afd5c2b0a1253716c855dbf445cc5dd6865\",\n    \"0xb8a4c60c5171189414887847b9ed9501bff4e4c107240f063e2d254820d2906b69ef70406c585918c4d24f1dd052142b\",\n    \"0x919f33a98e84015b2034b57b5ffe9340220926b2c6e45f86fd79ec879dbe06a148ae68b77b73bf7d01bd638a81165617\",\n    \"0x95c13e78d89474a47fbc0664f6f806744b75dede95a479bbf844db4a7f4c3ae410ec721cb6ffcd9fa9c323da5740d5ae\",\n    \"0xab7151acc41fffd8ec6e90387700bcd7e1cde291ea669567295bea1b9dd3f1df2e0f31f3588cd1a1c08af8120aca4921\",\n    \"0x80e74c5c47414bd6eeef24b6793fb1fa2d8fb397467045fcff887c52476741d5bc4ff8b6d3387cb53ad285485630537f\",\n    \"0xa296ad23995268276aa351a7764d36df3a5a3cffd7dbeddbcea6b1f77adc112629fdeffa0918b3242b3ccd5e7587e946\",\n    \"0x813d2506a28a2b01cb60f49d6bd5e63c9b056aa56946faf2f33bd4f28a8d947569cfead3ae53166fc65285740b210f86\",\n    \"0x924b265385e1646287d8c09f6c855b094daaee74b9e64a0dddcf9ad88c6979f8280ba30c8597b911ef58ddb6c67e9fe3\",\n    \"0x8d531513c70c2d3566039f7ca47cd2352fd2d55b25675a65250bdb8b06c3843db7b2d29c626eed6391c238fc651cf350\",\n    \"0x82b338181b62fdc81ceb558a6843df767b6a6e3ceedc5485664b4ea2f555904b1a45fbb35f6cf5d96f27da10df82a325\",\n    \"0x92e62faaedea83a37f314e1d3cb4faaa200178371d917938e59ac35090be1db4b4f4e0edb78b9c991de202efe4f313d8\",\n    \"0x99d645e1b642c2dc065bac9aaa0621bc648c9a8351efb6891559c3a41ba737bd155fb32d7731950514e3ecf4d75980e4\",\n    \"0xb34a13968b9e414172fb5d5ece9a39cf2eb656128c3f2f6cc7a9f0c69c6bae34f555ecc8f8837dc34b5e470e29055c78\",\n    \"0xa2a0bb7f3a0b23a2cbc6585d59f87cd7e56b2bbcb0ae48f828685edd9f7af0f5edb4c8e9718a0aaf6ef04553ba71f3b7\",\n    \"0x8e1a94bec053ed378e524b6685152d2b52d428266f2b6eadd4bcb7c4e162ed21ab3e1364879673442ee2162635b7a4d8\",\n    \"0x9944adaff14a85eab81c73f38f386701713b52513c4d4b838d58d4ffa1d17260a6d056b02334850ea9a31677c4b078bd\",\n    \"0xa450067c7eceb0854b3eca3db6cf38669d72cb7143c3a68787833cbca44f02c0be9bfbe082896f8a57debb13deb2afb1\",\n    \"0x8be4ad3ac9ef02f7df09254d569939757101ee2eda8586fefcd8c847adc1efe5bdcb963a0cafa17651befaafb376a531\",\n    \"0x90f6de91ea50255f148ac435e08cf2ac00c772a466e38155bd7e8acf9197af55662c7b5227f88589b71abe9dcf7ba343\",\n    \"0x86e5a24f0748b106dee2d4d54e14a3b0af45a96cbee69cac811a4196403ebbee17fd24946d7e7e1b962ac7f66dbaf610\",\n    \"0xafdd96fbcda7aa73bf9eeb2292e036c25753d249caee3b9c013009cc22e10d3ec29e2aa6ddbb21c4e949b0c0bccaa7f4\",\n    \"0xb5a4e7436d5473647c002120a2cb436b9b28e27ad4ebdd7c5f122b91597c507d256d0cbd889d65b3a908531936e53053\",\n    \"0xb632414c3da704d80ac2f3e5e0e9f18a3637cdc2ebeb613c29300745582427138819c4e7b0bec3099c1b8739dac1807b\",\n    \"0xa28df1464d3372ce9f37ef1db33cc010f752156afae6f76949d98cd799c0cf225c20228ae86a4da592d65f0cffe3951b\",\n    \"0x898b93d0a31f7d3f11f253cb7a102db54b669fd150da302d8354d8e02b1739a47cb9bd88015f3baf12b00b879442464e\",\n    \"0x96fb88d89a12049091070cb0048a381902965e67a8493e3991eaabe5d3b7ff7eecd5c94493a93b174df3d9b2c9511755\",\n    \"0xb899cb2176f59a5cfba3e3d346813da7a82b03417cad6342f19cc8f12f28985b03bf031e856a4743fd7ebe16324805b0\",\n    \"0xa60e2d31bc48e0c0579db15516718a03b73f5138f15037491f4dae336c904e312eda82d50862f4debd1622bb0e56d866\",\n    \"0x979fc8b987b5cef7d4f4b58b53a2c278bd25a5c0ea6f41c715142ea5ff224c707de38451b0ad3aa5e749aa219256650a\",\n    \"0xb2a75bff18e1a6b9cf2a4079572e41205741979f57e7631654a3c0fcec57c876c6df44733c9da3d863db8dff392b44a3\",\n    \"0xb7a0f0e811222c91e3df98ff7f286b750bc3b20d2083966d713a84a2281744199e664879401e77470d44e5a90f3e5181\",\n    \"0x82b74ba21c9d147fbc338730e8f1f8a6e7fc847c3110944eb17a48bea5e06eecded84595d485506d15a3e675fd0e5e62\",\n    \"0xa7f44eef817d5556f0d1abcf420301217d23c69dd2988f44d91ea1f1a16c322263cbacd0f190b9ba22b0f141b9267b4f\",\n    \"0xaadb68164ede84fc1cb3334b3194d84ba868d5a88e4c9a27519eef4923bc4abf81aab8114449496c073c2a6a0eb24114\",\n    \"0xb5378605fabe9a8c12a5dc55ef2b1de7f51aedb61960735c08767a565793cea1922a603a6983dc25f7cea738d0f7c40d\",\n    \"0xa97a4a5cd8d51302e5e670aee78fe6b5723f6cc892902bbb4f131e82ca1dfd5de820731e7e3367fb0c4c1922a02196e3\",\n    \"0x8bdfeb15c29244d4a28896f2b2cb211243cd6a1984a3f5e3b0ebe5341c419beeab3304b390a009ffb47588018034b0ea\",\n    \"0xa9af3022727f2aa2fca3b096968e97edad3f08edcbd0dbca107b892ae8f746a9c0485e0d6eb5f267999b23a845923ed0\",\n    \"0x8e7594034feef412f055590fbb15b6322dc4c6ab7a4baef4685bd13d71a83f7d682b5781bdfa0d1c659489ce9c2b8000\",\n    \"0x84977ca6c865ebee021c58106c1a4ad0c745949ecc5332948002fd09bd9b890524878d0c29da96fd11207621136421fe\",\n    \"0x8687551a79158e56b2375a271136756313122132a6670fa51f99a1b5c229ed8eea1655a734abae13228b3ebfd2a825dd\",\n    \"0xa0227d6708979d99edfc10f7d9d3719fd3fc68b0d815a7185b60307e4c9146ad2f9be2b8b4f242e320d4288ceeb9504c\",\n    \"0x89f75583a16735f9dd8b7782a130437805b34280ccea8dac6ecaee4b83fe96947e7b53598b06fecfffdf57ffc12cc445\",\n    \"0xa0056c3353227f6dd9cfc8e3399aa5a8f1d71edf25d3d64c982910f50786b1e395c508d3e3727ac360e3e040c64b5298\",\n    \"0xb070e61a6d813626144b312ded1788a6d0c7cec650a762b2f8df6e4743941dd82a2511cd956a3f141fc81e15f4e092da\",\n    \"0xb4e6db232e028a1f989bb5fc13416711f42d389f63564d60851f009dcffac01acfd54efa307aa6d4c0f932892d4e62b0\",\n    \"0x89b5991a67db90024ddd844e5e1a03ef9b943ad54194ae0a97df775dde1addf31561874f4e40fbc37a896630f3bbda58\",\n    \"0xad0e8442cb8c77d891df49cdb9efcf2b0d15ac93ec9be1ad5c3b3cca1f4647b675e79c075335c1f681d56f14dc250d76\",\n    \"0xb5d55a6ae65bb34dd8306806cb49b5ccb1c83a282ee47085cf26c4e648e19a52d9c422f65c1cd7e03ca63e926c5e92ea\",\n    \"0xb749501347e5ec07e13a79f0cb112f1b6534393458b3678a77f02ca89dca973fa7b30e55f0b25d8b92b97f6cb0120056\",\n    \"0x94144b4a3ffc5eec6ba35ce9c245c148b39372d19a928e236a60e27d7bc227d18a8cac9983851071935d8ffb64b3a34f\",\n    \"0x92bb4f9f85bc8c028a3391306603151c6896673135f8a7aefedd27acb322c04ef5dac982fc47b455d6740023e0dd3ea3\",\n    \"0xb9633a4a101461a782fc2aa092e9dbe4e2ad00987578f18cd7cf0021a909951d60fe79654eb7897806795f93c8ff4d1c\",\n    \"0x809f0196753024821b48a016eca5dbb449a7c55750f25981bb7a4b4c0e0846c09b8f6128137905055fc43a3f0deb4a74\",\n    \"0xa27dc9cdd1e78737a443570194a03d89285576d3d7f3a3cf15cc55b3013e42635d4723e2e8fe1d0b274428604b630db9\",\n    \"0x861f60f0462e04cd84924c36a28163def63e777318d00884ab8cb64c8df1df0bce5900342163edb60449296484a6c5bf\",\n    \"0xb7bc23fb4e14af4c4704a944253e760adefeca8caee0882b6bbd572c84434042236f39ae07a8f21a560f486b15d82819\",\n    \"0xb9a6eb492d6dd448654214bd01d6dc5ff12067a11537ab82023fc16167507ee25eed2c91693912f4155d1c07ed9650b3\",\n    \"0x97678af29c68f9a5e213bf0fb85c265303714482cfc4c2c00b4a1e8a76ed08834ee6af52357b143a1ca590fb0265ea5a\",\n    \"0x8a15b499e9eca5b6cac3070b5409e8296778222018ad8b53a5d1f6b70ad9bb10c68a015d105c941ed657bf3499299e33\",\n    \"0xb487fefede2e8091f2c7bfe85770db2edff1db83d4effe7f7d87bff5ab1ace35e9b823a71adfec6737fede8d67b3c467\",\n    \"0x8b51b916402aa2c437fce3bcad6dad3be8301a1a7eab9d163085b322ffb6c62abf28637636fe6114573950117fc92898\",\n    \"0xb06a2106d031a45a494adec0881cb2f82275dff9dcdd2bc16807e76f3bec28a6734edd3d54f0be8199799a78cd6228ad\",\n    \"0xaf0a185391bbe2315eb97feac98ad6dd2e5d931d012c621abd6e404a31cc188b286fef14871762190acf086482b2b5e2\",\n    \"0x8e78ee8206506dd06eb7729e32fceda3bebd8924a64e4d8621c72e36758fda3d0001af42443851d6c0aea58562870b43\",\n    \"0xa1ba52a569f0461aaf90b49b92be976c0e73ec4a2c884752ee52ffb62dd137770c985123d405dfb5de70692db454b54a\",\n    \"0x8d51b692fa1543c51f6b62b9acb8625ed94b746ef96c944ca02859a4133a5629da2e2ce84e111a7af8d9a5b836401c64\",\n    \"0xa7a20d45044cf6492e0531d0b8b26ffbae6232fa05a96ed7f06bdb64c2b0f5ca7ec59d5477038096a02579e633c7a3ff\",\n    \"0x84df867b98c53c1fcd4620fef133ee18849c78d3809d6aca0fb6f50ff993a053a455993f216c42ab6090fa5356b8d564\",\n    \"0xa7227c439f14c48e2577d5713c97a5205feb69acb0b449152842e278fa71e8046adfab468089c8b2288af1fc51fa945b\",\n    \"0x855189b3a105670779997690876dfaa512b4a25a24931a912c2f0f1936971d2882fb4d9f0b3d9daba77eaf660e9d05d5\",\n    \"0xb5696bd6706de51c502f40385f87f43040a5abf99df705d6aac74d88c913b8ecf7a99a63d7a37d9bdf3a941b9e432ff5\",\n    \"0xab997beb0d6df9c98d5b49864ef0b41a2a2f407e1687dfd6089959757ba30ed02228940b0e841afe6911990c74d536c4\",\n    \"0xb36b65f85546ebfdbe98823d5555144f96b4ab39279facd19c0de3b8919f105ba0315a0784dce4344b1bc62d8bb4a5a3\",\n    \"0xb8371f0e4450788720ac5e0f6cd3ecc5413d33895083b2c168d961ec2b5c3de411a4cc0712481cbe8df8c2fa1a7af006\",\n    \"0x98325d8026b810a8b7a114171ae59a57e8bbc9848e7c3df992efc523621729fd8c9f52114ce01d7730541a1ada6f1df1\",\n    \"0x8d0e76dbd37806259486cd9a31bc8b2306c2b95452dc395546a1042d1d17863ef7a74c636b782e214d3aa0e8d717f94a\",\n    \"0xa4e15ead76da0214d702c859fb4a8accdcdad75ed08b865842bd203391ec4cba2dcc916455e685f662923b96ee0c023f\",\n    \"0x8618190972086ebb0c4c1b4a6c94421a13f378bc961cc8267a301de7390c5e73c3333864b3b7696d81148f9d4843fd02\",\n    \"0x85369d6cc7342e1aa15b59141517d8db8baaaeb7ab9670f3ba3905353948d575923d283b7e5a05b13a30e7baf1208a86\",\n    \"0x87c51ef42233c24a6da901f28c9a075d9ba3c625687c387ad6757b72ca6b5a8885e6902a3082da7281611728b1e45f26\",\n    \"0xaa6348a4f71927a3106ad0ea8b02fc8d8c65531e4ab0bd0a17243e66f35afe252e40ab8eef9f13ae55a72566ffdaff5c\",\n    \"0x96a3bc976e9d03765cc3fee275fa05b4a84c94fed6b767e23ca689394501e96f56f7a97cffddc579a6abff632bf153be\",\n    \"0x97dbf96c6176379fdb2b888be4e757b2bca54e74124bd068d3fa1dbd82a011bbeb75079da38e0cd22a761fe208ecad9b\",\n    \"0xb70cf0a1d14089a4129ec4e295313863a59da8c7e26bf74cc0e704ed7f0ee4d7760090d0ddf7728180f1bf2c5ac64955\",\n    \"0x882d664714cc0ffe53cbc9bef21f23f3649824f423c4dbad1f893d22c4687ab29583688699efc4d5101aa08b0c3e267a\",\n    \"0x80ecb7cc963e677ccaddbe3320831dd6ee41209acf4ed41b16dc4817121a3d86a1aac9c4db3d8c08a55d28257088af32\",\n    \"0xa25ba667d832b145f9ce18c3f9b1bd00737aa36db020e1b99752c8ef7d27c6c448982bd8d352e1b6df266b8d8358a8d5\",\n    \"0x83734841c13dee12759d40bdd209b277e743b0d08cc0dd1e0b7afd2d65bfa640400eefcf6be4a52e463e5b3d885eeac6\",\n    \"0x848d16505b04804afc773aebabb51b36fd8aacfbb0e09b36c0d5d57df3c0a3b92f33e7d5ad0a7006ec46ebb91df42b8c\",\n    \"0x909a8d793f599e33bb9f1dc4792a507a97169c87cd5c087310bc05f30afcd247470b4b56dec59894c0fb1d48d39bb54e\",\n    \"0x8e558a8559df84a1ba8b244ece667f858095c50bb33a5381e60fcc6ba586b69693566d8819b4246a27287f16846c1dfa\",\n    \"0x84d6b69729f5aaa000cd710c2352087592cfbdf20d5e1166977e195818e593fa1a50d1e04566be23163a2523dc1612f1\",\n    \"0x9536d262b7a42125d89f4f32b407d737ba8d9242acfc99d965913ab3e043dcac9f7072a43708553562cac4cba841df30\",\n    \"0x9598548923ca119d6a15fd10861596601dd1dedbcccca97bb208cdc1153cf82991ea8cc17686fbaa867921065265970c\",\n    \"0xb87f2d4af6d026e4d2836bc3d390a4a18e98a6e386282ce96744603bab74974272e97ac2da281afa21885e2cbb3a8001\",\n    \"0x991ece62bf07d1a348dd22191868372904b9f8cf065ae7aa4e44fd24a53faf6d851842e35fb472895963aa1992894918\",\n    \"0xa8c53dea4c665b30e51d22ca6bc1bc78aaf172b0a48e64a1d4b93439b053877ec26cb5221c55efd64fa841bbf7d5aff4\",\n    \"0x93487ec939ed8e740f15335b58617c3f917f72d07b7a369befd479ae2554d04deb240d4a14394b26192efae4d2f4f35d\",\n    \"0xa44793ab4035443f8f2968a40e043b4555960193ffa3358d22112093aadfe2c136587e4139ffd46d91ed4107f61ea5e0\",\n    \"0xb13fe033da5f0d227c75927d3dacb06dbaf3e1322f9d5c7c009de75cdcba5e308232838785ab69a70f0bedea755e003f\",\n    \"0x970a29b075faccd0700fe60d1f726bdebf82d2cc8252f4a84543ebd3b16f91be42a75c9719a39c4096139f0f31393d58\",\n    \"0xa4c3eb1f7160f8216fc176fb244df53008ff32f2892363d85254002e66e2de21ccfe1f3b1047589abee50f29b9d507e3\",\n    \"0x8c552885eab04ba40922a8f0c3c38c96089c95ff1405258d3f1efe8d179e39e1295cbf67677894c607ae986e4e6b1fb0\",\n    \"0xb3671746fa7f848c4e2ae6946894defadd815230b906b419143523cc0597bc1d6c0a4c1e09d49b66b4a2c11cde3a4de3\",\n    \"0x937a249a95813a5e2ef428e355efd202e15a37d73e56cfb7e57ea9f943f2ce5ca8026f2f1fd25bf164ba89d07077d858\",\n    \"0x83646bdf6053a04aa9e2f112499769e5bd5d0d10f2e13db3ca89bd45c0b3b7a2d752b7d137fb3909f9c62b78166c9339\",\n    \"0xb4eac4b91e763666696811b7ed45e97fd78310377ebea1674b58a2250973f80492ac35110ed1240cd9bb2d17493d708c\",\n    \"0x82db43a99bc6573e9d92a3fd6635dbbb249ac66ba53099c3c0c8c8080b121dd8243cd5c6e36ba0a4d2525bae57f5c89c\",\n    \"0xa64d6a264a681b49d134c655d5fc7756127f1ee7c93d328820f32bca68869f53115c0d27fef35fe71f7bc4fdaed97348\",\n    \"0x8739b7a9e2b4bc1831e7f04517771bc7cde683a5e74e052542517f8375a2f64e53e0d5ac925ef722327e7bb195b4d1d9\",\n    \"0x8f337cdd29918a2493515ebb5cf702bbe8ecb23b53c6d18920cc22f519e276ca9b991d3313e2d38ae17ae8bdfa4f8b7e\",\n    \"0xb0edeab9850e193a61f138ef2739fc42ceec98f25e7e8403bfd5fa34a7bc956b9d0898250d18a69fa4625a9b3d6129da\",\n    \"0xa9920f26fe0a6d51044e623665d998745c9eca5bce12051198b88a77d728c8238f97d4196f26e43b24f8841500b998d0\",\n    \"0x86e655d61502b979eeeeb6f9a7e1d0074f936451d0a1b0d2fa4fb3225b439a3770767b649256fe481361f481a8dbc276\",\n    \"0x84d3b32fa62096831cc3bf013488a9f3f481dfe293ae209ed19585a03f7db8d961a7a9dd0db82bd7f62d612707575d9c\",\n    \"0x81c827826ec9346995ffccf62a241e3b2d32f7357acd1b1f8f7a7dbc97022d3eb51b8a1230e23ce0b401d2e535e8cd78\",\n    \"0x94a1e40c151191c5b055b21e86f32e69cbc751dcbdf759a48580951834b96a1eed75914c0d19a38aefd21fb6c8d43d0c\",\n    \"0xab890222b44bc21b71f7c75e15b6c6e16bb03371acce4f8d4353ff3b8fcd42a14026589c5ed19555a3e15e4d18bfc3a3\",\n    \"0xaccb0be851e93c6c8cc64724cdb86887eea284194b10e7a43c90528ed97e9ec71ca69c6fac13899530593756dd49eab2\",\n    \"0xb630220aa9e1829c233331413ee28c5efe94ea8ea08d0c6bfd781955078b43a4f92915257187d8526873e6c919c6a1de\",\n    \"0xadd389a4d358c585f1274b73f6c3c45b58ef8df11f9d11221f620e241bf3579fba07427b288c0c682885a700cc1fa28d\",\n    \"0xa9fe6ca8bf2961a3386e8b8dcecc29c0567b5c0b3bcf3b0f9169f88e372b80151af883871fc5229815f94f43a6f5b2b0\",\n    \"0xad839ae003b92b37ea431fa35998b46a0afc3f9c0dd54c3b3bf7a262467b13ff3c323ada1c1ae02ac7716528bdf39e3e\",\n    \"0x9356d3fd0edcbbb65713c0f2a214394f831b26f792124b08c5f26e7f734b8711a87b7c4623408da6a091c9aef1f6af3c\",\n    \"0x896b25b083c35ac67f0af3784a6a82435b0e27433d4d74cd6d1eafe11e6827827799490fb1c77c11de25f0d75f14e047\",\n    \"0x8bfa019391c9627e8e5f05c213db625f0f1e51ec68816455f876c7e55b8f17a4f13e5aae9e3fb9e1cf920b1402ee2b40\",\n    \"0x8ba3a6faa6a860a8f3ce1e884aa8769ceded86380a86520ab177ab83043d380a4f535fe13884346c5e51bee68da6ab41\",\n    \"0xa8292d0844084e4e3bb7af92b1989f841a46640288c5b220fecfad063ee94e86e13d3d08038ec2ac82f41c96a3bfe14d\",\n    \"0x8229bb030b2fc566e11fd33c7eab7a1bb7b49fed872ea1f815004f7398cb03b85ea14e310ec19e1f23e0bdaf60f8f76c\",\n    \"0x8cfbf869ade3ec551562ff7f63c2745cc3a1f4d4dc853a0cd42dd5f6fe54228f86195ea8fe217643b32e9f513f34a545\",\n    \"0xac52a3c8d3270ddfe1b5630159da9290a5ccf9ccbdef43b58fc0a191a6c03b8a5974cf6e2bbc7bd98d4a40a3581482d7\",\n    \"0xab13decb9e2669e33a7049b8eca3ca327c40dea15ad6e0e7fa63ed506db1d258bc36ac88b35f65cae0984e937eb6575d\",\n    \"0xb5e748eb1a7a1e274ff0cc56311c198f2c076fe4b7e73e5f80396fe85358549df906584e6bb2c8195b3e2be7736850a5\",\n    \"0xb5cb911325d8f963c41f691a60c37831c7d3bbd92736efa33d1f77a22b3fde7f283127256c2f47e197571e6fe0b46149\",\n    \"0x8a01dc6ed1b55f26427a014faa347130738b191a06b800e32042a46c13f60b49534520214359d68eb2e170c31e2b8672\",\n    \"0xa72fa874866e19b2efb8e069328362bf7921ec375e3bcd6b1619384c3f7ee980f6cf686f3544e9374ff54b4d17a1629c\",\n    \"0x8db21092f7c5f110fba63650b119e82f4b42a997095d65f08f8237b02dd66fdf959f788df2c35124db1dbd330a235671\",\n    \"0x8c65d50433d9954fe28a09fa7ba91a70a590fe7ba6b3060f5e4be0f6cef860b9897fa935fb4ebc42133524eb071dd169\",\n    \"0xb4614058e8fa21138fc5e4592623e78b8982ed72aa35ee4391b164f00c68d277fa9f9eba2eeefc890b4e86eba5124591\",\n    \"0xab2ad3a1bce2fbd55ca6b7c23786171fe1440a97d99d6df4d80d07dd56ac2d7203c294b32fc9e10a6c259381a73f24a1\",\n    \"0x812ae3315fdc18774a8da3713a4679e8ed10b9405edc548c00cacbe25a587d32040566676f135e4723c5dc25df5a22e9\",\n    \"0xa464b75f95d01e5655b54730334f443c8ff27c3cb79ec7af4b2f9da3c2039c609908cd128572e1fd0552eb597e8cef8d\",\n    \"0xa0db3172e93ca5138fe419e1c49a1925140999f6eff7c593e5681951ee0ec1c7e454c851782cbd2b8c9bc90d466e90e0\",\n    \"0x806db23ba7d00b87d544eed926b3443f5f9c60da6b41b1c489fba8f73593b6e3b46ebfcab671ee009396cd77d5e68aa1\",\n    \"0x8bfdf2c0044cc80260994e1c0374588b6653947b178e8b312be5c2a05e05767e98ea15077278506aee7df4fee1aaf89e\",\n    \"0x827f6558c16841b5592ff089c9c31e31eb03097623524394813a2e4093ad2d3f8f845504e2af92195aaa8a1679d8d692\",\n    \"0x925c4f8eab2531135cd71a4ec88e7035b5eea34ba9d799c5898856080256b4a15ed1a746e002552e2a86c9c157e22e83\",\n    \"0xa9f9a368f0e0b24d00a35b325964c85b69533013f9c2cfad9708be5fb87ff455210f8cb8d2ce3ba58ca3f27495552899\",\n    \"0x8ac0d3bebc1cae534024187e7c71f8927ba8fcc6a1926cb61c2b6c8f26bb7831019e635a376146c29872a506784a4aaa\",\n    \"0x97c577be2cbbfdb37ad754fae9df2ada5fc5889869efc7e18a13f8e502fbf3f4067a509efbd46fd990ab47ce9a70f5a8\",\n    \"0x935e7d82bca19f16614aa43b4a3474e4d20d064e4bfdf1cea2909e5c9ab72cfe3e54dc50030e41ee84f3588cebc524e9\",\n    \"0x941aafc08f7c0d94cebfbb1f0aad5202c02e6e37f2c12614f57e727efa275f3926348f567107ee6d8914dd71e6060271\",\n    \"0xaf0fbc1ba05b4b5b63399686df3619968be5d40073de0313cbf5f913d3d4b518d4c249cdd2176468ccaa36040a484f58\",\n    \"0xa0c414f23f46ca6d69ce74c6f8a00c036cb0edd098af0c1a7d39c802b52cfb2d5dbdf93fb0295453d4646e2af7954d45\",\n    \"0x909cf39e11b3875bb63b39687ae1b5d1f5a15445e39bf164a0b14691b4ddb39a8e4363f584ef42213616abc4785b5d66\",\n    \"0xa92bac085d1194fbd1c88299f07a061d0bdd3f980b663e81e6254dbb288bf11478c0ee880e28e01560f12c5ccb3c0103\",\n    \"0x841705cd5cd76b943e2b7c5e845b9dd3c8defe8ef67e93078d6d5e67ade33ad4b0fd413bc196f93b0a4073c855cd97d4\",\n    \"0x8e7eb8364f384a9161e81d3f1d52ceca9b65536ae49cc35b48c3e2236322ba4ae9973e0840802d9fa4f4d82ea833544f\",\n    \"0xaed3ab927548bc8bec31467ba80689c71a168e34f50dcb6892f19a33a099f5aa6b3f9cb79f5c0699e837b9a8c7f27efe\",\n    \"0xb8fbf7696210a36e20edabd77839f4dfdf50d6d015cdf81d587f90284a9bcef7d2a1ff520728d7cc69a4843d6c20dedd\",\n    \"0xa9d533769ce6830211c884ae50a82a7bf259b44ac71f9fb11f0296fdb3981e6b4c1753fe744647b247ebc433a5a61436\",\n    \"0x8b4bdf90d33360b7f428c71cde0a49fb733badba8c726876945f58c620ce7768ae0e98fc8c31fa59d8955a4823336bb1\",\n    \"0x808d42238e440e6571c59e52a35ae32547d502dc24fd1759d8ea70a7231a95859baf30b490a4ba55fa2f3aaa11204597\",\n    \"0x85594701f1d2fee6dc1956bc44c7b31db93bdeec2f3a7d622c1a08b26994760773e3d57521a44cfd7e407ac3fd430429\",\n    \"0xa66de045ce7173043a6825e9dc440ac957e2efb6df0a337f4f8003eb0c719d873a52e6eba3cb0d69d977ca37d9187674\",\n    \"0x87a1c6a1fdff993fa51efa5c3ba034c079c0928a7d599b906336af7c2dcab9721ceaf3108c646490af9dff9a754f54b3\",\n    \"0x926424223e462ceb75aed7c22ade8a7911a903b7e5dd4bc49746ddce8657f4616325cd12667d4393ac52cdd866396d0e\",\n    \"0xb5dc96106593b42b30f06f0b0a1e0c1aafc70432e31807252d3674f0b1ea5e58eac8424879d655c9488d85a879a3e572\",\n    \"0x997ca0987735cc716507cb0124b1d266d218b40c9d8e0ecbf26a1d65719c82a637ce7e8be4b4815d307df717bde7c72a\",\n    \"0x92994d3f57a569b7760324bb5ae4e8e14e1633d175dab06aa57b8e391540e05f662fdc08b8830f489a063f59b689a688\",\n    \"0xa8087fcc6aa4642cb998bea11facfe87eb33b90a9aa428ab86a4124ad032fc7d2e57795311a54ec9f55cc120ebe42df1\",\n    \"0xa9bd7d1de6c0706052ca0b362e2e70e8c8f70f1f026ea189b4f87a08ce810297ebfe781cc8004430776c54c1a05ae90c\",\n    \"0x856d33282e8a8e33a3d237fb0a0cbabaf77ba9edf2fa35a831fdafcadf620561846aa6cbb6bdc5e681118e1245834165\",\n    \"0x9524a7aa8e97a31a6958439c5f3339b19370f03e86b89b1d02d87e4887309dbbe9a3a8d2befd3b7ed5143c8da7e0a8ad\",\n    \"0x824fdf433e090f8acbd258ac7429b21f36f9f3b337c6d0b71d1416a5c88a767883e255b2888b7c906dd2e9560c4af24c\",\n    \"0x88c7fee662ca7844f42ed5527996b35723abffd0d22d4ca203b9452c639a5066031207a5ae763dbc0865b3299d19b1ec\",\n    \"0x919dca5c5595082c221d5ab3a5bc230f45da7f6dec4eb389371e142c1b9c6a2c919074842479c2844b72c0d806170c0c\",\n    \"0xb939be8175715e55a684578d8be3ceff3087f60fa875fff48e52a6e6e9979c955efef8ff67cfa2b79499ea23778e33b0\",\n    \"0x873b6db725e7397d11bc9bed9ac4468e36619135be686790a79bc6ed4249058f1387c9a802ea86499f692cf635851066\",\n    \"0xaeae06db3ec47e9e5647323fa02fac44e06e59b885ad8506bf71b184ab3895510c82f78b6b22a5d978e8218e7f761e9f\",\n    \"0xb99c0a8359c72ab88448bae45d4bf98797a26bca48b0d4460cd6cf65a4e8c3dd823970ac3eb774ae5d0cea4e7fadf33e\",\n    \"0x8f10c8ec41cdfb986a1647463076a533e6b0eec08520c1562401b36bb063ac972aa6b28a0b6ce717254e35940b900e3c\",\n    \"0xa106d9be199636d7add43b942290269351578500d8245d4aae4c083954e4f27f64740a3138a66230391f2d0e6043a8de\",\n    \"0xa469997908244578e8909ff57cffc070f1dbd86f0098df3cfeb46b7a085cfecc93dc69ee7cad90ff1dc5a34d50fe580c\",\n    \"0xa4ef087bea9c20eb0afc0ee4caba7a9d29dfa872137828c721391273e402fb6714afc80c40e98bbd8276d3836bffa080\",\n    \"0xb07a013f73cd5b98dae0d0f9c1c0f35bff8a9f019975c4e1499e9bee736ca6fcd504f9bc32df1655ff333062382cff04\",\n    \"0xb0a77188673e87cc83348c4cc5db1eecf6b5184e236220c8eeed7585e4b928db849944a76ec60ef7708ef6dac02d5592\",\n    \"0xb1284b37e59b529f0084c0dacf0af6c0b91fc0f387bf649a8c74819debf606f7b07fc3e572500016fb145ec2b24e9f17\",\n    \"0x97b20b5b4d6b9129da185adfbf0d3d0b0faeba5b9715f10299e48ea0521709a8296a9264ce77c275a59c012b50b6519a\",\n    \"0xb9d37e946fae5e4d65c1fbfacc8a62e445a1c9d0f882e60cca649125af303b3b23af53c81d7bac544fb7fcfc7a314665\",\n    \"0x8e5acaac379f4bb0127efbef26180f91ff60e4c525bc9b798fc50dfaf4fe8a5aa84f18f3d3cfb8baead7d1e0499af753\",\n    \"0xb0c0b8ab1235bf1cda43d4152e71efc1a06c548edb964eb4afceb201c8af24240bf8ab5cae30a08604e77432b0a5faf0\",\n    \"0x8cc28d75d5c8d062d649cbc218e31c4d327e067e6dbd737ec0a35c91db44fbbd0d40ec424f5ed79814add16947417572\",\n    \"0x95ae6219e9fd47efaa9cb088753df06bc101405ba50a179d7c9f7c85679e182d3033f35b00dbba71fdcd186cd775c52e\",\n    \"0xb5d28fa09f186ebc5aa37453c9b4d9474a7997b8ae92748ecb940c14868792292ac7d10ade01e2f8069242b308cf97e5\",\n    \"0x8c922a0faa14cc6b7221f302df3342f38fc8521ec6c653f2587890192732c6da289777a6cd310747ea7b7d104af95995\",\n    \"0xb9ad5f660b65230de54de535d4c0fcae5bc6b59db21dea5500fdc12eea4470fb8ea003690fdd16d052523418d5e01e8c\",\n    \"0xa39a9dd41a0ff78c82979483731f1cd68d3921c3e9965869662c22e02dde3877802e180ba93f06e7346f96d9fa9261d2\",\n    \"0x8b32875977ec372c583b24234c27ed73aef00cdff61eb3c3776e073afbdeade548de9497c32ec6d703ff8ad0a5cb7fe4\",\n    \"0x9644cbe755a5642fe9d26cfecf170d3164f1848c2c2e271d5b6574a01755f3980b3fc870b98cf8528fef6ecef4210c16\",\n    \"0x81ea9d1fdd9dd66d60f40ce0712764b99da9448ae0b300f8324e1c52f154e472a086dda840cb2e0b9813dc8ce8afd4b5\",\n    \"0x906aaa4a7a7cdf01909c5cfbc7ded2abc4b869213cbf7c922d4171a4f2e637e56f17020b852ad339d83b8ac92f111666\",\n    \"0x939b5f11acbdeff998f2a080393033c9b9d8d5c70912ea651c53815c572d36ee822a98d6dfffb2e339f29201264f2cf4\",\n    \"0xaba4898bf1ccea9b9e2df1ff19001e05891581659c1cbbde7ee76c349c7fc7857261d9785823c9463a8aea3f40e86b38\",\n    \"0x83ca1a56b8a0be4820bdb5a9346357c68f9772e43f0b887729a50d2eb2a326bbcede676c8bf2e51d7c89bbd8fdb778a6\",\n    \"0x94e86e9fe6addfe2c3ee3a547267ed921f4230d877a85bb4442c2d9350c2fa9a9c54e6fe662de82d1a2407e4ab1691c2\",\n    \"0xa0cc3bdef671a59d77c6984338b023fa2b431b32e9ed2abe80484d73edc6540979d6f10812ecc06d4d0c5d4eaca7183c\",\n    \"0xb5343413c1b5776b55ea3c7cdd1f3af1f6bd802ea95effe3f2b91a523817719d2ecc3f8d5f3cc2623ace7e35f99ca967\",\n    \"0x92085d1ed0ed28d8cabe3e7ff1905ed52c7ceb1eac5503760c52fb5ee3a726aba7c90b483c032acc3f166b083d7ec370\",\n    \"0x8ec679520455275cd957fca8122724d287db5df7d29f1702a322879b127bff215e5b71d9c191901465d19c86c8d8d404\",\n    \"0xb65eb2c63d8a30332eb24ee8a0c70156fc89325ebbb38bacac7cf3f8636ad8a472d81ccca80423772abc00192d886d8a\",\n    \"0xa9fe1c060b974bee4d590f2873b28635b61bfcf614e61ff88b1be3eee4320f4874e21e8d666d8ac8c9aba672efc6ecae\",\n    \"0xb3fe2a9a389c006a831dea7e777062df84b5c2803f9574d7fbe10b7e1c125817986af8b6454d6be9d931a5ac94cfe963\",\n    \"0x95418ad13b734b6f0d33822d9912c4c49b558f68d08c1b34a0127fcfa666bcae8e6fda8832d2c75bb9170794a20e4d7c\",\n    \"0xa9a7df761e7f18b79494bf429572140c8c6e9d456c4d4e336184f3f51525a65eb9582bea1e601bdb6ef8150b7ca736a5\",\n    \"0xa0de03b1e75edf7998c8c1ac69b4a1544a6fa675a1941950297917366682e5644a4bda9cdeedfaf9473d7fccd9080b0c\",\n    \"0xa61838af8d95c95edf32663a68f007d95167bf6e41b0c784a30b22d8300cfdd5703bd6d16e86396638f6db6ae7e42a85\",\n    \"0x8866d62084d905c145ff2d41025299d8b702ac1814a7dec4e277412c161bc9a62fed735536789cb43c88693c6b423882\",\n    \"0x91da22c378c81497fe363e7f695c0268443abee50f8a6625b8a41e865638a643f07b157ee566de09ba09846934b4e2d7\",\n    \"0x941d21dd57c9496aa68f0c0c05507405fdd413acb59bc668ce7e92e1936c68ec4b065c3c30123319884149e88228f0b2\",\n    \"0xa77af9b094bc26966ddf2bf9e1520c898194a5ccb694915950dadc204facbe3066d3d89f50972642d76b14884cfbaa21\",\n    \"0x8e76162932346869f4618bde744647f7ab52ab498ad654bdf2a4feeb986ac6e51370841e5acbb589e38b6e7142bb3049\",\n    \"0xb60979ace17d6937ece72e4f015da4657a443dd01cebc7143ef11c09e42d4aa8855999a65a79e2ea0067f31c9fc2ab0f\",\n    \"0xb3e2ffdd5ee6fd110b982fd4fad4b93d0fca65478f986d086eeccb0804960bfaa1919afa743c2239973ea65091fe57d2\",\n    \"0x8ce0ce05e7d7160d44574011da687454dbd3c8b8290aa671731b066e2c82f8cf2d63cb8e932d78c6122ec610e44660e6\",\n    \"0xab005dd8d297045c39e2f72fb1c48edb501ccf3575d3d04b9817b3afee3f0bb0f3f53f64bda37d1d9cde545aae999bae\",\n    \"0x95bd7edb4c4cd60e3cb8a72558845a3cce6bb7032ccdf33d5a49ebb6ddf203bc3c79e7b7e550735d2d75b04c8b2441e8\",\n    \"0x889953ee256206284094e4735dbbb17975bafc7c3cb94c9fbfee4c3e653857bfd49e818f64a47567f721b98411a3b454\",\n    \"0xb188423e707640ab0e75a061e0b62830cde8afab8e1ad3dae30db69ffae4e2fc005bababbdcbd7213b918ed4f70e0c14\",\n    \"0xa97e0fafe011abd70d4f99a0b36638b3d6e7354284588f17a88970ed48f348f88392779e9a038c6cbc9208d998485072\",\n    \"0x87db11014a91cb9b63e8dfaa82cdebca98272d89eb445ee1e3ff9dbaf2b3fad1a03b888cffc128e4fe208ed0dddece0f\",\n    \"0xaad2e40364edd905d66ea4ac9d51f9640d6fda9a54957d26ba233809851529b32c85660fa401dbee3679ec54fa6dd966\",\n    \"0x863e99336ca6edf03a5a259e59a2d0f308206e8a2fb320cfc0be06057366df8e0f94b33a28f574092736b3c5ada84270\",\n    \"0xb34bcc56a057589f34939a1adc51de4ff6a9f4fee9c7fa9aa131e28d0cf0759a0c871b640162acdfbf91f3f1b59a3703\",\n    \"0x935dd28f2896092995c5eff1618e5b6efe7a40178888d7826da9b0503c2d6e68a28e7fac1a334e166d0205f0695ef614\",\n    \"0xb842cd5f8f5de5ca6c68cb4a5c1d7b451984930eb4cc18fd0934d52fdc9c3d2d451b1c395594d73bc3451432bfba653f\",\n    \"0x9014537885ce2debad736bc1926b25fdab9f69b216bf024f589c49dc7e6478c71d595c3647c9f65ff980b14f4bb2283b\",\n    \"0x8e827ccca1dd4cd21707140d10703177d722be0bbe5cac578db26f1ef8ad2909103af3c601a53795435b27bf95d0c9ed\",\n    \"0x8a0b8ad4d466c09d4f1e9167410dbe2edc6e0e6229d4b3036d30f85eb6a333a18b1c968f6ca6d6889bb08fecde017ef4\",\n    \"0x9241ee66c0191b06266332dc9161dede384c4bb4e116dbd0890f3c3790ec5566da4568243665c4725b718ac0f6b5c179\",\n    \"0xaeb4d5fad81d2b505d47958a08262b6f1b1de9373c2c9ba6362594194dea3e002ab03b8cbb43f867be83065d3d370f19\",\n    \"0x8781bc83bb73f7760628629fe19e4714b494dbed444c4e4e4729b7f6a8d12ee347841a199888794c2234f51fa26fc2b9\",\n    \"0xb58864f0acd1c2afa29367e637cbde1968d18589245d9936c9a489c6c495f54f0113ecdcbe4680ac085dd3c397c4d0c3\",\n    \"0x94a24284afaeead61e70f3e30f87248d76e9726759445ca18cdb9360586c60cc9f0ec1c397f9675083e0b56459784e2e\",\n    \"0xaed358853f2b54dcbddf865e1816c2e89be12e940e1abfa661e2ee63ffc24a8c8096be2072fa83556482c0d89e975124\",\n    \"0xb95374e6b4fc0765708e370bc881e271abf2e35c08b056a03b847e089831ef4fe3124b9c5849d9c276eb2e35b3daf264\",\n    \"0xb834cdbcfb24c8f84bfa4c552e7fadc0028a140952fd69ed13a516e1314a4cd35d4b954a77d51a1b93e1f5d657d0315d\",\n    \"0x8fb6d09d23bfa90e7443753d45a918d91d75d8e12ec7d016c0dfe94e5c592ba6aaf483d2f16108d190822d955ad9cdc3\",\n    \"0xaa315cd3c60247a6ad4b04f26c5404c2713b95972843e4b87b5a36a89f201667d70f0adf20757ebe1de1b29ae27dda50\",\n    \"0xa116862dca409db8beff5b1ccd6301cdd0c92ca29a3d6d20eb8b87f25965f42699ca66974dd1a355200157476b998f3b\",\n    \"0xb4c2f5fe173c4dc8311b60d04a65ce1be87f070ac42e13cd19c6559a2931c6ee104859cc2520edebbc66a13dc7d30693\",\n    \"0x8d4a02bf99b2260c334e7d81775c5cf582b00b0c982ce7745e5a90624919028278f5e9b098573bad5515ce7fa92a80c8\",\n    \"0x8543493bf564ce6d97bd23be9bff1aba08bd5821ca834f311a26c9139c92a48f0c2d9dfe645afa95fec07d675d1fd53b\",\n    \"0x9344239d13fde08f98cb48f1f87d34cf6abe8faecd0b682955382a975e6eed64e863fa19043290c0736261622e00045c\",\n    \"0xaa49d0518f343005ca72b9e6c7dcaa97225ce6bb8b908ebbe7b1a22884ff8bfb090890364e325a0d414ad180b8f161d1\",\n    \"0x907d7fd3e009355ab326847c4a2431f688627faa698c13c03ffdd476ecf988678407f029b8543a475dcb3dafdf2e7a9c\",\n    \"0x845f1f10c6c5dad2adc7935f5cd2e2b32f169a99091d4f1b05babe7317b9b1cdce29b5e62f947dc621b9acbfe517a258\",\n    \"0x8f3be8e3b380ea6cdf9e9c237f5e88fd5a357e5ded80ea1fc2019810814de82501273b4da38916881125b6fa0cfd4459\",\n    \"0xb9c7f487c089bf1d20c822e579628db91ed9c82d6ca652983aa16d98b4270c4da19757f216a71b9c13ddee3e6e43705f\",\n    \"0x8ba2d8c88ad2b872db104ea8ddbb006ec2f3749fd0e19298a804bb3a5d94de19285cc7fb19fee58a66f7851d1a66c39f\",\n    \"0x9375ecd3ed16786fe161af5d5c908f56eeb467a144d3bbddfc767e90065b7c94fc53431adebecba2b6c9b5821184d36e\",\n    \"0xa49e069bfadb1e2e8bff6a4286872e2a9765d62f0eaa4fcb0e5af4bbbed8be3510fb19849125a40a8a81d1e33e81c3eb\",\n    \"0x9522cc66757b386aa6b88619525c8ce47a5c346d590bb3647d12f991e6c65c3ab3c0cfc28f0726b6756c892eae1672be\",\n    \"0xa9a0f1f51ff877406fa83a807aeb17b92a283879f447b8a2159653db577848cc451cbadd01f70441e351e9ed433c18bc\",\n    \"0x8ff7533dcff6be8714df573e33f82cf8e9f2bcaaa43e939c4759d52b754e502717950de4b4252fb904560fc31dce94a4\",\n    \"0x959724671e265a28d67c29d95210e97b894b360da55e4cf16e6682e7912491ed8ca14bfaa4dce9c25a25b16af580494f\",\n    \"0x92566730c3002f4046c737032487d0833c971e775de59fe02d9835c9858e2e3bc37f157424a69764596c625c482a2219\",\n    \"0xa84b47ceff13ed9c3e5e9cdf6739a66d3e7c2bd8a6ba318fefb1a9aecf653bb2981da6733ddb33c4b0a4523acc429d23\",\n    \"0xb4ddf571317e44f859386d6140828a42cf94994e2f1dcbcc9777f4eebbfc64fc1e160b49379acc27c4672b8e41835c5d\",\n    \"0x8ab95c94072b853d1603fdd0a43b30db617d13c1d1255b99075198e1947bfa5f59aed2b1147548a1b5e986cd9173d15c\",\n    \"0x89511f2eab33894fd4b3753d24249f410ff7263052c1fef6166fc63a79816656b0d24c529e45ccce6be28de6e375d916\",\n    \"0xa0866160ca63d4f2be1b4ea050dac6b59db554e2ebb4e5b592859d8df339b46fd7cb89aaed0951c3ee540aee982c238a\",\n    \"0x8fcc5cbba1b94970f5ff2eb1922322f5b0aa7d918d4b380c9e7abfd57afd8b247c346bff7b87af82efbce3052511cd1b\",\n    \"0x99aeb2a5e846b0a2874cca02c66ed40d5569eb65ab2495bc3f964a092e91e1517941f2688e79f8cca49cd3674c4e06dc\",\n    \"0xb7a096dc3bad5ca49bee94efd884aa3ff5615cf3825cf95fbe0ce132e35f46581d6482fa82666c7ef5f1643eaee8f1ca\",\n    \"0x94393b1da6eaac2ffd186b7725eca582f1ddc8cdd916004657f8a564a7c588175cb443fc6943b39029f5bbe0add3fad8\",\n    \"0x884b85fe012ccbcd849cb68c3ad832d83b3ef1c40c3954ffdc97f103b1ed582c801e1a41d9950f6bddc1d11f19d5ec76\",\n    \"0xb00061c00131eded8305a7ce76362163deb33596569afb46fe499a7c9d7a0734c084d336b38d168024c2bb42b58e7660\",\n    \"0xa439153ac8e6ca037381e3240e7ba08d056c83d7090f16ed538df25901835e09e27de2073646e7d7f3c65056af6e4ce7\",\n    \"0x830fc9ca099097d1f38b90e6843dc86f702be9d20bdacc3e52cae659dc41df5b8d2c970effa6f83a5229b0244a86fe22\",\n    \"0xb81ea2ffaaff2bb00dd59a9ab825ba5eed4db0d8ac9c8ed1a632ce8f086328a1cddd045fbe1ace289083c1325881b7e7\",\n    \"0xb51ea03c58daf2db32c99b9c4789b183365168cb5019c72c4cc91ac30b5fb7311d3db76e6fa41b7cd4a8c81e2f6cdc94\",\n    \"0xa4170b2c6d09ca5beb08318730419b6f19215ce6c631c854116f904be3bc30dd85a80c946a8ab054d3e307afaa3f8fbc\",\n    \"0x897cc42ff28971ff54d2a55dd6b35cfb8610ac902f3c06e3a5cea0e0a257e870c471236a8e84709211c742a09c5601a6\",\n    \"0xa18f2e98d389dace36641621488664ecbb422088ab03b74e67009b8b8acacaaa24fdcf42093935f355207d934adc52a8\",\n    \"0x92adcfb678cc2ba19c866f3f2b988fdcb4610567f3ab436cc0cb9acaf5a88414848d71133ebdbec1983e38e6190f1b5f\",\n    \"0xa86d43c2ce01b366330d3b36b3ca85f000c3548b8297e48478da1ee7d70d8576d4650cba7852ed125c0d7cb6109aa7f3\",\n    \"0x8ed31ceed9445437d7732dce78a762d72ff32a7636bfb3fd7974b7ae15db414d8184a1766915244355deb354fbc5803b\",\n    \"0x9268f70032584f416e92225d65af9ea18c466ebc7ae30952d56a4e36fd9ea811dde0a126da9220ba3c596ec54d8a335e\",\n    \"0x9433b99ee94f2d3fbdd63b163a2bdf440379334c52308bd24537f7defd807145a062ff255a50d119a7f29f4b85d250e3\",\n    \"0x90ce664f5e4628a02278f5cf5060d1a34f123854634b1870906e5723ac9afd044d48289be283b267d45fcbf3f4656aaf\",\n    \"0xaaf21c4d59378bb835d42ae5c5e5ab7a3c8c36a59e75997989313197752b79a472d866a23683b329ea69b048b87fa13e\",\n    \"0xb83c0589b304cec9ede549fde54f8a7c2a468c6657da8c02169a6351605261202610b2055c639b9ed2d5b8c401fb8f56\",\n    \"0x9370f326ea0f170c2c05fe2c5a49189f20aec93b6b18a5572a818cd4c2a6adb359e68975557b349fb54f065d572f4c92\",\n    \"0xac3232fa5ce6f03fca238bef1ce902432a90b8afce1c85457a6bee5571c033d4bceefafc863af04d4e85ac72a4d94d51\",\n    \"0x80d9ea168ff821b22c30e93e4c7960ce3ad3c1e6deeebedd342a36d01bd942419b187e2f382dbfd8caa34cca08d06a48\",\n    \"0xa387a3c61676fb3381eefa2a45d82625635a666e999aba30e3b037ec9e040f414f9e1ad9652abd3bcad63f95d85038db\",\n    \"0xa1b229fe32121e0b391b0f6e0180670b9dc89d79f7337de4c77ea7ad0073e9593846f06797c20e923092a08263204416\",\n    \"0x92164a9d841a2b828cedf2511213268b698520f8d1285852186644e9a0c97512cafa4bfbe29af892c929ebccd102e998\",\n    \"0x82ee2fa56308a67c7db4fd7ef539b5a9f26a1c2cc36da8c3206ba4b08258fbb3cec6fe5cdbd111433fb1ba2a1e275927\",\n    \"0x8c77bfe9e191f190a49d46f05600603fa42345592539b82923388d72392404e0b29a493a15e75e8b068dddcd444c2928\",\n    \"0x80b927f93ccf79dcf5c5b20bcf5a7d91d7a17bc0401bb7cc9b53a6797feac31026eb114257621f5a64a52876e4474cc1\",\n    \"0xb6b68b6501c37804d4833d5a063dd108a46310b1400549074e3cac84acc6d88f73948b7ad48d686de89c1ec043ae8c1a\",\n    \"0xab3da00f9bdc13e3f77624f58a3a18fc3728956f84b5b549d62f1033ae4b300538e53896e2d943f160618e05af265117\",\n    \"0xb6830e87233b8eace65327fdc764159645b75d2fd4024bf8f313b2dd5f45617d7ecfb4a0b53ccafb5429815a9a1adde6\",\n    \"0xb9251cfe32a6dc0440615aadcd98b6b1b46e3f4e44324e8f5142912b597ee3526bea2431e2b0282bb58f71be5b63f65e\",\n    \"0xaf8d70711e81cdddfb39e67a1b76643292652584c1ce7ce4feb1641431ad596e75c9120e85f1a341e7a4da920a9cdd94\",\n    \"0x98cd4e996594e89495c078bfd52a4586b932c50a449a7c8dfdd16043ca4cda94dafbaa8ad1b44249c99bbcc52152506e\",\n    \"0xb9fc6d1c24f48404a4a64fbe3e43342738797905db46e4132aee5f086aaa4c704918ad508aaefa455cfe1b36572e6242\",\n    \"0xa365e871d30ba9291cedaba1be7b04e968905d003e9e1af7e3b55c5eb048818ae5b913514fb08b24fb4fbdccbb35d0b8\",\n    \"0x93bf99510971ea9af9f1e364f1234c898380677c8e8de9b0dd24432760164e46c787bc9ec42a7ad450500706cf247b2d\",\n    \"0xb872f825a5b6e7b9c7a9ddfeded3516f0b1449acc9b4fd29fc6eba162051c17416a31e5be6d3563f424d28e65bab8b8f\",\n    \"0xb06b780e5a5e8eb4f4c9dc040f749cf9709c8a4c9ef15e925f442b696e41e5095db0778a6c73bcd329b265f2c6955c8b\",\n    \"0x848f1a981f5fc6cd9180cdddb8d032ad32cdfa614fc750d690dbae36cc0cd355cbf1574af9b3ffc8b878f1b2fafb9544\",\n    \"0xa03f48cbff3e9e8a3a655578051a5ae37567433093ac500ed0021c6250a51b767afac9bdb194ee1e3eac38a08c0eaf45\",\n    \"0xb5be78ce638ff8c4aa84352b536628231d3f7558c5be3bf010b28feac3022e64691fa672f358c8b663904aebe24a54ed\",\n    \"0xa9d4da70ff676fa55d1728ba6ab03b471fa38b08854d99e985d88c2d050102d8ccffbe1c90249a5607fa7520b15fe791\",\n    \"0x8fe9f7092ffb0b69862c8e972fb1ecf54308c96d41354ed0569638bb0364f1749838d6d32051fff1599112978c6e229c\",\n    \"0xae6083e95f37770ecae0df1e010456f165d96cfe9a7278c85c15cffd61034081ce5723e25e2bede719dc9341ec8ed481\",\n    \"0xa260891891103089a7afbd9081ea116cfd596fd1015f5b65e10b0961eb37fab7d09c69b7ce4be8bf35e4131848fb3fe4\",\n    \"0x8d729fa32f6eb9fd2f6a140bef34e8299a2f3111bffd0fe463aa8622c9d98bfd31a1df3f3e87cd5abc52a595f96b970e\",\n    \"0xa30ec6047ae4bc7da4daa7f4c28c93aedb1112cfe240e681d07e1a183782c9ff6783ac077c155af23c69643b712a533f\",\n    \"0xac830726544bfe7b5467339e5114c1a75f2a2a8d89453ce86115e6a789387e23551cd64620ead6283dfa4538eb313d86\",\n    \"0x8445c135b7a48068d8ed3e011c6d818cfe462b445095e2fbf940301e50ded23f272d799eea47683fc027430ce14613ef\",\n    \"0x95785411715c9ae9d8293ce16a693a2aa83e3cb1b4aa9f76333d0da2bf00c55f65e21e42e50e6c5772ce213dd7b4f7a0\",\n    \"0xb273b024fa18b7568c0d1c4d2f0c4e79ec509dafac8c5951f14192d63ddbcf2d8a7512c1c1b615cc38fa3e336618e0c5\",\n    \"0xa78b9d3ea4b6a90572eb27956f411f1d105fdb577ee2ffeec9f221da9b45db84bfe866af1f29597220c75e0c37a628d8\",\n    \"0xa4be2bf058c36699c41513c4d667681ce161a437c09d81383244fc55e1c44e8b1363439d0cce90a3e44581fb31d49493\",\n    \"0xb6eef13040f17dd4eba22aaf284d2f988a4a0c4605db44b8d2f4bf9567ac794550b543cc513c5f3e2820242dd704152e\",\n    \"0x87eb00489071fa95d008c5244b88e317a3454652dcb1c441213aa16b28cd3ecaa9b22fec0bdd483c1df71c37119100b1\",\n    \"0x92d388acdcb49793afca329cd06e645544d2269234e8b0b27d2818c809c21726bc9cf725651b951e358a63c83dedee24\",\n    \"0xae27e219277a73030da27ab5603c72c8bd81b6224b7e488d7193806a41343dff2456132274991a4722fdb0ef265d04cd\",\n    \"0x97583e08ecb82bbc27c0c8476d710389fa9ffbead5c43001bd36c1b018f29faa98de778644883e51870b69c5ffb558b5\",\n    \"0x90a799a8ce73387599babf6b7da12767c0591cadd36c20a7990e7c05ea1aa2b9645654ec65308ee008816623a2757a6a\",\n    \"0xa1b47841a0a2b06efd9ab8c111309cc5fc9e1d5896b3e42ed531f6057e5ade8977c29831ce08dbda40348386b1dcc06d\",\n    \"0xb92b8ef59bbddb50c9457691bc023d63dfcc54e0fd88bd5d27a09e0d98ac290fc90e6a8f6b88492043bf7c87fac8f3e4\",\n    \"0xa9d6240b07d62e22ec8ab9b1f6007c975a77b7320f02504fc7c468b4ee9cfcfd945456ff0128bc0ef2174d9e09333f8d\",\n    \"0x8e96534c94693226dc32bca79a595ca6de503af635f802e86442c67e77564829756961d9b701187fe91318da515bf0e6\",\n    \"0xb6ba290623cd8dd5c2f50931c0045d1cfb0c30877bc8fe58cbc3ff61ee8da100045a39153916efa1936f4aee0892b473\",\n    \"0xb43baa7717fac02d4294f5b3bb5e58a65b3557747e3188b482410388daac7a9c177f762d943fd5dcf871273921213da8\",\n    \"0xb9cf00f8fb5e2ef2b836659fece15e735060b2ea39b8e901d3dcbdcf612be8bf82d013833718c04cd46ffaa70b85f42e\",\n    \"0x8017d0c57419e414cbba504368723e751ef990cc6f05dad7b3c2de6360adc774ad95512875ab8337d110bf39a42026fa\",\n    \"0xae7401048b838c0dcd4b26bb6c56d79d51964a0daba780970b6c97daee4ea45854ea0ac0e4139b3fe60dac189f84df65\",\n    \"0x887b237b0cd0f816b749b21db0b40072f9145f7896c36916296973f9e6990ede110f14e5976c906d08987c9836cca57f\",\n    \"0xa88c3d5770148aee59930561ca1223aceb2c832fb5417e188dca935905301fc4c6c2c9270bc1dff7add490a125eb81c6\",\n    \"0xb6cf9b02c0cd91895ad209e38c54039523f137b5848b9d3ad33ae43af6c20c98434952db375fe378de7866f2d0e8b18a\",\n    \"0x84ef3d322ff580c8ad584b1fe4fe346c60866eb6a56e982ba2cf3b021ecb1fdb75ecc6c29747adda86d9264430b3f816\",\n    \"0xa0561c27224baf0927ad144cb71e31e54a064c598373fcf0d66aebf98ab7af1d8e2f343f77baefff69a6da750a219e11\",\n    \"0xaa5cc43f5b8162b016f5e1b61214c0c9d15b1078911c650b75e6cdfb49b85ee04c6739f5b1687d15908444f691f732de\",\n    \"0xad4ac099b935589c7b8fdfdf3db332b7b82bb948e13a5beb121ebd7db81a87d278024a1434bcf0115c54ca5109585c3d\",\n    \"0x8a00466abf3f109a1dcd19e643b603d3af23d42794ef8ca2514dd507ecea44a031ac6dbc18bd02f99701168b25c1791e\",\n    \"0xb00b5900dfad79645f8bee4e5adc7b84eb22e5b1e67df77ccb505b7fc044a6c08a8ea5faca662414eb945f874f884cea\",\n    \"0x950e204e5f17112250b22ea6bb8423baf522fc0af494366f18fe0f949f51d6e6812074a80875cf1ed9c8e7420058d541\",\n    \"0x91e5cbf8bb1a1d50c81608c9727b414d0dd2fb467ebc92f100882a3772e54f94979cfdf8e373fdef7c7fcdd60fec9e00\",\n    \"0xa093f6a857b8caaff80599c2e89c962b415ecbaa70d8fd973155fa976a284c6b29a855f5f7a3521134d00d2972755188\",\n    \"0xb4d55a3551b00da54cc010f80d99ddd2544bde9219a3173dfaadf3848edc7e4056ab532fb75ac26f5f7141e724267663\",\n    \"0xa03ea050fc9b011d1b04041b5765d6f6453a93a1819cd9bd6328637d0b428f08526466912895dcc2e3008ee58822e9a7\",\n    \"0x99b12b3665e473d01bc6985844f8994fb65cb15745024fb7af518398c4a37ff215da8f054e8fdf3286984ae36a73ca5e\",\n    \"0x9972c7e7a7fb12e15f78d55abcaf322c11249cd44a08f62c95288f34f66b51f146302bce750ff4d591707075d9123bd2\",\n    \"0xa64b4a6d72354e596d87cda213c4fc2814009461570ccb27d455bbe131f8d948421a71925425b546d8cf63d5458cd64b\",\n    \"0x91c215c73b195795ede2228b7ed1f6e37892e0c6b0f4a0b5a16c57aa1100c84df9239054a173b6110d6c2b7f4bf1ce52\",\n    \"0x88807198910ec1303480f76a3683870246a995e36adaeadc29c22f0bdba8152fe705bd070b75de657b04934f7d0ccf80\",\n    \"0xb37c0026c7b32eb02cacac5b55cb5fe784b8e48b2945c64d3037af83ece556a117f0ff053a5968c2f5fa230e291c1238\",\n    \"0x94c768384ce212bc2387e91ce8b45e4ff120987e42472888a317abc9dcdf3563b62e7a61c8e98d7cdcbe272167d91fc6\",\n    \"0xa10c2564936e967a390cb14ef6e8f8b04ea9ece5214a38837eda09e79e0c7970b1f83adf017c10efd6faa8b7ffa2c567\",\n    \"0xa5085eed3a95f9d4b1269182ea1e0d719b7809bf5009096557a0674bde4201b0ddc1f0f16a908fc468846b3721748ce3\",\n    \"0x87468eb620b79a0a455a259a6b4dfbc297d0d53336537b771254dd956b145dc816b195b7002647ea218552e345818a3f\",\n    \"0xace2b77ffb87366af0a9cb5d27d6fc4a14323dbbf1643f5f3c4559306330d86461bb008894054394cbfaefeaa0bc2745\",\n    \"0xb27f56e840a54fbd793f0b7a7631aa4cee64b5947e4382b2dfb5eb1790270288884c2a19afebe5dc0c6ef335d4531c1c\",\n    \"0x876e438633931f7f895062ee16c4b9d10428875f7bc79a8e156a64d379a77a2c45bf5430c5ab94330f03da352f1e9006\",\n    \"0xa2512a252587d200d2092b44c914df54e04ff8bcef36bf631f84bde0cf5a732e3dc7f00f662842cfd74b0b0f7f24180e\",\n    \"0x827f1bc8f54a35b7a4bd8154f79bcc055e45faed2e74adf7cf21cca95df44d96899e847bd70ead6bb27b9c0ed97bbd8b\",\n    \"0xa0c92cf5a9ed843714f3aea9fe7b880f622d0b4a3bf66de291d1b745279accf6ba35097849691370f41732ba64b5966b\",\n    \"0xa63f5c1e222775658421c487b1256b52626c6f79cb55a9b7deb2352622cedffb08502042d622eb3b02c97f9c09f9c957\",\n    \"0x8cc093d52651e65fb390e186db6cc4de559176af4624d1c44cb9b0e836832419dacac7b8db0627b96288977b738d785d\",\n    \"0xaa7b6a17dfcec146134562d32a12f7bd7fe9522e300859202a02939e69dbd345ed7ff164a184296268f9984f9312e8fc\",\n    \"0x8ac76721f0d2b679f023d06cbd28c85ae5f4b43c614867ccee88651d4101d4fd352dbdb65bf36bfc3ebc0109e4b0c6f9\",\n    \"0x8d350f7c05fc0dcd9a1170748846fb1f5d39453e4cb31e6d1457bed287d96fc393b2ecc53793ca729906a33e59c6834a\",\n    \"0xb9913510dfc5056d7ec5309f0b631d1ec53e3a776412ada9aefdaf033c90da9a49fdde6719e7c76340e86599b1f0eec2\",\n    \"0x94955626bf4ce87612c5cfffcf73bf1c46a4c11a736602b9ba066328dc52ad6d51e6d4f53453d4ed55a51e0aad810271\",\n    \"0xb0fcab384fd4016b2f1e53f1aafd160ae3b1a8865cd6c155d7073ecc1664e05b1d8bca1def39c158c7086c4e1103345e\",\n    \"0x827de3f03edfbde08570b72de6662c8bfa499b066a0a27ebad9b481c273097d17a5a0a67f01553da5392ec3f149b2a78\",\n    \"0xab7940384c25e9027c55c40df20bd2a0d479a165ced9b1046958353cd69015eeb1e44ed2fd64e407805ba42df10fc7bf\",\n    \"0x8ad456f6ff8cd58bd57567d931f923d0c99141978511b17e03cab7390a72b9f62498b2893e1b05c7c22dd274e9a31919\",\n    \"0xac75399e999effe564672db426faa17a839e57c5ef735985c70cd559a377adec23928382767b55ed5a52f7b11b54b756\",\n    \"0xb17f975a00b817299ac7af5f2024ea820351805df58b43724393bfb3920a8cd747a3bbd4b8286e795521489db3657168\",\n    \"0xa2bed800a6d95501674d9ee866e7314063407231491d794f8cf57d5be020452729c1c7cefd8c50dc1540181f5caab248\",\n    \"0x9743f5473171271ffdd3cc59a3ae50545901a7b45cd4bc3570db487865f3b73c0595bebabbfe79268809ee1862e86e4a\",\n    \"0xb7eab77c2d4687b60d9d7b04e842b3880c7940140012583898d39fcc22d9b9b0a9be2c2e3788b3e6f30319b39c338f09\",\n    \"0x8e2b8f797a436a1b661140e9569dcf3e1eea0a77c7ff2bc4ff0f3e49af04ed2de95e255df8765f1d0927fb456a9926b1\",\n    \"0x8aefea201d4a1f4ff98ffce94e540bb313f2d4dfe7e9db484a41f13fc316ed02b282e1acc9bc6f56cad2dc2e393a44c9\",\n    \"0xb950c17c0e5ca6607d182144aa7556bb0efe24c68f06d79d6413a973b493bfdf04fd147a4f1ab03033a32004cc3ea66f\",\n    \"0xb7b8dcbb179a07165f2dc6aa829fad09f582a71b05c3e3ea0396bf9e6fe73076f47035c031c2101e8e38e0d597eadd30\",\n    \"0xa9d77ed89c77ec1bf8335d08d41c3c94dcca9fd1c54f22837b4e54506b212aa38d7440126c80648ab7723ff18e65ed72\",\n    \"0xa819d6dfd4aef70e52b8402fe5d135f8082d40eb7d3bb5c4d7997395b621e2bb10682a1bad2c9caa33dd818550fc3ec6\",\n    \"0x8f6ee34128fac8bbf13ce2d68b2bb363eb4fd65b297075f88e1446ddeac242500eeb4ef0735e105882ff5ba8c44c139b\",\n    \"0xb4440e48255c1644bcecf3a1e9958f1ec4901cb5b1122ee5b56ffd02cad1c29c4266999dbb85aa2605c1b125490074d4\",\n    \"0xa43304a067bede5f347775d5811cf65a6380a8d552a652a0063580b5c5ef12a0867a39c7912fa219e184f4538eba1251\",\n    \"0xa891ad67a790089ffc9f6d53e6a3d63d3556f5f693e0cd8a7d0131db06fd4520e719cfcc3934f0a8f62a95f90840f1d4\",\n    \"0xaea6df8e9bb871081aa0fc5a9bafb00be7d54012c5baf653791907d5042a326aeee966fd9012a582cc16695f5baf7042\",\n    \"0x8ffa2660dc52ed1cd4eff67d6a84a8404f358a5f713d04328922269bee1e75e9d49afeec0c8ad751620f22352a438e25\",\n    \"0x87ec6108e2d63b06abed350f8b363b7489d642486f879a6c3aa90e5b0f335efc2ff2834eef9353951a42136f8e6a1b32\",\n    \"0x865619436076c2760d9e87ddc905023c6de0a8d56eef12c98a98c87837f2ca3f27fd26a2ad752252dbcbe2b9f1d5a032\",\n    \"0x980437dce55964293cb315c650c5586ffd97e7a944a83f6618af31c9d92c37b53ca7a21bb5bc557c151b9a9e217e7098\",\n    \"0x95d128fc369df4ad8316b72aea0ca363cbc7b0620d6d7bb18f7076a8717a6a46956ff140948b0cc4f6d2ce33b5c10054\",\n    \"0x8c7212d4a67b9ec70ebbca04358ad2d36494618d2859609163526d7b3acc2fc935ca98519380f55e6550f70a9bc76862\",\n    \"0x893a2968819401bf355e85eee0f0ed0406a6d4a7d7f172d0017420f71e00bb0ba984f6020999a3cdf874d3cd8ebcd371\",\n    \"0x9103c1af82dece25d87274e89ea0acd7e68c2921c4af3d8d7c82ab0ed9990a5811231b5b06113e7fa43a6bd492b4564f\",\n    \"0x99cfd87a94eab7d35466caa4ed7d7bb45e5c932b2ec094258fb14bf205659f83c209b83b2f2c9ccb175974b2a33e7746\",\n    \"0x874b6b93e4ee61be3f00c32dd84c897ccd6855c4b6251eb0953b4023634490ed17753cd3223472873cbc6095b2945075\",\n    \"0x84a32c0dc4ea60d33aac3e03e70d6d639cc9c4cc435c539eff915017be3b7bdaba33349562a87746291ebe9bc5671f24\",\n    \"0xa7057b24208928ad67914e653f5ac1792c417f413d9176ba635502c3f9c688f7e2ee81800d7e3dc0a340c464da2fd9c5\",\n    \"0xa03fb9ed8286aacfa69fbd5d953bec591c2ae4153400983d5dbb6cd9ea37fff46ca9e5cceb9d117f73e9992a6c055ad2\",\n    \"0x863b2de04e89936c9a4a2b40380f42f20aefbae18d03750fd816c658aee9c4a03df7b12121f795c85d01f415baaeaa59\",\n    \"0x8526eb9bd31790fe8292360d7a4c3eed23be23dd6b8b8f01d2309dbfdc0cfd33ad1568ddd7f8a610f3f85a9dfafc6a92\",\n    \"0xb46ab8c5091a493d6d4d60490c40aa27950574a338ea5bbc045be3a114af87bdcb160a8c80435a9b7ad815f3cb56a3f3\",\n    \"0xaeadc47b41a8d8b4176629557646202f868b1d728b2dda58a347d937e7ffc8303f20d26d6c00b34c851b8aeec547885d\",\n    \"0xaebb19fc424d72c1f1822aa7adc744cd0ef7e55727186f8df8771c784925058c248406ebeeaf3c1a9ee005a26e9a10c6\",\n    \"0x8ff96e81c1a4a2ab1b4476c21018fae0a67e92129ee36120cae8699f2d7e57e891f5c624902cb1b845b944926a605cc3\",\n    \"0x8251b8d2c43fadcaa049a9e7aff838dae4fb32884018d58d46403ac5f3beb5c518bfd45f03b8abb710369186075eb71c\",\n    \"0xa8b2a64f865f51a5e5e86a66455c093407933d9d255d6b61e1fd81ffafc9538d73caaf342338a66ba8ee166372a3d105\",\n    \"0xaad915f31c6ba7fdc04e2aaac62e84ef434b7ee76a325f07dc430d12c84081999720181067b87d792efd0117d7ee1eab\",\n    \"0xa13db3bb60389883fd41d565c54fb5180d9c47ce2fe7a169ae96e01d17495f7f4fa928d7e556e7c74319c4c25d653eb2\",\n    \"0xa4491b0198459b3f552855d680a59214eb74e6a4d6c5fa3b309887dc50ebea2ecf6d26c040550f7dc478b452481466fb\",\n    \"0x8f017f13d4b1e3f0c087843582b52d5f8d13240912254d826dd11f8703a99a2f3166dfbdfdffd9a3492979d77524276b\",\n    \"0x96c3d5dcd032660d50d7cd9db2914f117240a63439966162b10c8f1f3cf74bc83b0f15451a43b31dbd85e4a7ce0e4bb1\",\n    \"0xb479ec4bb79573d32e0ec93b92bdd7ec8c26ddb5a2d3865e7d4209d119fd3499eaac527615ffac78c440e60ef3867ae0\",\n    \"0xb2c49c4a33aa94b52b6410b599e81ff15490aafa7e43c8031c865a84e4676354a9c81eb4e7b8be6825fdcefd1e317d44\",\n    \"0x906dc51d6a90c089b6704b47592805578a6eed106608eeb276832f127e1b8e858b72e448edcbefb497d152447e0e68ff\",\n    \"0xb0e81c63b764d7dfbe3f3fddc9905aef50f3633e5d6a4af6b340495124abedcff5700dfd1577bbbed7b6bf97d02719cb\",\n    \"0x9304c64701e3b4ed6d146e48a881f7d83a17f58357cca0c073b2bb593afd2d94f6e2a7a1ec511d0a67ad6ff4c3be5937\",\n    \"0xb6fdbd12ba05aa598d80b83f70a15ef90e5cba7e6e75fa038540ee741b644cd1f408a6cecfd2a891ef8d902de586c6b5\",\n    \"0xb80557871a6521b1b3c74a1ba083ae055b575df607f1f7b04c867ba8c8c181ea68f8d90be6031f4d25002cca27c44da2\",\n    \"0xaa7285b8e9712e06b091f64163f1266926a36607f9d624af9996856ed2aaf03a580cb22ce407d1ade436c28b44ca173f\",\n    \"0x8148d72b975238b51e6ea389e5486940d22641b48637d7dfadfa603a605bfc6d74a016480023945d0b85935e396aea5d\",\n    \"0x8a014933a6aea2684b5762af43dcf4bdbb633cd0428d42d71167a2b6fc563ece5e618bff22f1db2ddb69b845b9a2db19\",\n    \"0x990d91740041db770d0e0eb9d9d97d826f09fd354b91c41e0716c29f8420e0e8aac0d575231efba12fe831091ec38d5a\",\n    \"0x9454d0d32e7e308ddec57cf2522fb1b67a2706e33fb3895e9e1f18284129ab4f4c0b7e51af25681d248d7832c05eb698\",\n    \"0xa5bd434e75bac105cb3e329665a35bce6a12f71dd90c15165777d64d4c13a82bceedb9b48e762bd24034e0fc9fbe45f4\",\n    \"0xb09e3b95e41800d4dc29c6ffdaab2cd611a0050347f6414f154a47ee20ee59bf8cf7181454169d479ebce1eb5c777c46\",\n    \"0xb193e341d6a047d15eea33766d656d807b89393665a783a316e9ba10518e5515c8e0ade3d6e15641d917a8a172a5a635\",\n    \"0xade435ec0671b3621dde69e07ead596014f6e1daa1152707a8c18877a8b067bde2895dd47444ffa69db2bbef1f1d8816\",\n    \"0xa7fd3d6d87522dfc56fb47aef9ce781a1597c56a8bbfd796baba907afdc872f753d732bfda1d3402aee6c4e0c189f52d\",\n    \"0xa298cb4f4218d0464b2fab393e512bbc477c3225aa449743299b2c3572f065bc3a42d07e29546167ed9e1b6b3b3a3af3\",\n    \"0xa9ee57540e1fd9c27f4f0430d194b91401d0c642456c18527127d1f95e2dba41c2c86d1990432eb38a692fda058fafde\",\n    \"0x81d6c1a5f93c04e6d8e5a7e0678c1fc89a1c47a5c920bcd36180125c49fcf7c114866b90e90a165823560b19898a7c16\",\n    \"0xa4b7a1ec9e93c899b9fd9aaf264c50e42c36c0788d68296a471f7a3447af4dbc81e4fa96070139941564083ec5b5b5a1\",\n    \"0xb3364e327d381f46940c0e11e29f9d994efc6978bf37a32586636c0070b03e4e23d00650c1440f448809e1018ef9f6d8\",\n    \"0x8056e0913a60155348300e3a62e28b5e30629a90f7dd4fe11289097076708110a1d70f7855601782a3cdc5bdb1ca9626\",\n    \"0xb4980fd3ea17bac0ba9ee1c470b17e575bb52e83ebdd7d40c93f4f87bebeaff1c8a679f9d3d09d635f068d37d5bd28bd\",\n    \"0x905a9299e7e1853648e398901dfcd437aa575c826551f83520df62984f5679cb5f0ea86aa45ed3e18b67ddc0dfafe809\",\n    \"0xab99553bf31a84f2e0264eb34a08e13d8d15e2484aa9352354becf9a15999c76cc568d68274b70a65e49703fc23540d0\",\n    \"0xa43681597bc574d2dae8964c9a8dc1a07613d7a1272bdcb818d98c85d44e16d744250c33f3b5e4d552d97396b55e601f\",\n    \"0xa54e5a31716fccb50245898c99865644405b8dc920ded7a11f3d19bdc255996054b268e16f2e40273f11480e7145f41e\",\n    \"0x8134f3ad5ef2ad4ba12a8a4e4d8508d91394d2bcdc38b7c8c8c0b0a820357ac9f79d286c65220f471eb1adca1d98fc68\",\n    \"0x94e2f755e60471578ab2c1adb9e9cea28d4eec9b0e92e0140770bca7002c365fcabfe1e5fb4fe6cfe79a0413712aa3ef\",\n    \"0xad48f8d0ce7eb3cc6e2a3086ad96f562e5bed98a360721492ae2e74dc158586e77ec8c35d5fd5927376301b7741bad2b\",\n    \"0x8614f0630bdd7fbad3a31f55afd9789f1c605dc85e7dc67e2edfd77f5105f878bb79beded6e9f0b109e38ea7da67e8d5\",\n    \"0x9804c284c4c5e77dabb73f655b12181534ca877c3e1e134aa3f47c23b7ec92277db34d2b0a5d38d2b69e5d1c3008a3e3\",\n    \"0xa51b99c3088e473afdaa9e0a9f7e75a373530d3b04e44e1148da0726b95e9f5f0c7e571b2da000310817c36f84b19f7f\",\n    \"0xac4ff909933b3b76c726b0a382157cdc74ab851a1ac6cef76953c6444441804cc43abb883363f416592e8f6cfbc4550b\",\n    \"0xae7d915eb9fc928b65a29d6edbc75682d08584d0014f7bcf17d59118421ae07d26a02137d1e4de6938bcd1ab8ef48fad\",\n    \"0x852f7e453b1af89b754df6d11a40d5d41ea057376e8ecacd705aacd2f917457f4a093d6b9a8801837fa0f62986ad7149\",\n    \"0x92c6bf5ada5d0c3d4dd8058483de36c215fa98edab9d75242f3eff9db07c734ad67337da6f0eefe23a487bf75a600dee\",\n    \"0xa2b42c09d0db615853763552a48d2e704542bbd786aae016eb58acbf6c0226c844f5fb31e428cb6450b9db855f8f2a6f\",\n    \"0x880cc07968266dbfdcfbc21815cd69e0eddfee239167ac693fb0413912d816f2578a74f7716eecd6deefa68c6eccd394\",\n    \"0xb885b3ace736cd373e8098bf75ba66fa1c6943ca1bc4408cd98ac7074775c4478594f91154b8a743d9c697e1b29f5840\",\n    \"0xa51ce78de512bd87bfa0835de819941dffbf18bec23221b61d8096fc9436af64e0693c335b54e7bfc763f287bdca2db6\",\n    \"0xa3c76166a3bdb9b06ef696e57603b58871bc72883ee9d45171a30fe6e1d50e30bc9c51b4a0f5a7270e19a77b89733850\",\n    \"0xacefc5c6f8a1e7c24d7b41e0fc7f6f3dc0ede6cf3115ffb9a6e54b1d954cbca9bda8ad7a084be9be245a1b8e9770d141\",\n    \"0xb420ed079941842510e31cfad117fa11fb6b4f97dfbc6298cb840f27ebaceba23eeaf3f513bcffbf5e4aae946310182d\",\n    \"0x95c3bb5ef26c5ed2f035aa5d389c6b3c15a6705b9818a3fefaed28922158b35642b2e8e5a1a620fdad07e75ad4b43af4\",\n    \"0x825149f9081ecf07a2a4e3e8b5d21bade86c1a882475d51c55ee909330b70c5a2ac63771c8600c6f38df716af61a3ea1\",\n    \"0x873b935aae16d9f08adbc25353cee18af2f1b8d5f26dec6538d6bbddc515f2217ed7d235dcfea59ae61b428798b28637\",\n    \"0x9294150843a2bedcedb3bb74c43eb28e759cf9499582c5430bccefb574a8ddd4f11f9929257ff4c153990f9970a2558f\",\n    \"0xb619563a811cc531da07f4f04e5c4c6423010ff9f8ed7e6ec9449162e3d501b269fb1c564c09c0429431879b0f45df02\",\n    \"0x91b509b87eb09f007d839627514658c7341bc76d468920fe8a740a8cb96a7e7e631e0ea584a7e3dc1172266f641d0f5c\",\n    \"0x8b8aceace9a7b9b4317f1f01308c3904d7663856946afbcea141a1c615e21ccad06b71217413e832166e9dd915fbe098\",\n    \"0x87b3b36e725833ea0b0f54753c3728c0dbc87c52d44d705ffc709f2d2394414c652d3283bab28dcce09799504996cee0\",\n    \"0xb2670aad5691cbf308e4a6a77a075c4422e6cbe86fdba24e9f84a313e90b0696afb6a067eebb42ba2d10340d6a2f6e51\",\n    \"0x876784a9aff3d54faa89b2bacd3ff5862f70195d0b2edc58e8d1068b3c9074c0da1cfa23671fe12f35e33b8a329c0ccd\",\n    \"0x8b48b9e758e8a8eae182f5cbec96f67d20cca6d3eee80a2d09208eb1d5d872e09ef23d0df8ebbb9b01c7449d0e3e3650\",\n    \"0xb79303453100654c04a487bdcadc9e3578bc80930c489a7069a52e8ca1dba36c492c8c899ce025f8364599899baa287d\",\n    \"0x961b35a6111da54ece6494f24dacd5ea46181f55775b5f03df0e370c34a5046ac2b4082925855325bb42bc2a2c98381d\",\n    \"0xa31feb1be3f5a0247a1f7d487987eb622e34fca817832904c6ee3ee60277e5847945a6f6ea1ac24542c72e47bdf647df\",\n    \"0xa12a2aa3e7327e457e1aae30e9612715dd2cfed32892c1cd6dcda4e9a18203af8a44afb46d03b2eed89f6b9c5a2c0c23\",\n    \"0xa08265a838e69a2ca2f80fead6ccf16f6366415b920c0b22ee359bcd8d4464ecf156f400a16a7918d52e6d733dd64211\",\n    \"0xb723d6344e938d801cca1a00032af200e541d4471fd6cbd38fb9130daa83f6a1dffbbe7e67fc20f9577f884acd7594b2\",\n    \"0xa6733d83ec78ba98e72ddd1e7ff79b7adb0e559e256760d0c590a986e742445e8cdf560d44b29439c26d87edd0b07c8c\",\n    \"0xa61c2c27d3f7b9ff4695a17afedf63818d4bfba390507e1f4d0d806ce8778d9418784430ce3d4199fd3bdbc2504d2af3\",\n    \"0x8332f3b63a6dc985376e8b1b25eeae68be6160fbe40053ba7bcf6f073204f682da72321786e422d3482fd60c9e5aa034\",\n    \"0xa280f44877583fbb6b860d500b1a3f572e3ee833ec8f06476b3d8002058e25964062feaa1e5bec1536d734a5cfa09145\",\n    \"0xa4026a52d277fcea512440d2204f53047718ebfcae7b48ac57ea7f6bfbc5de9d7304db9a9a6cbb273612281049ddaec5\",\n    \"0x95cdf69c831ab2fad6c2535ede9c07e663d2ddccc936b64e0843d2df2a7b1c31f1759c3c20f1e7a57b1c8f0dbb21b540\",\n    \"0x95c96cec88806469c277ab567863c5209027cecc06c7012358e5f555689c0d9a5ffb219a464f086b45817e8536b86d2f\",\n    \"0xafe38d4684132a0f03d806a4c8df556bf589b25271fbc6fe2e1ed16de7962b341c5003755da758d0959d2e6499b06c68\",\n    \"0xa9b77784fda64987f97c3a23c5e8f61b918be0f7c59ba285084116d60465c4a2aaafc8857eb16823282cc83143eb9126\",\n    \"0xa830f05881ad3ce532a55685877f529d32a5dbe56cea57ffad52c4128ee0fad0eeaf0da4362b55075e77eda7babe70e5\",\n    \"0x992b3ad190d6578033c13ed5abfee4ef49cbc492babb90061e3c51ee4b5790cdd4c8fc1abff1fa2c00183b6b64f0bbbe\",\n    \"0xb1015424d9364aeff75de191652dc66484fdbec3e98199a9eb9671ec57bec6a13ff4b38446e28e4d8aedb58dd619cd90\",\n    \"0xa745304604075d60c9db36cada4063ac7558e7ec2835d7da8485e58d8422e817457b8da069f56511b02601289fbb8981\",\n    \"0xa5ba4330bc5cb3dbe0486ddf995632a7260a46180a08f42ae51a2e47778142132463cc9f10021a9ad36986108fefa1a9\",\n    \"0xb419e9fd4babcaf8180d5479db188bb3da232ae77a1c4ed65687c306e6262f8083070a9ac32220cddb3af2ec73114092\",\n    \"0xa49e23dc5f3468f3bf3a0bb7e4a114a788b951ff6f23a3396ae9e12cbff0abd1240878a3d1892105413dbc38818e807c\",\n    \"0xb7ecc7b4831f650202987e85b86bc0053f40d983f252e9832ef503aea81c51221ce93279da4aa7466c026b2d2070e55d\",\n    \"0x96a8c35cb87f84fa84dcd6399cc2a0fd79cc9158ef4bdde4bae31a129616c8a9f2576cd19baa3f497ca34060979aed7d\",\n    \"0x8681b2c00aa62c2b519f664a95dcb8faef601a3b961bb4ce5d85a75030f40965e2983871d41ea394aee934e859581548\",\n    \"0x85c229a07efa54a713d0790963a392400f55fbb1a43995a535dc6c929f20d6a65cf4efb434e0ad1cb61f689b8011a3bc\",\n    \"0x90856f7f3444e5ad44651c28e24cc085a5db4d2ffe79aa53228c26718cf53a6e44615f3c5cda5aa752d5f762c4623c66\",\n    \"0x978999b7d8aa3f28a04076f74d11c41ef9c89fdfe514936c4238e0f13c38ec97e51a5c078ebc6409e517bfe7ccb42630\",\n    \"0xa099914dd7ed934d8e0d363a648e9038eb7c1ec03fa04dbcaa40f7721c618c3ef947afef7a16b4d7ac8c12aa46637f03\",\n    \"0xab2a104fed3c83d16f2cda06878fa5f30c8c9411de71bfb67fd2fc9aa454dcbcf3d299d72f8cc12e919466a50fcf7426\",\n    \"0xa4471d111db4418f56915689482f6144efc4664cfb0311727f36c864648d35734351becc48875df96f4abd3cfcf820f9\",\n    \"0x83be11727cd30ea94ccc8fa31b09b81c9d6a9a5d3a4686af9da99587332fe78c1f94282f9755854bafd6033549afec91\",\n    \"0x88020ff971dc1a01a9e993cd50a5d2131ffdcbb990c1a6aaa54b20d8f23f9546a70918ea57a21530dcc440c1509c24ad\",\n    \"0xae24547623465e87905eaffa1fa5d52bb7c453a8dbd89614fa8819a2abcedaf455c2345099b7324ae36eb0ad7c8ef977\",\n    \"0xb59b0c60997de1ee00b7c388bc7101d136c9803bf5437b1d589ba57c213f4f835a3e4125b54738e78abbc21b000f2016\",\n    \"0xa584c434dfe194546526691b68fa968c831c31da42303a1d735d960901c74011d522246f37f299555416b8cf25c5a548\",\n    \"0x80408ce3724f4837d4d52376d255e10f69eb8558399ae5ca6c11b78b98fe67d4b93157d2b9b639f1b5b64198bfe87713\",\n    \"0xabb941e8d406c2606e0ddc35c113604fdd9d249eacc51cb64e2991e551b8639ce44d288cc92afa7a1e7fc599cfc84b22\",\n    \"0xb223173f560cacb1c21dba0f1713839e348ad02cbfdef0626748604c86f89e0f4c919ed40b583343795bdd519ba952c8\",\n    \"0xaf1c70512ec3a19d98b8a1fc3ff7f7f5048a27d17d438d43f561974bbdd116fcd5d5c21040f3447af3f0266848d47a15\",\n    \"0x8a44809568ebe50405bede19b4d2607199159b26a1b33e03d180e6840c5cf59d991a4fb150d111443235d75ecad085b7\",\n    \"0xb06207cdca46b125a27b3221b5b50cf27af4c527dd7c80e2dbcebbb09778a96df3af67e50f07725239ce3583dad60660\",\n    \"0x993352d9278814ec89b26a11c4a7c4941bf8f0e6781ae79559d14749ee5def672259792db4587f85f0100c7bb812f933\",\n    \"0x9180b8a718b971fd27bc82c8582d19c4b4f012453e8c0ffeeeffe745581fc6c07875ab28be3af3fa3896d19f0c89ac5b\",\n    \"0x8b8e1263eb48d0fe304032dd5ea1f30e73f0121265f7458ba9054d3626894e8a5fef665340abd2ede9653045c2665938\",\n    \"0x99a2beee4a10b7941c24b2092192faf52b819afd033e4a2de050fd6c7f56d364d0cf5f99764c3357cf32399e60fc5d74\",\n    \"0x946a4aad7f8647ea60bee2c5fcdeb6f9a58fb2cfca70c4d10e458027a04846e13798c66506151be3df9454b1e417893f\",\n    \"0xa672a88847652d260b5472d6908d1d57e200f1e492d30dd1cecc441cdfc9b76e016d9bab560efd4d7f3c30801de884a9\",\n    \"0x9414e1959c156cde1eb24e628395744db75fc24b9df4595350aaad0bc38e0246c9b4148f6443ef68b8e253a4a6bcf11c\",\n    \"0x9316e9e4ec5fab4f80d6540df0e3a4774db52f1d759d2e5b5bcd3d7b53597bb007eb1887cb7dc61f62497d51ffc8d996\",\n    \"0x902d6d77bb49492c7a00bc4b70277bc28c8bf9888f4307bb017ac75a962decdedf3a4e2cf6c1ea9f9ba551f4610cbbd7\",\n    \"0xb07025a18b0e32dd5e12ec6a85781aa3554329ea12c4cd0d3b2c22e43d777ef6f89876dd90a9c8fb097ddf61cf18adc5\",\n    \"0xb355a849ad3227caa4476759137e813505ec523cbc2d4105bc7148a4630f9e81918d110479a2d5f5e4cd9ccec9d9d3e3\",\n    \"0xb49532cfdf02ee760109881ad030b89c48ee3bb7f219ccafc13c93aead754d29bdafe345be54c482e9d5672bd4505080\",\n    \"0x9477802410e263e4f938d57fa8f2a6cac7754c5d38505b73ee35ea3f057aad958cb9722ba6b7b3cfc4524e9ca93f9cdc\",\n    \"0x9148ea83b4436339580f3dbc9ba51509e9ab13c03063587a57e125432dd0915f5d2a8f456a68f8fff57d5f08c8f34d6e\",\n    \"0xb00b6b5392b1930b54352c02b1b3b4f6186d20bf21698689bbfc7d13e86538a4397b90e9d5c93fd2054640c4dbe52a4f\",\n    \"0x926a9702500441243cd446e7cbf15dde16400259726794694b1d9a40263a9fc9e12f7bcbf12a27cb9aaba9e2d5848ddc\",\n    \"0xa0c6155f42686cbe7684a1dc327100962e13bafcf3db97971fc116d9f5c0c8355377e3d70979cdbd58fd3ea52440901c\",\n    \"0xa277f899f99edb8791889d0817ea6a96c24a61acfda3ad8c3379e7c62b9d4facc4b965020b588651672fd261a77f1bfc\",\n    \"0x8f528cebb866b501f91afa50e995234bef5bf20bff13005de99cb51eaac7b4f0bf38580cfd0470de40f577ead5d9ba0f\",\n    \"0x963fc03a44e9d502cc1d23250efef44d299befd03b898d07ce63ca607bb474b5cf7c965a7b9b0f32198b04a8393821f7\",\n    \"0xab087438d0a51078c378bf4a93bd48ef933ff0f1fa68d02d4460820df564e6642a663b5e50a5fe509527d55cb510ae04\",\n    \"0xb0592e1f2c54746bb076be0fa480e1c4bebc4225e1236bcda3b299aa3853e3afb401233bdbcfc4a007b0523a720fbf62\",\n    \"0x851613517966de76c1c55a94dc4595f299398a9808f2d2f0a84330ba657ab1f357701d0895f658c18a44cb00547f6f57\",\n    \"0xa2fe9a1dd251e72b0fe4db27be508bb55208f8f1616b13d8be288363ec722826b1a1fd729fc561c3369bf13950bf1fd6\",\n    \"0xb896cb2bc2d0c77739853bc59b0f89b2e008ba1f701c9cbe3bef035f499e1baee8f0ff1e794854a48c320586a2dfc81a\",\n    \"0xa1b60f98e5e5106785a9b81a85423452ee9ef980fa7fa8464f4366e73f89c50435a0c37b2906052b8e58e212ebd366cf\",\n    \"0xa853b0ebd9609656636df2e6acd5d8839c0fda56f7bf9288a943b06f0b67901a32b95e016ca8bc99bd7b5eab31347e72\",\n    \"0xb290fa4c1346963bd5225235e6bdf7c542174dab4c908ab483d1745b9b3a6015525e398e1761c90e4b49968d05e30eea\",\n    \"0xb0f65a33ad18f154f1351f07879a183ad62e5144ad9f3241c2d06533dad09cbb2253949daff1bb02d24d16a3569f7ef0\",\n    \"0xa00db59b8d4218faf5aeafcd39231027324408f208ec1f54d55a1c41228b463b88304d909d16b718cfc784213917b71e\",\n    \"0xb8d695dd33dc2c3bc73d98248c535b2770ad7fa31aa726f0aa4b3299efb0295ba9b4a51c71d314a4a1bd5872307534d1\",\n    \"0xb848057cca2ca837ee49c42b88422303e58ea7d2fc76535260eb5bd609255e430514e927cc188324faa8e657396d63ec\",\n    \"0x92677836061364685c2aaf0313fa32322746074ed5666fd5f142a7e8f87135f45cd10e78a17557a4067a51dfde890371\",\n    \"0xa854b22c9056a3a24ab164a53e5c5cf388616c33e67d8ebb4590cb16b2e7d88b54b1393c93760d154208b5ca822dc68f\",\n    \"0x86fff174920388bfab841118fb076b2b0cdec3fdb6c3d9a476262f82689fb0ed3f1897f7be9dbf0932bb14d346815c63\",\n    \"0x99661cf4c94a74e182752bcc4b98a8c2218a8f2765642025048e12e88ba776f14f7be73a2d79bd21a61def757f47f904\",\n    \"0x8a8893144d771dca28760cba0f950a5d634195fd401ec8cf1145146286caffb0b1a6ba0c4c1828d0a5480ce49073c64c\",\n    \"0x938a59ae761359ee2688571e7b7d54692848eb5dde57ffc572b473001ea199786886f8c6346a226209484afb61d2e526\",\n    \"0x923f68a6aa6616714cf077cf548aeb845bfdd78f2f6851d8148cba9e33a374017f2f3da186c39b82d14785a093313222\",\n    \"0xac923a93d7da7013e73ce8b4a2b14b8fd0cc93dc29d5de941a70285bdd19be4740fedfe0c56b046689252a3696e9c5bc\",\n    \"0xb49b32c76d4ec1a2c68d4989285a920a805993bc6fcce6dacd3d2ddae73373050a5c44ba8422a3781050682fa0ef6ba2\",\n    \"0x8a367941c07c3bdca5712524a1411bad7945c7c48ffc7103b1d4dff2c25751b0624219d1ccde8c3f70c465f954be5445\",\n    \"0xb838f029df455efb6c530d0e370bbbf7d87d61a9aea3d2fe5474c5fe0a39cf235ceecf9693c5c6c5820b1ba8f820bd31\",\n    \"0xa8983b7c715eaac7f13a001d2abc462dfc1559dab4a6b554119c271aa8fe00ffcf6b6949a1121f324d6d26cb877bcbae\",\n    \"0xa2afb24ad95a6f14a6796315fbe0d8d7700d08f0cfaf7a2abe841f5f18d4fecf094406cbd54da7232a159f9c5b6e805e\",\n    \"0x87e8e95ad2d62f947b2766ff405a23f7a8afba14e7f718a691d95369c79955cdebe24c54662553c60a3f55e6322c0f6f\",\n    \"0x87c2cbcecb754e0cc96128e707e5c5005c9de07ffd899efa3437cadc23362f5a1d3fcdd30a1f5bdc72af3fb594398c2a\",\n    \"0x91afd6ee04f0496dc633db88b9370d41c428b04fd991002502da2e9a0ef051bcd7b760e860829a44fbe5539fa65f8525\",\n    \"0x8c50e5d1a24515a9dd624fe08b12223a75ca55196f769f24748686315329b337efadca1c63f88bee0ac292dd0a587440\",\n    \"0x8a07e8f912a38d94309f317c32068e87f68f51bdfa082d96026f5f5f8a2211621f8a3856dda8069386bf15fb2d28c18f\",\n    \"0x94ad1dbe341c44eeaf4dc133eed47d8dbfe752575e836c075745770a6679ff1f0e7883b6aa917462993a7f469d74cab5\",\n    \"0x8745f8bd86c2bb30efa7efb7725489f2654f3e1ac4ea95bd7ad0f3cfa223055d06c187a16192d9d7bdaea7b050c6a324\",\n    \"0x900d149c8d79418cda5955974c450a70845e02e5a4ecbcc584a3ca64d237df73987c303e3eeb79da1af83bf62d9e579f\",\n    \"0x8f652ab565f677fb1a7ba03b08004e3cda06b86c6f1b0b9ab932e0834acf1370abb2914c15b0d08327b5504e5990681c\",\n    \"0x9103097d088be1f75ab9d3da879106c2f597e2cc91ec31e73430647bdd5c33bcfd771530d5521e7e14df6acda44f38a6\",\n    \"0xb0fec7791cfb0f96e60601e1aeced9a92446b61fedab832539d1d1037558612d78419efa87ff5f6b7aab8fd697d4d9de\",\n    \"0xb9d2945bdb188b98958854ba287eb0480ef614199c4235ce5f15fc670b8c5ffe8eeb120c09c53ea8a543a022e6a321ac\",\n    \"0xa9461bb7d5490973ebaa51afc0bb4a5e42acdccb80e2f939e88b77ac28a98870e103e1042899750f8667a8cc9123bae9\",\n    \"0xa37fdf11d4bcb2aed74b9f460a30aa34afea93386fa4cdb690f0a71bc58f0b8df60bec56e7a24f225978b862626fa00e\",\n    \"0xa214420e183e03d531cf91661466ea2187d84b6e814b8b20b3730a9400a7d25cf23181bb85589ebc982cec414f5c2923\",\n    \"0xad09a45a698a6beb3e0915f540ef16e9af7087f53328972532d6b5dfe98ce4020555ece65c6cbad8bd6be8a4dfefe6fd\",\n    \"0xab6742800b02728c92d806976764cb027413d6f86edd08ad8bb5922a2969ee9836878cd39db70db0bd9a2646862acc4f\",\n    \"0x974ca9305bd5ea1dc1755dff3b63e8bfe9f744321046c1395659bcea2a987b528e64d5aa96ac7b015650b2253b37888d\",\n    \"0x84eee9d6bce039c52c2ebc4fccc0ad70e20c82f47c558098da4be2f386a493cbc76adc795b5488c8d11b6518c2c4fab8\",\n    \"0x875d7bda46efcb63944e1ccf760a20144df3b00d53282b781e95f12bfc8f8316dfe6492c2efbf796f1150e36e436e9df\",\n    \"0xb68a2208e0c587b5c31b5f6cb32d3e6058a9642e2d9855da4f85566e1412db528475892060bb932c55b3a80877ad7b4a\",\n    \"0xba006368ecab5febb6ab348644d9b63de202293085ed468df8bc24d992ae8ce468470aa37f36a73630c789fb9c819b30\",\n    \"0x90a196035150846cd2b482c7b17027471372a8ce7d914c4d82b6ea7fa705d8ed5817bd42d63886242585baf7d1397a1c\",\n    \"0xa223b4c85e0daa8434b015fd9170b5561fe676664b67064974a1e9325066ecf88fc81f97ab5011c59fad28cedd04b240\",\n    \"0x82e8ec43139cf15c6bbeed484b62e06cded8a39b5ce0389e4cbe9c9e9c02f2f0275d8d8d4e8dfec8f69a191bef220408\",\n    \"0x81a3fc07a7b68d92c6ee4b6d28f5653ee9ec85f7e2ee1c51c075c1b130a8c5097dc661cf10c5aff1c7114b1a6a19f11a\",\n    \"0x8ed2ef8331546d98819a5dd0e6c9f8cb2630d0847671314a28f277faf68da080b53891dd75c82cbcf7788b255490785d\",\n    \"0xacecabf84a6f9bbed6b2fc2e7e4b48f02ef2f15e597538a73aea8f98addc6badda15e4695a67ecdb505c1554e8f345ec\",\n    \"0xb8f51019b2aa575f8476e03dcadf86cc8391f007e5f922c2a36b2daa63f5a503646a468990cd5c65148d323942193051\",\n    \"0xaaa595a84b403ec65729bc1c8055a94f874bf9adddc6c507b3e1f24f79d3ad359595a672b93aab3394db4e2d4a7d8970\",\n    \"0x895144c55fcbd0f64d7dd69e6855cfb956e02b5658eadf0f026a70703f3643037268fdd673b0d21b288578a83c6338dd\",\n    \"0xa2e92ae6d0d237d1274259a8f99d4ea4912a299816350b876fba5ebc60b714490e198a916e1c38c6e020a792496fa23c\",\n    \"0xa45795fda3b5bb0ad1d3c628f6add5b2a4473a1414c1a232e80e70d1cfffd7f8a8d9861f8df2946999d7dbb56bf60113\",\n    \"0xb6659bf7f6f2fef61c39923e8c23b8c70e9c903028d8f62516d16755cd3fba2fe41c285aa9432dc75ab08f8a1d8a81fc\",\n    \"0xa735609a6bc5bfd85e58234fc439ff1f58f1ff1dd966c5921d8b649e21f006bf2b8642ad8a75063c159aaf6935789293\",\n    \"0xa3c622eb387c9d15e7bda2e3e84d007cb13a6d50d655c3f2f289758e49d3b37b9a35e4535d3cc53d8efd51f407281f19\",\n    \"0x8afe147b53ad99220f5ef9d763bfc91f9c20caecbcf823564236fb0e6ede49414c57d71eec4772c8715cc65a81af0047\",\n    \"0xb5f0203233cf71913951e9c9c4e10d9243e3e4a1f2cb235bf3f42009120ba96e04aa414c9938ea8873b63148478927e8\",\n    \"0x93c52493361b458d196172d7ba982a90a4f79f03aa8008edc322950de3ce6acf4c3977807a2ffa9e924047e02072b229\",\n    \"0xb9e72b805c8ac56503f4a86c82720afbd5c73654408a22a2ac0b2e5caccdfb0e20b59807433a6233bc97ae58cf14c70a\",\n    \"0xaf0475779b5cee278cca14c82da2a9f9c8ef222eb885e8c50cca2315fea420de6e04146590ed0dd5a29c0e0812964df5\",\n    \"0xb430ccab85690db02c2d0eb610f3197884ca12bc5f23c51e282bf3a6aa7e4a79222c3d8761454caf55d6c01a327595f9\",\n    \"0x830032937418b26ee6da9b5206f3e24dc76acd98589e37937e963a8333e5430abd6ce3dd93ef4b8997bd41440eed75d6\",\n    \"0x8820a6d73180f3fe255199f3f175c5eb770461ad5cfdde2fb11508041ed19b8c4ce66ad6ecebf7d7e836cc2318df47ca\",\n    \"0xaef1393e7d97278e77bbf52ef6e1c1d5db721ccf75fe753cf47a881fa034ca61eaa5098ee5a344c156d2b14ff9e284ad\",\n    \"0x8a4a26c07218948c1196c45d927ef4d2c42ade5e29fe7a91eaebe34a29900072ce5194cf28d51f746f4c4c649daf4396\",\n    \"0x84011dc150b7177abdcb715efbd8c201f9cb39c36e6069af5c50a096021768ba40cef45b659c70915af209f904ede3b6\",\n    \"0xb1bd90675411389bb66910b21a4bbb50edce5330850c5ab0b682393950124252766fc81f5ecfc72fb7184387238c402e\",\n    \"0x8dfdcd30583b696d2c7744655f79809f451a60c9ad5bf1226dc078b19f4585d7b3ef7fa9d54e1ac09520d95cbfd20928\",\n    \"0xb351b4dc6d98f75b8e5a48eb7c6f6e4b78451991c9ba630e5a1b9874c15ac450cd409c1a024713bf2cf82dc400e025ef\",\n    \"0xa462b8bc97ac668b97b28b3ae24b9f5de60e098d7b23ecb600d2194cd35827fb79f77c3e50d358f5bd72ee83fef18fa0\",\n    \"0xa183753265c5f7890270821880cce5f9b2965b115ba783c6dba9769536f57a04465d7da5049c7cf8b3fcf48146173c18\",\n    \"0xa8a771b81ed0d09e0da4d79f990e58eabcd2be3a2680419502dd592783fe52f657fe55125b385c41d0ba3b9b9cf54a83\",\n    \"0xa71ec577db46011689d073245e3b1c3222a9b1fe6aa5b83629adec5733dd48617ebea91346f0dd0e6cdaa86e4931b168\",\n    \"0xa334b8b244f0d598a02da6ae0f918a7857a54dce928376c4c85df15f3b0f2ba3ac321296b8b7c9dd47d770daf16c8f8c\",\n    \"0xa29037f8ef925c417c90c4df4f9fb27fb977d04e2b3dd5e8547d33e92ab72e7a00f5461de21e28835319eae5db145eb7\",\n    \"0xb91054108ae78b00e3298d667b913ebc44d8f26e531eae78a8fe26fdfb60271c97efb2dee5f47ef5a3c15c8228138927\",\n    \"0x926c13efbe90604f6244be9315a34f72a1f8d1aab7572df431998949c378cddbf2fe393502c930fff614ff06ae98a0ce\",\n    \"0x995c758fd5600e6537089b1baa4fbe0376ab274ff3e82a17768b40df6f91c2e443411de9cafa1e65ea88fb8b87d504f4\",\n    \"0x9245ba307a7a90847da75fca8d77ec03fdfc812c871e7a2529c56a0a79a6de16084258e7a9ac4ae8a3756f394336e21c\",\n    \"0x99e0cfa2bb57a7e624231317044c15e52196ecce020db567c8e8cb960354a0be9862ee0c128c60b44777e65ac315e59f\",\n    \"0xad4f6b3d27bbbb744126601053c3dc98c07ff0eb0b38a898bd80dce778372846d67e5ab8fb34fb3ad0ef3f235d77ba7f\",\n    \"0xa0f12cae3722bbbca2e539eb9cc7614632a2aefe51410430070a12b5bc5314ecec5857b7ff8f41e9980cac23064f7c56\",\n    \"0xb487f1bc59485848c98222fd3bc36c8c9bb3d2912e2911f4ceca32c840a7921477f9b1fe00877e05c96c75d3eecae061\",\n    \"0xa6033db53925654e18ecb3ce715715c36165d7035db9397087ac3a0585e587998a53973d011ac6d48af439493029cee6\",\n    \"0xa6b4d09cd01c70a3311fd131d3710ccf97bde3e7b80efd5a8c0eaeffeb48cca0f951ced905290267b115b06d46f2693b\",\n    \"0xa9dff1df0a8f4f218a98b6f818a693fb0d611fed0fc3143537cbd6578d479af13a653a8155e535548a2a0628ae24fa58\",\n    \"0xa58e469f65d366b519f9a394cacb7edaddac214463b7b6d62c2dbc1316e11c6c5184ce45c16de2d77f990dcdd8b55430\",\n    \"0x989e71734f8119103586dc9a3c5f5033ddc815a21018b34c1f876cdfc112efa868d5751bf6419323e4e59fa6a03ece1c\",\n    \"0xa2da00e05036c884369e04cf55f3de7d659cd5fa3f849092b2519dd263694efe0f051953d9d94b7e121f0aee8b6174d7\",\n    \"0x968f3c029f57ee31c4e1adea89a7f92e28483af9a74f30fbdb995dc2d40e8e657dff8f8d340d4a92bf65f54440f2859f\",\n    \"0x932778df6f60ac1639c1453ef0cbd2bf67592759dcccb3e96dcc743ff01679e4c7dd0ef2b0833dda548d32cb4eba49e2\",\n    \"0xa805a31139f8e0d6dae1ac87d454b23a3dc9fc653d4ca18d4f8ebab30fc189c16e73981c2cb7dd6f8c30454a5208109d\",\n    \"0xa9ba0991296caa2aaa4a1ceacfb205544c2a2ec97088eace1d84ee5e2767656a172f75d2f0c4e16a3640a0e0dec316e0\",\n    \"0xb1e49055c968dced47ec95ae934cf45023836d180702e20e2df57e0f62fb85d7ac60d657ba3ae13b8560b67210449459\",\n    \"0xa94e1da570a38809c71e37571066acabff7bf5632737c9ab6e4a32856924bf6211139ab3cedbf083850ff2d0e0c0fcfc\",\n    \"0x88ef1bb322000c5a5515b310c838c9af4c1cdbb32eab1c83ac3b2283191cd40e9573747d663763a28dad0d64adc13840\",\n    \"0xa987ce205f923100df0fbd5a85f22c9b99b9b9cbe6ddfa8dfda1b8fe95b4f71ff01d6c5b64ca02eb24edb2b255a14ef0\",\n    \"0x84fe8221a9e95d9178359918a108de4763ebfa7a6487facb9c963406882a08a9a93f492f8e77cf9e7ea41ae079c45993\",\n    \"0xaa1cf3dc7c5dcfa15bbbc811a4bb6dbac4fba4f97fb1ed344ab60264d7051f6eef19ea9773441d89929ee942ed089319\",\n    \"0x8f6a7d610d59d9f54689bbe6a41f92d9f6096cde919c1ab94c3c7fcecf0851423bc191e5612349e10f855121c0570f56\",\n    \"0xb5af1fa7894428a53ea520f260f3dc3726da245026b6d5d240625380bfb9c7c186df0204bb604efac5e613a70af5106e\",\n    \"0xa5bce6055ff812e72ce105f147147c7d48d7a2313884dd1f488b1240ee320f13e8a33f5441953a8e7a3209f65b673ce1\",\n    \"0xb9b55b4a1422677d95821e1d042ab81bbf0bf087496504021ec2e17e238c2ca6b44fb3b635a5c9eac0871a724b8d47c3\",\n    \"0x941c38e533ce4a673a3830845b56786585e5fe49c427f2e5c279fc6db08530c8f91db3e6c7822ec6bb4f956940052d18\",\n    \"0xa38e191d66c625f975313c7007bbe7431b5a06ed2da1290a7d5d0f2ec73770d476efd07b8e632de64597d47df175cbb0\",\n    \"0x94ba76b667abf055621db4c4145d18743a368d951565632ed4e743dd50dd3333507c0c34f286a5c5fdbf38191a2255cd\",\n    \"0xa5ca38c60be5602f2bfa6e00c687ac96ac36d517145018ddbee6f12eb0faa63dd57909b9eeed26085fe5ac44e55d10ab\",\n    \"0xb00fea3b825e60c1ed1c5deb4b551aa65a340e5af36b17d5262c9cd2c508711e4dc50dc2521a2c16c7c901902266e64a\",\n    \"0x971b86fc4033485e235ccb0997a236206ba25c6859075edbcdf3c943116a5030b7f75ebca9753d863a522ba21a215a90\",\n    \"0xb3b31f52370de246ee215400975b674f6da39b2f32514fe6bd54e747752eedca22bb840493b44a67df42a3639c5f901f\",\n    \"0xaffbbfac9c1ba7cbfa1839d2ae271dd6149869b75790bf103230637da41857fc326ef3552ff31c15bda0694080198143\",\n    \"0xa95d42aa7ef1962520845aa3688f2752d291926f7b0d73ea2ee24f0612c03b43f2b0fe3c9a9a99620ffc8d487b981bc2\",\n    \"0x914a266065caf64985e8c5b1cb2e3f4e3fe94d7d085a1881b1fefa435afef4e1b39a98551d096a62e4f5cc1a7f0fdc2e\",\n    \"0x81a0b4a96e2b75bc1bf2dbd165d58d55cfd259000a35504d1ffb18bc346a3e6f07602c683723864ffb980f840836fd8d\",\n    \"0x91c1556631cddd4c00b65b67962b39e4a33429029d311c8acf73a18600e362304fb68bccb56fde40f49e95b7829e0b87\",\n    \"0x8befbacc19e57f7c885d1b7a6028359eb3d80792fe13b92a8400df21ce48deb0bb60f2ddb50e3d74f39f85d7eab23adc\",\n    \"0x92f9458d674df6e990789690ec9ca73dacb67fc9255b58c417c555a8cc1208ace56e8e538f86ba0f3615573a0fbac00d\",\n    \"0xb4b1b3062512d6ae7417850c08c13f707d5838e43d48eb98dd4621baf62eee9e82348f80fe9b888a12874bfa538771f8\",\n    \"0xa13c4a3ac642ede37d9c883f5319e748d2b938f708c9d779714108a449b343f7b71a6e3ef4080fee125b416762920273\",\n    \"0xaf44983d5fc8cceee0551ef934e6e653f2d3efa385e5c8a27a272463a6f333e290378cc307c2b664eb923c78994e706e\",\n    \"0xa389fd6c59fe2b4031cc244e22d3991e541bd203dd5b5e73a6159e72df1ab41d49994961500dcde7989e945213184778\",\n    \"0x8d2141e4a17836c548de9598d7b298b03f0e6c73b7364979a411c464e0628e21cff6ac3d6decdba5d1c4909eff479761\",\n    \"0x980b22ef53b7bdf188a3f14bc51b0dbfdf9c758826daa3cbc1e3986022406a8aa9a6a79e400567120b88c67faa35ce5f\",\n    \"0xa28882f0a055f96df3711de5d0aa69473e71245f4f3e9aa944e9d1fb166e02caa50832e46da6d3a03b4801735fd01b29\",\n    \"0x8db106a37d7b88f5d995c126abb563934dd8de516af48e85695d02b1aea07f79217e3cdd03c6f5ca57421830186c772b\",\n    \"0xb5a7e50da0559a675c472f7dfaee456caab6695ab7870541b2be8c2b118c63752427184aad81f0e1afc61aef1f28c46f\",\n    \"0x9962118780e20fe291d10b64f28d09442a8e1b5cffd0f3dd68d980d0614050a626c616b44e9807fbee7accecae00686a\",\n    \"0xb38ddf33745e8d2ad6a991aefaf656a33c5f8cbe5d5b6b6fd03bd962153d8fd0e01b5f8f96d80ae53ab28d593ab1d4e7\",\n    \"0x857dc12c0544ff2c0c703761d901aba636415dee45618aba2e3454ff9cbc634a85c8b05565e88520ff9be2d097c8b2b1\",\n    \"0xa80d465c3f8cc63af6d74a6a5086b626c1cb4a8c0fee425964c3bd203d9d7094e299f81ce96d58afc20c8c9a029d9dae\",\n    \"0x89e1c8fbde8563763be483123a3ed702efac189c6d8ab4d16c85e74bbaf856048cc42d5d6e138633a38572ba5ec3f594\",\n    \"0x893a594cf495535f6d216508f8d03c317dcf03446668cba688da90f52d0111ac83d76ad09bf5ea47056846585ee5c791\",\n    \"0xaadbd8be0ae452f7f9450c7d2957598a20cbf10139a4023a78b4438172d62b18b0de39754dd2f8862dbd50a3a0815e53\",\n    \"0xae7d39670ecca3eb6db2095da2517a581b0e8853bdfef619b1fad9aacd443e7e6a40f18209fadd44038a55085c5fe8b2\",\n    \"0x866ef241520eacb6331593cfcb206f7409d2f33d04542e6e52cba5447934e02d44c471f6c9a45963f9307e9809ab91d9\",\n    \"0xb1a09911ad3864678f7be79a9c3c3eb5c84a0a45f8dcb52c67148f43439aeaaa9fd3ed3471276b7e588b49d6ebe3033a\",\n    \"0xadd07b7f0dbb34049cd8feeb3c18da5944bf706871cfd9f14ff72f6c59ad217ebb1f0258b13b167851929387e4e34cfe\",\n    \"0xae048892d5c328eefbdd4fba67d95901e3c14d974bfc0a1fc68155ca9f0d59e61d7ba17c6c9948b120cf35fd26e6fee9\",\n    \"0x9185b4f3b7da0ddb4e0d0f09b8a9e0d6943a4611e43f13c3e2a767ed8592d31e0ba3ebe1914026a3627680274291f6e5\",\n    \"0xa9c022d4e37b0802284ce3b7ee9258628ab4044f0db4de53d1c3efba9de19d15d65cc5e608dbe149c21c2af47d0b07b5\",\n    \"0xb24dbd5852f8f24921a4e27013b6c3fa8885b973266cb839b9c388efad95821d5d746348179dcc07542bd0d0aefad1ce\",\n    \"0xb5fb4f279300876a539a27a441348764908bc0051ebd66dc51739807305e73db3d2f6f0f294ffb91b508ab150eaf8527\",\n    \"0xace50841e718265b290c3483ed4b0fdd1175338c5f1f7530ae9a0e75d5f80216f4de37536adcbc8d8c95982e88808cd0\",\n    \"0xb19cadcde0f63bd1a9c24bd9c2806f53c14c0b9735bf351601498408ba503ddbd2037c891041cbba47f58b8c483f3b21\",\n    \"0xb6061e63558d312eb891b97b39aa552fa218568d79ee26fe6dd5b864aea9e3216d8f2e2f3b093503be274766dac41426\",\n    \"0x89730fdb2876ab6f0fe780d695f6e12090259027e789b819956d786e977518057e5d1d7f5ab24a3ae3d5d4c97773bd2b\",\n    \"0xb6fa841e81f9f2cad0163a02a63ae96dc341f7ae803b616efc6e1da2fbea551c1b96b11ad02c4afbdf6d0cc9f23da172\",\n    \"0x8fb66187182629c861ddb6896d7ed3caf2ad050c3dba8ab8eb0d7a2c924c3d44c48d1a148f9e33fb1f061b86972f8d21\",\n    \"0x86022ac339c1f84a7fa9e05358c1a5b316b4fc0b83dbe9c8c7225dc514f709d66490b539359b084ce776e301024345fa\",\n    \"0xb50b9c321468da950f01480bb62b6edafd42f83c0001d6e97f2bd523a1c49a0e8574fb66380ea28d23a7c4d54784f9f0\",\n    \"0xa31c05f7032f30d1dac06678be64d0250a071fd655e557400e4a7f4c152be4d5c7aa32529baf3e5be7c4bd49820054f6\",\n    \"0xb95ac0848cd322684772119f5b682d90a66bbf9dac411d9d86d2c34844bbd944dbaf8e47aa41380455abd51687931a78\",\n    \"0xae4a6a5ce9553b65a05f7935e61e496a4a0f6fd8203367a2c627394c9ce1e280750297b74cdc48fd1d9a31e93f97bef4\",\n    \"0xa22daf35f6e9b05e52e0b07f7bd1dbbebd2c263033fb0e1b2c804e2d964e2f11bc0ece6aca6af079dd3a9939c9c80674\",\n    \"0x902150e0cb1f16b9b59690db35281e28998ce275acb313900da8b2d8dfd29fa1795f8ca3ff820c31d0697de29df347c1\",\n    \"0xb17b5104a5dc665cdd7d47e476153d715eb78c6e5199303e4b5445c21a7fa7cf85fe7cfd08d7570f4e84e579b005428c\",\n    \"0xa03f49b81c15433f121680aa02d734bb9e363af2156654a62bcb5b2ba2218398ccb0ff61104ea5d7df5b16ea18623b1e\",\n    \"0x802101abd5d3c88876e75a27ffc2f9ddcce75e6b24f23dba03e5201281a7bd5cc7530b6a003be92d225093ca17d3c3bb\",\n    \"0xa4d183f63c1b4521a6b52226fc19106158fc8ea402461a5cccdaa35fee93669df6a8661f45c1750cd01308149b7bf08e\",\n    \"0x8d17c22e0c8403b69736364d460b3014775c591032604413d20a5096a94d4030d7c50b9fe3240e31d0311efcf9816a47\",\n    \"0x947225acfcce5992eab96276f668c3cbe5f298b90a59f2bb213be9997d8850919e8f496f182689b5cbd54084a7332482\",\n    \"0x8df6f4ed216fc8d1905e06163ba1c90d336ab991a18564b0169623eb39b84e627fa267397da15d3ed754d1f3423bff07\",\n    \"0x83480007a88f1a36dea464c32b849a3a999316044f12281e2e1c25f07d495f9b1710b4ba0d88e9560e72433addd50bc2\",\n    \"0xb3019d6e591cf5b33eb972e49e06c6d0a82a73a75d78d383dd6f6a4269838289e6e07c245f54fed67f5c9bb0fd5e1c5f\",\n    \"0x92e8ce05e94927a9fb02debadb99cf30a26172b2705003a2c0c47b3d8002bf1060edb0f6a5750aad827c98a656b19199\",\n    \"0xac2aff801448dbbfc13cca7d603fd9c69e82100d997faf11f465323b97255504f10c0c77401e4d1890339d8b224f5803\",\n    \"0xb0453d9903d08f508ee27e577445dc098baed6cde0ac984b42e0f0efed62760bd58d5816cf1e109d204607b7b175e30c\",\n    \"0xae68dc4ba5067e825d46d2c7c67f1009ceb49d68e8d3e4c57f4bcd299eb2de3575d42ea45e8722f8f28497a6e14a1cfe\",\n    \"0xb22486c2f5b51d72335ce819bbafb7fa25eb1c28a378a658f13f9fc79cd20083a7e573248d911231b45a5cf23b561ca7\",\n    \"0x89d1201d1dbd6921867341471488b4d2fd0fc773ae1d4d074c78ae2eb779a59b64c00452c2a0255826fca6b3d03be2b1\",\n    \"0xa2998977c91c7a53dc6104f5bc0a5b675e5350f835e2f0af69825db8af4aeb68435bdbcc795f3dd1f55e1dd50bc0507f\",\n    \"0xb0be4937a925b3c05056ed621910d535ccabf5ab99fd3b9335080b0e51d9607d0fd36cb5781ff340018f6acfca4a9736\",\n    \"0xaea145a0f6e0ba9df8e52e84bb9c9de2c2dc822f70d2724029b153eb68ee9c17de7d35063dcd6a39c37c59fdd12138f7\",\n    \"0x91cb4545d7165ee8ffbc74c874baceca11fdebbc7387908d1a25877ca3c57f2c5def424dab24148826832f1e880bede0\",\n    \"0xb3b579cb77573f19c571ad5eeeb21f65548d7dff9d298b8d7418c11f3e8cd3727c5b467f013cb87d6861cfaceee0d2e3\",\n    \"0xb98a1eeec2b19fecc8378c876d73645aa52fb99e4819903735b2c7a885b242787a30d1269a04bfb8573d72d9bbc5f0f0\",\n    \"0x940c1f01ed362bd588b950c27f8cc1d52276c71bb153d47f07ec85b038c11d9a8424b7904f424423e714454d5e80d1cd\",\n    \"0xaa343a8ecf09ce11599b8cf22f7279cf80f06dbf9f6d62cb05308dbbb39c46fd0a4a1240b032665fbb488a767379b91b\",\n    \"0x87c3ac72084aca5974599d3232e11d416348719e08443acaba2b328923af945031f86432e170dcdd103774ec92e988c9\",\n    \"0x91d6486eb5e61d2b9a9e742c20ec974a47627c6096b3da56209c2b4e4757f007e793ebb63b2b246857c9839b64dc0233\",\n    \"0xaebcd3257d295747dd6fc4ff910d839dd80c51c173ae59b8b2ec937747c2072fa85e3017f9060aa509af88dfc7529481\",\n    \"0xb3075ba6668ca04eff19efbfa3356b92f0ab12632dcda99cf8c655f35b7928c304218e0f9799d68ef9f809a1492ff7db\",\n    \"0x93ba7468bb325639ec2abd4d55179c69fd04eaaf39fc5340709227bbaa4ad0a54ea8b480a1a3c8d44684e3be0f8d1980\",\n    \"0xa6aef86c8c0d92839f38544d91b767c582568b391071228ff5a5a6b859c87bf4f81a7d926094a4ada1993ddbd677a920\",\n    \"0x91dcd6d14207aa569194aa224d1e5037b999b69ade52843315ca61ba26abe9a76412c9e88259bc5cf5d7b95b97d9c3bc\",\n    \"0xb3b483d31c88f78d49bd065893bc1e3d2aa637e27dedb46d9a7d60be7660ce7a10aaaa7deead362284a52e6d14021178\",\n    \"0x8e5730070acf8371461ef301cc4523e8e672aa0e3d945d438a0e0aa6bdf8cb9c685dcf38df429037b0c8aff3955c6f5b\",\n    \"0xb8c6d769890a8ee18dc4f9e917993315877c97549549b34785a92543cbeec96a08ae3a28d6e809c4aacd69de356c0012\",\n    \"0x95ca86cd384eaceaa7c077c5615736ca31f36824bd6451a16142a1edc129fa42b50724aeed7c738f08d7b157f78b569e\",\n    \"0x94df609c6d71e8eee7ab74226e371ccc77e01738fe0ef1a6424435b4570fe1e5d15797b66ed0f64eb88d4a3a37631f0e\",\n    \"0x89057b9783212add6a0690d6bb99097b182738deff2bd9e147d7fd7d6c8eacb4c219923633e6309ad993c24572289901\",\n    \"0x83a0f9f5f265c5a0e54defa87128240235e24498f20965009fef664f505a360b6fb4020f2742565dfc7746eb185bcec0\",\n    \"0x91170da5306128931349bc3ed50d7df0e48a68b8cc8420975170723ac79d8773e4fa13c5f14dc6e3fafcad78379050b1\",\n    \"0xb7178484d1b55f7e56a4cc250b6b2ec6040437d96bdfddfa7b35ed27435860f3855c2eb86c636f2911b012eb83b00db8\",\n    \"0xac0b00c4322d1e4208e09cd977b4e54d221133ff09551f75b32b0b55d0e2be80941dda26257b0e288c162e63c7e9cf68\",\n    \"0x9690ed9e7e53ed37ff362930e4096b878b12234c332fd19d5d064824084245952eda9f979e0098110d6963e468cf513e\",\n    \"0xb6fa547bb0bb83e5c5be0ed462a8783fba119041c136a250045c09d0d2af330c604331e7de960df976ff76d67f8000cd\",\n    \"0x814603907c21463bcf4e59cfb43066dfe1a50344ae04ef03c87c0f61b30836c3f4dea0851d6fa358c620045b7f9214c8\",\n    \"0x9495639e3939fad2a3df00a88603a5a180f3c3a0fe4d424c35060e2043e0921788003689887b1ed5be424d9a89bb18bb\",\n    \"0xaba4c02d8d57f2c92d5bc765885849e9ff8393d6554f5e5f3e907e5bfac041193a0d8716d7861104a4295d5a03c36b03\",\n    \"0x8ead0b56c1ca49723f94a998ba113b9058059321da72d9e395a667e6a63d5a9dac0f5717cec343f021695e8ced1f72af\",\n    \"0xb43037f7e3852c34ed918c5854cd74e9d5799eeddfe457d4f93bb494801a064735e326a76e1f5e50a339844a2f4a8ec9\",\n    \"0x99db8422bb7302199eb0ff3c3d08821f8c32f53a600c5b6fb43e41205d96adae72be5b460773d1280ad1acb806af9be8\",\n    \"0x8a9be08eae0086c0f020838925984df345c5512ff32e37120b644512b1d9d4fecf0fd30639ca90fc6cf334a86770d536\",\n    \"0x81b43614f1c28aa3713a309a88a782fb2bdfc4261dd52ddc204687791a40cf5fd6a263a8179388596582cccf0162efc2\",\n    \"0xa9f3a8b76912deb61d966c75daf5ddb868702ebec91bd4033471c8e533183df548742a81a2671de5be63a502d827437d\",\n    \"0x902e2415077f063e638207dc7e14109652e42ab47caccd6204e2870115791c9defac5425fd360b37ac0f7bd8fe7011f8\",\n    \"0xaa18e4fdc1381b59c18503ae6f6f2d6943445bd00dd7d4a2ad7e5adad7027f2263832690be30d456e6d772ad76f22350\",\n    \"0xa348b40ba3ba7d81c5d4631f038186ebd5e5f314f1ea737259151b07c3cc8cf0c6ed4201e71bcc1c22fefda81a20cde6\",\n    \"0xaa1306f7ac1acbfc47dc6f7a0cb6d03786cec8c8dc8060388ccda777bca24bdc634d03e53512c23dba79709ff64f8620\",\n    \"0x818ccfe46e700567b7f3eb400e5a35f6a5e39b3db3aa8bc07f58ace35d9ae5a242faf8dbccd08d9a9175bbce15612155\",\n    \"0xb7e3da2282b65dc8333592bb345a473f03bd6df69170055fec60222de9897184536bf22b9388b08160321144d0940279\",\n    \"0xa4d976be0f0568f4e57de1460a1729129252b44c552a69fceec44e5b97c96c711763360d11f9e5bf6d86b4976bf40d69\",\n    \"0x85d185f0397c24c2b875b09b6328a23b87982b84ee880f2677a22ff4c9a1ba9f0fea000bb3f7f66375a00d98ebafce17\",\n    \"0xb4ccbb8c3a2606bd9b87ce022704663af71d418351575f3b350d294f4efc68c26f9a2ce49ff81e6ff29c3b63d746294e\",\n    \"0x93ffd3265fddb63724dfde261d1f9e22f15ecf39df28e4d89e9fea03221e8e88b5dd9b77628bacaa783c6f91802d47cc\",\n    \"0xb1fd0f8d7a01378e693da98d03a2d2fda6b099d03454b6f2b1fa6472ff6bb092751ce6290059826b74ac0361eab00e1e\",\n    \"0xa89f440c71c561641589796994dd2769616b9088766e983c873fae0716b95c386c8483ab8a4f367b6a68b72b7456dd32\",\n    \"0xaf4fe92b01d42d03dd5d1e7fa55e96d4bbcb7bf7d4c8c197acd16b3e0f3455807199f683dcd263d74547ef9c244b35cc\",\n    \"0xa8227f6e0a344dfe76bfbe7a1861be32c4f4bed587ccce09f9ce2cf481b2dda8ae4f566154bc663d15f962f2d41761bd\",\n    \"0xa7b361663f7495939ed7f518ba45ea9ff576c4e628995b7aea026480c17a71d63fc2c922319f0502eb7ef8f14a406882\",\n    \"0x8ddcf382a9f39f75777160967c07012cfa89e67b19714a7191f0c68eaf263935e5504e1104aaabd0899348c972a8d3c6\",\n    \"0x98c95b9f6f5c91f805fb185eedd06c6fc4457d37dd248d0be45a6a168a70031715165ea20606245cbdf8815dc0ac697f\",\n    \"0x805b44f96e001e5909834f70c09be3efcd3b43632bcac5b6b66b6d227a03a758e4b1768ce2a723045681a1d34562aaeb\",\n    \"0xb0e81b07cdc45b3dca60882676d9badb99f25c461b7efe56e3043b80100bb62d29e1873ae25eb83087273160ece72a55\",\n    \"0xb0c53f0abe78ee86c7b78c82ae1f7c070bb0b9c45c563a8b3baa2c515d482d7507bb80771e60b38ac13f78b8af92b4a9\",\n    \"0xa7838ef6696a9e4d2e5dfd581f6c8d6a700467e8fd4e85adabb5f7a56f514785dd4ab64f6f1b48366f7d94728359441b\",\n    \"0x88c76f7700a1d23c30366a1d8612a796da57b2500f97f88fdf2d76b045a9d24e7426a8ffa2f4e86d3046937a841dad58\",\n    \"0xad8964baf98c1f02e088d1d9fcb3af6b1dfa44cdfe0ed2eae684e7187c33d3a3c28c38e8f4e015f9c04d451ed6f85ff6\",\n    \"0x90e9d00a098317ececaa9574da91fc149eda5b772dedb3e5a39636da6603aa007804fa86358550cfeff9be5a2cb7845e\",\n    \"0xa56ff4ddd73d9a6f5ab23bb77efa25977917df63571b269f6a999e1ad6681a88387fcc4ca3b26d57badf91b236503a29\",\n    \"0x97ad839a6302c410a47e245df84c01fb9c4dfef86751af3f9340e86ff8fc3cd52fa5ff0b9a0bd1d9f453e02ca80658a6\",\n    \"0xa4c8c44cbffa804129e123474854645107d1f0f463c45c30fd168848ebea94880f7c0c5a45183e9eb837f346270bdb35\",\n    \"0xa72e53d0a1586d736e86427a93569f52edd2f42b01e78aee7e1961c2b63522423877ae3ac1227a2cf1e69f8e1ff15bc3\",\n    \"0x8559f88a7ef13b4f09ac82ae458bbae6ab25671cfbf52dae7eac7280d6565dd3f0c3286aec1a56a8a16dc3b61d78ce47\",\n    \"0x8221503f4cdbed550876c5dc118a3f2f17800c04e8be000266633c83777b039a432d576f3a36c8a01e8fd18289ebc10b\",\n    \"0x99bfbe5f3e46d4d898a578ba86ed26de7ed23914bd3bcdf3c791c0bcd49398a52419077354a5ab75cea63b6c871c6e96\",\n    \"0xaa134416d8ff46f2acd866c1074af67566cfcf4e8be8d97329dfa0f603e1ff208488831ce5948ac8d75bfcba058ddcaa\",\n    \"0xb02609d65ebfe1fe8e52f21224a022ea4b5ea8c1bd6e7b9792eed8975fc387cdf9e3b419b8dd5bcce80703ab3a12a45f\",\n    \"0xa4f14798508698fa3852e5cac42a9db9797ecee7672a54988aa74037d334819aa7b2ac7b14efea6b81c509134a6b7ad2\",\n    \"0x884f01afecbcb987cb3e7c489c43155c416ed41340f61ecb651d8cba884fb9274f6d9e7e4a46dd220253ae561614e44c\",\n    \"0xa05523c9e71dce1fe5307cc71bd721feb3e1a0f57a7d17c7d1c9fb080d44527b7dbaa1f817b1af1c0b4322e37bc4bb1e\",\n    \"0x8560aec176a4242b39f39433dd5a02d554248c9e49d3179530815f5031fee78ba9c71a35ceeb2b9d1f04c3617c13d8f0\",\n    \"0x996aefd402748d8472477cae76d5a2b92e3f092fc834d5222ae50194dd884c9fb8b6ed8e5ccf8f6ed483ddbb4e80c747\",\n    \"0x8fd09900320000cbabc40e16893e2fcf08815d288ec19345ad7b6bb22f7d78a52b6575a3ca1ca2f8bc252d2eafc928ec\",\n    \"0x939e51f73022bc5dc6862a0adf8fb8a3246b7bfb9943cbb4b27c73743926cc20f615a036c7e5b90c80840e7f1bfee0e7\",\n    \"0xa0a6258700cadbb9e241f50766573bf9bdb7ad380b1079dc3afb4054363d838e177b869cad000314186936e40359b1f2\",\n    \"0x972699a4131c8ed27a2d0e2104d54a65a7ff1c450ad9da3a325c662ab26869c21b0a84d0700b98c8b5f6ce3b746873d7\",\n    \"0xa454c7fe870cb8aa6491eafbfb5f7872d6e696033f92e4991d057b59d70671f2acdabef533e229878b60c7fff8f748b1\",\n    \"0xa167969477214201f09c79027b10221e4707662e0c0fde81a0f628249f2f8a859ce3d30a7dcc03b8ecca8f7828ad85c7\",\n    \"0x8ff6b7265175beb8a63e1dbf18c9153fb2578c207c781282374f51b40d57a84fd2ef2ea2b9c6df4a54646788a62fd17f\",\n    \"0xa3d7ebeccde69d73d8b3e76af0da1a30884bb59729503ff0fb0c3bccf9221651b974a6e72ea33b7956fc3ae758226495\",\n    \"0xb71ef144c9a98ce5935620cb86c1590bd4f48e5a2815d25c0cdb008fde628cf628c31450d3d4f67abbfeb16178a74cfd\",\n    \"0xb5e0a16d115134f4e2503990e3f2035ed66b9ccf767063fe6747870d97d73b10bc76ed668550cb82eedc9a2ca6f75524\",\n    \"0xb30ffaaf94ee8cbc42aa2c413175b68afdb207dbf351fb20be3852cb7961b635c22838da97eaf43b103aff37e9e725cc\",\n    \"0x98aa7d52284f6c1f22e272fbddd8c8698cf8f5fbb702d5de96452141fafb559622815981e50b87a72c2b1190f59a7deb\",\n    \"0x81fbacda3905cfaf7780bb4850730c44166ed26a7c8d07197a5d4dcd969c09e94a0461638431476c16397dd7bdc449f9\",\n    \"0x95e47021c1726eac2e5853f570d6225332c6e48e04c9738690d53e07c6b979283ebae31e2af1fc9c9b3e59f87e5195b1\",\n    \"0xac024a661ba568426bb8fce21780406537f518075c066276197300841e811860696f7588188bc01d90bace7bc73d56e3\",\n    \"0xa4ebcaf668a888dd404988ab978594dee193dad2d0aec5cdc0ccaf4ec9a7a8228aa663db1da8ddc52ec8472178e40c32\",\n    \"0xa20421b8eaf2199d93b083f2aff37fb662670bd18689d046ae976d1db1fedd2c2ff897985ecc6277b396db7da68bcb27\",\n    \"0x8bc33d4b40197fd4d49d1de47489d10b90d9b346828f53a82256f3e9212b0cbc6930b895e879da9cec9fedf026aadb3e\",\n    \"0xaaafdd1bec8b757f55a0433eddc0a39f818591954fd4e982003437fcceb317423ad7ee74dbf17a2960380e7067a6b4e2\",\n    \"0xaad34277ebaed81a6ec154d16736866f95832803af28aa5625bf0461a71d02b1faba02d9d9e002be51c8356425a56867\",\n    \"0x976e9c8b150d08706079945bd0e84ab09a648ecc6f64ded9eb5329e57213149ae409ae93e8fbd8eda5b5c69f5212b883\",\n    \"0x8097fae1653247d2aed4111533bc378171d6b2c6d09cbc7baa9b52f188d150d645941f46d19f7f5e27b7f073c1ebd079\",\n    \"0x83905f93b250d3184eaba8ea7d727c4464b6bdb027e5cbe4f597d8b9dc741dcbea709630bd4fd59ce24023bec32fc0f3\",\n    \"0x8095030b7045cff28f34271386e4752f9a9a0312f8df75de4f424366d78534be2b8e1720a19cb1f9a2d21105d790a225\",\n    \"0xa7b7b73a6ae2ed1009c49960374b0790f93c74ee03b917642f33420498c188a169724945a975e5adec0a1e83e07fb1b2\",\n    \"0x856a41c54df393b6660b7f6354572a4e71c8bfca9cabaffb3d4ef2632c015e7ee2bc10056f3eccb3dbed1ad17d939178\",\n    \"0xa8f7a55cf04b38cd4e330394ee6589da3a07dc9673f74804fdf67b364e0b233f14aec42e783200a2e4666f7c5ff62490\",\n    \"0x82c529f4e543c6bca60016dc93232c115b359eaee2798a9cf669a654b800aafe6ab4ba58ea8b9cdda2b371c8d62fa845\",\n    \"0x8caab020c1baddce77a6794113ef1dfeafc5f5000f48e97f4351b588bf02f1f208101745463c480d37f588d5887e6d8c\",\n    \"0x8fa91b3cc400f48b77b6fd77f3b3fbfb3f10cdff408e1fd22d38f77e087b7683adad258804409ba099f1235b4b4d6fea\",\n    \"0x8aa02787663d6be9a35677d9d8188b725d5fcd770e61b11b64e3def8808ea5c71c0a9afd7f6630c48634546088fcd8e2\",\n    \"0xb5635b7b972e195cab878b97dea62237c7f77eb57298538582a330b1082f6207a359f2923864630136d8b1f27c41b9aa\",\n    \"0x8257bb14583551a65975946980c714ecd6e5b629672bb950b9caacd886fbd22704bc9e3ba7d30778adab65dc74f0203a\",\n    \"0xab5fe1cd12634bfa4e5c60d946e2005cbd38f1063ec9a5668994a2463c02449a0a185ef331bd86b68b6e23a8780cb3ba\",\n    \"0xa7d3487da56cda93570cc70215d438204f6a2709bfb5fda6c5df1e77e2efc80f4235c787e57fbf2c74aaff8cbb510a14\",\n    \"0xb61cff7b4c49d010e133319fb828eb900f8a7e55114fc86b39c261a339c74f630e1a7d7e1350244ada566a0ff3d46c4b\",\n    \"0x8d4d1d55d321d278db7a85522ccceca09510374ca81d4d73e3bb5249ace7674b73900c35a531ec4fa6448fabf7ad00dc\",\n    \"0x966492248aee24f0f56c8cfca3c8ec6ba3b19abb69ae642041d4c3be8523d22c65c4dafcab4c58989ccc4e0bd2f77919\",\n    \"0xb20c320a90cb220b86e1af651cdc1e21315cd215da69f6787e28157172f93fc8285dcd59b039c626ed8ca4633cba1a47\",\n    \"0xaae9e6b22f018ceb5c0950210bb8182cb8cb61014b7e14581a09d36ebd1bbfebdb2b82afb7fdb0cf75e58a293d9c456d\",\n    \"0x875547fb67951ad37b02466b79f0c9b985ccbc500cfb431b17823457dc79fb9597ec42cd9f198e15523fcd88652e63a4\",\n    \"0x92afce49773cb2e20fb21e4f86f18e0959ebb9c33361547ddb30454ee8e36b1e234019cbdca0e964cb292f7f77df6b90\",\n    \"0x8af85343dfe1821464c76ba11c216cbef697b5afc69c4d821342e55afdac047081ec2e3f7b09fc14b518d9a23b78c003\",\n    \"0xb7de4a1648fd63f3a918096ea669502af5357438e69dac77cb8102b6e6c15c76e033cfaa80dafc806e535ede5c1a20aa\",\n    \"0xac80e9b545e8bd762951d96c9ce87f629d01ffcde07efc2ef7879ca011f1d0d8a745abf26c9d452541008871304fac00\",\n    \"0xa4cf0f7ed724e481368016c38ea5816698a5f68eb21af4d3c422d2ba55f96a33e427c2aa40de1b56a7cfac7f7cf43ab0\",\n    \"0x899b0a678bb2db2cae1b44e75a661284844ebcdd87abf308fedeb2e4dbe5c5920c07db4db7284a7af806a2382e8b111a\",\n    \"0xaf0588a2a4afce2b1b13c1230816f59e8264177e774e4a341b289a101dcf6af813638fed14fb4d09cb45f35d5d032609\",\n    \"0xa4b8df79e2be76e9f5fc5845f06fe745a724cf37c82fcdb72719b77bdebea3c0e763f37909373e3a94480cc5e875cba0\",\n    \"0x83e42c46d88930c8f386b19fd999288f142d325e2ebc86a74907d6d77112cb0d449bc511c95422cc810574031a8cbba9\",\n    \"0xb5e39534070de1e5f6e27efbdd3dc917d966c2a9b8cf2d893f964256e95e954330f2442027dc148c776d63a95bcde955\",\n    \"0x958607569dc28c075e658cd4ae3927055c6bc456eef6212a6fea8205e48ed8777a8064f584cda38fe5639c371e2e7fba\",\n    \"0x812adf409fa63575113662966f5078a903212ffb65c9b0bbe62da0f13a133443a7062cb8fd70f5e5dd5559a32c26d2c8\",\n    \"0xa679f673e5ce6a3cce7fa31f22ee3785e96bcb55e5a776e2dd3467bef7440e3555d1a9b87cb215e86ee9ed13a090344b\",\n    \"0xafedbb34508b159eb25eb2248d7fe328f86ef8c7d84c62d5b5607d74aae27cc2cc45ee148eb22153b09898a835c58df4\",\n    \"0xb75505d4f6b67d31e665cfaf5e4acdb5838ae069166b7fbcd48937c0608a59e40a25302fcc1873d2e81c1782808c70f0\",\n    \"0xb62515d539ec21a155d94fc00ea3c6b7e5f6636937bce18ed5b618c12257fb82571886287fd5d1da495296c663ebc512\",\n    \"0xab8e1a9446bbdd588d1690243b1549d230e6149c28f59662b66a8391a138d37ab594df38e7720fae53217e5c3573b5be\",\n    \"0xb31e8abf4212e03c3287bb2c0a153065a7290a16764a0bac8f112a72e632185a654bb4e88fdd6053e6c7515d9719fadb\",\n    \"0xb55165477fe15b6abd2d0f4fddaa9c411710dcc4dd712daba3d30e303c9a3ee5415c256f9dc917ecf18c725b4dbab059\",\n    \"0xa0939d4f57cacaae549b78e87cc234de4ff6a35dc0d9cd5d7410abc30ebcd34c135e008651c756e5a9d2ca79c40ef42b\",\n    \"0x8cf10e50769f3443340844aad4d56ec790850fed5a41fcbd739abac4c3015f0a085a038fbe7fae9f5ad899cce5069f6b\",\n    \"0x924055e804d82a99ea4bb160041ea4dc14b568abf379010bc1922fde5d664718c31d103b8b807e3a1ae809390e708c73\",\n    \"0x8ec0f9d26f71b0f2e60a179e4fd1778452e2ffb129d50815e5d7c7cb9415fa69ae5890578086e8ef6bfde35ad2a74661\",\n    \"0x98c7f12b15ec4426b59f737f73bf5faea4572340f4550b7590dfb7f7ffedb2372e3e555977c63946d579544c53210ad0\",\n    \"0x8a935f7a955c78f69d66f18eee0092e5e833fa621781c9581058e219af4d7ceee48b84e472e159dda6199715fb2f9acf\",\n    \"0xb78d4219f95a2dbfaa7d0c8a610c57c358754f4f43c2af312ab0fe8f10a5f0177e475332fb8fd23604e474fc2abeb051\",\n    \"0x8d086a14803392b7318c28f1039a17e3cfdcece8abcaca3657ec3d0ac330842098a85c0212f889fabb296dfb133ce9aa\",\n    \"0xa53249f417aac82f2c2a50c244ce21d3e08a5e5a8bd33bec2a5ab0d6cd17793e34a17edfa3690899244ce201e2fb9986\",\n    \"0x8619b0264f9182867a1425be514dc4f1ababc1093138a728a28bd7e4ecc99b9faaff68c23792264bc6e4dce5f52a5c52\",\n    \"0x8c171edbbbde551ec19e31b2091eb6956107dd9b1f853e1df23bff3c10a3469ac77a58335eee2b79112502e8e163f3de\",\n    \"0xa9d19ec40f0ca07c238e9337c6d6a319190bdba2db76fb63902f3fb459aeeb50a1ac30db5b25ee1b4201f3ca7164a7f4\",\n    \"0xb9c6ec14b1581a03520b8d2c1fbbc31fb8ceaef2c0f1a0d0080b6b96e18442f1734bea7ef7b635d787c691de4765d469\",\n    \"0x8cb437beb4cfa013096f40ccc169a713dc17afee6daa229a398e45fd5c0645a9ad2795c3f0cd439531a7151945d7064d\",\n    \"0xa6e8740cc509126e146775157c2eb278003e5bb6c48465c160ed27888ca803fa12eee1f6a8dd7f444f571664ed87fdc1\",\n    \"0xb75c1fecc85b2732e96b3f23aefb491dbd0206a21d682aee0225838dc057d7ed3b576176353e8e90ae55663f79e986e4\",\n    \"0xad8d249b0aea9597b08358bce6c77c1fd552ef3fbc197d6a1cfe44e5e6f89b628b12a6fb04d5dcfcbacc51f46e4ae7bb\",\n    \"0xb998b2269932cbd58d04b8e898d373ac4bb1a62e8567484f4f83e224061bc0f212459f1daae95abdbc63816ae6486a55\",\n    \"0x827988ef6c1101cddc96b98f4a30365ff08eea2471dd949d2c0a9b35c3bbfa8c07054ad1f4c88c8fbf829b20bb5a9a4f\",\n    \"0x8692e638dd60babf7d9f2f2d2ce58e0ac689e1326d88311416357298c6a2bffbfebf55d5253563e7b3fbbf5072264146\",\n    \"0xa685d75b91aea04dbc14ab3c1b1588e6de96dae414c8e37b8388766029631b28dd860688079b12d09cd27f2c5af11adf\",\n    \"0xb57eced93eec3371c56679c259b34ac0992286be4f4ff9489d81cf9712403509932e47404ddd86f89d7c1c3b6391b28c\",\n    \"0xa1c8b4e42ebcbd8927669a97f1b72e236fb19249325659e72be7ddaaa1d9e81ca2abb643295d41a8c04a2c01f9c0efd7\",\n    \"0x877c33de20d4ed31674a671ba3e8f01a316581e32503136a70c9c15bf0b7cb7b1cba6cd4eb641fad165fb3c3c6c235fd\",\n    \"0xa2a469d84ec478da40838f775d11ad38f6596eb41caa139cc190d6a10b5108c09febae34ffdafac92271d2e73c143693\",\n    \"0x972f817caedb254055d52e963ed28c206848b6c4cfdb69dbc961c891f8458eaf582a6d4403ce1177d87bc2ea410ef60a\",\n    \"0xaccbd739e138007422f28536381decc54bb6bd71d93edf3890e54f9ef339f83d2821697d1a4ac1f5a98175f9a9ecb9b5\",\n    \"0x8940f8772e05389f823b62b3adc3ed541f91647f0318d7a0d3f293aeeb421013de0d0a3664ea53dd24e5fbe02d7efef6\",\n    \"0x8ecce20f3ef6212edef07ec4d6183fda8e0e8cad2c6ccd0b325e75c425ee1faba00b5c26b4d95204238931598d78f49d\",\n    \"0x97cc72c36335bd008afbed34a3b0c7225933faba87f7916d0a6d2161e6f82e0cdcda7959573a366f638ca75d30e9dab1\",\n    \"0x9105f5de8699b5bdb6bd3bb6cc1992d1eac23929c29837985f83b22efdda92af64d9c574aa9640475087201bbbe5fd73\",\n    \"0x8ffb33c4f6d05c413b9647eb6933526a350ed2e4278ca2ecc06b0e8026d8dbe829c476a40e45a6df63a633090a3f82ef\",\n    \"0x8bfc6421fdc9c2d2aaa68d2a69b1a2728c25b84944cc3e6a57ff0c94bfd210d1cbf4ff3f06702d2a8257024d8be7de63\",\n    \"0xa80e1dc1dddfb41a70220939b96dc6935e00b32fb8be5dff4eed1f1c650002ff95e4af481c43292e3827363b7ec4768a\",\n    \"0x96f714ebd54617198bd636ba7f7a7f8995a61db20962f2165078d9ed8ee764d5946ef3cbdc7ebf8435bb8d5dd4c1deac\",\n    \"0x8cdb0890e33144d66391d2ae73f5c71f5a861f72bc93bff6cc399fc25dd1f9e17d8772592b44593429718784802ac377\",\n    \"0x8ccf9a7f80800ee770b92add734ed45a73ecc31e2af0e04364eefc6056a8223834c7c0dc9dfc52495bdec6e74ce69994\",\n    \"0xaa0875f423bd68b5f10ba978ddb79d3b96ec093bfbac9ff366323193e339ed7c4578760fb60f60e93598bdf1e5cc4995\",\n    \"0xa9214f523957b59c7a4cb61a40251ad72aba0b57573163b0dc0f33e41d2df483fb9a1b85a5e7c080e9376c866790f8cb\",\n    \"0xb6224b605028c6673a536cc8ff9aeb94e7a22e686fda82cf16068d326469172f511219b68b2b3affb7933af0c1f80d07\",\n    \"0xb6d58968d8a017c6a34e24c2c09852f736515a2c50f37232ac6b43a38f8faa7572cc31dade543b594b61b5761c4781d0\",\n    \"0x8a97cefe5120020c38deeb861d394404e6c993c6cbd5989b6c9ebffe24f46ad11b4ba6348e2991cbf3949c28cfc3c99d\",\n    \"0x95bf046f8c3a9c0ce2634be4de3713024daec3fc4083e808903b25ce3ac971145af90686b451efcc72f6b22df0216667\",\n    \"0xa6a4e2f71b8fa28801f553231eff2794c0f10d12e7e414276995e21195abc9c2983a8997e41af41e78d19ff6fbb2680b\",\n    \"0x8e5e62a7ca9c2f58ebaab63db2ff1fb1ff0877ae94b7f5e2897f273f684ae639dff44cc65718f78a9c894787602ab26a\",\n    \"0x8542784383eec4f565fcb8b9fc2ad8d7a644267d8d7612a0f476fc8df3aff458897a38003d506d24142ad18f93554f2b\",\n    \"0xb7db68ba4616ea072b37925ec4fb39096358c2832cc6d35169e032326b2d6614479f765ae98913c267105b84afcb9bf2\",\n    \"0x8b31dbb9457d23d416c47542c786e07a489af35c4a87dadb8ee91bea5ac4a5315e65625d78dad2cf8f9561af31b45390\",\n    \"0xa8545a1d91ac17257732033d89e6b7111db8242e9c6ebb0213a88906d5ef407a2c6fdb444e29504b06368b6efb4f4839\",\n    \"0xb1bd85d29ebb28ccfb05779aad8674906b267c2bf8cdb1f9a0591dd621b53a4ee9f2942687ee3476740c0b4a7621a3ae\",\n    \"0xa2b54534e152e46c50d91fff03ae9cd019ff7cd9f4168b2fe7ac08ef8c3bbc134cadd3f9d6bd33d20ae476c2a8596c8a\",\n    \"0xb19b571ff4ae3e9f5d95acda133c455e72c9ea9973cae360732859836c0341c4c29ab039224dc5bc3deb824e031675d8\",\n    \"0x940b5f80478648bac025a30f3efeb47023ce20ee98be833948a248bca6979f206bb28fc0f17b90acf3bb4abd3d14d731\",\n    \"0x8f106b40588586ac11629b96d57808ad2808915d89539409c97414aded90b4ff23286a692608230a52bff696055ba5d6\",\n    \"0xae6bda03aa10da3d2abbc66d764ca6c8d0993e7304a1bdd413eb9622f3ca1913baa6da1e9f4f9e6cf847f14f44d6924d\",\n    \"0xa18e7796054a340ef826c4d6b5a117b80927afaf2ebd547794c400204ae2caf277692e2eabb55bc2f620763c9e9da66d\",\n    \"0x8d2d25180dc2c65a4844d3e66819ccfcf48858f0cc89e1c77553b463ec0f7feb9a4002ce26bc618d1142549b9850f232\",\n    \"0x863f413a394de42cc8166c1c75d513b91d545fff1de6b359037a742c70b008d34bf8e587afa2d62c844d0c6f0ea753e7\",\n    \"0x83cd0cf62d63475e7fcad18a2e74108499cdbf28af2113cfe005e3b5887794422da450b1944d0a986eb7e1f4c3b18f25\",\n    \"0xb4f8b350a6d88fea5ab2e44715a292efb12eb52df738c9b2393da3f1ddee68d0a75b476733ccf93642154bceb208f2b8\",\n    \"0xb3f52aaa4cd4221cb9fc45936cc67fd3864bf6d26bf3dd86aa85aa55ecfc05f5e392ecce5e7cf9406b4b1c4fce0398c8\",\n    \"0xb33137084422fb643123f40a6df2b498065e65230fc65dc31791c330e898c51c3a65ff738930f32c63d78f3c9315f85b\",\n    \"0x91452bfa75019363976bb7337fe3a73f1c10f01637428c135536b0cdc7da5ce558dae3dfc792aa55022292600814a8ef\",\n    \"0xad6ba94c787cd4361ca642c20793ea44f1f127d4de0bb4a77c7fbfebae0fcadbf28e2cb6f0c12c12a07324ec8c19761d\",\n    \"0x890aa6248b17f1501b0f869c556be7bf2b1d31a176f9978bb97ab7a6bd4138eed32467951c5ef1871944b7f620542f43\",\n    \"0x82111db2052194ee7dd22ff1eafffac0443cf969d3762cceae046c9a11561c0fdce9c0711f88ac01d1bed165f8a7cee3\",\n    \"0xb1527b71df2b42b55832f72e772a466e0fa05743aacc7814f4414e4bcc8d42a4010c9e0fd940e6f254cafedff3cd6543\",\n    \"0x922370fa49903679fc565f09c16a5917f8125e72acfeb060fcdbadbd1644eb9f4016229756019c93c6d609cda5d5d174\",\n    \"0xaa4c7d98a96cab138d2a53d4aee8ebff6ef903e3b629a92519608d88b3bbd94de5522291a1097e6acf830270e64c8ee1\",\n    \"0xb3dc21608a389a72d3a752883a382baaafc61ecc44083b832610a237f6a2363f24195acce529eb4aed4ef0e27a12b66e\",\n    \"0x94619f5de05e07b32291e1d7ab1d8b7337a2235e49d4fb5f3055f090a65e932e829efa95db886b32b153bdd05a53ec8c\",\n    \"0xade1e92722c2ffa85865d2426fb3d1654a16477d3abf580cfc45ea4b92d5668afc9d09275d3b79283e13e6b39e47424d\",\n    \"0xb7201589de7bed094911dd62fcd25c459a8e327ac447b69f541cdba30233063e5ddffad0b67e9c3e34adcffedfd0e13d\",\n    \"0x809d325310f862d6549e7cb40f7e5fc9b7544bd751dd28c4f363c724a0378c0e2adcb5e42ec8f912f5f49f18f3365c07\",\n    \"0xa79c20aa533de7a5d671c99eb9eb454803ba54dd4f2efa3c8fec1a38f8308e9905c71e9282955225f686146388506ff6\",\n    \"0xa85eeacb5e8fc9f3ed06a3fe2dc3108ab9f8c5877b148c73cf26e4e979bf5795edbe2e63a8d452565fd1176ed40402b2\",\n    \"0x97ef55662f8a1ec0842b22ee21391227540adf7708f491436044f3a2eb18c471525e78e1e14fa292507c99d74d7437c6\",\n    \"0x93110d64ed5886f3d16ce83b11425576a3a7a9bb831cd0de3f9a0b0f2270a730d68136b4ef7ff035ede004358f419b5c\",\n    \"0xac9ed0a071517f0ae4f61ce95916a90ba9a77a3f84b0ec50ef7298acdcd44d1b94525d191c39d6bd1bb68f4471428760\",\n    \"0x98abd6a02c7690f5a339adf292b8c9368dfc12e0f8069cf26a5e0ce54b4441638f5c66ea735142f3c28e00a0024267e6\",\n    \"0xb51efb73ba6d44146f047d69b19c0722227a7748b0e8f644d0fc9551324cf034c041a2378c56ce8b58d06038fb8a78de\",\n    \"0x8f115af274ef75c1662b588b0896b97d71f8d67986ae846792702c4742ab855952865ce236b27e2321967ce36ff93357\",\n    \"0xb3c4548f14d58b3ab03c222da09e4381a0afe47a72d18d50a94e0008797f78e39e99990e5b4757be62310d400746e35a\",\n    \"0xa9b1883bd5f31f909b8b1b6dcb48c1c60ed20aa7374b3ffa7f5b2ed036599b5bef33289d23c80a5e6420d191723b92f7\",\n    \"0x85d38dffd99487ae5bb41ab4a44d80a46157bbbe8ef9497e68f061721f74e4da513ccc3422936b059575975f6787c936\",\n    \"0xadf870fcb96e972c033ab7a35d28ae79ee795f82bc49c3bd69138f0e338103118d5529c53f2d72a9c0d947bf7d312af2\",\n    \"0xab4c7a44e2d9446c6ff303eb49aef0e367a58b22cc3bb27b4e69b55d1d9ee639c9234148d2ee95f9ca8079b1457d5a75\",\n    \"0xa386420b738aba2d7145eb4cba6d643d96bda3f2ca55bb11980b318d43b289d55a108f4bc23a9606fb0bccdeb3b3bb30\",\n    \"0x847020e0a440d9c4109773ecca5d8268b44d523389993b1f5e60e541187f7c597d79ebd6e318871815e26c96b4a4dbb1\",\n    \"0xa530aa7e5ca86fcd1bec4b072b55cc793781f38a666c2033b510a69e110eeabb54c7d8cbcb9c61fee531a6f635ffa972\",\n    \"0x87364a5ea1d270632a44269d686b2402da737948dac27f51b7a97af80b66728b0256547a5103d2227005541ca4b7ed04\",\n    \"0x8816fc6e16ea277de93a6d793d0eb5c15e9e93eb958c5ef30adaf8241805adeb4da8ce19c3c2167f971f61e0b361077d\",\n    \"0x8836a72d301c42510367181bb091e4be377777aed57b73c29ef2ce1d475feedd7e0f31676284d9a94f6db01cc4de81a2\",\n    \"0xb0d9d8b7116156d9dde138d28aa05a33e61f8a85839c1e9071ccd517b46a5b4b53acb32c2edd7150c15bc1b4bd8db9e3\",\n    \"0xae931b6eaeda790ba7f1cd674e53dc87f6306ff44951fa0df88d506316a5da240df9794ccbd7215a6470e6b31c5ea193\",\n    \"0x8c6d5bdf87bd7f645419d7c6444e244fe054d437ed1ba0c122fde7800603a5fadc061e5b836cb22a6cfb2b466f20f013\",\n    \"0x90d530c6d0cb654999fa771b8d11d723f54b8a8233d1052dc1e839ea6e314fbed3697084601f3e9bbb71d2b4eaa596df\",\n    \"0xb0d341a1422588c983f767b1ed36c18b141774f67ef6a43cff8e18b73a009da10fc12120938b8bba27f225bdfd3138f9\",\n    \"0xa131b56f9537f460d304e9a1dd75702ace8abd68cb45419695cb8dee76998139058336c87b7afd6239dc20d7f8f940cc\",\n    \"0xaa6c51fa28975f709329adee1bbd35d49c6b878041841a94465e8218338e4371f5cb6c17f44a63ac93644bf28f15d20f\",\n    \"0x88440fb584a99ebd7f9ea04aaf622f6e44e2b43bbb49fb5de548d24a238dc8f26c8da2ccf03dd43102bda9f16623f609\",\n    \"0x9777b8695b790e702159a4a750d5e7ff865425b95fa0a3c15495af385b91c90c00a6bd01d1b77bffe8c47d01baae846f\",\n    \"0x8b9d764ece7799079e63c7f01690c8eff00896a26a0d095773dea7a35967a8c40db7a6a74692f0118bf0460c26739af4\",\n    \"0x85808c65c485520609c9e61fa1bb67b28f4611d3608a9f7a5030ee61c3aa3c7e7dc17fff48af76b4aecee2cb0dbd22ac\",\n    \"0xad2783a76f5b3db008ef5f7e67391fda4e7e36abde6b3b089fc4835b5c339370287935af6bd53998bed4e399eda1136d\",\n    \"0x96f18ec03ae47c205cc4242ca58e2eff185c9dca86d5158817e2e5dc2207ab84aadda78725f8dc080a231efdc093b940\",\n    \"0x97de1ab6c6cc646ae60cf7b86df73b9cf56cc0cd1f31b966951ebf79fc153531af55ca643b20b773daa7cab784b832f7\",\n    \"0x870ba266a9bfa86ef644b1ef025a0f1b7609a60de170fe9508de8fd53170c0b48adb37f19397ee8019b041ce29a16576\",\n    \"0xad990e888d279ac4e8db90619d663d5ae027f994a3992c2fbc7d262b5990ae8a243e19157f3565671d1cb0de17fe6e55\",\n    \"0x8d9d5adcdd94c5ba3be4d9a7428133b42e485f040a28d16ee2384758e87d35528f7f9868de9bd23d1a42a594ce50a567\",\n    \"0x85a33ed75d514ece6ad78440e42f7fcdb59b6f4cff821188236d20edae9050b3a042ce9bc7d2054296e133d033e45022\",\n    \"0x92afd2f49a124aaba90de59be85ff269457f982b54c91b06650c1b8055f9b4b0640fd378df02a00e4fc91f7d226ab980\",\n    \"0x8c0ee09ec64bd831e544785e3d65418fe83ed9c920d9bb4d0bf6dd162c1264eb9d6652d2def0722e223915615931581c\",\n    \"0x8369bedfa17b24e9ad48ebd9c5afea4b66b3296d5770e09b00446c5b0a8a373d39d300780c01dcc1c6752792bccf5fd0\",\n    \"0x8b9e960782576a59b2eb2250d346030daa50bbbec114e95cdb9e4b1ba18c3d34525ae388f859708131984976ca439d94\",\n    \"0xb682bface862008fea2b5a07812ca6a28a58fd151a1d54c708fc2f8572916e0d678a9cb8dc1c10c0470025c8a605249e\",\n    \"0xa38d5e189bea540a824b36815fc41e3750760a52be0862c4cac68214febdc1a754fb194a7415a8fb7f96f6836196d82a\",\n    \"0xb9e7fbda650f18c7eb8b40e42cc42273a7298e65e8be524292369581861075c55299ce69309710e5b843cb884de171bd\",\n    \"0xb6657e5e31b3193874a1bace08f42faccbd3c502fb73ad87d15d18a1b6c2a146f1baa929e6f517db390a5a47b66c0acf\",\n    \"0xae15487312f84ed6265e4c28327d24a8a0f4d2d17d4a5b7c29b974139cf93223435aaebe3af918f5b4bb20911799715f\",\n    \"0x8bb4608beb06bc394e1a70739b872ce5a2a3ffc98c7547bf2698c893ca399d6c13686f6663f483894bccaabc3b9c56ad\",\n    \"0xb58ac36bc6847077584308d952c5f3663e3001af5ecf2e19cb162e1c58bd6c49510205d453cffc876ca1dc6b8e04a578\",\n    \"0x924f65ced61266a79a671ffb49b300f0ea44c50a0b4e3b02064faa99fcc3e4f6061ea8f38168ab118c5d47bd7804590e\",\n    \"0x8d67d43b8a06b0ff4fafd7f0483fa9ed1a9e3e658a03fb49d9d9b74e2e24858dc1bed065c12392037b467f255d4e5643\",\n    \"0xb4d4f87813125a6b355e4519a81657fa97c43a6115817b819a6caf4823f1d6a1169683fd68f8d025cdfa40ebf3069acb\",\n    \"0xa7fd4d2c8e7b59b8eed3d4332ae94b77a89a2616347402f880bc81bde072220131e6dbec8a605be3a1c760b775375879\",\n    \"0x8d4a7d8fa6f55a30df37bcf74952e2fa4fd6676a2e4606185cf154bdd84643fd01619f8fb8813a564f72e3f574f8ce30\",\n    \"0x8086fb88e6260e9a9c42e9560fde76315ff5e5680ec7140f2a18438f15bc2cc7d7d43bfb5880b180b738c20a834e6134\",\n    \"0x916c4c54721de03934fee6f43de50bb04c81f6f8dd4f6781e159e71c40c60408aa54251d457369d133d4ba3ed7c12cb4\",\n    \"0x902e5bf468f11ed9954e2a4a595c27e34abe512f1d6dc08bbca1c2441063f9af3dc5a8075ab910a10ff6c05c1c644a35\",\n    \"0xa1302953015e164bf4c15f7d4d35e3633425a78294406b861675667eec77765ff88472306531e5d3a4ec0a2ff0dd6a9e\",\n    \"0x87874461df3c9aa6c0fa91325576c0590f367075f2f0ecfeb34afe162c04c14f8ce9d608c37ac1adc8b9985bc036e366\",\n    \"0x84b50a8a61d3cc609bfb0417348133e698fe09a6d37357ce3358de189efcf35773d78c57635c2d26c3542b13cc371752\",\n    \"0xacaed2cff8633d12c1d12bb7270c54d65b0b0733ab084fd47f81d0a6e1e9b6f300e615e79538239e6160c566d8bb8d29\",\n    \"0x889e6a0e136372ca4bac90d1ab220d4e1cad425a710e8cdd48b400b73bb8137291ceb36a39440fa84305783b1d42c72f\",\n    \"0x90952e5becec45b2b73719c228429a2c364991cf1d5a9d6845ae5b38018c2626f4308daa322cab1c72e0f6c621bb2b35\",\n    \"0x8f5a97a801b6e9dcd66ccb80d337562c96f7914e7169e8ff0fda71534054c64bf2a9493bb830623d612cfe998789be65\",\n    \"0x84f3df8b9847dcf1d63ca470dc623154898f83c25a6983e9b78c6d2d90a97bf5e622445be835f32c1e55e6a0a562ea78\",\n    \"0x91d12095cd7a88e7f57f254f02fdb1a1ab18984871dead2f107404bcf8069fe68258c4e6f6ebd2477bddf738135400bb\",\n    \"0xb771a28bc04baef68604d4723791d3712f82b5e4fe316d7adc2fc01b935d8e644c06d59b83bcb542afc40ebafbee0683\",\n    \"0x872f6341476e387604a7e93ae6d6117e72d164e38ebc2b825bc6df4fcce815004d7516423c190c1575946b5de438c08d\",\n    \"0x90d6b4aa7d40a020cdcd04e8b016d041795961a8e532a0e1f4041252131089114a251791bf57794cadb7d636342f5d1c\",\n    \"0x899023ba6096a181448d927fed7a0fe858be4eac4082a42e30b3050ee065278d72fa9b9d5ce3bc1372d4cbd30a2f2976\",\n    \"0xa28f176571e1a9124f95973f414d5bdbf5794d41c3839d8b917100902ac4e2171eb940431236cec93928a60a77ede793\",\n    \"0x838dbe5bcd29c4e465d02350270fa0036cd46f8730b13d91e77afb7f5ed16525d0021d3b2ae173a76c378516a903e0cb\",\n    \"0x8e105d012dd3f5d20f0f1c4a7e7f09f0fdd74ce554c3032e48da8cce0a77260d7d47a454851387770f5c256fa29bcb88\",\n    \"0x8f4df0f9feeb7a487e1d138d13ea961459a6402fd8f8cabb226a92249a0d04ded5971f3242b9f90d08da5ff66da28af6\",\n    \"0xad1cfda4f2122a20935aa32fb17c536a3653a18617a65c6836700b5537122af5a8206befe9eaea781c1244c43778e7f1\",\n    \"0x832c6f01d6571964ea383292efc8c8fa11e61c0634a25fa180737cc7ab57bc77f25e614aac9a2a03d98f27b3c1c29de2\",\n    \"0x903f89cc13ec6685ac7728521898781fecb300e9094ef913d530bf875c18bcc3ceed7ed51e7b482d45619ab4b025c2e9\",\n    \"0xa03c474bb915aad94f171e8d96f46abb2a19c9470601f4c915512ec8b9e743c3938450a2a5b077b4618b9df8809e1dc1\",\n    \"0x83536c8456f306045a5f38ae4be2e350878fa7e164ea408d467f8c3bc4c2ee396bd5868008c089183868e4dfad7aa50b\",\n    \"0x88f26b4ea1b236cb326cd7ad7e2517ec8c4919598691474fe15d09cabcfc37a8d8b1b818f4d112432ee3a716b0f37871\",\n    \"0xa44324e3fe96e9c12b40ded4f0f3397c8c7ee8ff5e96441118d8a6bfad712d3ac990b2a6a23231a8f691491ac1fd480f\",\n    \"0xb0de4693b4b9f932191a21ee88629964878680152a82996c0019ffc39f8d9369bbe2fe5844b68d6d9589ace54af947e4\",\n    \"0x8e5d8ba948aea5fd26035351a960e87f0d23efddd8e13236cc8e4545a3dda2e9a85e6521efb8577e03772d3637d213d9\",\n    \"0x93efc82d2017e9c57834a1246463e64774e56183bb247c8fc9dd98c56817e878d97b05f5c8d900acf1fbbbca6f146556\",\n    \"0x8731176363ad7658a2862426ee47a5dce9434216cef60e6045fa57c40bb3ce1e78dac4510ae40f1f31db5967022ced32\",\n    \"0xb10c9a96745722c85bdb1a693100104d560433d45b9ac4add54c7646a7310d8e9b3ca9abd1039d473ae768a18e489845\",\n    \"0xa2ac374dfbb464bf850b4a2caf15b112634a6428e8395f9c9243baefd2452b4b4c61b0cb2836d8eae2d57d4900bf407e\",\n    \"0xb69fe3ded0c4f5d44a09a0e0f398221b6d1bf5dbb8bc4e338b93c64f1a3cac1e4b5f73c2b8117158030ec03787f4b452\",\n    \"0x8852cdbaf7d0447a8c6f211b4830711b3b5c105c0f316e3a6a18dcfbb9be08bd6f4e5c8ae0c3692da08a2dfa532f9d5c\",\n    \"0x93bbf6d7432a7d98ade3f94b57bf9f4da9bc221a180a370b113066dd42601bb9e09edd79e2e6e04e00423399339eebda\",\n    \"0xa80941c391f1eeafc1451c59e4775d6a383946ff22997aeaadf806542ba451d3b0f0c6864eeba954174a296efe2c1550\",\n    \"0xa045fe2bb011c2a2f71a0181a8f457a3078470fb74c628eab8b59aef69ffd0d649723bf74d6885af3f028bc5a104fb39\",\n    \"0xb9d8c35911009c4c8cad64692139bf3fc16b78f5a19980790cb6a7aea650a25df4231a4437ae0c351676a7e42c16134f\",\n    \"0x94c79501ded0cfcbab99e1841abe4a00a0252b3870e20774c3da16c982d74c501916ec28304e71194845be6e3113c7ab\",\n    \"0x900a66418b082a24c6348d8644ddb1817df5b25cb33044a519ef47cc8e1f7f1e38d2465b7b96d32ed472d2d17f8414c6\",\n    \"0xb26f45d393b8b2fcb29bdbb16323dc7f4b81c09618519ab3a39f8ee5bd148d0d9f3c0b5dfab55b5ce14a1cb9206d777b\",\n    \"0xaa1a87735fc493a80a96a9a57ca40a6d9c32702bfcaa9869ce1a116ae65d69cefe2f3e79a12454b4590353e96f8912b4\",\n    \"0xa922b188d3d0b69b4e4ea2a2aa076566962844637da12c0832105d7b31dea4a309eee15d12b7a336be3ea36fcbd3e3b7\",\n    \"0x8f3841fcf4105131d8c4d9885e6e11a46c448226401cf99356c291fadb864da9fa9d30f3a73c327f23f9fd99a11d633e\",\n    \"0x9791d1183fae270e226379af6c497e7da803ea854bb20afa74b253239b744c15f670ee808f708ede873e78d79a626c9a\",\n    \"0xa4cad52e3369491ada61bf28ada9e85de4516d21c882e5f1cd845bea9c06e0b2887b0c5527fcff6fc28acd3c04f0a796\",\n    \"0xb9ac86a900899603452bd11a7892a9bfed8054970bfcbeaa8c9d1930db891169e38d6977f5258c25734f96c8462eee3b\",\n    \"0xa3a154c28e5580656a859f4efc2f5ebfa7eaa84ca40e3f134fa7865e8581586db74992dbfa4036aa252fba103773ddde\",\n    \"0x95cc2a0c1885a029e094f5d737e3ecf4d26b99036453a8773c77e360101f9f98676ee246f6f732a377a996702d55691f\",\n    \"0x842651bbe99720438d8d4b0218feb60481280c05beb17750e9ca0d8c0599a60f873b7fbdcc7d8835ba9a6d57b16eec03\",\n    \"0x81ee54699da98f5620307893dcea8f64670609fa20e5622265d66283adeac122d458b3308c5898e6c57c298db2c8b24f\",\n    \"0xb97868b0b2bc98032d68352a535a1b341b9ff3c7af4e3a7f3ebc82d3419daa1b5859d6aedc39994939623c7cd878bd9b\",\n    \"0xb60325cd5d36461d07ef253d826f37f9ee6474a760f2fff80f9873d01fd2b57711543cdc8d7afa1c350aa753c2e33dea\",\n    \"0x8c205326c11d25a46717b780c639d89714c7736c974ae71287e3f4b02e6605ac2d9b4928967b1684f12be040b7bf2dd3\",\n    \"0x95a392d82db51e26ade6c2ccd3396d7e40aff68fa570b5951466580d6e56dda51775dce5cf3a74a7f28c3cb2eb551c4d\",\n    \"0x8f2cc8071eb56dffb70bda6dd433b556221dc8bba21c53353c865f00e7d4d86c9e39f119ea9a8a12ef583e9a55d9a6b6\",\n    \"0x9449a71af9672aaf8856896d7e3d788b22991a7103f75b08c0abbcc2bfe60fda4ed8ce502cea4511ff0ea52a93e81222\",\n    \"0x857090ab9fdb7d59632d068f3cc8cf27e61f0d8322d30e6b38e780a1f05227199b4cd746aac1311c36c659ef20931f28\",\n    \"0x98a891f4973e7d9aaf9ac70854608d4f7493dffc7e0987d7be9dd6029f6ea5636d24ef3a83205615ca1ff403750058e1\",\n    \"0xa486e1365bbc278dd66a2a25d258dc82f46b911103cb16aab3945b9c95ae87b386313a12b566df5b22322ede0afe25ad\",\n    \"0xa9a1eb399ed95d396dccd8d1ac718043446f8b979ec62bdce51c617c97a312f01376ab7fb87d27034e5f5570797b3c33\",\n    \"0xb7abc3858d7a74bb446218d2f5a037e0fae11871ed9caf44b29b69c500c1fa1dcfad64c9cdccc9d80d5e584f06213deb\",\n    \"0x8cfb09fe2e202faa4cebad932b1d35f5ca204e1c2a0c740a57812ac9a6792130d1312aabd9e9d4c58ca168bfebd4c177\",\n    \"0xa90a305c2cd0f184787c6be596fa67f436afd1f9b93f30e875f817ac2aae8bdd2e6e656f6be809467e6b3ad84adb86b1\",\n    \"0x80a9ef993c2b009ae172cc8f7ec036f5734cf4f4dfa06a7db4d54725e7fbfae5e3bc6f22687bdbb6961939d6f0c87537\",\n    \"0x848ade1901931e72b955d7db1893f07003e1708ff5d93174bac5930b9a732640f0578839203e9b77eb27965c700032d3\",\n    \"0x93fdf4697609c5ae9c33b9ca2f5f1af44abeb2b98dc4fdf732cf7388de086f410730dc384d9b7a7f447bb009653c8381\",\n    \"0x89ce3fb805aea618b5715c0d22a9f46da696b6fa86794f56fdf1d44155a33d42daf1920bcbe36cbacf3cf4c92df9cbc7\",\n    \"0x829ce2c342cf82aa469c65f724f308f7a750bd1494adc264609cd790c8718b8b25b5cab5858cf4ee2f8f651d569eea67\",\n    \"0xaf2f0cee7bf413204be8b9df59b9e4991bc9009e0d6dbe6815181df0ec2ca93ab8f4f3135b1c14d8f53d74bff0bd6f27\",\n    \"0xb87998cecf7b88cde93d1779f10a521edd5574a2fbd240102978639ec57433ba08cdb53849038a329cebbe74657268d2\",\n    \"0xa64542a1261a6ed3d720c2c3a802303aad8c4c110c95d0f12e05c1065e66f42da494792b6bfc5b9272363f3b1d457f58\",\n    \"0x86a6fd042e4f282fadf07a4bfee03fc96a3aea49f7a00f52bf249a20f1ec892326855410e61f37fbb27d9305eb2fc713\",\n    \"0x967ea5bc403b6db269682f7fd0df90659350d7e1aa66bc4fab4c9dfcd75ed0bba4b52f1cebc5f34dc8ba810793727629\",\n    \"0xa52990f9f3b8616ce3cdc2c74cd195029e6a969753dcf2d1630438700e7d6ebde36538532b3525ac516f5f2ce9dd27a3\",\n    \"0xa64f7ff870bab4a8bf0d4ef6f5c744e9bf1021ed08b4c80903c7ad318e80ba1817c3180cc45cb5a1cae1170f0241655f\",\n    \"0xb00f706fa4de1f663f021e8ad3d155e84ce6084a409374b6e6cd0f924a0a0b51bebaaaf1d228c77233a73b0a5a0df0e9\",\n    \"0x8b882cc3bff3e42babdb96df95fb780faded84887a0a9bab896bef371cdcf169d909f5658649e93006aa3c6e1146d62e\",\n    \"0x9332663ef1d1dcf805c3d0e4ce7a07d9863fb1731172e766b3cde030bf81682cc011e26b773fb9c68e0477b4ae2cfb79\",\n    \"0xa8aa8151348dbd4ef40aaeb699b71b4c4bfd3218560c120d85036d14f678f6736f0ec68e80ce1459d3d35feccc575164\",\n    \"0xa16cd8b729768f51881c213434aa28301fa78fcb554ddd5f9012ee1e4eae7b5cb3dd88d269d53146dea92d10790faf0b\",\n    \"0x86844f0ef9d37142faf3b1e196e44fbe280a3ba4189aa05c356778cb9e3b388a2bff95eed305ada8769935c9974e4c57\",\n    \"0xae2eec6b328fccf3b47bcdac32901ac2744a51beb410b04c81dea34dee4912b619466a4f5e2780d87ecefaebbe77b46d\",\n    \"0x915df4c38d301c8a4eb2dc5b1ba0ffaad67cbb177e0a80095614e9c711f4ef24a4cef133f9d982a63d2a943ba6c8669d\",\n    \"0xae6a2a4dedfc2d1811711a8946991fede972fdf2a389b282471280737536ffc0ac3a6d885b1f8bda0366eb0b229b9979\",\n    \"0xa9b628c63d08b8aba6b1317f6e91c34b2382a6c85376e8ef2410a463c6796740ae936fc4e9e0737cb9455d1daa287bd8\",\n    \"0x848e30bf7edf2546670b390d5cf9ab71f98fcb6add3c0b582cb34996c26a446dee5d1bde4fdcde4fc80c10936e117b29\",\n    \"0x907d6096c7c8c087d1808dd995d5d2b9169b3768c3f433475b50c2e2bd4b082f4d543afd8b0b0ddffa9c66222a72d51d\",\n    \"0xa59970a2493b07339124d763ac9d793c60a03354539ecbcf6035bc43d1ea6e35718202ae6d7060b7d388f483d971573c\",\n    \"0xb9cfef2af9681b2318f119d8611ff6d9485a68d8044581b1959ab1840cbca576dbb53eec17863d2149966e9feb21122f\",\n    \"0xad47271806161f61d3afa45cdfe2babceef5e90031a21779f83dc8562e6076680525b4970b2f11fe9b2b23c382768323\",\n    \"0x8e425a99b71677b04fe044625d338811fbb8ee32368a424f6ab2381c52e86ee7a6cecedf777dc97181519d41c351bc22\",\n    \"0x86b55b54d7adefc12954a9252ee23ae83efe8b5b4b9a7dc307904413e5d69868c7087a818b2833f9b004213d629be8ad\",\n    \"0xa14fda6b93923dd11e564ae4457a66f397741527166e0b16a8eb91c6701c244fd1c4b63f9dd3515193ec88fa6c266b35\",\n    \"0xa9b17c36ae6cd85a0ed7f6cabc5b47dc8f80ced605db327c47826476dc1fb8f8669aa7a7dc679fbd4ee3d8e8b4bd6a6f\",\n    \"0x82a0829469c1458d959c821148f15dacae9ea94bf56c59a6ab2d4dd8b3d16d73e313b5a3912a6c1f131d73a8f06730c4\",\n    \"0xb22d56d549a53eaef549595924bdb621ff807aa4513feedf3fdcbf7ba8b6b9cfa4481c2f67fc642db397a6b794a8b63a\",\n    \"0x974c59c24392e2cb9294006cbe3c52163e255f3bd0c2b457bdc68a6338e6d5b6f87f716854492f8d880a6b896ccf757c\",\n    \"0xb70d247ba7cad97c50b57f526c2ba915786e926a94e8f8c3eebc2e1be6f4255411b9670e382060049c8f4184302c40b2\",\n    \"0xad80201fe75ef21c3ddbd98cf23591e0d7a3ba1036dfe77785c32f44755a212c31f0ceb0a0b6f5ee9b6dc81f358d30c3\",\n    \"0x8c656e841f9bb90b9a42d425251f3fdbc022a604d75f5845f479ed4be23e02aaf9e6e56cde351dd7449c50574818a199\",\n    \"0x8b88dd3fa209d3063b7c5b058f7249ee9900fbc2287d16da61a0704a0a1d71e45d9c96e1cda7fdf9654534ec44558b22\",\n    \"0x961da00cc8750bd84d253c08f011970ae1b1158ad6778e8ed943d547bceaf52d6d5a212a7de3bf2706688c4389b827d2\",\n    \"0xa5dd379922549a956033e3d51a986a4b1508e575042b8eaa1df007aa77cf0b8c2ab23212f9c075702788fa9c53696133\",\n    \"0xac8fcfde3a349d1e93fc8cf450814e842005c545c4844c0401bc80e6b96cdb77f29285a14455e167c191d4f312e866cd\",\n    \"0xac63d79c799783a8466617030c59dd5a8f92ee6c5204676fd8d881ce5f7f8663bdbeb0379e480ea9b6340ab0dc88e574\",\n    \"0x805874fde19ce359041ae2bd52a39e2841acabfd31f965792f2737d7137f36d4e4722ede8340d8c95afa6af278af8acb\",\n    \"0x8d2f323a228aa8ba7b7dc1399138f9e6b41df1a16a7069003ab8104b8b68506a45141bc5fe66acf430e23e13a545190b\",\n    \"0xa1610c721a2d9af882bb6b39bea97cff1527a3aea041d25934de080214ae77c959e79957164440686d15ab301e897d4d\",\n    \"0xaba16d29a47fc36f12b654fde513896723e2c700c4190f11b26aa4011da57737ad717daa02794aa3246e4ae5f0b0cc3a\",\n    \"0xa406db2f15fdd135f346cc4846623c47edd195e80ba8c7cb447332095314d565e4040694ca924696bb5ee7f8996ea0ba\",\n    \"0x8b30e2cd9b47d75ba57b83630e40f832249af6c058d4f490416562af451993eec46f3e1f90bc4d389e4c06abd1b32a46\",\n    \"0xaacf9eb7036e248e209adbfc3dd7ce386569ea9b312caa4b240726549db3c68c4f1c8cbf8ed5ea9ea60c7e57c9df3b8e\",\n    \"0xb20fcac63bf6f5ee638a42d7f89be847f348c085ddcbec3fa318f4323592d136c230495f188ef2022aa355cc2b0da6f9\",\n    \"0x811eff750456a79ec1b1249d76d7c1547065b839d8d4aaad860f6d4528eb5b669473dcceeeea676cddbc3980b68461b7\",\n    \"0xb52d14ae33f4ab422f953392ae76a19c618cc31afc96290bd3fe2fb44c954b5c92c4789f3f16e8793f2c0c1691ade444\",\n    \"0xa7826dafeeba0db5b66c4dfcf2b17fd7b40507a5a53ac2e42942633a2cb30b95ba1739a6e9f3b7a0e0f1ec729bf274e2\",\n    \"0x8acfd83ddf7c60dd7c8b20c706a3b972c65d336b8f9b3d907bdd8926ced271430479448100050b1ef17578a49c8fa616\",\n    \"0xaf0c69f65184bb06868029ad46f8465d75c36814c621ac20a5c0b06a900d59305584f5a6709683d9c0e4b6cd08d650a6\",\n    \"0xb6cc8588191e00680ee6c3339bd0f0a17ad8fd7f4be57d5d7075bede0ea593a19e67f3d7c1a20114894ee5bfcab71063\",\n    \"0xa82fd4f58635129dbb6cc3eb9391cf2d28400018b105fc41500fbbd12bd890b918f97d3d359c29dd3b4c4e34391dfab0\",\n    \"0x92fc544ed65b4a3625cf03c41ddff7c039bc22d22c0d59dcc00efd5438401f2606adb125a1d5de294cca216ec8ac35a3\",\n    \"0x906f67e4a32582b71f15940523c0c7ce370336935e2646bdaea16a06995256d25e99df57297e39d6c39535e180456407\",\n    \"0x97510337ea5bbd5977287339197db55c60533b2ec35c94d0a460a416ae9f60e85cee39be82abeeacd5813cf54df05862\",\n    \"0x87e6894643815c0ea48cb96c607266c5ee4f1f82ba5fe352fb77f9b6ed14bfc2b8e09e80a99ac9047dfcf62b2ae26795\",\n    \"0xb6fd55dd156622ad7d5d51b7dde75e47bd052d4e542dd6449e72411f68275775c846dde301e84613312be8c7bce58b07\",\n    \"0xb98461ac71f554b2f03a94e429b255af89eec917e208a8e60edf5fc43b65f1d17a20de3f31d2ce9f0cb573c25f2f4d98\",\n    \"0x96f0dea40ca61cefbee41c4e1fe9a7d81fbe1f49bb153d083ab70f5d0488a1f717fd28cedcf6aa18d07cce2c62801898\",\n    \"0x8d7c3ab310184f7dc34b6ce4684e4d29a31e77b09940448ea4daac730b7eb308063125d4dd229046cf11bfd521b771e0\",\n    \"0x96f0564898fe96687918bbf0a6adead99cf72e3a35ea3347e124af9d006221f8e82e5a9d2fe80094d5e8d48e610f415e\",\n    \"0xad50fcb92c2675a398cf07d4c40a579e44bf8d35f27cc330b57e54d5ea59f7d898af0f75dccfe3726e5471133d70f92b\",\n    \"0x828beed62020361689ae7481dd8f116902b522fb0c6c122678e7f949fdef70ead011e0e6bffd25678e388744e17cdb69\",\n    \"0x8349decac1ca16599eee2efc95bcaabf67631107da1d34a2f917884bd70dfec9b4b08ab7bc4379d6c73b19c0b6e54fb8\",\n    \"0xb2a6a2e50230c05613ace9e58bb2e98d94127f196f02d9dddc53c43fc68c184549ca12d713cb1b025d8260a41e947155\",\n    \"0x94ff52181aadae832aed52fc3b7794536e2a31a21fc8be3ea312ca5c695750d37f08002f286b33f4023dba1e3253ecfa\",\n    \"0xa21d56153c7e5972ee9a319501be4faff199fdf09bb821ea9ce64aa815289676c00f105e6f00311b3a5b627091b0d0fc\",\n    \"0xa27a60d219f1f0c971db73a7f563b371b5c9fc3ed1f72883b2eac8a0df6698400c9954f4ca17d7e94e44bd4f95532afb\",\n    \"0xa2fc56fae99b1f18ba5e4fe838402164ce82f8a7f3193d0bbd360c2bac07c46f9330c4c7681ffb47074c6f81ee6e7ac6\",\n    \"0xb748e530cd3afb96d879b83e89c9f1a444f54e55372ab1dcd46a0872f95ce8f49cf2363fc61be82259e04f555937ed16\",\n    \"0x8bf8993e81080c7cbba1e14a798504af1e4950b2f186ab3335b771d6acaee4ffe92131ae9c53d74379d957cb6344d9cd\",\n    \"0x96774d0ef730d22d7ab6d9fb7f90b9ead44285219d076584a901960542756700a2a1603cdf72be4708b267200f6c36a9\",\n    \"0xb47703c2ab17be1e823cc7bf3460db1d6760c0e33862c90ca058845b2ff234b0f9834ddba2efb2ee1770eb261e7d8ffd\",\n    \"0x84319e67c37a9581f8b09b5e4d4ae88d0a7fb4cbb6908971ab5be28070c3830f040b1de83ee663c573e0f2f6198640e4\",\n    \"0x96811875fa83133e0b3c0e0290f9e0e28bca6178b77fdf5350eb19344d453dbd0d71e55a0ef749025a5a2ca0ad251e81\",\n    \"0x81a423423e9438343879f2bfd7ee9f1c74ebebe7ce3cfffc8a11da6f040cc4145c3b527bd3cf63f9137e714dbcb474ef\",\n    \"0xb8c3535701ddbeec2db08e17a4fa99ba6752d32ece5331a0b8743676f421fcb14798afc7c783815484f14693d2f70db8\",\n    \"0x81aee980c876949bf40782835eec8817d535f6f3f7e00bf402ddd61101fdcd60173961ae90a1cf7c5d060339a18c959d\",\n    \"0x87e67b928d97b62c49dac321ce6cb680233f3a394d4c9a899ac2e8db8ccd8e00418e66cdfd68691aa3cb8559723b580c\",\n    \"0x8eac204208d99a2b738648df96353bbb1b1065e33ee4f6bba174b540bbbd37d205855e1f1e69a6b7ff043ca377651126\",\n    \"0x848e6e7a54ad64d18009300b93ea6f459ce855971dddb419b101f5ac4c159215626fadc20cc3b9ab1701d8f6dfaddd8b\",\n    \"0x88aa123d9e0cf309d46dddb6acf634b1ade3b090a2826d6e5e78669fa1220d6df9a6697d7778cd9b627db17eea846126\",\n    \"0x9200c2a629b9144d88a61151b661b6c4256cc5dadfd1e59a8ce17a013c2d8f7e754aabe61663c3b30f1bc47784c1f8cf\",\n    \"0xb6e1a2827c3bdda91715b0e1b1f10dd363cef337e7c80cac1f34165fc0dea7c8b69747e310563db5818390146ce3e231\",\n    \"0x92c333e694f89f0d306d54105b2a5dcc912dbe7654d9e733edab12e8537350815be472b063e56cfde5286df8922fdecb\",\n    \"0xa6fac04b6d86091158ebb286586ccfec2a95c9786e14d91a9c743f5f05546073e5e3cc717635a0c602cad8334e922346\",\n    \"0xa581b4af77feebc1fb897d49b5b507c6ad513d8f09b273328efbb24ef0d91eb740d01b4d398f2738125dacfe550330cd\",\n    \"0x81c4860cccf76a34f8a2bc3f464b7bfd3e909e975cce0d28979f457738a56e60a4af8e68a3992cf273b5946e8d7f76e2\",\n    \"0x8d1eaa09a3180d8af1cbaee673db5223363cc7229a69565f592fa38ba0f9d582cedf91e15dabd06ebbf2862fc0feba54\",\n    \"0x9832f49b0147f4552402e54593cfa51f99540bffada12759b71fcb86734be8e500eea2d8b3d036710bdf04c901432de9\",\n    \"0x8bdb0e8ec93b11e5718e8c13cb4f5de545d24829fd76161216340108098dfe5148ed25e3b57a89a516f09fa79043734d\",\n    \"0xab96f06c4b9b0b2c0571740b24fca758e6976315053a7ecb20119150a9fa416db2d3a2e0f8168b390bb063f0c1caf785\",\n    \"0xab777f5c52acd62ecf4d1f168b9cc8e1a9b45d4ec6a8ff52c583e867c2239aba98d7d3af977289b367edce03d9c2dfb1\",\n    \"0xa09d3ce5e748da84802436951acc3d3ea5d8ec1d6933505ed724d6b4b0d69973ab0930daec9c6606960f6e541e4a3ce2\",\n    \"0x8ef94f7be4d85d5ad3d779a5cf4d7b2fc3e65c52fb8e1c3c112509a4af77a0b5be994f251e5e40fabeeb1f7d5615c22b\",\n    \"0xa7406a5bf5708d9e10922d3c5c45c03ef891b8d0d74ec9f28328a72be4cdc05b4f2703fa99366426659dfca25d007535\",\n    \"0xb7f52709669bf92a2e070bfe740f422f0b7127392c5589c7f0af71bb5a8428697c762d3c0d74532899da24ea7d8695c2\",\n    \"0xb9dfb0c8df84104dbf9239ccefa4672ef95ddabb8801b74997935d1b81a78a6a5669a3c553767ec19a1281f6e570f4ff\",\n    \"0xae4d5c872156061ce9195ac640190d8d71dd406055ee43ffa6f9893eb24b870075b74c94d65bc1d5a07a6573282b5520\",\n    \"0xafe6bd3eb72266d333f1807164900dcfa02a7eb5b1744bb3c86b34b3ee91e3f05e38fa52a50dc64eeb4bdb1dd62874b8\",\n    \"0x948043cf1bc2ef3c01105f6a78dc06487f57548a3e6ef30e6ebc51c94b71e4bf3ff6d0058c72b6f3ecc37efd7c7fa8c0\",\n    \"0xa22fd17c2f7ffe552bb0f23fa135584e8d2d8d75e3f742d94d04aded2a79e22a00dfe7acbb57d44e1cdb962fb22ae170\",\n    \"0x8cd0f4e9e4fb4a37c02c1bde0f69359c43ab012eb662d346487be0c3758293f1ca560122b059b091fddce626383c3a8f\",\n    \"0x90499e45f5b9c81426f3d735a52a564cafbed72711d9279fdd88de8038e953bc48c57b58cba85c3b2e4ce56f1ddb0e11\",\n    \"0x8c30e4c034c02958384564cac4f85022ef36ab5697a3d2feaf6bf105049675bbf23d01b4b6814711d3d9271abff04cac\",\n    \"0x81f7999e7eeea30f3e1075e6780bbf054f2fb6f27628a2afa4d41872a385b4216dd5f549da7ce6cf39049b2251f27fb7\",\n    \"0xb36a7191f82fc39c283ffe53fc1f5a9a00b4c64eee7792a8443475da9a4d226cf257f226ea9d66e329af15d8f04984ec\",\n    \"0xaad4da528fdbb4db504f3041c747455baff5fcd459a2efd78f15bdf3aea0bdb808343e49df88fe7a7c8620009b7964a3\",\n    \"0x99ebd8c6dd5dd299517fb6381cfc2a7f443e6e04a351440260dd7c2aee3f1d8ef06eb6c18820b394366ecdfd2a3ce264\",\n    \"0x8873725b81871db72e4ec3643084b1cdce3cbf80b40b834b092767728605825c19b6847ad3dcf328438607e8f88b4410\",\n    \"0xb008ee2f895daa6abd35bd39b6f7901ae4611a11a3271194e19da1cdcc7f1e1ea008fe5c5440e50d2c273784541ad9c5\",\n    \"0x9036feafb4218d1f576ef89d0e99124e45dacaa6d816988e34d80f454d10e96809791d5b78f7fd65f569e90d4d7238c5\",\n    \"0x92073c1d11b168e4fa50988b0288638b4868e48bbc668c5a6dddf5499875d53be23a285acb5e4bad60114f6cf6c556e9\",\n    \"0x88c87dfcb8ba6cbfe7e1be081ccfadbd589301db2cb7c99f9ee5d7db90aa297ed1538d5a867678a763f2deede5fd219a\",\n    \"0xb42a562805c661a50f5dea63108002c0f27c0da113da6a9864c9feb5552225417c0356c4209e8e012d9bcc9d182c7611\",\n    \"0x8e6317d00a504e3b79cd47feb4c60f9df186467fe9ca0f35b55c0364db30528f5ff071109dabb2fc80bb9cd4949f0c24\",\n    \"0xb7b1ea6a88694f8d2f539e52a47466695e39e43a5eb9c6f23bca15305fe52939d8755cc3ac9d6725e60f82f994a3772f\",\n    \"0xa3cd55161befe795af93a38d33290fb642b8d80da8b786c6e6fb02d393ea308fbe87f486994039cbd7c7b390414594b6\",\n    \"0xb416d2d45b44ead3b1424e92c73c2cf510801897b05d1724ff31cbd741920cd858282fb5d6040fe1f0aa97a65bc49424\",\n    \"0x950ee01291754feace97c2e933e4681e7ddfbc4fcd079eb6ff830b0e481d929c93d0c7fb479c9939c28ca1945c40da09\",\n    \"0x869bd916aee8d86efe362a49010382674825d49195b413b4b4018e88ce43fe091b475d0b863ff0ba2259400f280c2b23\",\n    \"0x9782f38cd9c9d3385ec286ebbc7cba5b718d2e65a5890b0a5906b10a89dc8ed80d417d71d7c213bf52f2af1a1f513ea7\",\n    \"0x91cd33bc2628d096269b23faf47ee15e14cb7fdc6a8e3a98b55e1031ea0b68d10ba30d97e660f7e967d24436d40fad73\",\n    \"0x8becc978129cc96737034c577ae7225372dd855da8811ae4e46328e020c803833b5bdbc4a20a93270e2b8bd1a2feae52\",\n    \"0xa36b1d8076783a9522476ce17f799d78008967728ce920531fdaf88303321bcaf97ecaa08e0c01f77bc32e53c5f09525\",\n    \"0xb4720e744943f70467983aa34499e76de6d59aa6fadf86f6b787fdce32a2f5b535b55db38fe2da95825c51002cfe142d\",\n    \"0x91ad21fc502eda3945f6de874d1b6bf9a9a7711f4d61354f9e5634fc73f9c06ada848de15ab0a75811d3250be862827d\",\n    \"0x84f78e2ebf5fc077d78635f981712daf17e2475e14c2a96d187913006ad69e234746184a51a06ef510c9455b38acb0d7\",\n    \"0x960aa7906e9a2f11db64a26b5892ac45f20d2ccb5480f4888d89973beb6fa0dfdc06d68d241ff5ffc7f1b82b1aac242d\",\n    \"0xa99365dcd1a00c66c9db6924b97c920f5c723380e823b250db85c07631b320ec4e92e586f7319e67a522a0578f7b6d6c\",\n    \"0xa25d92d7f70cf6a88ff317cfec071e13774516da664f5fac0d4ecaa65b8bf4eb87a64a4d5ef2bd97dfae98d388dbf5cc\",\n    \"0xa7af47cd0041295798f9779020a44653007444e8b4ef0712982b06d0dcdd434ec4e1f7c5f7a049326602cb605c9105b7\",\n    \"0xaefe172eac5568369a05980931cc476bebd9dea573ba276d59b9d8c4420784299df5a910033b7e324a6c2dfc62e3ef05\",\n    \"0xb69bc9d22ffa645baa55e3e02522e9892bb2daa7fff7c15846f13517d0799766883ee09ae0869df4139150c5b843ca8a\",\n    \"0x95a10856140e493354fdd12722c7fdded21b6a2ffbc78aa2697104af8ad0c8e2206f44b0bfee077ef3949d46bbf7c16b\",\n    \"0x891f2fcd2c47cbea36b7fa715968540c233313f05333f09d29aba23c193f462ed490dd4d00969656e89c53155fdfe710\",\n    \"0xa6c33e18115e64e385c843dde34e8a228222795c7ca90bc2cc085705d609025f3351d9be61822c69035a49fb3e48f2d5\",\n    \"0xb87fb12f12c0533b005adad0487f03393ff682e13575e3cb57280c3873b2c38ba96a63c49eef7a442753d26b7005230b\",\n    \"0xb905c02ba451bfd411c135036d92c27af3b0b1c9c2f1309d6948544a264b125f39dd41afeff4666b12146c545adc168a\",\n    \"0x8b29c513f43a78951cf742231cf5457a6d9d55edf45df5481a0f299a418d94effef561b15d2c1a01d1b8067e7153fda9\",\n    \"0xb9941cccd51dc645920d2781c81a317e5a33cb7cf76427b60396735912cb6d2ca9292bb4d36b6392467d390d2c58d9f3\",\n    \"0xa8546b627c76b6ef5c93c6a98538d8593dbe21cb7673fd383d5401b0c935eea0bdeeefeb1af6ad41bad8464fb87bbc48\",\n    \"0xaa286b27de2812de63108a1aec29d171775b69538dc6198640ac1e96767c2b83a50391f49259195957d457b493b667c9\",\n    \"0xa932fb229f641e9abbd8eb2bd874015d97b6658ab6d29769fc23b7db9e41dd4f850382d4c1f08af8f156c5937d524473\",\n    \"0xa1412840fcc86e2aeec175526f2fb36e8b3b8d21a78412b7266daf81e51b3f68584ed8bd42a66a43afdd8c297b320520\",\n    \"0x89c78be9efb624c97ebca4fe04c7704fa52311d183ffd87737f76b7dadc187c12c982bd8e9ed7cd8beb48cdaafd2fd01\",\n    \"0xa3f5ddec412a5bec0ce15e3bcb41c6214c2b05d4e9135a0d33c8e50a78eaba71e0a5a6ea8b45854dec5c2ed300971fc2\",\n    \"0x9721f9cec7a68b7758e3887548790de49fa6a442d0396739efa20c2f50352a7f91d300867556d11a703866def2d5f7b5\",\n    \"0xa23764e140a87e5991573521af039630dd28128bf56eed2edbed130fd4278e090b60cf5a1dca9de2910603d44b9f6d45\",\n    \"0xa1a6494a994215e48ab55c70efa8ffdddce6e92403c38ae7e8dd2f8288cad460c6c7db526bbdf578e96ca04d9fe12797\",\n    \"0xb1705ea4cb7e074efe0405fc7b8ee2ec789af0426142f3ec81241cacd4f7edcd88e39435e4e4d8e7b1df64f3880d6613\",\n    \"0x85595d061d677116089a6064418b93eb44ff79e68d12bd9625078d3bbc440a60d0b02944eff6054433ee34710ae6fbb4\",\n    \"0x9978d5e30bedb7526734f9a1febd973a70bfa20890490e7cc6f2f9328feab1e24f991285dbc3711d892514e2d7d005ad\",\n    \"0xaf30243c66ea43b9f87a061f947f7bce745f09194f6e95f379c7582b9fead920e5d6957eaf05c12ae1282ada4670652f\",\n    \"0xa1930efb473f88001e47aa0b2b2a7566848cccf295792e4544096ecd14ee5d7927c173a8576b405bfa2eec551cd67eb5\",\n    \"0xb0446d1c590ee5a45f7e22d269c044f3848c97aec1d226b44bfd0e94d9729c28a38bccddc3a1006cc5fe4e3c24f001f2\",\n    \"0xb8a8380172df3d84b06176df916cf557966d4f2f716d3e9437e415d75b646810f79f2b2b71d857181b7fc944018883a3\",\n    \"0xa563afec25b7817bfa26e19dc9908bc00aa8fc3d19be7d6de23648701659009d10e3e4486c28e9c6b13d48231ae29ac5\",\n    \"0xa5a8e80579de886fb7d6408f542791876885947b27ad6fa99a8a26e381f052598d7b4e647b0115d4b5c64297e00ce28e\",\n    \"0x8f87afcc7ad33c51ac719bade3cd92da671a37a82c14446b0a2073f4a0a23085e2c8d31913ed2d0be928f053297de8f6\",\n    \"0xa43c455ce377e0bc434386c53c752880687e017b2f5ae7f8a15c044895b242dffde4c92fb8f8bb50b18470b17351b156\",\n    \"0x8368f8b12a5bceb1dba25adb3a2e9c7dc9b1a77a1f328e5a693f5aec195cd1e06b0fe9476b554c1c25dac6c4a5b640a3\",\n    \"0x919878b27f3671fc78396f11531c032f3e2bd132d04cc234fa4858676b15fb1db3051c0b1db9b4fc49038216f11321ce\",\n    \"0xb48cd67fb7f1242696c1f877da4bdf188eac676cd0e561fbac1a537f7b8229aff5a043922441d603a26aae56a15faee4\",\n    \"0xa3e0fdfd4d29ea996517a16f0370b54787fefe543c2fe73bfc6f9e560c1fd30dad8409859e2d7fa2d44316f24746c712\",\n    \"0x8bb156ade8faf149df7bea02c140c7e392a4742ae6d0394d880a849127943e6f26312033336d3b9fdc0092d71b5efe87\",\n    \"0x8845e5d5cc555ca3e0523244300f2c8d7e4d02aaebcb5bd749d791208856c209a6f84dd99fd55968c9f0ab5f82916707\",\n    \"0xa3e90bb5c97b07789c2f32dff1aec61d0a2220928202f5ad5355ae71f8249237799d6c8a22602e32e572cb12eabe0c17\",\n    \"0xb150bcc391884c996149dc3779ce71f15dda63a759ee9cc05871f5a8379dcb62b047098922c0f26c7bd04deb394c33f9\",\n    \"0x95cd4ad88d51f0f2efcfd0c2df802fe252bb9704d1afbf9c26a248df22d55da87bdfaf41d7bc6e5df38bd848f0b13f42\",\n    \"0xa05a49a31e91dff6a52ac8b9c2cfdd646a43f0d488253f9e3cfbce52f26667166bbb9b608fc358763a65cbf066cd6d05\",\n    \"0xa59c3c1227fdd7c2e81f5e11ef5c406da44662987bac33caed72314081e2eed66055d38137e01b2268e58ec85dd986c0\",\n    \"0xb7020ec3bd73a99861f0f1d88cf5a19abab1cbe14b7de77c9868398c84bb8e18dbbe9831838a96b6d6ca06e82451c67b\",\n    \"0x98d1ff2525e9718ee59a21d8900621636fcd873d9a564b8dceb4be80a194a0148daf1232742730b3341514b2e5a5436c\",\n    \"0x886d97b635975fc638c1b6afc493e5998ca139edba131b75b65cfe5a8e814f11bb678e0eeee5e6e5cd913ad3f2fefdfc\",\n    \"0x8fb9fd928d38d5d813b671c924edd56601dd7163b686c13f158645c2f869d9250f3859aa5463a39258c90fef0f41190a\",\n    \"0xaac35e1cd655c94dec3580bb3800bd9c2946c4a9856f7d725af15fbea6a2d8ca51c8ad2772abed60ee0e3fb9cb24046b\",\n    \"0xb8d71fa0fa05ac9e443c9b4929df9e7f09a919be679692682e614d24227e04894bfc14a5c73a62fb927fedff4a0e4aa7\",\n    \"0xa45a19f11fbbb531a704badbb813ed8088ab827c884ee4e4ebf363fa1132ff7cfa9d28be9c85b143e4f7cdbc94e7cf1a\",\n    \"0x82b54703a4f295f5471b255ab59dce00f0fe90c9fb6e06b9ee48b15c91d43f4e2ef4a96c3118aeb03b08767be58181bb\",\n    \"0x8283264c8e6d2a36558f0d145c18576b6600ff45ff99cc93eca54b6c6422993cf392668633e5df396b9331e873d457e5\",\n    \"0x8c549c03131ead601bc30eb6b9537b5d3beb7472f5bb1bcbbfd1e9f3704477f7840ab3ab7f7dc13bbbbcdff886a462d4\",\n    \"0xafbb0c520ac1b5486513587700ad53e314cb74bfbc12e0b5fbdcfdaac36d342e8b59856196a0d84a25cff6e6e1d17e76\",\n    \"0x89e4c22ffb51f2829061b3c7c1983c5c750cad158e3a825d46f7cf875677da5d63f653d8a297022b5db5845c9271b32b\",\n    \"0xafb27a86c4c2373088c96b9adf4433f2ebfc78ac5c526e9f0510670b6e4e5e0057c0a4f75b185e1a30331b9e805c1c15\",\n    \"0xa18e16b57445f88730fc5d3567bf5a176861dc14c7a08ed2996fe80eed27a0e7628501bcb78a1727c5e9ac55f29c12c4\",\n    \"0x93d61bf88b192d6825cf4e1120af1c17aa0f994d158b405e25437eaeefae049f7b721a206e7cc8a04fdc29d3c42580a1\",\n    \"0xa99f2995a2e3ed2fd1228d64166112038de2f516410aa439f4c507044e2017ea388604e2d0f7121256fadf7fbe7023d1\",\n    \"0x914fd91cffc23c32f1c6d0e98bf660925090d873367d543034654389916f65f552e445b0300b71b61b721a72e9a5983c\",\n    \"0xb42a578a7787b71f924e7def425d849c1c777156b1d4170a8ee7709a4a914e816935131afd9a0412c4cb952957b20828\",\n    \"0x82fb30590e84b9e45db1ec475a39971cf554dc01bcc7050bc89265740725c02e2be5a972168c5170c86ae83e5b0ad2c0\",\n    \"0xb14f8d8e1e93a84976289e0cf0dfa6f3a1809e98da16ee5c4932d0e1ed6bf8a07697fdd4dd86a3df84fb0003353cdcc0\",\n    \"0x85d7a2f4bda31aa2cb208b771fe03291a4ebdaf6f1dc944c27775af5caec412584c1f45bc741fca2a6a85acb3f26ad7d\",\n    \"0xaf02e56ce886ff2253bc0a68faad76f25ead84b2144e5364f3fb9b648f03a50ee9dc0b2c33ebacf7c61e9e43201ef9ef\",\n    \"0x87e025558c8a0b0abd06dfc350016847ea5ced7af2d135a5c9eec9324a4858c4b21510fb0992ec52a73447f24945058e\",\n    \"0x80fff0bafcd058118f5e7a4d4f1ae0912efeb281d2cbe4d34ba8945cc3dbe5d8baf47fb077343b90b8d895c90b297aca\",\n    \"0xb6edcf3a40e7b1c3c0148f47a263cd819e585a51ef31c2e35a29ce6f04c53e413f743034c0d998d9c00a08ba00166f31\",\n    \"0xabb87ed86098c0c70a76e557262a494ff51a30fb193f1c1a32f8e35eafa34a43fcc07aa93a3b7a077d9e35afa07b1a3d\",\n    \"0xa280214cd3bb0fb7ecd2d8bcf518cbd9078417f2b91d2533ec2717563f090fb84f2a5fcfdbbeb2a2a1f8a71cc5aa5941\",\n    \"0xa63083ca7238ea2b57d15a475963cf1d4f550d8cd76db290014a0461b90351f1f26a67d674c837b0b773b330c7c3d534\",\n    \"0xa8fa39064cb585ece5263e2f42f430206476bf261bd50f18d2b694889bd79d04d56410664cecad62690e5c5a20b3f6ff\",\n    \"0x85ba52ce9d700a5dcf6c5b00559acbe599d671ce5512467ff4b6179d7fad550567ce2a9c126a50964e3096458ea87920\",\n    \"0xb913501e1008f076e5eac6d883105174f88b248e1c9801e568fefaffa1558e4909364fc6d9512aa4d125cbd7cc895f05\",\n    \"0x8eb33b5266c8f2ed4725a6ad147a322e44c9264cf261c933cbbe230a43d47fca0f29ec39756b20561dabafadd5796494\",\n    \"0x850ebc8b661a04318c9db5a0515066e6454fa73865aa4908767a837857ecd717387f614acb614a88e075d4edc53a2f5a\",\n    \"0xa08d6b92d866270f29f4ce23a3f5d99b36b1e241a01271ede02817c8ec3f552a5c562db400766c07b104a331835c0c64\",\n    \"0x8131804c89bb3e74e9718bfc4afa547c1005ff676bd4db9604335032b203390cfa54478d45c6c78d1fe31a436ed4be9f\",\n    \"0x9106d94f23cc1eacec8316f16d6f0a1cc160967c886f51981fdb9f3f12ee1182407d2bb24e5b873de58cb1a3ee915a6b\",\n    \"0xa13806bfc3eae7a7000c9d9f1bd25e10218d4e67f59ae798b145b098bca3edad2b1040e3fc1e6310e612fb8818f459ac\",\n    \"0x8c69fbca502046cb5f6db99900a47b34117aef3f4b241690cdb3b84ca2a2fc7833e149361995dc41fa78892525bce746\",\n    \"0x852c473150c91912d58ecb05769222fa18312800c3f56605ad29eec9e2d8667b0b81c379048d3d29100ed2773bb1f3c5\",\n    \"0xb1767f6074426a00e01095dbb1795beb4e4050c6411792cbad6537bc444c3165d1058bafd1487451f9c5ddd209e0ae7e\",\n    \"0x80c600a5fe99354ce59ff0f84c760923dc8ff66a30bf47dc0a086181785ceb01f9b951c4e66df800ea6d705e8bc47055\",\n    \"0xb5cf19002fbc88a0764865b82afcb4d64a50196ea361e5c71dff7de084f4dcbbc34ec94a45cc9e0247bd51da565981aa\",\n    \"0x93e67a254ea8ce25e112d93cc927fadaa814152a2c4ec7d9a56eaa1ed47aec99b7e9916b02e64452cc724a6641729bbb\",\n    \"0xace70b32491bda18eee4a4d041c3bc9effae9340fe7e6c2f5ad975ee0874c17f1a7da7c96bd85fccff9312c518fac6e9\",\n    \"0xab4cfa02065017dd7f1aadc66f2c92f78f0f11b8597c03a5d69d82cb2eaf95a4476a836ac102908f137662472c8d914b\",\n    \"0xa40b8cd8deb8ae503d20364d64cab7c2801b7728a9646ed19c65edea6a842756a2f636283494299584ad57f4bb12cd0b\",\n    \"0x8594e11d5fc2396bcd9dbf5509ce4816dbb2b7305168021c426171fb444d111da5a152d6835ad8034542277011c26c0e\",\n    \"0x8024de98c26b4c994a66628dc304bb737f4b6859c86ded552c5abb81fd4c6c2e19d5a30beed398a694b9b2fdea1dd06a\",\n    \"0x8843f5872f33f54df8d0e06166c1857d733995f67bc54abb8dfa94ad92407cf0179bc91b0a50bbb56cdc2b350d950329\",\n    \"0xb8bab44c7dd53ef9edf497dcb228e2a41282c90f00ba052fc52d57e87b5c8ab132d227af1fcdff9a12713d1f980bcaae\",\n    \"0x982b4d7b29aff22d527fd82d2a52601d95549bfb000429bb20789ed45e5abf1f4b7416c7b7c4b79431eb3574b29be658\",\n    \"0x8eb1f571b6a1878e11e8c1c757e0bc084bab5e82e897ca9be9b7f4b47b91679a8190bf0fc8f799d9b487da5442415857\",\n    \"0xa6e74b588e5af935c8b243e888582ef7718f8714569dd4992920740227518305eb35fab674d21a5551cca44b3e511ef2\",\n    \"0xa30fc2f3a4cb4f50566e82307de73cd7bd8fe2c1184e9293c136a9b9e926a018d57c6e4f308c95b9eb8299e94d90a2a1\",\n    \"0xa50c5869ca5d2b40722c056a32f918d47e0b65ca9d7863ca7d2fb4a7b64fe523fe9365cf0573733ceaadebf20b48fff8\",\n    \"0x83bbdd32c04d17581418cf360749c7a169b55d54f2427390defd9f751f100897b2d800ce6636c5bbc046c47508d60c8c\",\n    \"0xa82904bdf614de5d8deaff688c8a5e7ac5b3431687acbcda8fa53960b7c417a39c8b2e462d7af91ce6d79260f412db8e\",\n    \"0xa4362e31ff4b05d278b033cf5eebea20de01714ae16d4115d04c1da4754269873afc8171a6f56c5104bfd7b0db93c3e7\",\n    \"0xb5b8daa63a3735581e74a021b684a1038cea77168fdb7fdf83c670c2cfabcfc3ab2fc7359069b5f9048188351aef26b5\",\n    \"0xb48d723894b7782d96ac8433c48faca1bdfa5238019c451a7f47d958097cce3ae599b876cf274269236b9d6ff8b6d7ca\",\n    \"0x98ffff6a61a3a6205c7820a91ca2e7176fab5dba02bc194c4d14942ac421cb254183c705506ab279e4f8db066f941c6c\",\n    \"0xae7db24731da2eaa6efc4f7fcba2ecc26940ddd68038dce43acf2cee15b72dc4ef42a7bfdd32946d1ed78786dd7696b3\",\n    \"0xa656db14f1de9a7eb84f6301b4acb2fbf78bfe867f48a270e416c974ab92821eb4df1cb881b2d600cfed0034ac784641\",\n    \"0xaa315f8ecba85a5535e9a49e558b15f39520fce5d4bf43131bfbf2e2c9dfccc829074f9083e8d49f405fb221d0bc4c3c\",\n    \"0x90bffba5d9ff40a62f6c8e9fc402d5b95f6077ed58d030c93e321b8081b77d6b8dac3f63a92a7ddc01585cf2c127d66c\",\n    \"0xabdd733a36e0e0f05a570d0504e73801bf9b5a25ff2c78786f8b805704997acb2e6069af342538c581144d53149fa6d3\",\n    \"0xb4a723bb19e8c18a01bd449b1bb3440ddb2017f10bb153da27deb7a6a60e9bb37619d6d5435fbb1ba617687838e01dd0\",\n    \"0x870016b4678bab3375516db0187a2108b2e840bae4d264b9f4f27dbbc7cc9cac1d7dc582d7a04d6fd1ed588238e5e513\",\n    \"0x80d33d2e20e8fc170aa3cb4f69fffb72aeafb3b5bb4ea0bc79ab55da14142ca19b2d8b617a6b24d537366e3b49cb67c3\",\n    \"0xa7ee76aec273aaae03b3b87015789289551969fb175c11557da3ab77e39ab49d24634726f92affae9f4d24003050d974\",\n    \"0x8415ea4ab69d779ebd42d0fe0c6aef531d6a465a5739e429b1fcf433ec45aa8296c527e965a20f0ec9f340c9273ea3cf\",\n    \"0x8c7662520794e8b4405d0b33b5cac839784bc86a5868766c06cbc1fa306dbe334978177417b31baf90ce7b0052a29c56\",\n    \"0x902b2abecc053a3dbdea9897ee21e74821f3a1b98b2d560a514a35799f4680322550fd3a728d4f6d64e1de98033c32b8\",\n    \"0xa05e84ed9ecab8d508d670c39f2db61ad6e08d2795ec32a3c9d0d3737ef3801618f4fc2a95f90ec2f068606131e076c5\",\n    \"0x8b9208ff4d5af0c2e3f53c9375da666773ac57197dfabb0d25b1c8d0588ba7f3c15ee9661bb001297f322ea2fbf6928b\",\n    \"0xa3c827741b34a03254d4451b5ab74a96f2b9f7fb069e2f5adaf54fd97cc7a4d516d378db5ca07da87d8566d6eef13726\",\n    \"0x8509d8a3f4a0ed378e0a1e28ea02f6bf1d7f6c819c6c2f5297c7df54c895b848f841653e32ba2a2c22c2ff739571acb8\",\n    \"0xa0ce988b7d3c40b4e496aa83a09e4b5472a2d98679622f32bea23e6d607bc7de1a5374fb162bce0549a67dad948519be\",\n    \"0xaa8a3dd12bd60e3d2e05f9c683cdcb8eab17fc59134815f8d197681b1bcf65108cba63ac5c58ee632b1e5ed6bba5d474\",\n    \"0x8b955f1d894b3aefd883fb4b65f14cd37fc2b9db77db79273f1700bef9973bf3fd123897ea2b7989f50003733f8f7f21\",\n    \"0xac79c00ddac47f5daf8d9418d798d8af89fc6f1682e7e451f71ea3a405b0d36af35388dd2a332af790bc83ca7b819328\",\n    \"0xa0d44dd2a4438b809522b130d0938c3fe7c5c46379365dbd1810a170a9aa5818e1c783470dd5d0b6d4ac7edbb7330910\",\n    \"0xa30b69e39ad43dd540a43c521f05b51b5f1b9c4eed54b8162374ae11eac25da4f5756e7b70ce9f3c92c2eeceee7431ed\",\n    \"0xac43220b762c299c7951222ea19761ab938bf38e4972deef58ed84f4f9c68c230647cf7506d7cbfc08562fcca55f0485\",\n    \"0xb28233b46a8fb424cfa386a845a3b5399d8489ceb83c8f3e05c22c934798d639c93718b7b68ab3ce24c5358339e41cbb\",\n    \"0xac30d50ee8ce59a10d4b37a3a35e62cdb2273e5e52232e202ca7d7b8d09d28958ee667fae41a7bb6cdc6fe8f6e6c9c85\",\n    \"0xb199842d9141ad169f35cc7ff782b274cbaa645fdb727761e0a89edbf0d781a15f8218b4bf4eead326f2903dd88a9cc1\",\n    \"0x85e018c7ddcad34bb8285a737c578bf741ccd547e68c734bdb3808380e12c5d4ef60fc896b497a87d443ff9abd063b38\",\n    \"0x8c856e6ba4a815bdb891e1276f93545b7072f6cb1a9aa6aa5cf240976f29f4dee01878638500a6bf1daf677b96b54343\",\n    \"0xb8a47555fa8710534150e1a3f13eab33666017be6b41005397afa647ea49708565f2b86b77ad4964d140d9ced6b4d585\",\n    \"0x8cd1f1db1b2f4c85a3f46211599caf512d5439e2d8e184663d7d50166fd3008f0e9253272f898d81007988435f715881\",\n    \"0xb1f34b14612c973a3eceb716dc102b82ab18afef9de7630172c2780776679a7706a4874e1df3eaadf541fb009731807f\",\n    \"0xb25464af9cff883b55be2ff8daf610052c02df9a5e147a2cf4df6ce63edcdee6dc535c533590084cc177da85c5dc0baa\",\n    \"0x91c3c4b658b42d8d3448ae1415d4541d02379a40dc51e36a59bd6e7b9ba3ea51533f480c7c6e8405250ee9b96a466c29\",\n    \"0x86dc027b95deb74c36a58a1333a03e63cb5ae22d3b29d114cfd2271badb05268c9d0c819a977f5e0c6014b00c1512e3a\",\n    \"0xae0e6ff58eb5fa35da5107ebeacf222ab8f52a22bb1e13504247c1dfa65320f40d97b0e6b201cb6613476687cb2f0681\",\n    \"0x8f13415d960b9d7a1d93ef28afc2223e926639b63bdefce0f85e945dfc81670a55df288893a0d8b3abe13c5708f82f91\",\n    \"0x956f67ca49ad27c1e3a68c1faad5e7baf0160c459094bf6b7baf36b112de935fdfd79fa4a9ea87ea8de0ac07272969f4\",\n    \"0x835e45e4a67df9fb51b645d37840b3a15c171d571a10b03a406dd69d3c2f22df3aa9c5cbe1e73f8d767ce01c4914ea9a\",\n    \"0x919b938e56d4b32e2667469d0bdccb95d9dda3341aa907683ee70a14bbbe623035014511c261f4f59b318b610ac90aa3\",\n    \"0x96b48182121ccd9d689bf1dfdc228175564cd68dc904a99c808a7f0053a6f636c9d953e12198bdf2ea49ea92772f2e18\",\n    \"0xac5e5a941d567fa38fdbcfa8cf7f85bb304e3401c52d88752bcd516d1fa9bac4572534ea2205e38423c1df065990790f\",\n    \"0xac0bd594fb85a8d4fc26d6df0fa81f11919401f1ecf9168b891ec7f061a2d9368af99f7fd8d9b43b2ce361e7b8482159\",\n    \"0x83d92c69ca540d298fe80d8162a1c7af3fa9b49dfb69e85c1d136a3ec39fe419c9fa78e0bb6d96878771fbd37fe92e40\",\n    \"0xb35443ae8aa66c763c2db9273f908552fe458e96696b90e41dd509c17a5c04ee178e3490d9c6ba2dc0b8f793c433c134\",\n    \"0x923b2d25aa45b2e580ffd94cbb37dc8110f340f0f011217ee1bd81afb0714c0b1d5fb4db86006cdd2457563276f59c59\",\n    \"0x96c9125d38fca1a61ac21257b696f8ac3dae78def50285e44d90ea293d591d1c58f703540a7e4e99e070afe4646bbe15\",\n    \"0xb57946b2332077fbcdcb406b811779aefd54473b5559a163cd65cb8310679b7e2028aa55c12a1401fdcfcac0e6fae29a\",\n    \"0x845daedc5cf972883835d7e13c937b63753c2200324a3b8082a6c4abb4be06c5f7c629d4abe4bfaf1d80a1f073eb6ce6\",\n    \"0x91a55dfd0efefcd03dc6dacc64ec93b8d296cb83c0ee72400a36f27246e7f2a60e73b7b70ba65819e9cfb73edb7bd297\",\n    \"0x8874606b93266455fe8fdd25df9f8d2994e927460af06f2e97dd4d2d90db1e6b06d441b72c2e76504d753badca87fb37\",\n    \"0x8ee99e6d231274ff9252c0f4e84549da173041299ad1230929c3e3d32399731c4f20a502b4a307642cac9306ccd49d3c\",\n    \"0x8836497714a525118e20849d6933bb8535fb6f72b96337d49e3133d936999c90a398a740f42e772353b5f1c63581df6d\",\n    \"0xa6916945e10628f7497a6cdc5e2de113d25f7ade3e41e74d3de48ccd4fce9f2fa9ab69645275002e6f49399b798c40af\",\n    \"0x9597706983107eb23883e0812e1a2c58af7f3499d50c6e29b455946cb9812fde1aa323d9ed30d1c0ffd455abe32303cd\",\n    \"0xa24ee89f7f515cc33bdbdb822e7d5c1877d337f3b2162303cfc2dae028011c3a267c5cb4194afa63a4856a6e1c213448\",\n    \"0x8cd25315e4318801c2776824ae6e7d543cb85ed3bc2498ba5752df2e8142b37653cf9e60104d674be3aeb0a66912e97a\",\n    \"0xb5085ecbe793180b40dbeb879f4c976eaaccaca3a5246807dced5890e0ed24d35f3f86955e2460e14fb44ff5081c07ba\",\n    \"0x960188cc0b4f908633a6840963a6fa2205fc42c511c6c309685234911c5304ef4c304e3ae9c9c69daa2fb6a73560c256\",\n    \"0xa32d0a70bf15d569b4cda5aebe3e41e03c28bf99cdd34ffa6c5d58a097f322772acca904b3a47addb6c7492a7126ebac\",\n    \"0x977f72d06ad72d4aa4765e0f1f9f4a3231d9f030501f320fe7714cc5d329d08112789fa918c60dd7fdb5837d56bb7fc6\",\n    \"0x99fa038bb0470d45852bb871620d8d88520adb701712fcb1f278fed2882722b9e729e6cdce44c82caafad95e37d0e6f7\",\n    \"0xb855e8f4fc7634ada07e83b6c719a1e37acb06394bc8c7dcab7747a8c54e5df3943915f021364bd019fdea103864e55f\",\n    \"0x88bc2cd7458532e98c596ef59ea2cf640d7cc31b4c33cef9ed065c078d1d4eb49677a67de8e6229cc17ea48bace8ee5a\",\n    \"0xaaa78a3feaa836d944d987d813f9b9741afb076e6aca1ffa42682ab06d46d66e0c07b8f40b9dbd63e75e81efa1ef7b08\",\n    \"0xb7b080420cc4d808723b98b2a5b7b59c81e624ab568ecdfdeb8bf3aa151a581b6f56e983ef1b6f909661e25db40b0c69\",\n    \"0xabee85c462ac9a2c58e54f06c91b3e5cd8c5f9ab5b5deb602b53763c54826ed6deb0d6db315a8d7ad88733407e8d35e2\",\n    \"0x994d075c1527407547590df53e9d72dd31f037c763848d1662eebd4cefec93a24328c986802efa80e038cb760a5300f5\",\n    \"0xab8777640116dfb6678e8c7d5b36d01265dfb16321abbfc277da71556a34bb3be04bc4ae90124ed9c55386d2bfb3bda0\",\n    \"0x967e3a828bc59409144463bcf883a3a276b5f24bf3cbfdd7a42343348cba91e00b46ac285835a9b91eef171202974204\",\n    \"0x875a9f0c4ffe5bb1d8da5e3c8e41d0397aa6248422a628bd60bfae536a651417d4e8a7d2fb98e13f2dad3680f7bd86d3\",\n    \"0xacaa330c3e8f95d46b1880126572b238dbb6d04484d2cd4f257ab9642d8c9fc7b212188b9c7ac9e0fd135c520d46b1bf\",\n    \"0xaceb762edbb0f0c43dfcdb01ea7a1ac5918ca3882b1e7ebc4373521742f1ed5250d8966b498c00b2b0f4d13212e6dd0b\",\n    \"0x81d072b4ad258b3646f52f399bced97c613b22e7ad76373453d80b1650c0ca87edb291a041f8253b649b6e5429bb4cff\",\n    \"0x980a47d27416ac39c7c3a0ebe50c492f8c776ea1de44d5159ac7d889b6d554357f0a77f0e5d9d0ff41aae4369eba1fc2\",\n    \"0x8b4dfd5ef5573db1476d5e43aacfb5941e45d6297794508f29c454fe50ea622e6f068b28b3debe8635cf6036007de2e3\",\n    \"0xa60831559d6305839515b68f8c3bc7abbd8212cc4083502e19dd682d56ca37c9780fc3ce4ec2eae81ab23b221452dc57\",\n    \"0x951f6b2c1848ced9e8a2339c65918e00d3d22d3e59a0a660b1eca667d18f8430d737884e9805865ef3ed0fe1638a22d9\",\n    \"0xb02e38fe790b492aa5e89257c4986c9033a8b67010fa2add9787de857d53759170fdd67715ca658220b4e14b0ca48124\",\n    \"0xa51007e4346060746e6b0e4797fc08ef17f04a34fe24f307f6b6817edbb8ce2b176f40771d4ae8a60d6152cbebe62653\",\n    \"0xa510005b05c0b305075b27b243c9d64bcdce85146b6ed0e75a3178b5ff9608213f08c8c9246f2ca6035a0c3e31619860\",\n    \"0xaaff4ef27a7a23be3419d22197e13676d6e3810ceb06a9e920d38125745dc68a930f1741c9c2d9d5c875968e30f34ab5\",\n    \"0x864522a9af9857de9814e61383bebad1ba9a881696925a0ea6bfc6eff520d42c506bbe5685a9946ed710e889765be4a0\",\n    \"0xb63258c080d13f3b7d5b9f3ca9929f8982a6960bdb1b0f8676f4dca823971601672f15e653917bf5d3746bb220504913\",\n    \"0xb51ce0cb10869121ae310c7159ee1f3e3a9f8ad498827f72c3d56864808c1f21fa2881788f19ece884d3f705cd7bd0c5\",\n    \"0x95d9cecfc018c6ed510e441cf84c712d9909c778c16734706c93222257f64dcd2a9f1bd0b400ca271e22c9c487014274\",\n    \"0x8beff4d7d0140b86380ff4842a9bda94c2d2be638e20ac68a4912cb47dbe01a261857536375208040c0554929ced1ddc\",\n    \"0x891ff49258749e2b57c1e9b8e04b12c77d79c3308b1fb615a081f2aacdfb4b39e32d53e069ed136fdbd43c53b87418fa\",\n    \"0x9625cad224e163d387738825982d1e40eeff35fe816d10d7541d15fdc4d3eee48009090f3faef4024b249205b0b28f72\",\n    \"0x8f3947433d9bd01aa335895484b540a9025a19481a1c40b4f72dd676bfcf332713714fd4010bde936eaf9470fd239ed0\",\n    \"0xa00ec2d67789a7054b53f0e858a8a232706ccc29a9f3e389df7455f1a51a2e75801fd78469a13dbc25d28399ae4c6182\",\n    \"0xa3f65884506d4a62b8775a0ea0e3d78f5f46bc07910a93cd604022154eabdf1d73591e304d61edc869e91462951975e1\",\n    \"0xa14eef4fd5dfac311713f0faa9a60415e3d30b95a4590cbf95f2033dffb4d16c02e7ceff3dcd42148a4e3bc49cce2dd4\",\n    \"0x8afa11c0eef3c540e1e3460bc759bb2b6ea90743623f88e62950c94e370fe4fd01c22b6729beba4dcd4d581198d9358f\",\n    \"0xafb05548a69f0845ffcc5f5dc63e3cdb93cd270f5655173b9a950394b0583663f2b7164ba6df8d60c2e775c1d9f120af\",\n    \"0x97f179e01a947a906e1cbeafa083960bc9f1bade45742a3afee488dfb6011c1c6e2db09a355d77f5228a42ccaa7bdf8e\",\n    \"0x8447fca4d35f74b3efcbd96774f41874ca376bf85b79b6e66c92fa3f14bdd6e743a051f12a7fbfd87f319d1c6a5ce217\",\n    \"0xa57ca39c23617cd2cf32ff93b02161bd7baf52c4effb4679d9d5166406e103bc8f3c6b5209e17c37dbb02deb8bc72ddd\",\n    \"0x9667c7300ff80f0140be002b0e36caab07aaee7cce72679197c64d355e20d96196acaf54e06e1382167d081fe6f739c1\",\n    \"0x828126bb0559ce748809b622677267ca896fa2ee76360fd2c02990e6477e06a667241379ca7e65d61a5b64b96d7867de\",\n    \"0x8b8835dea6ba8cf61c91f01a4b3d2f8150b687a4ee09b45f2e5fc8f80f208ae5d142d8e3a18153f0722b90214e60c5a7\",\n    \"0xa98e8ff02049b4da386e3ee93db23bbb13dfeb72f1cfde72587c7e6d962780b7671c63e8ac3fbaeb1a6605e8d79e2f29\",\n    \"0x87a4892a0026d7e39ef3af632172b88337cb03669dea564bcdb70653b52d744730ebb5d642e20cb627acc9dbb547a26b\",\n    \"0x877352a22fc8052878a57effc159dac4d75fe08c84d3d5324c0bab6d564cdf868f33ceee515eee747e5856b62cfa0cc7\",\n    \"0x8b801ba8e2ff019ee62f64b8cb8a5f601fc35423eb0f9494b401050103e1307dc584e4e4b21249cd2c686e32475e96c3\",\n    \"0xa9e7338d6d4d9bfec91b2af28a8ed13b09415f57a3a00e5e777c93d768fdb3f8e4456ae48a2c6626b264226e911a0e28\",\n    \"0x99c05fedf40ac4726ed585d7c1544c6e79619a0d3fb6bda75a08c7f3c0008e8d5e19ed4da48de3216135f34a15eba17c\",\n    \"0xa61cce8a1a8b13a4a650fdbec0eeea8297c352a8238fb7cac95a0df18ed16ee02a3daa2de108fa122aca733bd8ad7855\",\n    \"0xb97f37da9005b440b4cb05870dd881bf8491fe735844f2d5c8281818583b38e02286e653d9f2e7fa5e74c3c3eb616540\",\n    \"0xa72164a8554da8e103f692ac5ebb4aece55d5194302b9f74b6f2a05335b6e39beede0bf7bf8c5bfd4d324a784c5fb08c\",\n    \"0xb87e8221c5341cd9cc8bb99c10fe730bc105550f25ed4b96c0d45e6142193a1b2e72f1b3857373a659b8c09be17b3d91\",\n    \"0xa41fb1f327ef91dcb7ac0787918376584890dd9a9675c297c45796e32d6e5985b12f9b80be47fc3a8596c245f419d395\",\n    \"0x90dafa3592bdbb3465c92e2a54c2531822ba0459d45d3e7a7092fa6b823f55af28357cb51896d4ec2d66029c82f08e26\",\n    \"0xa0a9adc872ebc396557f484f1dd21954d4f4a21c4aa5eec543f5fa386fe590839735c01f236574f7ff95407cd12de103\",\n    \"0xb8c5c940d58be7538acf8672852b5da3af34f82405ef2ce8e4c923f1362f97fc50921568d0fd2fe846edfb0823e62979\",\n    \"0x85aaf06a8b2d0dac89dafd00c28533f35dbd074978c2aaa5bef75db44a7b12aeb222e724f395513b9a535809a275e30b\",\n    \"0x81f3cbe82fbc7028c26a6c1808c604c63ba023a30c9f78a4c581340008dbda5ec07497ee849a2183fcd9124f7936af32\",\n    \"0xa11ac738de75fd60f15a34209d3825d5e23385796a4c7fc5931822f3f380af977dd0f7b59fbd58eed7777a071e21b680\",\n    \"0x85a279c493de03db6fa6c3e3c1b1b29adc9a8c4effc12400ae1128da8421954fa8b75ad19e5388fe4543b76fb0812813\",\n    \"0x83a217b395d59ab20db6c4adb1e9713fc9267f5f31a6c936042fe051ce8b541f579442f3dcf0fa16b9e6de9fd3518191\",\n    \"0x83a0b86e7d4ed8f9ccdc6dfc8ff1484509a6378fa6f09ed908e6ab9d1073f03011dc497e14304e4e3d181b57de06a5ab\",\n    \"0xa63ad69c9d25704ce1cc8e74f67818e5ed985f8f851afa8412248b2df5f833f83b95b27180e9e7273833ed0d07113d3b\",\n    \"0x99b1bc2021e63b561fe44ddd0af81fcc8627a91bfeecbbc989b642bc859abc0c8d636399701aad7bbaf6a385d5f27d61\",\n    \"0xb53434adb66f4a807a6ad917c6e856321753e559b1add70824e5c1e88191bf6993fccb9b8b911fc0f473fb11743acacd\",\n    \"0x97ed3b9e6fb99bf5f945d4a41f198161294866aa23f2327818cdd55cb5dc4c1a8eff29dd8b8d04902d6cd43a71835c82\",\n    \"0xb1e808260e368a18d9d10bdea5d60223ba1713b948c782285a27a99ae50cc5fc2c53d407de07155ecc16fb8a36d744a0\",\n    \"0xa3eb4665f18f71833fec43802730e56b3ee5a357ea30a888ad482725b169d6f1f6ade6e208ee081b2e2633079b82ba7d\",\n    \"0xab8beb2c8353fc9f571c18fdd02bdb977fc883313469e1277b0372fbbb33b80dcff354ca41de436d98d2ed710faa467e\",\n    \"0xaa9071cfa971e4a335a91ad634c98f2be51544cb21f040f2471d01bb97e1df2277ae1646e1ea8f55b7ba9f5c8c599b39\",\n    \"0x80b7dbfdcaf40f0678012acc634eba44ea51181475180d9deb2050dc4f2de395289edd0223018c81057ec79b04b04c49\",\n    \"0x89623d7f6cb17aa877af14de842c2d4ab7fd576d61ddd7518b5878620a01ded40b6010de0da3cdf31d837eecf30e9847\",\n    \"0xa773bb024ae74dd24761f266d4fb27d6fd366a8634febe8235376b1ae9065c2fe12c769f1d0407867dfbe9f5272c352f\",\n    \"0x8455a561c3aaa6ba64c881a5e13921c592b3a02e968f4fb24a2243c36202795d0366d9cc1a24e916f84d6e158b7aeac7\",\n    \"0x81d8bfc4b283cf702a40b87a2b96b275bdbf0def17e67d04842598610b67ea08c804d400c3e69fa09ea001eaf345b276\",\n    \"0xb8f8f82cb11fea1c99467013d7e167ff03deb0c65a677fab76ded58826d1ba29aa7cf9fcd7763615735ea3ad38e28719\",\n    \"0x89a6a04baf9cccc1db55179e1650b1a195dd91fb0aebc197a25143f0f393524d2589975e3fbfc2547126f0bced7fd6f2\",\n    \"0xb81b2162df045390f04df07cbd0962e6b6ca94275a63edded58001a2f28b2ae2af2c7a6cba4ecd753869684e77e7e799\",\n    \"0xa3757f722776e50de45c62d9c4a2ee0f5655a512344c4cbec542d8045332806568dd626a719ef21a4eb06792ca70f204\",\n    \"0x8c5590df96ec22179a4e8786de41beb44f987a1dcc508eb341eecbc0b39236fdfad47f108f852e87179ccf4e10091e59\",\n    \"0x87502f026ed4e10167419130b88c3737635c5b9074c364e1dd247cef5ef0fc064b4ae99b187e33301e438bbd2fe7d032\",\n    \"0xaf925a2165e980ced620ff12289129fe17670a90ae0f4db9d4b39bd887ccb1f5d2514ac9ecf910f6390a8fc66bd5be17\",\n    \"0x857fca899828cf5c65d26e3e8a6e658542782fc72762b3b9c73514919f83259e0f849a9d4838b40dc905fe43024d0d23\",\n    \"0x87ffebdbfb69a9e1007ebac4ffcb4090ff13705967b73937063719aa97908986effcb7262fdadc1ae0f95c3690e3245d\",\n    \"0xa9ff6c347ac6f4c6ab993b748802e96982eaf489dc69032269568412fc9a79e7c2850dfc991b28211b3522ee4454344b\",\n    \"0xa65b3159df4ec48bebb67cb3663cd744027ad98d970d620e05bf6c48f230fa45bf17527fe726fdf705419bb7a1bb913e\",\n    \"0x84b97b1e6408b6791831997b03cd91f027e7660fd492a93d95daafe61f02427371c0e237c75706412f442991dfdff989\",\n    \"0xab761c26527439b209af0ae6afccd9340bbed5fbe098734c3145b76c5d2cd7115d9227b2eb523882b7317fbb09180498\",\n    \"0xa0479a8da06d7a69c0b0fee60df4e691c19c551f5e7da286dab430bfbcabf31726508e20d26ea48c53365a7f00a3ad34\",\n    \"0xa732dfc9baa0f4f40b5756d2e8d8937742999623477458e0bc81431a7b633eefc6f53b3b7939fe0a020018549c954054\",\n    \"0x901502436a1169ba51dc479a5abe7c8d84e0943b16bc3c6a627b49b92cd46263c0005bc324c67509edd693f28e612af1\",\n    \"0xb627aee83474e7f84d1bab9b7f6b605e33b26297ac6bbf52d110d38ba10749032bd551641e73a383a303882367af429b\",\n    \"0x95108866745760baef4a46ef56f82da6de7e81c58b10126ebd2ba2cd13d339f91303bf2fb4dd104a6956aa3b13739503\",\n    \"0x899ed2ade37236cec90056f3569bc50f984f2247792defafcceb49ad0ca5f6f8a2f06573705300e07f0de0c759289ff5\",\n    \"0xa9f5eee196d608efe4bcef9bf71c646d27feb615e21252cf839a44a49fd89da8d26a758419e0085a05b1d59600e2dc42\",\n    \"0xb36c6f68fed6e6c85f1f4a162485f24817f2843ec5cbee45a1ebfa367d44892e464949c6669f7972dc7167af08d55d25\",\n    \"0xaaaede243a9a1b6162afbc8f571a52671a5a4519b4062e3f26777664e245ba873ed13b0492c5dbf0258c788c397a0e9e\",\n    \"0x972b4fb39c31cbe127bf9a32a5cc10d621ebdd9411df5e5da3d457f03b2ab2cd1f6372d8284a4a9400f0b06ecdbfd38e\",\n    \"0x8f6ca1e110e959a4b1d9a5ce5f212893cec21db40d64d5ac4d524f352d72198f923416a850bf845bc5a22a79c0ea2619\",\n    \"0xa0f3c93b22134f66f04b2553a53b738644d1665ceb196b8494b315a4c28236fb492017e4a0de4224827c78e42f9908b7\",\n    \"0x807fb5ee74f6c8735b0b5ca07e28506214fe4047dbeb00045d7c24f7849e98706aea79771241224939cb749cf1366c7d\",\n    \"0x915eb1ff034224c0b645442cdb7d669303fdc00ca464f91aaf0b6fde0b220a3a74ff0cb043c26c9f3a5667b3fdaa9420\",\n    \"0x8fda6cef56ed33fefffa9e6ac8e6f76b1af379f89761945c63dd448801f7bb8ca970504a7105fac2f74f652ccff32327\",\n    \"0x87380cffdcffb1d0820fa36b63cc081e72187f86d487315177d4d04da4533eb19a0e2ff6115ceab528887819c44a5164\",\n    \"0x8cd89e03411a18e7f16f968b89fb500c36d47d229f6487b99e62403a980058db5925ce249206743333538adfad168330\",\n    \"0x974451b1df33522ce7056de9f03e10c70bf302c44b0741a59df3d6877d53d61a7394dcee1dd46e013d7cb9d73419c092\",\n    \"0x98c35ddf645940260c490f384a49496a7352bb8e3f686feed815b1d38f59ded17b1ad6e84a209e773ed08f7b8ff1e4c2\",\n    \"0x963f386cf944bb9b2ddebb97171b64253ea0a2894ac40049bdd86cda392292315f3a3d490ca5d9628c890cfb669f0acb\",\n    \"0x8d507712152babd6d142ee682638da8495a6f3838136088df9424ef50d5ec28d815a198c9a4963610b22e49b4cdf95e9\",\n    \"0x83d4bc6b0be87c8a4f1e9c53f257719de0c73d85b490a41f7420e777311640937320557ff2f1d9bafd1daaa54f932356\",\n    \"0x82f5381c965b7a0718441131c4d13999f4cdce637698989a17ed97c8ea2e5bdb5d07719c5f7be8688edb081b23ede0f4\",\n    \"0xa6ebecab0b72a49dfd01d69fa37a7f74d34fb1d4fef0aa10e3d6fceb9eccd671225c230af89f6eb514250e41a5f91f52\",\n    \"0x846d185bdad6e11e604df7f753b7a08a28b643674221f0e750ebdb6b86ec584a29c869e131bca868972a507e61403f6a\",\n    \"0x85a98332292acb744bd1c0fd6fdcf1f889a78a2c9624d79413ffa194cc8dfa7821a4b60cde8081d4b5f71f51168dd67f\",\n    \"0x8f7d97c3b4597880d73200d074eb813d95432306e82dafc70b580b8e08cb8098b70f2d07b4b3ac6a4d77e92d57035031\",\n    \"0x8185439c8751e595825d7053518cbe121f191846a38d4dbcb558c3f9d7a3104f3153401adaaaf27843bbe2edb504bfe3\",\n    \"0xb3c00d8ece1518fca6b1215a139b0a0e26d9cba1b3a424f7ee59f30ce800a5db967279ed60958dd1f3ee69cf4dd1b204\",\n    \"0xa2e6cb6978e883f9719c3c0d44cfe8de0cc6f644b98f98858433bea8bbe7b612c8aca5952fccce4f195f9d54f9722dc2\",\n    \"0x99663087e3d5000abbec0fbda4e7342ec38846cc6a1505191fb3f1a337cb369455b7f8531a6eb8b0f7b2c4baf83cbe2b\",\n    \"0xab0836c6377a4dbc7ca6a4d6cf021d4cd60013877314dd05f351706b128d4af6337711ed3443cb6ca976f40d74070a9a\",\n    \"0x87abfd5126152fd3bac3c56230579b489436755ea89e0566aa349490b36a5d7b85028e9fb0710907042bcde6a6f5d7e3\",\n    \"0x974ba1033f75f60e0cf7c718a57ae1da3721cf9d0fb925714c46f027632bdd84cd9e6de4cf4d00bc55465b1c5ebb7384\",\n    \"0xa607b49d73689ac64f25cec71221d30d53e781e1100d19a2114a21da6507a60166166369d860bd314acb226596525670\",\n    \"0xa7c2b0b915d7beba94954f2aa7dd08ec075813661e2a3ecca5d28a0733e59583247fed9528eb28aba55b972cdbaf06eb\",\n    \"0xb8b3123e44128cc8efbe3270f2f94e50ca214a4294c71c3b851f8cbb70cb67fe9536cf07d04bf7fe380e5e3a29dd3c15\",\n    \"0xa59a07e343b62ad6445a0859a32b58c21a593f9ddbfe52049650f59628c93715aa1f4e1f45b109321756d0eeec8a5429\",\n    \"0x94f51f8a4ed18a6030d0aaa8899056744bd0e9dc9ac68f62b00355cddab11da5da16798db75f0bfbce0e5bdfe750c0b6\",\n    \"0x97460a97ca1e1fa5ce243b81425edc0ec19b7448e93f0b55bc9785eedeeafe194a3c8b33a61a5c72990edf375f122777\",\n    \"0x8fa859a089bc17d698a7ee381f37ce9beadf4e5b44fce5f6f29762bc04f96faff5d58c48c73631290325f05e9a1ecf49\",\n    \"0xabdf38f3b20fc95eff31de5aa9ef1031abfa48f1305ee57e4d507594570401503476d3bcc493838fc24d6967a3082c7f\",\n    \"0xb8914bfb82815abb86da35c64d39ab838581bc0bf08967192697d9663877825f2b9d6fbdcf9b410463482b3731361aef\",\n    \"0xa8187f9d22b193a5f578999954d6ec9aa9b32338ccadb8a3e1ce5bad5ea361d69016e1cdfac44e9d6c54e49dd88561b9\",\n    \"0xaac262cb7cba7fd62c14daa7b39677cabc1ef0947dd06dd89cac8570006a200f90d5f0353e84f5ff03179e3bebe14231\",\n    \"0xa630ef5ece9733b8c46c0a2df14a0f37647a85e69c63148e79ffdcc145707053f9f9d305c3f1cf3c7915cb46d33abd07\",\n    \"0xb102c237cb2e254588b6d53350dfda6901bd99493a3fbddb4121d45e0b475cf2663a40d7b9a75325eda83e4ba1e68cb3\",\n    \"0x86a930dd1ddcc16d1dfa00aa292cb6c2607d42c367e470aa920964b7c17ab6232a7108d1c2c11fc40fb7496547d0bbf8\",\n    \"0xa832fdc4500683e72a96cce61e62ac9ee812c37fe03527ad4cf893915ca1962cee80e72d4f82b20c8fc0b764376635a1\",\n    \"0x88ad985f448dabb04f8808efd90f273f11f5e6d0468b5489a1a6a3d77de342992a73eb842d419034968d733f101ff683\",\n    \"0x98a8538145f0d86f7fbf9a81c9140f6095c5bdd8960b1c6f3a1716428cd9cca1bf8322e6d0af24e6169abcf7df2b0ff6\",\n    \"0x9048c6eba5e062519011e177e955a200b2c00b3a0b8615bdecdebc217559d41058d3315f6d05617be531ef0f6aef0e51\",\n    \"0x833bf225ab6fc68cdcacf1ec1b50f9d05f5410e6cdcd8d56a3081dc2be8a8d07b81534d1ec93a25c2e270313dfb99e3b\",\n    \"0xa84bcd24c3da5e537e64a811b93c91bfc84d7729b9ead7f79078989a6eb76717d620c1fad17466a0519208651e92f5ff\",\n    \"0xb7cdd0a3fbd79aed93e1b5a44ca44a94e7af5ed911e4492f332e3a5ed146c7286bde01b52276a2fcc02780d2109874dd\",\n    \"0x8a19a09854e627cb95750d83c20c67442b66b35896a476358f993ba9ac114d32c59c1b3d0b8787ee3224cf3888b56c64\",\n    \"0xa9abd5afb8659ee52ada8fa5d57e7dd355f0a7350276f6160bec5fbf70d5f99234dd179eb221c913e22a49ec6d267846\",\n    \"0x8c13c4274c0d30d184e73eaf812200094bbbd57293780bdadbceb262e34dee5b453991e7f37c7333a654fc71c69d6445\",\n    \"0xa4320d73296ff8176ce0127ca1921c450e2a9c06eff936681ebaffb5a0b05b17fded24e548454de89aca2dcf6d7a9de4\",\n    \"0xb2b8b3e15c1f645f07783e5628aba614e60157889db41d8161d977606788842b67f83f361eae91815dc0abd84e09abd5\",\n    \"0xad26c3aa35ddfddc15719b8bb6c264aaec7065e88ac29ba820eb61f220fef451609a7bb037f3722d022e6c86e4f1dc88\",\n    \"0xb8615bf43e13ae5d7b8dd903ce37190800cd490f441c09b22aa29d7a29ed2c0417b7a08ead417868f1de2589deaadd80\",\n    \"0x8d3425e1482cd1e76750a76239d33c06b3554c3c3c87c15cb7ab58b1cee86a4c5c4178b44e23f36928365a1b484bde02\",\n    \"0x806893a62e38c941a7dd6f249c83af16596f69877cc737d8f73f6b8cd93cbc01177a7a276b2b8c6b0e5f2ad864db5994\",\n    \"0x86618f17fa4b0d65496b661bbb5ba3bc3a87129d30a4b7d4f515b904f4206ca5253a41f49fd52095861e5e065ec54f21\",\n    \"0x9551915da1304051e55717f4c31db761dcdcf3a1366c89a4af800a9e99aca93a357bf928307f098e62b44a02cb689a46\",\n    \"0x8f79c4ec0ec1146cb2a523b52fe33def90d7b5652a0cb9c2d1c8808a32293e00aec6969f5b1538e3a94cd1efa3937f86\",\n    \"0xa0c03e329a707300081780f1e310671315b4c6a4cedcb29697aedfabb07a9d5df83f27b20e9c44cf6b16e39d9ded5b98\",\n    \"0x86a7cfa7c8e7ce2c01dd0baec2139e97e8e090ad4e7b5f51518f83d564765003c65968f85481bbb97cb18f005ccc7d9f\",\n    \"0xa33811770c6dfda3f7f74e6ad0107a187fe622d61b444bbd84fd7ef6e03302e693b093df76f6ab39bb4e02afd84a575a\",\n    \"0x85480f5c10d4162a8e6702b5e04f801874d572a62a130be94b0c02b58c3c59bdcd48cd05f0a1c2839f88f06b6e3cd337\",\n    \"0x8e181011564b17f7d787fe0e7f3c87f6b62da9083c54c74fd6c357a1f464c123c1d3d8ade3cf72475000b464b14e2be3\",\n    \"0x8ee178937294b8c991337e0621ab37e9ffa4ca2bdb3284065c5e9c08aad6785d50cf156270ff9daf9a9127289710f55b\",\n    \"0x8bd1e8e2d37379d4b172f1aec96f2e41a6e1393158d7a3dbd9a95c8dd4f8e0b05336a42efc11a732e5f22b47fc5c271d\",\n    \"0x8f3da353cd487c13136a85677de8cedf306faae0edec733cf4f0046f82fa4639db4745b0095ff33a9766aba50de0cbcf\",\n    \"0x8d187c1e97638df0e4792b78e8c23967dac43d98ea268ca4aabea4e0fa06cb93183fd92d4c9df74118d7cc27bf54415e\",\n    \"0xa4c992f08c2f8bac0b74b3702fb0c75c9838d2ce90b28812019553d47613c14d8ce514d15443159d700b218c5a312c49\",\n    \"0xa6fd1874034a34c3ea962a316c018d9493d2b3719bb0ec4edbc7c56b240802b2228ab49bee6f04c8a3e9f6f24a48c1c2\",\n    \"0xb2efed8e799f8a15999020900dc2c58ece5a3641c90811b86a5198e593d7318b9d53b167818ccdfbe7df2414c9c34011\",\n    \"0x995ff7de6181ddf95e3ead746089c6148da3508e4e7a2323c81785718b754d356789b902e7e78e2edc6b0cbd4ff22c78\",\n    \"0x944073d24750a9068cbd020b834afc72d2dde87efac04482b3287b40678ad07588519a4176b10f2172a2c463d063a5cd\",\n    \"0x99db4b1bb76475a6fd75289986ef40367960279524378cc917525fb6ba02a145a218c1e9caeb99332332ab486a125ac0\",\n    \"0x89fce4ecd420f8e477af4353b16faabb39e063f3f3c98fde2858b1f2d1ef6eed46f0975a7c08f233b97899bf60ccd60a\",\n    \"0x8c09a4f07a02b80654798bc63aada39fd638d3e3c4236ccd8a5ca280350c31e4a89e5f4c9aafb34116e71da18c1226b8\",\n    \"0x85325cfa7ded346cc51a2894257eab56e7488dbff504f10f99f4cd2b630d913003761a50f175ed167e8073f1b6b63fb0\",\n    \"0xb678b4fbec09a8cc794dcbca185f133578f29e354e99c05f6d07ac323be20aecb11f781d12898168e86f2e0f09aca15e\",\n    \"0xa249cfcbca4d9ba0a13b5f6aac72bf9b899adf582f9746bb2ad043742b28915607467eb794fca3704278f9136f7642be\",\n    \"0x9438e036c836a990c5e17af3d78367a75b23c37f807228362b4d13e3ddcb9e431348a7b552d09d11a2e9680704a4514f\",\n    \"0x925ab70450af28c21a488bfb5d38ac994f784cf249d7fd9ad251bb7fd897a23e23d2528308c03415074d43330dc37ef4\",\n    \"0xa290563904d5a8c0058fc8330120365bdd2ba1fdbaef7a14bc65d4961bb4217acfaed11ab82669e359531f8bf589b8db\",\n    \"0xa7e07a7801b871fc9b981a71e195a3b4ba6b6313bc132b04796a125157e78fe5c11a3a46cf731a255ac2d78a4ae78cd0\",\n    \"0xb26cd2501ee72718b0eebab6fb24d955a71f363f36e0f6dff0ab1d2d7836dab88474c0cef43a2cc32701fca7e82f7df3\",\n    \"0xa1dc3b6c968f3de00f11275092290afab65b2200afbcfa8ddc70e751fa19dbbc300445d6d479a81bda3880729007e496\",\n    \"0xa9bc213e28b630889476a095947d323b9ac6461dea726f2dc9084473ae8e196d66fb792a21905ad4ec52a6d757863e7d\",\n    \"0xb25d178df8c2df8051e7c888e9fa677fde5922e602a95e966db9e4a3d6b23ce043d7dc48a5b375c6b7c78e966893e8c3\",\n    \"0xa1c8d88d72303692eaa7adf68ea41de4febec40cc14ae551bb4012afd786d7b6444a3196b5d9d5040655a3366d96b7cd\",\n    \"0xb22bd44f9235a47118a9bbe2ba5a2ba9ec62476061be2e8e57806c1a17a02f9a51403e849e2e589520b759abd0117683\",\n    \"0xb8add766050c0d69fe81d8d9ea73e1ed05f0135d093ff01debd7247e42dbb86ad950aceb3b50b9af6cdc14ab443b238f\",\n    \"0xaf2cf95f30ef478f018cf81d70d47d742120b09193d8bb77f0d41a5d2e1a80bfb467793d9e2471b4e0ad0cb2c3b42271\",\n    \"0x8af5ef2107ad284e246bb56e20fef2a255954f72de791cbdfd3be09f825298d8466064f3c98a50496c7277af32b5c0bc\",\n    \"0x85dc19558572844c2849e729395a0c125096476388bd1b14fa7f54a7c38008fc93e578da3aac6a52ff1504d6ca82db05\",\n    \"0xae8c9b43c49572e2e166d704caf5b4b621a3b47827bb2a3bcd71cdc599bba90396fd9a405261b13e831bb5d44c0827d7\",\n    \"0xa7ba7efede25f02e88f6f4cbf70643e76784a03d97e0fbd5d9437c2485283ad7ca3abb638a5f826cd9f6193e5dec0b6c\",\n    \"0x94a9d122f2f06ef709fd8016fd4b712d88052245a65a301f5f177ce22992f74ad05552b1f1af4e70d1eac62cef309752\",\n    \"0x82d999b3e7cf563833b8bc028ff63a6b26eb357dfdb3fd5f10e33a1f80a9b2cfa7814d871b32a7ebfbaa09e753e37c02\",\n    \"0xaec6edcde234df502a3268dd2c26f4a36a2e0db730afa83173f9c78fcb2b2f75510a02b80194327b792811caefda2725\",\n    \"0x94c0bfa66c9f91d462e9194144fdd12d96f9bbe745737e73bab8130607ee6ea9d740e2cfcbbd00a195746edb6369ee61\",\n    \"0xab7573dab8c9d46d339e3f491cb2826cabe8b49f85f1ede78d845fc3995537d1b4ab85140b7d0238d9c24daf0e5e2a7e\",\n    \"0x87e8b16832843251fe952dadfd01d41890ed4bb4b8fa0254550d92c8cced44368225eca83a6c3ad47a7f81ff8a80c984\",\n    \"0x9189d2d9a7c64791b19c0773ad4f0564ce6bea94aa275a917f78ad987f150fdb3e5e26e7fef9982ac184897ecc04683f\",\n    \"0xb3661bf19e2da41415396ae4dd051a9272e8a2580b06f1a1118f57b901fa237616a9f8075af1129af4eabfefedbe2f1c\",\n    \"0xaf43c86661fb15daf5d910a4e06837225e100fb5680bd3e4b10f79a2144c6ec48b1f8d6e6b98e067d36609a5d038889a\",\n    \"0x82ac0c7acaa83ddc86c5b4249aae12f28155989c7c6b91e5137a4ce05113c6cbc16f6c44948b0efd8665362d3162f16a\",\n    \"0x8f268d1195ab465beeeb112cd7ffd5d5548559a8bc01261106d3555533fc1971081b25558d884d552df0db1cddda89d8\",\n    \"0x8ef7caa5521f3e037586ce8ac872a4182ee20c7921c0065ed9986c047e3dda08294da1165f385d008b40d500f07d895f\",\n    \"0x8c2f98f6880550573fad46075d3eba26634b5b025ce25a0b4d6e0193352c8a1f0661064027a70fe8190b522405f9f4e3\",\n    \"0xb7653f353564feb164f0f89ec7949da475b8dad4a4d396d252fc2a884f6932d027b7eb2dc4d280702c74569319ed701a\",\n    \"0xa026904f4066333befd9b87a8fad791d014096af60cdd668ef919c24dbe295ff31f7a790e1e721ba40cf5105abca67f4\",\n    \"0x988f982004ada07a22dd345f2412a228d7a96b9cae2c487de42e392afe1e35c2655f829ce07a14629148ce7079a1f142\",\n    \"0x9616add009067ed135295fb74d5b223b006b312bf14663e547a0d306694ff3a8a7bb9cfc466986707192a26c0bce599f\",\n    \"0xad4c425de9855f6968a17ee9ae5b15e0a5b596411388cf976df62ecc6c847a6e2ddb2cea792a5f6e9113c2445dba3e5c\",\n    \"0xb698ac9d86afa3dc69ff8375061f88e3b0cff92ff6dfe747cebaf142e813c011851e7a2830c10993b715e7fd594604a9\",\n    \"0xa386fa189847bb3b798efca917461e38ead61a08b101948def0f82cd258b945ed4d45b53774b400af500670149e601b7\",\n    \"0x905c95abda2c68a6559d8a39b6db081c68cef1e1b4be63498004e1b2f408409be9350b5b5d86a30fd443e2b3e445640a\",\n    \"0x9116dade969e7ce8954afcdd43e5cab64dc15f6c1b8da9d2d69de3f02ba79e6c4f6c7f54d6bf586d30256ae405cd1e41\",\n    \"0xa3084d173eacd08c9b5084a196719b57e47a0179826fda73466758235d7ecdb87cbcf097bd6b510517d163a85a7c7edd\",\n    \"0x85bb00415ad3c9be99ff9ba83672cc59fdd24356b661ab93713a3c8eab34e125d8867f628a3c3891b8dc056e69cd0e83\",\n    \"0x8d58541f9f39ed2ee4478acce5d58d124031338ec11b0d55551f00a5a9a6351faa903a5d7c132dc5e4bb026e9cbd18e4\",\n    \"0xa622adf72dc250e54f672e14e128c700166168dbe0474cecb340da175346e89917c400677b1bc1c11fcc4cc26591d9db\",\n    \"0xb3f865014754b688ca8372e8448114fff87bf3ca99856ab9168894d0c4679782c1ced703f5b74e851b370630f5e6ee86\",\n    \"0xa7e490b2c40c2446fcd91861c020da9742c326a81180e38110558bb5d9f2341f1c1885e79b364e6419023d1cbdc47380\",\n    \"0xb3748d472b1062e54572badbb8e87ac36534407f74932e7fc5b8392d008e8e89758f1671d1e4d30ab0fa40551b13bb5e\",\n    \"0x89898a5c5ec4313aabc607b0049fd1ebad0e0c074920cf503c9275b564d91916c2c446d3096491c950b7af3ac5e4b0ed\",\n    \"0x8eb8c83fef2c9dd30ea44e286e9599ec5c20aba983f702e5438afe2e5b921884327ad8d1566c72395587efac79ca7d56\",\n    \"0xb92479599e806516ce21fb0bd422a1d1d925335ebe2b4a0a7e044dd275f30985a72b97292477053ac5f00e081430da80\",\n    \"0xa34ae450a324fe8a3c25a4d653a654f9580ed56bbea213b8096987bbad0f5701d809a17076435e18017fea4d69f414bc\",\n    \"0x81381afe6433d62faf62ea488f39675e0091835892ecc238e02acf1662669c6d3962a71a3db652f6fe3bc5f42a0e5dc5\",\n    \"0xa430d475bf8580c59111103316fe1aa79c523ea12f1d47a976bbfae76894717c20220e31cf259f08e84a693da6688d70\",\n    \"0xb842814c359754ece614deb7d184d679d05d16f18a14b288a401cef5dad2cf0d5ee90bad487b80923fc5573779d4e4e8\",\n    \"0x971d9a2627ff2a6d0dcf2af3d895dfbafca28b1c09610c466e4e2bff2746f8369de7f40d65b70aed135fe1d72564aa88\",\n    \"0x8f4ce1c59e22b1ce7a0664caaa7e53735b154cfba8d2c5cc4159f2385843de82ab58ed901be876c6f7fce69cb4130950\",\n    \"0x86cc9dc321b6264297987000d344fa297ef45bcc2a4df04e458fe2d907ad304c0ea2318e32c3179af639a9a56f3263cf\",\n    \"0x8229e0876dfe8f665c3fb19b250bd89d40f039bbf1b331468b403655be7be2e104c2fd07b9983580c742d5462ca39a43\",\n    \"0x99299d73066e8eb128f698e56a9f8506dfe4bd014931e86b6b487d6195d2198c6c5bf15cccb40ccf1f8ddb57e9da44a2\",\n    \"0xa3a3be37ac554c574b393b2f33d0a32a116c1a7cfeaf88c54299a4da2267149a5ecca71f94e6c0ef6e2f472b802f5189\",\n    \"0xa91700d1a00387502cdba98c90f75fbc4066fefe7cc221c8f0e660994c936badd7d2695893fde2260c8c11d5bdcdd951\",\n    \"0x8e03cae725b7f9562c5c5ab6361644b976a68bada3d7ca508abca8dfc80a469975689af1fba1abcf21bc2a190dab397d\",\n    \"0xb01461ad23b2a8fa8a6d241e1675855d23bc977dbf4714add8c4b4b7469ccf2375cec20e80cedfe49361d1a30414ac5b\",\n    \"0xa2673bf9bc621e3892c3d7dd4f1a9497f369add8cbaa3472409f4f86bd21ac67cfac357604828adfee6ada1835365029\",\n    \"0xa042dff4bf0dfc33c178ba1b335e798e6308915128de91b12e5dbbab7c4ac8d60a01f6aea028c3a6d87b9b01e4e74c01\",\n    \"0x86339e8a75293e4b3ae66b5630d375736b6e6b6b05c5cda5e73fbf7b2f2bd34c18a1d6cefede08625ce3046e77905cb8\",\n    \"0xaf2ebe1b7d073d03e3d98bc61af83bf26f7a8c130fd607aa92b75db22d14d016481b8aa231e2c9757695f55b7224a27f\",\n    \"0xa00ee882c9685e978041fd74a2c465f06e2a42ffd3db659053519925be5b454d6f401e3c12c746e49d910e4c5c9c5e8c\",\n    \"0x978a781c0e4e264e0dad57e438f1097d447d891a1e2aa0d5928f79a9d5c3faae6f258bc94fdc530b7b2fa6a9932bb193\",\n    \"0xaa4b7ce2e0c2c9e9655bf21e3e5651c8503bce27483017b0bf476be743ba06db10228b3a4c721219c0779747f11ca282\",\n    \"0xb003d1c459dacbcf1a715551311e45d7dbca83a185a65748ac74d1800bbeaba37765d9f5a1a221805c571910b34ebca8\",\n    \"0x95b6e531b38648049f0d19de09b881baa1f7ea3b2130816b006ad5703901a05da57467d1a3d9d2e7c73fb3f2e409363c\",\n    \"0xa6cf9c06593432d8eba23a4f131bb7f72b9bd51ab6b4b772a749fe03ed72b5ced835a349c6d9920dba2a39669cb7c684\",\n    \"0xaa3d59f6e2e96fbb66195bc58c8704e139fa76cd15e4d61035470bd6e305db9f98bcbf61ac1b95e95b69ba330454c1b3\",\n    \"0xb57f97959c208361de6d7e86dff2b873068adb0f158066e646f42ae90e650079798f165b5cd713141cd3a2a90a961d9a\",\n    \"0xa76ee8ed9052f6a7a8c69774bb2597be182942f08115baba03bf8faaeaee526feba86120039fe8ca7b9354c3b6e0a8e6\",\n    \"0x95689d78c867724823f564627d22d25010f278674c6d2d0cdb10329169a47580818995d1d727ce46c38a1e47943ebb89\",\n    \"0xab676d2256c6288a88e044b3d9ffd43eb9d5aaee00e8fc60ac921395fb835044c71a26ca948e557fed770f52d711e057\",\n    \"0x96351c72785c32e5d004b6f4a1259fb8153d631f0c93fed172f18e8ba438fbc5585c1618deeabd0d6d0b82173c2e6170\",\n    \"0x93dd8d3db576418e22536eba45ab7f56967c6c97c64260d6cddf38fb19c88f2ec5cd0e0156f50e70855eee8a2b879ffd\",\n    \"0xad6ff16f40f6de3d7a737f8e6cebd8416920c4ff89dbdcd75eabab414af9a6087f83ceb9aff7680aa86bff98bd09c8cc\",\n    \"0x84de53b11671abc9c38710e19540c5c403817562aeb22a88404cdaff792c1180f717dbdfe8f54940c062c4d032897429\",\n    \"0x872231b9efa1cdd447b312099a5c164c560440a9441d904e70f5abfc3b2a0d16be9a01aca5e0a2599a61e19407587e3d\",\n    \"0x88f44ac27094a2aa14e9dc40b099ee6d68f97385950f303969d889ee93d4635e34dff9239103bdf66a4b7cbba3e7eb7a\",\n    \"0xa59afebadf0260e832f6f44468443562f53fbaf7bcb5e46e1462d3f328ac437ce56edbca617659ac9883f9e13261fad7\",\n    \"0xb1990e42743a88de4deeacfd55fafeab3bc380cb95de43ed623d021a4f2353530bcab9594389c1844b1c5ea6634c4555\",\n    \"0x85051e841149a10e83f56764e042182208591396d0ce78c762c4a413e6836906df67f38c69793e158d64fef111407ba3\",\n    \"0x9778172bbd9b1f2ec6bbdd61829d7b39a7df494a818e31c654bf7f6a30139899c4822c1bf418dd4f923243067759ce63\",\n    \"0x9355005b4878c87804fc966e7d24f3e4b02bed35b4a77369d01f25a3dcbff7621b08306b1ac85b76fe7b4a3eb5f839b1\",\n    \"0x8f9dc6a54fac052e236f8f0e1f571ac4b5308a43acbe4cc8183bce26262ddaf7994e41cf3034a4cbeca2c505a151e3b1\",\n    \"0x8cc59c17307111723fe313046a09e0e32ea0cce62c13814ab7c6408c142d6a0311d801be4af53fc9240523f12045f9ef\",\n    \"0x8e6057975ed40a1932e47dd3ac778f72ee2a868d8540271301b1aa6858de1a5450f596466494a3e0488be4fbeb41c840\",\n    \"0x812145efbd6559ae13325d56a15940ca4253b17e72a9728986b563bb5acc13ec86453796506ac1a8f12bd6f9e4a288c3\",\n    \"0x911da0a6d6489eb3dab2ec4a16e36127e8a291ae68a6c2c9de33e97f3a9b1f00da57a94e270a0de79ecc5ecb45d19e83\",\n    \"0xb72ea85973f4b2a7e6e71962b0502024e979a73c18a9111130e158541fa47bbaaf53940c8f846913a517dc69982ba9e1\",\n    \"0xa7a56ad1dbdc55f177a7ad1d0af78447dc2673291e34e8ab74b26e2e2e7d8c5fe5dc89e7ef60f04a9508847b5b3a8188\",\n    \"0xb52503f6e5411db5d1e70f5fb72ccd6463fa0f197b3e51ca79c7b5a8ab2e894f0030476ada72534fa4eb4e06c3880f90\",\n    \"0xb51c7957a3d18c4e38f6358f2237b3904618d58b1de5dec53387d25a63772e675a5b714ad35a38185409931157d4b529\",\n    \"0xb86b4266e719d29c043d7ec091547aa6f65bbf2d8d831d1515957c5c06513b72aa82113e9645ad38a7bc3f5383504fa6\",\n    \"0xb95b547357e6601667b0f5f61f261800a44c2879cf94e879def6a105b1ad2bbf1795c3b98a90d588388e81789bd02681\",\n    \"0xa58fd4c5ae4673fa350da6777e13313d5d37ed1dafeeb8f4f171549765b84c895875d9d3ae6a9741f3d51006ef81d962\",\n    \"0x9398dc348d078a604aadc154e6eef2c0be1a93bb93ba7fe8976edc2840a3a318941338cc4d5f743310e539d9b46613d2\",\n    \"0x902c9f0095014c4a2f0dccaaab543debba6f4cc82c345a10aaf4e72511725dbed7a34cd393a5f4e48a3e5142b7be84ed\",\n    \"0xa7c0447849bb44d04a0393a680f6cd390093484a79a147dd238f5d878030d1c26646d88211108e59fe08b58ad20c6fbd\",\n    \"0x80db045535d6e67a422519f5c89699e37098449d249698a7cc173a26ccd06f60238ae6cc7242eb780a340705c906790c\",\n    \"0x8e52b451a299f30124505de2e74d5341e1b5597bdd13301cc39b05536c96e4380e7f1b5c7ef076f5b3005a868657f17c\",\n    \"0x824499e89701036037571761e977654d2760b8ce21f184f2879fda55d3cda1e7a95306b8abacf1caa79d3cc075b9d27f\",\n    \"0x9049b956b77f8453d2070607610b79db795588c0cec12943a0f5fe76f358dea81e4f57a4692112afda0e2c05c142b26f\",\n    \"0x81911647d818a4b5f4990bfd4bc13bf7be7b0059afcf1b6839333e8569cdb0172fd2945410d88879349f677abaed5eb3\",\n    \"0xad4048f19b8194ed45b6317d9492b71a89a66928353072659f5ce6c816d8f21e69b9d1817d793effe49ca1874daa1096\",\n    \"0x8d22f7b2ddb31458661abd34b65819a374a1f68c01fc6c9887edeba8b80c65bceadb8f57a3eb686374004b836261ef67\",\n    \"0x92637280c259bc6842884db3d6e32602a62252811ae9b019b3c1df664e8809ffe86db88cfdeb8af9f46435c9ee790267\",\n    \"0xa2f416379e52e3f5edc21641ea73dc76c99f7e29ea75b487e18bd233856f4c0183429f378d2bfc6cd736d29d6cadfa49\",\n    \"0x882cb6b76dbdc188615dcf1a8439eba05ffca637dd25197508156e03c930b17b9fed2938506fdd7b77567cb488f96222\",\n    \"0xb68b621bb198a763fb0634eddb93ed4b5156e59b96c88ca2246fd1aea3e6b77ed651e112ac41b30cd361fadc011d385e\",\n    \"0xa3cb22f6b675a29b2d1f827cacd30df14d463c93c3502ef965166f20d046af7f9ab7b2586a9c64f4eae4fad2d808a164\",\n    \"0x8302d9ce4403f48ca217079762ce42cee8bc30168686bb8d3a945fbd5acd53b39f028dce757b825eb63af2d5ae41169d\",\n    \"0xb2eef1fbd1a176f1f4cd10f2988c7329abe4eb16c7405099fb92baa724ab397bc98734ef7d4b24c0f53dd90f57520d04\",\n    \"0xa1bbef0bd684a3f0364a66bde9b29326bac7aa3dde4caed67f14fb84fed3de45c55e406702f1495a3e2864d4ee975030\",\n    \"0x976acdb0efb73e3a3b65633197692dedc2adaed674291ae3df76b827fc866d214e9cac9ca46baefc4405ff13f953d936\",\n    \"0xb9fbf71cc7b6690f601f0b1c74a19b7d14254183a2daaafec7dc3830cba5ae173d854bbfebeca985d1d908abe5ef0cda\",\n    \"0x90591d7b483598c94e38969c4dbb92710a1a894bcf147807f1bcbd8aa3ac210b9f2be65519aa829f8e1ccdc83ad9b8cf\",\n    \"0xa30568577c91866b9c40f0719d46b7b3b2e0b4a95e56196ac80898a2d89cc67880e1229933f2cd28ee3286f8d03414d7\",\n    \"0x97589a88c3850556b359ec5e891f0937f922a751ac7c95949d3bbc7058c172c387611c0f4cb06351ef02e5178b3dd9e4\",\n    \"0x98e7bbe27a1711f4545df742f17e3233fbcc63659d7419e1ca633f104cb02a32c84f2fac23ca2b84145c2672f68077ab\",\n    \"0xa7ddb91636e4506d8b7e92aa9f4720491bb71a72dadc47c7f4410e15f93e43d07d2b371951a0e6a18d1bd087aa96a5c4\",\n    \"0xa7c006692227a06db40bceac3d5b1daae60b5692dd9b54772bedb5fea0bcc91cbcdb530cac31900ffc70c5b3ffadc969\",\n    \"0x8d3ec6032778420dfa8be52066ba0e623467df33e4e1901dbadd586c5d750f4ccde499b5197e26b9ea43931214060f69\",\n    \"0x8d9a8410518ea64f89df319bfd1fc97a0971cdb9ad9b11d1f8fe834042ea7f8dce4db56eeaf179ff8dda93b6db93e5ce\",\n    \"0xa3c533e9b3aa04df20b9ff635cb1154ce303e045278fcf3f10f609064a5445552a1f93989c52ce852fd0bbd6e2b6c22e\",\n    \"0x81934f3a7f8c1ae60ec6e4f212986bcc316118c760a74155d06ce0a8c00a9b9669ec4e143ca214e1b995e41271774fd9\",\n    \"0xab8e2d01a71192093ef8fafa7485e795567cc9db95a93fb7cc4cf63a391ef89af5e2bfad4b827fffe02b89271300407f\",\n    \"0x83064a1eaa937a84e392226f1a60b7cfad4efaa802f66de5df7498962f7b2649924f63cd9962d47906380b97b9fe80e1\",\n    \"0xb4f5e64a15c6672e4b55417ee5dc292dcf93d7ea99965a888b1cc4f5474a11e5b6520eacbcf066840b343f4ceeb6bf33\",\n    \"0xa63d278b842456ef15c278b37a6ea0f27c7b3ffffefca77c7a66d2ea06c33c4631eb242bbb064d730e70a8262a7b848a\",\n    \"0x83a41a83dbcdf0d22dc049de082296204e848c453c5ab1ba75aa4067984e053acf6f8b6909a2e1f0009ed051a828a73b\",\n    \"0x819485b036b7958508f15f3c19436da069cbe635b0318ebe8c014cf1ef9ab2df038c81161b7027475bcfa6fff8dd9faf\",\n    \"0xaa40e38172806e1e045e167f3d1677ef12d5dcdc89b43639a170f68054bd196c4fae34c675c1644d198907a03f76ba57\",\n    \"0x969bae484883a9ed1fbed53b26b3d4ee4b0e39a6c93ece5b3a49daa01444a1c25727dabe62518546f36b047b311b177c\",\n    \"0x80a9e73a65da99664988b238096a090d313a0ee8e4235bc102fa79bb337b51bb08c4507814eb5baec22103ec512eaab0\",\n    \"0x86604379aec5bddda6cbe3ef99c0ac3a3c285b0b1a15b50451c7242cd42ae6b6c8acb717dcca7917838432df93a28502\",\n    \"0xa23407ee02a495bed06aa7e15f94cfb05c83e6d6fba64456a9bbabfa76b2b68c5c47de00ba169e710681f6a29bb41a22\",\n    \"0x98cff5ecc73b366c6a01b34ac9066cb34f7eeaf4f38a5429bad2d07e84a237047e2a065c7e8a0a6581017dadb4695deb\",\n    \"0x8de9f68a938f441f3b7ab84bb1f473c5f9e5c9e139e42b7ccee1d254bd57d0e99c2ccda0f3198f1fc5737f6023dd204e\",\n    \"0xb0ce48d815c2768fb472a315cad86aa033d0e9ca506f146656e2941829e0acb735590b4fbc713c2d18d3676db0a954ac\",\n    \"0x82f485cdefd5642a6af58ac6817991c49fac9c10ace60f90b27f1788cc026c2fe8afc83cf499b3444118f9f0103598a8\",\n    \"0x82c24550ed512a0d53fc56f64cc36b553823ae8766d75d772dacf038c460f16f108f87a39ceef7c66389790f799dbab3\",\n    \"0x859ffcf1fe9166388316149b9acc35694c0ea534d43f09dae9b86f4aa00a23b27144dda6a352e74b9516e8c8d6fc809c\",\n    \"0xb8f7f353eec45da77fb27742405e5ad08d95ec0f5b6842025be9def3d9892f85eb5dd0921b41e6eff373618dba215bca\",\n    \"0x8ccca4436f9017e426229290f5cd05eac3f16571a4713141a7461acfe8ae99cd5a95bf5b6df129148693c533966145da\",\n    \"0xa2c67ecc19c0178b2994846fea4c34c327a5d786ac4b09d1d13549d5be5996d8a89021d63d65cb814923388f47cc3a03\",\n    \"0xaa0ff87d676b418ec08f5cbf577ac7e744d1d0e9ebd14615b550eb86931eafd2a36d4732cc5d6fab1713fd7ab2f6f7c0\",\n    \"0x8aef4730bb65e44efd6bb9441c0ae897363a2f3054867590a2c2ecf4f0224e578c7a67f10b40f8453d9f492ac15a9b2d\",\n    \"0x86a187e13d8fba5addcfdd5b0410cedd352016c930f913addd769ee09faa6be5ca3e4b1bdb417a965c643a99bd92be42\",\n    \"0xa0a4e9632a7a094b14b29b78cd9c894218cdf6783e61671e0203865dc2a835350f465fbaf86168f28af7c478ca17bc89\",\n    \"0xa8c7b02d8deff2cd657d8447689a9c5e2cd74ef57c1314ac4d69084ac24a7471954d9ff43fe0907d875dcb65fd0d3ce5\",\n    \"0x97ded38760aa7be6b6960b5b50e83b618fe413cbf2bcc1da64c05140bcc32f5e0e709cd05bf8007949953fac5716bad9\",\n    \"0xb0d293835a24d64c2ae48ce26e550b71a8c94a0883103757fb6b07e30747f1a871707d23389ba2b2065fa6bafe220095\",\n    \"0x8f9e291bf849feaa575592e28e3c8d4b7283f733d41827262367ea1c40f298c7bcc16505255a906b62bf15d9f1ba85fb\",\n    \"0x998f4e2d12708b4fd85a61597ca2eddd750f73c9e0c9b3cf0825d8f8e01f1628fd19797dcaed3b16dc50331fc6b8b821\",\n    \"0xb30d1f8c115d0e63bf48f595dd10908416774c78b3bbb3194192995154d80ea042d2e94d858de5f8aa0261b093c401fd\",\n    \"0xb5d9c75bb41f964cbff3f00e96d9f1480c91df8913f139f0d385d27a19f57a820f838eb728e46823cbff00e21c660996\",\n    \"0xa6edec90b5d25350e2f5f0518777634f9e661ec9d30674cf5b156c4801746d62517751d90074830ac0f4b09911c262f1\",\n    \"0x82f98da1264b6b75b8fbeb6a4d96d6a05b25c24db0d57ba3a38efe3a82d0d4e331b9fc4237d6494ccfe4727206457519\",\n    \"0xb89511843453cf4ecd24669572d6371b1e529c8e284300c43e0d5bb6b3aaf35aeb634b3cb5c0a2868f0d5e959c1d0772\",\n    \"0xa82bf065676583e5c1d3b81987aaae5542f522ba39538263a944bb33ea5b514c649344a96c0205a3b197a3f930fcda6c\",\n    \"0xa37b47ea527b7e06c460776aa662d9a49ff4149d3993f1a974b0dd165f7171770d189b0e2ea54fd5fccb6a14b116e68a\",\n    \"0xa1017677f97dda818274d47556d09d0e4ccacb23a252f82a6cfe78c630ad46fb9806307445a59fb61262182de3a2b29c\",\n    \"0xb01e9fcac239ba270e6877b79273ddd768bf8a51d2ed8a051b1c11e18eff3de5920e2fcbfbd26f06d381eddd3b1f1e1b\",\n    \"0x82fcd53d803b1c8e4ed76adc339b7f3a5962d37042b9683aabac7513ac68775d4a566a9460183926a6a95dbe7d551a1f\",\n    \"0xa763e78995d55cd21cdb7ef75d9642d6e1c72453945e346ab6690c20a4e1eeec61bb848ef830ae4b56182535e3c71d8f\",\n    \"0xb769f4db602251d4b0a1186782799bdcef66de33c110999a5775c50b349666ffd83d4c89714c4e376f2efe021a5cfdb2\",\n    \"0xa59cbd1b785efcfa6e83fc3b1d8cf638820bc0c119726b5368f3fba9dce8e3414204fb1f1a88f6c1ff52e87961252f97\",\n    \"0x95c8c458fd01aa23ecf120481a9c6332ebec2e8bb70a308d0576926a858457021c277958cf79017ddd86a56cacc2d7db\",\n    \"0x82eb41390800287ae56e77f2e87709de5b871c8bdb67c10a80fc65f3acb9f7c29e8fa43047436e8933f27449ea61d94d\",\n    \"0xb3ec25e3545eb83aed2a1f3558d1a31c7edde4be145ecc13b33802654b77dc049b4f0065069dd9047b051e52ab11dcdd\",\n    \"0xb78a0c715738f56f0dc459ab99e252e3b579b208142836b3c416b704ca1de640ca082f29ebbcee648c8c127df06f6b1e\",\n    \"0xa4083149432eaaf9520188ebf4607d09cf664acd1f471d4fb654476e77a9eaae2251424ffda78d09b6cb880df35c1219\",\n    \"0x8c52857d68d6e9672df3db2df2dbf46b516a21a0e8a18eec09a6ae13c1ef8f369d03233320dd1c2c0bbe00abfc1ea18b\",\n    \"0x8c856089488803066bff3f8d8e09afb9baf20cecc33c8823c1c0836c3d45498c3de37e87c016b705207f60d2b00f8609\",\n    \"0x831a3df39be959047b2aead06b4dcd3012d7b29417f642b83c9e8ce8de24a3dbbd29c6fdf55e2db3f7ea04636c94e403\",\n    \"0xaed84d009f66544addabe404bf6d65af7779ce140dc561ff0c86a4078557b96b2053b7b8a43432ffb18cd814f143b9da\",\n    \"0x93282e4d72b0aa85212a77b336007d8ba071eea17492da19860f1ad16c1ea8867ccc27ef5c37c74b052465cc11ea4f52\",\n    \"0xa7b78b8c8d057194e8d68767f1488363f77c77bddd56c3da2bc70b6354c7aa76247c86d51f7371aa38a4aa7f7e3c0bb7\",\n    \"0xb1c77283d01dcd1bde649b5b044eac26befc98ff57cbee379fb5b8e420134a88f2fc7f0bf04d15e1fbd45d29e7590fe6\",\n    \"0xa4aa8de70330a73b2c6458f20a1067eed4b3474829b36970a8df125d53bbdda4f4a2c60063b7cccb0c80fc155527652f\",\n    \"0x948a6c79ba1b8ad7e0bed2fae2f0481c4e41b4d9bbdd9b58164e28e9065700e83f210c8d5351d0212e0b0b68b345b3a5\",\n    \"0x86a48c31dcbbf7b082c92d28e1f613a2378a910677d7db3a349dc089e4a1e24b12eee8e8206777a3a8c64748840b7387\",\n    \"0x976adb1af21e0fc34148917cf43d933d7bfd3fd12ed6c37039dcd5a4520e3c6cf5868539ba5bf082326430deb8a4458d\",\n    \"0xb93e1a4476f2c51864bb4037e7145f0635eb2827ab91732b98d49b6c07f6ac443111aa1f1da76d1888665cb897c3834e\",\n    \"0x8afd46fb23bf869999fa19784b18a432a1f252d09506b8dbb756af900518d3f5f244989b3d7c823d9029218c655d3dc6\",\n    \"0x83f1e59e3abeed18cdc632921672673f1cb6e330326e11c4e600e13e0d5bc11bdc970ae12952e15103a706fe720bf4d6\",\n    \"0x90ce4cc660714b0b673d48010641c09c00fc92a2c596208f65c46073d7f349dd8e6e077ba7dcef9403084971c3295b76\",\n    \"0x8b09b0f431a7c796561ecf1549b85048564de428dac0474522e9558b6065fede231886bc108539c104ce88ebd9b5d1b0\",\n    \"0x85d6e742e2fb16a7b0ba0df64bc2c0dbff9549be691f46a6669bca05e89c884af16822b85faefefb604ec48c8705a309\",\n    \"0xa87989ee231e468a712c66513746fcf03c14f103aadca0eac28e9732487deb56d7532e407953ab87a4bf8961588ef7b0\",\n    \"0xb00da10efe1c29ee03c9d37d5918e391ae30e48304e294696b81b434f65cf8c8b95b9d1758c64c25e534d045ba28696f\",\n    \"0x91c0e1fb49afe46c7056400baa06dbb5f6e479db78ee37e2d76c1f4e88994357e257b83b78624c4ef6091a6c0eb8254d\",\n    \"0x883fb797c498297ccbf9411a3e727c3614af4eccde41619b773dc7f3259950835ee79453debf178e11dec4d3ada687a0\",\n    \"0xa14703347e44eb5059070b2759297fcfcfc60e6893c0373eea069388eba3950aa06f1c57cd2c30984a2d6f9e9c92c79e\",\n    \"0xafebc7585b304ceba9a769634adff35940e89cd32682c78002822aab25eec3edc29342b7f5a42a56a1fec67821172ad5\",\n    \"0xaea3ff3822d09dba1425084ca95fd359718d856f6c133c5fabe2b2eed8303b6e0ba0d8698b48b93136a673baac174fd9\",\n    \"0xaf2456a09aa777d9e67aa6c7c49a1845ea5cdda2e39f4c935c34a5f8280d69d4eec570446998cbbe31ede69a91e90b06\",\n    \"0x82cada19fed16b891ef3442bafd49e1f07c00c2f57b2492dd4ee36af2bd6fd877d6cb41188a4d6ce9ec8d48e8133d697\",\n    \"0x82a21034c832287f616619a37c122cee265cc34ae75e881fcaea4ea7f689f3c2bc8150bbf7dbcfd123522bfb7f7b1d68\",\n    \"0x86877217105f5d0ec3eeff0289fc2a70d505c9fdf7862e8159553ef60908fb1a27bdaf899381356a4ef4649072a9796c\",\n    \"0x82b196e49c6e861089a427c0b4671d464e9d15555ffb90954cd0d630d7ae02eb3d98ceb529d00719c2526cd96481355a\",\n    \"0xa29b41d0d43d26ce76d4358e0db2b77df11f56e389f3b084d8af70a636218bd3ac86b36a9fe46ec9058c26a490f887f7\",\n    \"0xa4311c4c20c4d7dd943765099c50f2fd423e203ccfe98ff00087d205467a7873762510cac5fdce7a308913ed07991ed7\",\n    \"0xb1f040fc5cc51550cb2c25cf1fd418ecdd961635a11f365515f0cb4ffb31da71f48128c233e9cc7c0cf3978d757ec84e\",\n    \"0xa9ebae46f86d3bd543c5f207ed0d1aed94b8375dc991161d7a271f01592912072e083e2daf30c146430894e37325a1b9\",\n    \"0x826418c8e17ad902b5fe88736323a47e0ca7a44bce4cbe27846ec8fe81de1e8942455dda6d30e192cdcc73e11df31256\",\n    \"0x85199db563427c5edcbac21f3d39fec2357be91fb571982ddcdc4646b446ad5ced84410de008cb47b3477ee0d532daf8\",\n    \"0xb7eed9cd400b2ca12bf1d9ae008214b8561fb09c8ad9ff959e626ffde00fee5ff2f5b6612e231f2a1a9b1646fcc575e3\",\n    \"0x8b40bf12501dcbac78f5a314941326bfcddf7907c83d8d887d0bb149207f85d80cd4dfbd7935439ea7b14ea39a3fded7\",\n    \"0x83e3041af302485399ba6cd5120e17af61043977083887e8d26b15feec4a6b11171ac5c06e6ad0971d4b58a81ff12af3\",\n    \"0x8f5b9a0eecc589dbf8c35a65d5e996a659277ef6ea509739c0cb7b3e2da9895e8c8012de662e5b23c5fa85d4a8f48904\",\n    \"0x835d71ed5e919d89d8e6455f234f3ff215462c4e3720c371ac8c75e83b19dfe3ae15a81547e4dc1138e5f5997f413cc9\",\n    \"0x8b7d2e4614716b1db18e9370176ea483e6abe8acdcc3dcdf5fb1f4d22ca55d652feebdccc171c6de38398d9f7bfdec7a\",\n    \"0x93eace72036fe57d019676a02acf3d224cf376f166658c1bf705db4f24295881d477d6fdd7916efcfceff8c7a063deda\",\n    \"0xb1ac460b3d516879a84bc886c54f020a9d799e7c49af3e4d7de5bf0d2793c852254c5d8fe5616147e6659512e5ccb012\",\n    \"0xacd0947a35cb167a48bcd9667620464b54ac0e78f9316b4aa92dcaab5422d7a732087e52e1c827faa847c6b2fe6e7766\",\n    \"0x94ac33d21c3d12ff762d32557860e911cd94d666609ddcc42161b9c16f28d24a526e8b10bb03137257a92cec25ae637d\",\n    \"0x832e02058b6b994eadd8702921486241f9a19e68ed1406dad545e000a491ae510f525ccf9d10a4bba91c68f2c53a0f58\",\n    \"0x9471035d14f78ff8f463b9901dd476b587bb07225c351161915c2e9c6114c3c78a501379ab6fb4eb03194c457cbd22bf\",\n    \"0xab64593e034c6241d357fcbc32d8ea5593445a5e7c24cac81ad12bd2ef01843d477a36dc1ba21dbe63b440750d72096a\",\n    \"0x9850f3b30045e927ad3ec4123a32ed2eb4c911f572b6abb79121873f91016f0d80268de8b12e2093a4904f6e6cab7642\",\n    \"0x987212c36b4722fe2e54fa30c52b1e54474439f9f35ca6ad33c5130cd305b8b54b532dd80ffd2c274105f20ce6d79f6e\",\n    \"0x8b4d0c6abcb239b5ed47bef63bc17efe558a27462c8208fa652b056e9eae9665787cd1aee34fbb55beb045c8bfdb882b\",\n    \"0xa9f3483c6fee2fe41312d89dd4355d5b2193ac413258993805c5cbbf0a59221f879386d3e7a28e73014f10e65dd503d9\",\n    \"0xa2225da3119b9b7c83d514b9f3aeb9a6d9e32d9cbf9309cbb971fd53c4b2c001d10d880a8ad8a7c281b21d85ceca0b7c\",\n    \"0xa050be52e54e676c151f7a54453bbb707232f849beab4f3bf504b4d620f59ed214409d7c2bd3000f3ff13184ccda1c35\",\n    \"0xadbccf681e15b3edb6455a68d292b0a1d0f5a4cb135613f5e6db9943f02181341d5755875db6ee474e19ace1c0634a28\",\n    \"0x8b6eff675632a6fad0111ec72aacc61c7387380eb87933fd1d098856387d418bd38e77d897e65d6fe35951d0627c550b\",\n    \"0xaabe2328ddf90989b15e409b91ef055cb02757d34987849ae6d60bef2c902bf8251ed21ab30acf39e500d1d511e90845\",\n    \"0x92ba4eb1f796bc3d8b03515f65c045b66e2734c2da3fc507fdd9d6b5d1e19ab3893726816a32141db7a31099ca817d96\",\n    \"0x8a98b3cf353138a1810beb60e946183803ef1d39ac4ea92f5a1e03060d35a4774a6e52b14ead54f6794d5f4022b8685c\",\n    \"0x909f8a5c13ec4a59b649ed3bee9f5d13b21d7f3e2636fd2bb3413c0646573fdf9243d63083356f12f5147545339fcd55\",\n    \"0x9359d914d1267633141328ed0790d81c695fea3ddd2d406c0df3d81d0c64931cf316fe4d92f4353c99ff63e2aefc4e34\",\n    \"0xb88302031681b54415fe8fbfa161c032ea345c6af63d2fb8ad97615103fd4d4281c5a9cae5b0794c4657b97571a81d3b\",\n    \"0x992c80192a519038082446b1fb947323005b275e25f2c14c33cc7269e0ec038581cc43705894f94bad62ae33a8b7f965\",\n    \"0xa78253e3e3eece124bef84a0a8807ce76573509f6861d0b6f70d0aa35a30a123a9da5e01e84969708c40b0669eb70aa6\",\n    \"0x8d5724de45270ca91c94792e8584e676547d7ac1ac816a6bb9982ee854eb5df071d20545cdfd3771cd40f90e5ba04c8e\",\n    \"0x825a6f586726c68d45f00ad0f5a4436523317939a47713f78fd4fe81cd74236fdac1b04ecd97c2d0267d6f4981d7beb1\"\n  ],\n  \"g2_monomial\": [\n    \"0x93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8\",\n    \"0xb5bfd7dd8cdeb128843bc287230af38926187075cbfbefa81009a2ce615ac53d2914e5870cb452d2afaaab24f3499f72185cbfee53492714734429b7b38608e23926c911cceceac9a36851477ba4c60b087041de621000edc98edada20c1def2\",\n    \"0xb5337ba0ce5d37224290916e268e2060e5c14f3f9fc9e1ec3af5a958e7a0303122500ce18f1a4640bf66525bd10e763501fe986d86649d8d45143c08c3209db3411802c226e9fe9a55716ac4a0c14f9dcef9e70b2bb309553880dc5025eab3cc\",\n    \"0xb3c1dcdc1f62046c786f0b82242ef283e7ed8f5626f72542aa2c7a40f14d9094dd1ebdbd7457ffdcdac45fd7da7e16c51200b06d791e5e43e257e45efdf0bd5b06cd2333beca2a3a84354eb48662d83aef5ecf4e67658c851c10b13d8d87c874\",\n    \"0x954d91c7688983382609fca9e211e461f488a5971fd4e40d7e2892037268eacdfd495cfa0a7ed6eb0eb11ac3ae6f651716757e7526abe1e06c64649d80996fd3105c20c4c94bc2b22d97045356fe9d791f21ea6428ac48db6f9e68e30d875280\",\n    \"0x88a6b6bb26c51cf9812260795523973bb90ce80f6820b6c9048ab366f0fb96e48437a7f7cb62aedf64b11eb4dfefebb0147608793133d32003cb1f2dc47b13b5ff45f1bb1b2408ea45770a08dbfaec60961acb8119c47b139a13b8641e2c9487\",\n    \"0x85cd7be9728bd925d12f47fb04b32d9fad7cab88788b559f053e69ca18e463113ecc8bbb6dbfb024835f901b3a957d3108d6770fb26d4c8be0a9a619f6e3a4bf15cbfd48e61593490885f6cee30e4300c5f9cf5e1c08e60a2d5b023ee94fcad0\",\n    \"0x80477dba360f04399821a48ca388c0fa81102dd15687fea792ee8c1114e00d1bc4839ad37ac58900a118d863723acfbe08126ea883be87f50e4eabe3b5e72f5d9e041db8d9b186409fd4df4a7dde38c0e0a3b1ae29b098e5697e7f110b6b27e4\",\n    \"0xb7a6aec08715a9f8672a2b8c367e407be37e59514ac19dd4f0942a68007bba3923df22da48702c63c0d6b3efd3c2d04e0fe042d8b5a54d562f9f33afc4865dcbcc16e99029e25925580e87920c399e710d438ac1ce3a6dc9b0d76c064a01f6f7\",\n    \"0xac1b001edcea02c8258aeffbf9203114c1c874ad88dae1184fadd7d94cd09053649efd0ca413400e6e9b5fa4eac33261000af88b6bd0d2abf877a4f0355d2fb4d6007adb181695201c5432e50b850b51b3969f893bddf82126c5a71b042b7686\",\n    \"0x90043fda4de53fb364fab2c04be5296c215599105ecff0c12e4917c549257125775c29f2507124d15f56e30447f367db0596c33237242c02d83dfd058735f1e3c1ff99069af55773b6d51d32a68bf75763f59ec4ee7267932ae426522b8aaab6\",\n    \"0xa8660ce853e9dc08271bf882e29cd53397d63b739584dda5263da4c7cc1878d0cf6f3e403557885f557e184700575fee016ee8542dec22c97befe1d10f414d22e84560741cdb3e74c30dda9b42eeaaf53e27822de2ee06e24e912bf764a9a533\",\n    \"0x8fe3921a96d0d065e8aa8fce9aa42c8e1461ca0470688c137be89396dd05103606dab6cdd2a4591efd6addf72026c12e065da7be276dee27a7e30afa2bd81c18f1516e7f068f324d0bad9570b95f6bd02c727cd2343e26db0887c3e4e26dceda\",\n    \"0x8ae1ad97dcb9c192c9a3933541b40447d1dc4eebf380151440bbaae1e120cc5cdf1bcea55180b128d8e180e3af623815191d063cc0d7a47d55fb7687b9d87040bf7bc1a7546b07c61db5ccf1841372d7c2fe4a5431ffff829f3c2eb590b0b710\",\n    \"0x8c2fa96870a88150f7876c931e2d3cc2adeaaaf5c73ef5fa1cf9dfa0991ae4819f9321af7e916e5057d87338e630a2f21242c29d76963cf26035b548d2a63d8ad7bd6efefa01c1df502cbdfdfe0334fb21ceb9f686887440f713bf17a89b8081\",\n    \"0xb9aa98e2f02bb616e22ee5dd74c7d1049321ac9214d093a738159850a1dbcc7138cb8d26ce09d8296368fd5b291d74fa17ac7cc1b80840fdd4ee35e111501e3fa8485b508baecda7c1ab7bd703872b7d64a2a40b3210b6a70e8a6ffe0e5127e3\",\n    \"0x9292db67f8771cdc86854a3f614a73805bf3012b48f1541e704ea4015d2b6b9c9aaed36419769c87c49f9e3165f03edb159c23b3a49c4390951f78e1d9b0ad997129b17cdb57ea1a6638794c0cca7d239f229e589c5ae4f9fe6979f7f8cba1d7\",\n    \"0x91cd9e86550f230d128664f7312591fee6a84c34f5fc7aed557bcf986a409a6de722c4330453a305f06911d2728626e611acfdf81284f77f60a3a1595053a9479964fd713117e27c0222cc679674b03bc8001501aaf9b506196c56de29429b46\",\n    \"0xa9516b73f605cc31b89c68b7675dc451e6364595243d235339437f556cf22d745d4250c1376182273be2d99e02c10eee047410a43eff634d051aeb784e76cb3605d8e079b9eb6ad1957dfdf77e1cd32ce4a573c9dfcc207ca65af6eb187f6c3d\",\n    \"0xa9667271f7d191935cc8ad59ef3ec50229945faea85bfdfb0d582090f524436b348aaa0183b16a6231c00332fdac2826125b8c857a2ed9ec66821cfe02b3a2279be2412441bc2e369b255eb98614e4be8490799c4df22f18d47d24ec70bba5f7\",\n    \"0xa4371144d2aa44d70d3cb9789096d3aa411149a6f800cb46f506461ee8363c8724667974252f28aea61b6030c05930ac039c1ee64bb4bd56532a685cae182bf2ab935eee34718cffcb46cae214c77aaca11dbb1320faf23c47247db1da04d8dc\",\n    \"0x89a7eb441892260b7e81168c386899cd84ffc4a2c5cad2eae0d1ab9e8b5524662e6f660fe3f8bfe4c92f60b060811bc605b14c5631d16709266886d7885a5eb5930097127ec6fb2ebbaf2df65909cf48f253b3d5e22ae48d3e9a2fd2b01f447e\",\n    \"0x9648c42ca97665b5eccb49580d8532df05eb5a68db07f391a2340769b55119eaf4c52fe4f650c09250fa78a76c3a1e271799b8333cc2628e3d4b4a6a3e03da1f771ecf6516dd63236574a7864ff07e319a6f11f153406280d63af9e2b5713283\",\n    \"0x9663bf6dd446ea7a90658ee458578d4196dc0b175ef7fcfa75f44d41670850774c2e46c5a6be132a2c072a3c0180a24f0305d1acac49d2d79878e5cda80c57feda3d01a6af12e78b5874e2a4b3717f11c97503b41a4474e2e95b179113726199\",\n    \"0xb212aeb4814e0915b432711b317923ed2b09e076aaf558c3ae8ef83f9e15a83f9ea3f47805b2750ab9e8106cb4dc6ad003522c84b03dc02829978a097899c773f6fb31f7fe6b8f2d836d96580f216fec20158f1590c3e0d7850622e15194db05\",\n    \"0x925f005059bf07e9ceccbe66c711b048e236ade775720d0fe479aebe6e23e8af281225ad18e62458dc1b03b42ad4ca290d4aa176260604a7aad0d9791337006fbdebe23746f8060d42876f45e4c83c3643931392fde1cd13ff8bddf8111ef974\",\n    \"0x9553edb22b4330c568e156a59ef03b26f5c326424f830fe3e8c0b602f08c124730ffc40bc745bec1a22417adb22a1a960243a10565c2be3066bfdb841d1cd14c624cd06e0008f4beb83f972ce6182a303bee3fcbcabc6cfe48ec5ae4b7941bfc\",\n    \"0x935f5a404f0a78bdcce709899eda0631169b366a669e9b58eacbbd86d7b5016d044b8dfc59ce7ed8de743ae16c2343b50e2f925e88ba6319e33c3fc76b314043abad7813677b4615c8a97eb83cc79de4fedf6ccbcfa4d4cbf759a5a84e4d9742\",\n    \"0xa5b014ab936eb4be113204490e8b61cd38d71da0dec7215125bcd131bf3ab22d0a32ce645bca93e7b3637cf0c2db3d6601a0ddd330dc46f9fae82abe864ffc12d656c88eb50c20782e5bb6f75d18760666f43943abb644b881639083e122f557\",\n    \"0x935b7298ae52862fa22bf03bfc1795b34c70b181679ae27de08a9f5b4b884f824ef1b276b7600efa0d2f1d79e4a470d51692fd565c5cf8343dd80e5d3336968fc21c09ba9348590f6206d4424eb229e767547daefa98bc3aa9f421158dee3f2a\",\n    \"0x9830f92446e708a8f6b091cc3c38b653505414f8b6507504010a96ffda3bcf763d5331eb749301e2a1437f00e2415efb01b799ad4c03f4b02de077569626255ac1165f96ea408915d4cf7955047620da573e5c439671d1fa5c833fb11de7afe6\",\n    \"0x840dcc44f673fff3e387af2bb41e89640f2a70bcd2b92544876daa92143f67c7512faf5f90a04b7191de01f3e2b1bde00622a20dc62ca23bbbfaa6ad220613deff43908382642d4d6a86999f662efd64b1df448b68c847cfa87630a3ffd2ec76\",\n    \"0x92950c895ed54f7f876b2fda17ecc9c41b7accfbdd42c210cc5b475e0737a7279f558148531b5c916e310604a1de25a80940c94fe5389ae5d6a5e9c371be67bceea1877f5401725a6595bcf77ece60905151b6dfcb68b75ed2e708c73632f4fd\",\n    \"0x8010246bf8e94c25fd029b346b5fbadb404ef6f44a58fd9dd75acf62433d8cc6db66974f139a76e0c26dddc1f329a88214dbb63276516cf325c7869e855d07e0852d622c332ac55609ba1ec9258c45746a2aeb1af0800141ee011da80af175d4\",\n    \"0xb0f1bad257ebd187bdc3f37b23f33c6a5d6a8e1f2de586080d6ada19087b0e2bf23b79c1b6da1ee82271323f5bdf3e1b018586b54a5b92ab6a1a16bb3315190a3584a05e6c37d5ca1e05d702b9869e27f513472bcdd00f4d0502a107773097da\",\n    \"0x9636d24f1ede773ce919f309448dd7ce023f424afd6b4b69cb98c2a988d849a283646dc3e469879daa1b1edae91ae41f009887518e7eb5578f88469321117303cd3ac2d7aee4d9cb5f82ab9ae3458e796dfe7c24284b05815acfcaa270ff22e2\",\n    \"0xb373feb5d7012fd60578d7d00834c5c81df2a23d42794fed91aa9535a4771fde0341c4da882261785e0caca40bf83405143085e7f17e55b64f6c5c809680c20b050409bf3702c574769127c854d27388b144b05624a0e24a1cbcc4d08467005b\",\n    \"0xb15680648949ce69f82526e9b67d9b55ce5c537dc6ab7f3089091a9a19a6b90df7656794f6edc87fb387d21573ffc847062623685931c2790a508cbc8c6b231dd2c34f4d37d4706237b1407673605a604bcf6a50cc0b1a2db20485e22b02c17e\",\n    \"0x8817e46672d40c8f748081567b038a3165f87994788ec77ee8daea8587f5540df3422f9e120e94339be67f186f50952504cb44f61e30a5241f1827e501b2de53c4c64473bcc79ab887dd277f282fbfe47997a930dd140ac08b03efac88d81075\",\n    \"0xa6e4ef6c1d1098f95aae119905f87eb49b909d17f9c41bcfe51127aa25fee20782ea884a7fdf7d5e9c245b5a5b32230b07e0dbf7c6743bf52ee20e2acc0b269422bd6cf3c07115df4aa85b11b2c16630a07c974492d9cdd0ec325a3fabd95044\",\n    \"0x8634aa7c3d00e7f17150009698ce440d8e1b0f13042b624a722ace68ead870c3d2212fbee549a2c190e384d7d6ac37ce14ab962c299ea1218ef1b1489c98906c91323b94c587f1d205a6edd5e9d05b42d591c26494a6f6a029a2aadb5f8b6f67\",\n    \"0x821a58092900bdb73decf48e13e7a5012a3f88b06288a97b855ef51306406e7d867d613d9ec738ebacfa6db344b677d21509d93f3b55c2ebf3a2f2a6356f875150554c6fff52e62e3e46f7859be971bf7dd9d5b3e1d799749c8a97c2e04325df\",\n    \"0x8dba356577a3a388f782e90edb1a7f3619759f4de314ad5d95c7cc6e197211446819c4955f99c5fc67f79450d2934e3c09adefc91b724887e005c5190362245eec48ce117d0a94d6fa6db12eda4ba8dde608fbbd0051f54dcf3bb057adfb2493\",\n    \"0xa32a690dc95c23ed9fb46443d9b7d4c2e27053a7fcc216d2b0020a8cf279729c46114d2cda5772fd60a97016a07d6c5a0a7eb085a18307d34194596f5b541cdf01b2ceb31d62d6b55515acfd2b9eec92b27d082fbc4dc59fc63b551eccdb8468\",\n    \"0xa040f7f4be67eaf0a1d658a3175d65df21a7dbde99bfa893469b9b43b9d150fc2e333148b1cb88cfd0447d88fa1a501d126987e9fdccb2852ecf1ba907c2ca3d6f97b055e354a9789854a64ecc8c2e928382cf09dda9abde42bbdf92280cdd96\",\n    \"0x864baff97fa60164f91f334e0c9be00a152a416556b462f96d7c43b59fe1ebaff42f0471d0bf264976f8aa6431176eb905bd875024cf4f76c13a70bede51dc3e47e10b9d5652d30d2663b3af3f08d5d11b9709a0321aba371d2ef13174dcfcaf\",\n    \"0x95a46f32c994133ecc22db49bad2c36a281d6b574c83cfee6680b8c8100466ca034b815cfaedfbf54f4e75188e661df901abd089524e1e0eb0bf48d48caa9dd97482d2e8c1253e7e8ac250a32fd066d5b5cb08a8641bdd64ecfa48289dca83a3\",\n    \"0xa2cce2be4d12144138cb91066e0cd0542c80b478bf467867ebef9ddaf3bd64e918294043500bf5a9f45ee089a8d6ace917108d9ce9e4f41e7e860cbce19ac52e791db3b6dde1c4b0367377b581f999f340e1d6814d724edc94cb07f9c4730774\",\n    \"0xb145f203eee1ac0a1a1731113ffa7a8b0b694ef2312dabc4d431660f5e0645ef5838e3e624cfe1228cfa248d48b5760501f93e6ab13d3159fc241427116c4b90359599a4cb0a86d0bb9190aa7fabff482c812db966fd2ce0a1b48cb8ac8b3bca\",\n    \"0xadabe5d215c608696e03861cbd5f7401869c756b3a5aadc55f41745ad9478145d44393fec8bb6dfc4ad9236dc62b9ada0f7ca57fe2bae1b71565dbf9536d33a68b8e2090b233422313cc96afc7f1f7e0907dc7787806671541d6de8ce47c4cd0\",\n    \"0xae7845fa6b06db53201c1080e01e629781817f421f28956589c6df3091ec33754f8a4bd4647a6bb1c141ac22731e3c1014865d13f3ed538dcb0f7b7576435133d9d03be655f8fbb4c9f7d83e06d1210aedd45128c2b0c9bab45a9ddde1c862a5\",\n    \"0x9159eaa826a24adfa7adf6e8d2832120ebb6eccbeb3d0459ffdc338548813a2d239d22b26451fda98cc0c204d8e1ac69150b5498e0be3045300e789bcb4e210d5cd431da4bdd915a21f407ea296c20c96608ded0b70d07188e96e6c1a7b9b86b\",\n    \"0xa9fc6281e2d54b46458ef564ffaed6944bff71e389d0acc11fa35d3fcd8e10c1066e0dde5b9b6516f691bb478e81c6b20865281104dcb640e29dc116daae2e884f1fe6730d639dbe0e19a532be4fb337bf52ae8408446deb393d224eee7cfa50\",\n    \"0x84291a42f991bfb36358eedead3699d9176a38f6f63757742fdbb7f631f2c70178b1aedef4912fed7b6cf27e88ddc7eb0e2a6aa4b999f3eb4b662b93f386c8d78e9ac9929e21f4c5e63b12991fcde93aa64a735b75b535e730ff8dd2abb16e04\",\n    \"0xa1b7fcacae181495d91765dfddf26581e8e39421579c9cbd0dd27a40ea4c54af3444a36bf85a11dda2114246eaddbdd619397424bb1eb41b5a15004b902a590ede5742cd850cf312555be24d2df8becf48f5afba5a8cd087cb7be0a521728386\",\n    \"0x92feaaf540dbd84719a4889a87cdd125b7e995a6782911931fef26da9afcfbe6f86aaf5328fe1f77631491ce6239c5470f44c7791506c6ef1626803a5794e76d2be0af92f7052c29ac6264b7b9b51f267ad820afc6f881460521428496c6a5f1\",\n    \"0xa525c925bfae1b89320a5054acc1fa11820f73d0cf28d273092b305467b2831fab53b6daf75fb926f332782d50e2522a19edcd85be5eb72f1497193c952d8cd0bcc5d43b39363b206eae4cb1e61668bde28a3fb2fc1e0d3d113f6dfadb799717\",\n    \"0x98752bb6f5a44213f40eda6aa4ff124057c1b13b6529ab42fe575b9afa66e59b9c0ed563fb20dff62130c436c3e905ee17dd8433ba02c445b1d67182ab6504a90bbe12c26a754bbf734665c622f76c62fe2e11dd43ce04fd2b91a8463679058b\",\n    \"0xa9aa9a84729f7c44219ff9e00e651e50ddea3735ef2a73fdf8ed8cd271961d8ed7af5cd724b713a89a097a3fe65a3c0202f69458a8b4c157c62a85668b12fc0d3957774bc9b35f86c184dd03bfefd5c325da717d74192cc9751c2073fe9d170e\",\n    \"0xb221c1fd335a4362eff504cd95145f122bf93ea02ae162a3fb39c75583fc13a932d26050e164da97cff3e91f9a7f6ff80302c19dd1916f24acf6b93b62f36e9665a8785413b0c7d930c7f1668549910f849bca319b00e59dd01e5dec8d2edacc\",\n    \"0xa71e2b1e0b16d754b848f05eda90f67bedab37709550171551050c94efba0bfc282f72aeaaa1f0330041461f5e6aa4d11537237e955e1609a469d38ed17f5c2a35a1752f546db89bfeff9eab78ec944266f1cb94c1db3334ab48df716ce408ef\",\n    \"0xb990ae72768779ba0b2e66df4dd29b3dbd00f901c23b2b4a53419226ef9232acedeb498b0d0687c463e3f1eead58b20b09efcefa566fbfdfe1c6e48d32367936142d0a734143e5e63cdf86be7457723535b787a9cfcfa32fe1d61ad5a2617220\",\n    \"0x8d27e7fbff77d5b9b9bbc864d5231fecf817238a6433db668d5a62a2c1ee1e5694fdd90c3293c06cc0cb15f7cbeab44d0d42be632cb9ff41fc3f6628b4b62897797d7b56126d65b694dcf3e298e3561ac8813fbd7296593ced33850426df42db\",\n    \"0xa92039a08b5502d5b211a7744099c9f93fa8c90cedcb1d05e92f01886219dd464eb5fb0337496ad96ed09c987da4e5f019035c5b01cc09b2a18b8a8dd419bc5895388a07e26958f6bd26751929c25f89b8eb4a299d822e2d26fec9ef350e0d3c\",\n    \"0x92dcc5a1c8c3e1b28b1524e3dd6dbecd63017c9201da9dbe077f1b82adc08c50169f56fc7b5a3b28ec6b89254de3e2fd12838a761053437883c3e01ba616670cea843754548ef84bcc397de2369adcca2ab54cd73c55dc68d87aec3fc2fe4f10\"\n  ]\n}"
  },
  {
    "path": "testing/networks/80069/spec.toml",
    "content": "# Bepolia Chain Spec Configuration\n\n# Gwei value constants\nmax-effective-balance = 10_000_000_000_000_000\neffective-balance-increment = 10_000_000_000_000\n\n# Hysteresis parameters\nhysteresis-quotient = 4\nhysteresis-downward-multiplier = 1\nhysteresis-upward-multiplier = 5\n\n# Time parameters\nslots-per-epoch = 192\nslots-per-historical-root = 8\nmin-epochs-to-inactivity-penalty = 4\n\n# Signature domains (each will be interpreted as a numeric value)\ndomain-type-beacon-proposer = 0\ndomain-type-beacon-attester = 1\ndomain-type-randao = 2\ndomain-type-deposit = 3\ndomain-type-voluntary-exit = 4\ndomain-type-selection-proof = 5\ndomain-type-aggregate-and-proof = 6\ndomain-type-application-mask = 16777216\n\n# Eth1-related values\ndeposit-contract-address = \"0x4242424242424242424242424242424242424242\"\nmax-deposits-per-block = 16\ndeposit-eth1-chain-id = 80069\neth1-follow-distance = 1\ntarget-seconds-per-eth1-block = 2\n\n# Fork-related values\ngenesis-time = 1_739_976_735\ndeneb-one-fork-time = 1_740_090_694\nelectra-fork-time = 1_746_633_600\nelectra-one-fork-time = 1_754_496_000\nfulu-fork-time = 9_999_999_999_999_999\n\n# State list lengths\nepochs-per-historical-vector = 8\nepochs-per-slashings-vector = 8\nhistorical-roots-limit = 8\nvalidator-registry-limit = 1_099_511_627_776\n\n# Capella values\nmax-withdrawals-per-payload = 16\nmax-validators-per-withdrawals-sweep = 31\n\n# Deneb values\nmin-epochs-for-blobs-sidecars-request = 4096\nmax-blob-commitments-per-block = 4096\nmax-blobs-per-block = 6\nfield-elements-per-blob = 4096\nbytes-per-blob = 131072\n\n# Berachain genesis values\nvalidator-set-cap = 69\nevm-inflation-address = \"0x0000000000000000000000000000000000000000\"\nevm-inflation-per-block = 0\n\n# Deneb1 value changes\nevm-inflation-address-deneb-one = \"0x656b95E550C07a9ffe548bd4085c72418Ceb1dba\"\nevm-inflation-per-block-deneb-one = 5_750_000_000\n\n# Electra values\nmin-activation-balance = 250_000_000_000_000\nmin-validator-withdrawability-delay = 256\n\n# Fulu values (BRIP-0008 hysteresis + PoL vNext -- TODO: update values)\nhysteresis-quotient-fulu = 100\nhysteresis-upward-multiplier-fulu = 10\nevm-inflation-address-fulu = \"0x0000000000000000000000000000000000000000\"\nevm-inflation-per-block-fulu = 0\n\n[block-delay-configuration]\nmax-block-delay = 300_000_000_000\ntarget-block-time = 2_000_000_000\nconst-block-delay = 500_000_000\nconsensus-update-height = 7_768_334\nconsensus-enable-height = 7_768_335\n"
  },
  {
    "path": "testing/networks/80094/app.toml",
    "content": "# This is a TOML config file.\n# For more information, see https://github.com/toml-lang/toml\n\n###############################################################################\n###                           Base Configuration                            ###\n###############################################################################\n\n# default: the last 362880 states are kept, pruning at 10 block intervals\n# nothing: all historic states will be saved, nothing will be deleted (i.e. archiving node)\n# everything: 2 latest states will be kept; pruning at 10 block intervals.\n# custom: allow pruning options to be manually specified through 'pruning-keep-recent', and 'pruning-interval'\npruning = \"everything\"\n\n# These are applied if and only if the pruning strategy is custom.\npruning-keep-recent = \"0\"\npruning-interval = \"0\"\n\n# HaltHeight contains a non-zero block height at which a node will gracefully\n# halt and shutdown that can be used to assist upgrades and testing.\n#\n# Note: Commitment of state will be attempted on the corresponding block.\nhalt-height = 0\n\n# HaltTime contains a non-zero minimum block time (in Unix seconds) at which\n# a node will gracefully halt and shutdown that can be used to assist upgrades\n# and testing.\n#\n# Note: Commitment of state will be attempted on the corresponding block.\nhalt-time = 0\n\n# MinRetainBlocks defines the minimum block height offset from the current\n# block being committed, such that all blocks past this offset are pruned\n# from CometBFT. It is used as part of the process of determining the\n# ResponseCommit.RetainHeight value during ABCI Commit. A value of 0 indicates\n# that no blocks should be pruned.\n#\n# This configuration value is only responsible for pruning CometBFT blocks.\n# It has no bearing on application state pruning which is determined by the\n# \"pruning-*\" configurations.\n#\n# Note: CometBFT block pruning is dependant on this parameter in conjunction\n# with the unbonding (safety threshold) period, state pruning and state sync\n# snapshot parameters to determine the correct minimum value of\n# ResponseCommit.RetainHeight.\nmin-retain-blocks = 0\n\n# InterBlockCache enables inter-block caching.\ninter-block-cache = true\n\n# IndexEvents defines the set of events in the form {eventType}.{attributeKey},\n# which informs CometBFT what to index. If empty, all events will be indexed.\n#\n# Example:\n# [\"message.sender\", \"message.recipient\"]\nindex-events = []\n\n# IavlCacheSize set the size of the iavl tree cache (in number of nodes).\niavl-cache-size = 781250\n\n# IAVLDisableFastNode enables or disables the fast node feature of IAVL.\n# Default is false.\niavl-disable-fastnode = true\n\n# AppDBBackend defines the database backend type to use for the application and snapshots DBs.\n# An empty string indicates that a fallback will be used.\n# The fallback is the db_backend value set in CometBFT's config.toml.\napp-db-backend = \"pebbledb\"\n\n###############################################################################\n###                         Telemetry Configuration                         ###\n###############################################################################\n\n[telemetry]\n\n# Prefixed with keys to separate services.\nservice-name = \"beacond_node\"\n\n# Enabled enables the application telemetry functionality. When enabled,\n# an in-memory sink is also enabled by default. Operators may also enabled\n# other sinks such as Prometheus.\nenabled = true\n\n# Enable prefixing gauge values with hostname.\nenable-hostname = true\n\n# Enable adding hostname to labels.\nenable-hostname-label = true\n\n# Enable adding service to labels.\nenable-service-label = true\n\n# PrometheusRetentionTime, when positive, enables a Prometheus metrics sink.\nprometheus-retention-time = 60\n\n# GlobalLabels defines a global set of name/value label tuples applied to all\n# metrics emitted using the wrapper functions defined in telemetry package.\n#\n# Example:\n# [[\"chain_id\", \"cosmoshub-1\"]]\nglobal-labels = []\n\n# MetricsSink defines the type of metrics sink to use.\nmetrics-sink = \"\"\n\n# StatsdAddr defines the address of a statsd server to send metrics to.\n# Only utilized if MetricsSink is set to \"statsd\" or \"dogstatsd\".\nstatsd-addr = \"\"\n\n# DatadogHostname defines the hostname to use when emitting metrics to\n# Datadog. Only utilized if MetricsSink is set to \"dogstatsd\".\ndatadog-hostname = \"my_beacond_node\"\n\n###############################################################################\n###                                BeaconKit                                ###\n###############################################################################\n\n[beacon-kit]\n# ChainSpec is the type of chain spec to use.\nchain-spec = \"mainnet\"\n\n# ChainSpecFilePath is the path to the chain spec file to use.\nchain-spec-file = \"\"\n\n# ShutdownTimeout is the maximum time to wait for the node to gracefully\n# shutdown before forcing an exit.\nshutdown-timeout = \"5m0s\"\n\n[beacon-kit.engine]\n# HTTP url of the execution client JSON-RPC endpoint.\nrpc-dial-url = \"http://localhost:8551\"\n\n# RPC timeout for execution client requests.\nrpc-timeout = \"2s\"\n\n# RPC retry interval for execution client requests.\nrpc-retry-interval = \"100ms\"\n\n# RPC max retry interval for execution client requests.\nrpc-max-retry-interval = \"10s\"\n\n# Interval for the startup check.\nrpc-startup-check-interval = \"3s\"\n\n# Interval for the JWT refresh.\nrpc-jwt-refresh-interval = \"30s\"\n\n# Path to the execution client JWT-secret\njwt-secret-path = \"~/.beacond/config/jwt.hex\"\n\n[beacon-kit.logger]\n# TimeFormat is a string that defines the format of the time in the logger.\ntime-format = \"RFC3339\"\n\n# LogLevel is the level of logging. Logger will log messages with verbosity up\n# to LogLevel.\nlog-level = \"info\"\n\n# Style is the style of the logger.\nstyle = \"pretty\"\n\n[beacon-kit.kzg]\n# Path to the trusted setup path.\ntrusted-setup-path = \"~/.beacond/config/kzg-trusted-setup.json\"\n\n# KZG implementation to use.\n# Options are \"crate-crypto/go-kzg-4844\".\nimplementation = \"crate-crypto/go-kzg-4844\"\n\n[beacon-kit.payload-builder]\n# Enabled determines if the local payload builder is enabled.\n# It should be enabled for validators, but it can be disabled\n# for full nodes.\nenabled = true\n\n# Post bellatrix, this address will receive the transaction fees produced by any blocks\n# from this node.\nsuggested-fee-recipient = \"0x0000000000000000000000000000000000000000\"\n\n# The timeout for local build payload. This should match, or be slightly less\n# than the configured timeout on your execution client. It also must be less than\n# timeout_proposal in the CometBFT configuration.\npayload-timeout = \"850ms\"\n\n[beacon-kit.validator]\n# Graffiti string that will be included in the graffiti field of the beacon block.\ngraffiti = \"\"\n\n# AvailabilityWindow is the number of slots to keep in the store.\n# Setting AvailabilityWindow to 0 disables block store and does not allow the node\n# to serve proof or namespace apis from beacon node-api.\navailability-window = \"8192\"\n\n[beacon-kit.node-api]\n# Enabled determines if the node API is enabled.\nenabled = \"false\"\n\n# Address is the address to bind the node API to.\naddress = \"0.0.0.0:3500\"\n\n# Logging determines if the node API logging is enabled.\nlogging = \"false\"\n"
  },
  {
    "path": "testing/networks/80094/client.toml",
    "content": "# This is a TOML config file.\n# For more information, see https://github.com/toml-lang/toml\n\n###############################################################################\n###                           Client Configuration                            ###\n###############################################################################\n\n# The network chain ID\nchain-id = \"mainnet-beacon-80094\"\n# The keyring's backend, where the keys are stored (os|file|kwallet|pass|test|memory)\nkeyring-backend = \"test\"\n# CLI output format (text|json)\noutput = \"text\"\n# <host>:<port> to Tendermint RPC interface for this chain\nnode = \"tcp://localhost:26657\"\n# Transaction broadcasting mode (sync|async)\nbroadcast-mode = \"sync\"\n"
  },
  {
    "path": "testing/networks/80094/config.toml",
    "content": "# This is a TOML config file.\n# For more information, see https://github.com/toml-lang/toml\n\n# NOTE: Any path below can be absolute (e.g. \"/var/myawesomeapp/data\") or\n# relative to the home directory (e.g. \"data\"). The home directory is\n# \"$HOME/.cometbft\" by default, but could be changed via $CMTHOME env variable\n# or --home cmd flag.\n\n# The version of the CometBFT binary that created or\n# last modified the config file. Do not modify this.\nversion = \"1.0.0\"\n\n#######################################################################\n###                   Main Base Config Options                      ###\n#######################################################################\n\n# TCP or UNIX socket address of the ABCI application,\n# or the name of an ABCI application compiled in with the CometBFT binary\nproxy_app = \"tcp://127.0.0.1:26658\"\n\n# A custom human readable name for this node\nmoniker = \"oogabooga\"\n\n# Database backend: goleveldb | cleveldb | boltdb | rocksdb | badgerdb\n# * goleveldb (github.com/syndtr/goleveldb - most popular implementation)\n#   - pure go\n#   - stable\n# * cleveldb (uses levigo wrapper)\n#   - fast\n#   - requires gcc\n#   - use cleveldb build tag (go build -tags cleveldb)\n# * boltdb (uses etcd's fork of bolt - github.com/etcd-io/bbolt)\n#   - EXPERIMENTAL\n#   - may be faster is some use-cases (random reads - indexer)\n#   - use boltdb build tag (go build -tags boltdb)\n# * rocksdb (uses github.com/tecbot/gorocksdb)\n#   - EXPERIMENTAL\n#   - requires gcc\n#   - use rocksdb build tag (go build -tags rocksdb)\n# * badgerdb (uses github.com/dgraph-io/badger)\n#   - EXPERIMENTAL\n#   - use badgerdb build tag (go build -tags badgerdb)\ndb_backend = \"pebbledb\"\n\n# Database directory\ndb_dir = \"data\"\n\n# Output level for logging, including package level options\nlog_level = \"info\"\n\n# Output format: 'plain' (colored text) or 'json'\nlog_format = \"plain\"\n\n##### additional base config options #####\n\n# Path to the JSON file containing the initial validator set and other meta data\ngenesis_file = \"config/genesis.json\"\n\n# Path to the JSON file containing the private key to use as a validator in the consensus protocol\npriv_validator_key_file = \"config/priv_validator_key.json\"\n\n\n# Path to the JSON file containing the last sign state of a validator\npriv_validator_state_file = \"data/priv_validator_state.json\"\n\n# TCP or UNIX socket address for CometBFT to listen on for\n# connections from an external PrivValidator process\npriv_validator_laddr = \"\"\n\n# Path to the JSON file containing the private key to use for node authentication in the p2p protocol\nnode_key_file = \"config/node_key.json\"\n\n# Mechanism to connect to the ABCI application: socket | grpc\nabci = \"socket\"\n\n\n# If true, query the ABCI app on connecting to a new peer\n# so the app can decide if we should keep the connection or not\nfilter_peers = false\n\n\n#######################################################################\n###                 Advanced Configuration Options                  ###\n#######################################################################\n\n#######################################################\n###       RPC Server Configuration Options          ###\n#######################################################\n[rpc]\n\n# TCP or UNIX socket address for the RPC server to listen on\nladdr = \"tcp://127.0.0.1:26657\"\n\n# A list of origins a cross-domain request can be executed from\n# Default value '[]' disables cors support\n# Use '[\"*\"]' to allow any origin\ncors_allowed_origins = []\n\n# A list of methods the client is allowed to use with cross-domain requests\ncors_allowed_methods = ['HEAD', 'GET', 'POST']\n\n# A list of non simple headers the client is allowed to use with cross-domain requests\ncors_allowed_headers = ['Origin', 'Accept', 'Content-Type', 'X-Requested-With', 'X-Server-Time']\n\n# Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool\nunsafe = false\n\n# Maximum number of simultaneous connections (including WebSocket).\n# Does not include gRPC connections. See grpc_max_open_connections\n# If you want to accept a larger number than the default, make sure\n# you increase your OS limits.\n# 0 - unlimited.\n# Should be < {ulimit -Sn} - {MaxNumInboundPeers} - {MaxNumOutboundPeers} - {N of wal, db and other open files}\n# 1024 - 40 - 10 - 50 = 924 = ~900\nmax_open_connections = 900\n\n# Maximum number of unique clientIDs that can /subscribe\n# If you're using /broadcast_tx_commit, set to the estimated maximum number\n# of broadcast_tx_commit calls per block.\nmax_subscription_clients = 100\n\n# Maximum number of unique queries a given client can /subscribe to\n# If you're using GRPC (or Local RPC client) and /broadcast_tx_commit, set to\n# the estimated # maximum number of broadcast_tx_commit calls per block.\nmax_subscriptions_per_client = 5\n\n# Experimental parameter to specify the maximum number of events a node will\n# buffer, per subscription, before returning an error and closing the\n# subscription. Must be set to at least 100, but higher values will accommodate\n# higher event throughput rates (and will use more memory).\nexperimental_subscription_buffer_size = 200\n\n# Experimental parameter to specify the maximum number of RPC responses that\n# can be buffered per WebSocket client. If clients cannot read from the\n# WebSocket endpoint fast enough, they will be disconnected, so increasing this\n# parameter may reduce the chances of them being disconnected (but will cause\n# the node to use more memory).\n#\n# Must be at least the same as \"experimental_subscription_buffer_size\",\n# otherwise connections could be dropped unnecessarily. This value should\n# ideally be somewhat higher than \"experimental_subscription_buffer_size\" to\n# accommodate non-subscription-related RPC responses.\nexperimental_websocket_write_buffer_size = 200\n\n# If a WebSocket client cannot read fast enough, at present we may\n# silently drop events instead of generating an error or disconnecting the\n# client.\n#\n# Enabling this experimental parameter will cause the WebSocket connection to\n# be closed instead if it cannot read fast enough, allowing for greater\n# predictability in subscription behavior.\nexperimental_close_on_slow_client = false\n\n# How long to wait for a tx to be committed during /broadcast_tx_commit.\n# WARNING: Using a value larger than 10s will result in increasing the\n# global HTTP write timeout, which applies to all connections and endpoints.\n# See https://github.com/tendermint/tendermint/issues/3435\ntimeout_broadcast_tx_commit = \"10s\"\n\n# Maximum size of request body, in bytes\nmax_body_bytes = 1000000\n\n# Maximum size of request header, in bytes\nmax_header_bytes = 1048576\n\n# The path to a file containing certificate that is used to create the HTTPS server.\n# Might be either absolute path or path related to CometBFT's config directory.\n# If the certificate is signed by a certificate authority,\n# the certFile should be the concatenation of the server's certificate, any intermediates,\n# and the CA's certificate.\n# NOTE: both tls_cert_file and tls_key_file must be present for CometBFT to create HTTPS server.\n# Otherwise, HTTP server is run.\ntls_cert_file = \"\"\n\n# The path to a file containing matching private key that is used to create the HTTPS server.\n# Might be either absolute path or path related to CometBFT's config directory.\n# NOTE: both tls-cert-file and tls-key-file must be present for CometBFT to create HTTPS server.\n# Otherwise, HTTP server is run.\ntls_key_file = \"\"\n\n# pprof listen address (https://golang.org/pkg/net/http/pprof)\n#pprof_laddr = \"0.0.0.0:6060\"\npprof_laddr = \"\"\n\n#######################################################\n###           P2P Configuration Options             ###\n#######################################################\n[p2p]\n\n# Address to listen for incoming connections\nladdr = \"tcp://0.0.0.0:26656\"\n\n# Address to advertise to peers for them to dial. If empty, will use the same\n# port as the laddr, and will introspect on the listener to figure out the\n# address. IP and port are required. Example: 159.89.10.97:26656\nexternal_address = \"\"\n\n# Comma separated list of seed nodes to connect to\nseeds = \"1af8f82739bf4031302d9ec5a21508e09245a75d@34.159.172.173:26656,9551cfb45e5220e28b397da58b022841cc4fd258@35.198.184.184:26656,da82fec973bb65b2dce04f5824ce27b5510adce1@35.198.137.87:26656,6aadbeb00cde44d3fef065d58e1a59b3a211b5ca@34.141.37.10:26656,19ebee0c648cdf45b4933335b27d98f4acfa2f56@34.159.32.171:26656,7aa92c3227155390ce9a4cd0135c46a1ee9d5a80@34.159.140.231:26656,2784663b1c3fa2984b18cba3cffcd9af6c6ecef5@35.203.60.135:26656,157a420b52213bdc6f8169f2a3283b43d4851a23@34.118.176.138:26656,7b525992c6d6a882aeba3e7a6659c47549d46654@35.203.45.113:26656,ce5a29ac97e0ceb3a255cb991775fbfde80c52a3@34.47.19.7:26656,2bce8d3a4cd4b67b00d9595d38c4929fab76ada5@34.95.41.91:26656,c6b73f0a3621ac84c8b56af643134bea6d8acc72@34.47.62.196:26656,90071ab5ecc7c83e974bc2cc32739926d9b8a34d@34.95.19.199:26656,6f121dafe50e3c9bd9716a950e70ded165e686a9@34.95.32.61:26656,335a9a6b41338fb4dd6f819e7525c2316a33d593@64.34.94.91:26656,44aaf5938d5d06f42722ed73f41403620fbdc77d@64.34.94.87:26656\"\n\n# Comma separated list of nodes to keep persistent connections to\npersistent_peers = \"\"\n\n# Path to address book\naddr_book_file = \"config/addrbook.json\"\n\n# Set true for strict address routability rules\n# Set false for private or local networks\naddr_book_strict = true\n\n# Maximum number of inbound peers\nmax_num_inbound_peers = 40\n\n# Maximum number of outbound peers to connect to, excluding persistent peers\nmax_num_outbound_peers = 10\n\n# List of node IDs, to which a connection will be (re)established ignoring any existing limits\nunconditional_peer_ids = \"\"\n\n# Maximum pause when redialing a persistent peer (if zero, exponential backoff is used)\npersistent_peers_max_dial_period = \"0s\"\n\n# Time to wait before flushing messages out on the connection\nflush_throttle_timeout = \"10ms\"\n\n# Maximum size of a message packet payload, in bytes\nmax_packet_msg_payload_size = 1024\n\n# Rate at which packets can be sent, in bytes/second\nsend_rate = 5120000\n\n# Rate at which packets can be received, in bytes/second\nrecv_rate = 5120000\n\n# Set true to enable the peer-exchange reactor\npex = true\n\n# Seed mode, in which node constantly crawls the network and looks for\n# peers. If another node asks it for addresses, it responds and disconnects.\n#\n# Does not work if the peer-exchange reactor is disabled.\nseed_mode = false\n\n# Comma separated list of peer IDs to keep private (will not be gossiped to other peers)\nprivate_peer_ids = \"\"\n\n# Toggle to disable guard against peers connecting from the same ip.\nallow_duplicate_ip = false\n\n# Peer connection configuration.\nhandshake_timeout = \"20s\"\ndial_timeout = \"3s\"\n\n#######################################################\n###          Mempool Configuration Option          ###\n#######################################################\n[mempool]\n\n# The type of mempool for this node to use.\n#\n#  Possible types:\n#  - \"flood\" : concurrent linked list mempool with flooding gossip protocol\n#  (default)\n#  - \"nop\"   : nop-mempool (short for no operation; the ABCI app is responsible\n#  for storing, disseminating and proposing txs). \"create_empty_blocks=false\" is\n#  not supported.\ntype = \"nop\"\n\n\n# Recheck (default: true) defines whether CometBFT should recheck the\n# validity for all remaining transaction in the mempool after a block.\n# Since a block affects the application state, some transactions in the\n# mempool may become invalid. If this does not apply to your application,\n# you can disable rechecking.\nrecheck = false\n\n# recheck_timeout is the time the application has during the rechecking process\n# to return CheckTx responses, once all requests have been sent. Responses that\n# arrive after the timeout expires are discarded. It only applies to\n# non-local ABCI clients and when recheck is enabled.\nrecheck_timeout = \"0s\"\n\n# Broadcast (default: true) defines whether the mempool should relay\n# transactions to other peers. Setting this to false will stop the mempool\n# from relaying transactions to other peers until they are included in a\n# block. In other words, if Broadcast is disabled, only the peer you send\n# the tx to will see it until it is included in a block.\nbroadcast = false\n\n# WalPath (default: \"\") configures the location of the Write Ahead Log\n# (WAL) for the mempool. The WAL is disabled by default. To enable, set\n# WalPath to where you want the WAL to be written (e.g.\n# \"data/mempool.wal\").\nwal_dir = \"\"\n\n# Maximum number of transactions in the mempool\nsize = 0\n\n# Limit the total size of all txs in the mempool.\n# This only accounts for raw transactions (e.g. given 1MB transactions and\n# max_txs_bytes=5MB, mempool will only accept 5 transactions).\nmax_txs_bytes = 0\n\n# Size of the cache (used to filter transactions we saw earlier) in transactions\ncache_size = 0\n\n# Do not remove invalid transactions from the cache (default: false)\n# Set to true if it's not possible for any invalid transaction to become valid\n# again in the future.\nkeep-invalid-txs-in-cache = false\n\n# Maximum size of a single transaction.\n# NOTE: the max size of a tx transmitted over the network is {max_tx_bytes}.\nmax_tx_bytes = 1048576\n\n# Maximum size of a batch of transactions to send to a peer\n# Including space needed by encoding (one varint per transaction).\n# XXX: Unused due to https://github.com/tendermint/tendermint/issues/5796\nmax_batch_size = 0\n\n# Experimental parameters to limit gossiping txs to up to the specified number of peers.\n# We use two independent upper values for persistent and non-persistent peers.\n# Unconditional peers are not affected by this feature.\n# If we are connected to more than the specified number of persistent peers, only send txs to\n# ExperimentalMaxGossipConnectionsToPersistentPeers of them. If one of those\n# persistent peers disconnects, activate another persistent peer.\n# Similarly for non-persistent peers, with an upper limit of\n# ExperimentalMaxGossipConnectionsToNonPersistentPeers.\n# If set to 0, the feature is disabled for the corresponding group of peers, that is, the\n# number of active connections to that group of peers is not bounded.\n# For non-persistent peers, if enabled, a value of 10 is recommended based on experimental\n# performance results using the default P2P configuration.\nexperimental_max_gossip_connections_to_persistent_peers = 0\nexperimental_max_gossip_connections_to_non_persistent_peers = 0\n\n#######################################################\n###         State Sync Configuration Options        ###\n#######################################################\n[statesync]\n# State sync rapidly bootstraps a new node by discovering, fetching, and restoring a state machine\n# snapshot from peers instead of fetching and replaying historical blocks. Requires some peers in\n# the network to take and serve state machine snapshots. State sync is not attempted if the node\n# has any local state (LastBlockHeight > 0). The node will have a truncated block history,\n# starting from the height of the snapshot.\nenable = false\n\n# RPC servers (comma-separated) for light client verification of the synced state machine and\n# retrieval of state data for node bootstrapping. Also needs a trusted height and corresponding\n# header hash obtained from a trusted source, and a period during which validators can be trusted.\n#\n# For Cosmos SDK-based chains, trust_period should usually be about 2/3 of the unbonding time (~2\n# weeks) during which they can be financially punished (slashed) for misbehavior.\nrpc_servers = \"\"\ntrust_height = 0\ntrust_hash = \"\"\ntrust_period = \"168h0m0s\"\n\n# Time to spend discovering snapshots before initiating a restore.\ndiscovery_time = \"15s\"\n\n# Temporary directory for state sync snapshot chunks, defaults to the OS tempdir (typically /tmp).\n# Will create a new, randomly named directory within, and remove it when done.\ntemp_dir = \"\"\n\n# The timeout duration before re-requesting a chunk, possibly from a different\n# peer (default: 1 minute).\nchunk_request_timeout = \"10s\"\n\n# The number of concurrent chunk fetchers to run (default: 1).\nchunk_fetchers = \"4\"\n\n#######################################################\n###       Block Sync Configuration Options          ###\n#######################################################\n[blocksync]\n\n# Block Sync version to use:\n#\n# In v0.37, v1 and v2 of the block sync protocols were deprecated.\n# Please use v0 instead.\n#\n#   1) \"v0\" - the default block sync implementation\nversion = \"v0\"\n\n#######################################################\n###         Consensus Configuration Options         ###\n#######################################################\n[consensus]\n\nwal_file = \"data/cs.wal/wal\"\n\n# How long we wait for a proposal block before prevoting nil\ntimeout_propose = \"2s\"\n# How much timeout_propose increases with each round\ntimeout_propose_delta = \"500ms\"\n# How long we wait after receiving +2/3 prevotes for “anything” (ie. not a single block or nil)\ntimeout_prevote = \"2s\"\n# How much the timeout_prevote increases with each round\ntimeout_prevote_delta = \"500ms\"\n# How long we wait after receiving +2/3 precommits for “anything” (ie. not a single block or nil)\ntimeout_precommit = \"2s\"\n# How much the timeout_precommit increases with each round\ntimeout_precommit_delta = \"500ms\"\n# How long we wait after committing a block, before starting on the new\n# height (this gives us a chance to receive some more precommits, even\n# though we already have +2/3).\n# Set to 0 if you want to make progress as soon as the node has all the precommits.\ntimeout_commit = \"500ms\"\n\n# Make progress as soon as we have all the precommits (as if TimeoutCommit = 0)\nskip_timeout_commit = false\n\n# How many blocks to look back to check existence of the node's consensus votes before joining consensus\n# When non-zero, the node will panic upon restart\n# if the same consensus key was used to sign {double_sign_check_height} last blocks.\n# So, validators should stop the state machine, wait for some blocks, and then restart the state machine to avoid panic.\ndouble_sign_check_height = 0\n\n# EmptyBlocks mode and possible interval between empty blocks\ncreate_empty_blocks = true\ncreate_empty_blocks_interval = \"0s\"\n\n# Reactor sleep duration parameters\npeer_gossip_sleep_duration = \"300ms\"\npeer_gossip_intraloop_sleep_duration = \"0s\"\npeer_query_maj23_sleep_duration = \"2s\"\n\n#######################################################\n###         Storage Configuration Options           ###\n#######################################################\n[storage]\n\n# Set to true to discard ABCI responses from the state store, which can save a\n# considerable amount of disk space. Set to false to ensure ABCI responses are\n# persisted. ABCI responses are required for /block_results RPC queries, and to\n# reindex events in the command-line tool.\ndiscard_abci_responses = true\n\n# The representation of keys in the database.\n# The current representation of keys in Comet's stores is considered to be v1\n# Users can experiment with a different layout by setting this field to v2.\n# Note that this is an experimental feature and switching back from v2 to v1\n# is not supported by CometBFT.\n# If the database was initially created with v1, it is necessary to migrate the DB\n# before switching to v2. The migration is not done automatically.\n# v1 - the legacy layout existing in Comet prior to v1.\n# v2 - Order preserving representation ordering entries by height.\nexperimental_db_key_layout = \"v1\"\n\n# If set to true, CometBFT will force compaction to happen for databases that support this feature.\n# and save on storage space. Setting this to true is most benefits when used in combination\n# with pruning as it will physically delete the entries marked for deletion.\n# false by default (forcing compaction is disabled).\ncompact = false\n\n# To avoid forcing compaction every time, this parameter instructs CometBFT to wait\n# the given amount of blocks to be pruned before triggering compaction.\n# It should be tuned depending on the number of items. If your retain height is 1 block,\n# it is too much of an overhead to try compaction every block. But it should also not be a very\n# large multiple of your retain height as it might occur bigger overheads.\ncompaction_interval = \"1000\"\n\n[storage.pruning]\n\n# The time period between automated background pruning operations.\ninterval = \"10s\"\n\n#\n# Storage pruning configuration relating only to the data companion.\n#\n[storage.pruning.data_companion]\n\n# Whether automatic pruning respects values set by the data companion. Disabled\n# by default. All other parameters in this section are ignored when this is\n# disabled.\n#\n# If disabled, only the application retain height will influence block pruning\n# (but not block results pruning). Only enabling this at a later stage will\n# potentially mean that blocks below the application-set retain height at the\n# time will not be available to the data companion.\nenabled = false\n\n# The initial value for the data companion block retain height if the data\n# companion has not yet explicitly set one. If the data companion has already\n# set a block retain height, this is ignored.\ninitial_block_retain_height = 0\n\n# The initial value for the data companion block results retain height if the\n# data companion has not yet explicitly set one. If the data companion has\n# already set a block results retain height, this is ignored.\ninitial_block_results_retain_height = 0\n\n#######################################################\n###   Transaction Indexer Configuration Options     ###\n#######################################################\n[tx_index]\n\n# What indexer to use for transactions\n#\n# The application will set which txs to index. In some cases a node operator will be able\n# to decide which txs to index based on configuration set in the application.\n#\n# Options:\n#   1) \"null\"\n#   2) \"kv\" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend).\n# \t\t- When \"kv\" is chosen \"tx.height\" and \"tx.hash\" will always be indexed.\n#   3) \"psql\" - the indexer services backed by PostgreSQL.\n# When \"kv\" or \"psql\" is chosen \"tx.height\" and \"tx.hash\" will always be indexed.\nindexer = \"null\"\n\n# The PostgreSQL connection configuration, the connection format:\n#   postgresql://<user>:<password>@<host>:<port>/<db>?<opts>\npsql-conn = \"\"\n\n#######################################################\n###       Instrumentation Configuration Options     ###\n#######################################################\n[instrumentation]\n\n# When true, Prometheus metrics are served under /metrics on\n# PrometheusListenAddr.\n# Check out the documentation for the list of available metrics.\nprometheus = true\n\n# Address to listen for Prometheus collector(s) connections\nprometheus_listen_addr = \":26660\"\n\n# Maximum number of simultaneous connections.\n# If you want to accept a larger number than the default, make sure\n# you increase your OS limits.\n# 0 - unlimited.\nmax_open_connections = 800\n\n# Instrumentation namespace\nnamespace = \"cometbft\"\n"
  },
  {
    "path": "testing/networks/80094/el-bootnodes.txt",
    "content": "South Korea\n\nenode://0c5a4a3c0e81fce2974e4d317d88df783731183d534325e32e0fdf8f4b119d7889fa254d3a38890606ec300d744e2aa9c87099a4a032f5c94efe53f3fcdfecfe@34.64.176.79:30303\nenode://b6a3137d3a36ef37c4d31843775a9dc293f41bcbde33b6309c80b1771b6634827cd188285136a57474427bd8845adc2f6fe2e0b106bd58d14795b08910b9c326@34.64.181.70:30303\nenode://0b6633300614bc2b9749aee0cace7a091ec5348762aee7b1d195f7616d03a9409019d9bef336624bab72e0d069cd4cf0b0de6fbbf53f04f6b6e4c5b39c6bdca6@34.64.39.31:30303\nenode://552b001abebb5805fcd734ad367cd05d9078d18f23ec598d7165460fadcfc51116ad95c418f7ea9a141aa8cbc496c8bea3322b67a5de0d3380f11aab1a797513@34.64.183.158:30303\n\nSingapore\n\nenode://5b037f66099d5ded86eb7e1619f6d06ceb15609e8cc345ced22a4772b06178004e1490a3cd32fd1222789de4c6e4021c2d648a3d750f6d5323e64b771bbd8de7@34.87.142.180:30303\nenode://846db253c53753d3ea1197aec296306dc84c25f3afdf142b65cb0fe0f984de55072daa3bbf05a9aea046a38a2292403137b6eafefd5646fcf62120b74e3b898d@34.142.170.110:30303\nenode://64b7f6ee9bcd942ad4949c70f2077627f078a057dfd930e6e904e12643d8952f5ae87c91e24559765393f244a72c9d5c011d7d5176e59191d38f315db85a20f5@34.126.161.16:30303\nenode://cf4d19bfb8ec507427ec882bac0bac85a0c8c9ddaa0ec91b773bb614e5e09d107cd9fbe323b96f62f31c493f8f42cc5495c18b87c08560c5dea1dfd25256dcf6@35.247.162.2:30303\n\nGermany\n\nenode://bb7e44178543431feac8f0ee3827056b7b84d8235b802a8bdbbcd4939dab7f7dd2579ff577a38b002bb0139792af67abd2dd5c9f4f85b8da6e914fa76dca82bc@35.198.150.35:30303\nenode://8fef1f5df45e7b31be00a21e1da5665d5a5f5bf4c379086b843f03eade941bdd157f08c95b31880c492577edb9a9b185df7191eaebf54ab06d5bd683b289f3af@34.107.7.241:30303\nenode://ce9c87cfe089f6811d26c96913fa3ec10b938d9017fc6246684c74a33679ee34ceca9447180fb509e37bf2b706c2877a82085d34bfd83b5b520ee1288b0fc32f@35.198.109.49:30303\nenode://713657eb6a53feadcbc47e634ad557326a51eb6818a3e19a00a8111492f50a666ccbf2f5d334d247ecf941e68d242ef5c3b812b63c44d381ef11f79c2cdb45c7@34.141.15.100:30303\n\nCanada\n\nenode://d071fa740e063ce1bb9cdc2b7937baeff6dc4000f91588d730a731c38a6ff0d4015814812c160fab8695e46f74b9b618735368ea2f16db4d785f16d29b3fb7b0@35.203.2.210:30303\nenode://ffc452fe451a2e5f89fe634744aea334d92dcd30d881b76209d2db7dbf4b7ee047e7c69a5bb1633764d987a7441d9c4bc57ccdbfd6442a2f860bf953bc89a9b9@34.152.50.224:30303\nenode://da94328302a1d1422209d1916744e90b6095a48b2340dcec39b22002c098bb4d58a880dab98eb26edf03fa4705d1b62f99a8c5c14e6666e4726b6d3066d8a4d7@34.95.61.106:30303\nenode://19c7671a4844699b481e81a5bcfe7bafc7fefa953c16ebbe1951b1046371e73839e9058de6b7d3c934318fe7e7233dde3621c1c1018eb8b294ea3d4516147150@35.203.82.137:30303\n"
  },
  {
    "path": "testing/networks/80094/el-peers.txt",
    "content": "enode://0c5a4a3c0e81fce2974e4d317d88df783731183d534325e32e0fdf8f4b119d7889fa254d3a38890606ec300d744e2aa9c87099a4a032f5c94efe53f3fcdfecfe@34.22.104.177:30303,enode://b6a3137d3a36ef37c4d31843775a9dc293f41bcbde33b6309c80b1771b6634827cd188285136a57474427bd8845adc2f6fe2e0b106bd58d14795b08910b9c326@34.64.247.85:30303,enode://0b6633300614bc2b9749aee0cace7a091ec5348762aee7b1d195f7616d03a9409019d9bef336624bab72e0d069cd4cf0b0de6fbbf53f04f6b6e4c5b39c6bdca6@34.22.73.21:30303,enode://552b001abebb5805fcd734ad367cd05d9078d18f23ec598d7165460fadcfc51116ad95c418f7ea9a141aa8cbc496c8bea3322b67a5de0d3380f11aab1a797513@34.64.37.55:30303,enode://5b037f66099d5ded86eb7e1619f6d06ceb15609e8cc345ced22a4772b06178004e1490a3cd32fd1222789de4c6e4021c2d648a3d750f6d5323e64b771bbd8de7@35.247.182.34:30303,enode://846db253c53753d3ea1197aec296306dc84c25f3afdf142b65cb0fe0f984de55072daa3bbf05a9aea046a38a2292403137b6eafefd5646fcf62120b74e3b898d@34.87.9.231:30303,enode://64b7f6ee9bcd942ad4949c70f2077627f078a057dfd930e6e904e12643d8952f5ae87c91e24559765393f244a72c9d5c011d7d5176e59191d38f315db85a20f5@34.126.78.49:30303,enode://cf4d19bfb8ec507427ec882bac0bac85a0c8c9ddaa0ec91b773bb614e5e09d107cd9fbe323b96f62f31c493f8f42cc5495c18b87c08560c5dea1dfd25256dcf6@35.240.200.36:30303,enode://bb7e44178543431feac8f0ee3827056b7b84d8235b802a8bdbbcd4939dab7f7dd2579ff577a38b002bb0139792af67abd2dd5c9f4f85b8da6e914fa76dca82bc@34.40.14.50:30303,enode://8fef1f5df45e7b31be00a21e1da5665d5a5f5bf4c379086b843f03eade941bdd157f08c95b31880c492577edb9a9b185df7191eaebf54ab06d5bd683b289f3af@35.246.168.217:30303,enode://ce9c87cfe089f6811d26c96913fa3ec10b938d9017fc6246684c74a33679ee34ceca9447180fb509e37bf2b706c2877a82085d34bfd83b5b520ee1288b0fc32f@34.40.28.159:30303,enode://713657eb6a53feadcbc47e634ad557326a51eb6818a3e19a00a8111492f50a666ccbf2f5d334d247ecf941e68d242ef5c3b812b63c44d381ef11f79c2cdb45c7@35.234.82.236:30303,enode://d071fa740e063ce1bb9cdc2b7937baeff6dc4000f91588d730a731c38a6ff0d4015814812c160fab8695e46f74b9b618735368ea2f16db4d785f16d29b3fb7b0@35.203.86.197:30303,enode://ffc452fe451a2e5f89fe634744aea334d92dcd30d881b76209d2db7dbf4b7ee047e7c69a5bb1633764d987a7441d9c4bc57ccdbfd6442a2f860bf953bc89a9b9@34.118.187.161:30303,enode://da94328302a1d1422209d1916744e90b6095a48b2340dcec39b22002c098bb4d58a880dab98eb26edf03fa4705d1b62f99a8c5c14e6666e4726b6d3066d8a4d7@34.95.30.190:30303,enode://19c7671a4844699b481e81a5bcfe7bafc7fefa953c16ebbe1951b1046371e73839e9058de6b7d3c934318fe7e7233dde3621c1c1018eb8b294ea3d4516147150@34.47.60.196:30303"
  },
  {
    "path": "testing/networks/80094/genesis.json",
    "content": "{\n  \"app_name\": \"beacond\",\n  \"app_version\": \"v1.0.0\",\n  \"genesis_time\": \"2025-01-20T14:00:00Z\",\n  \"chain_id\": \"mainnet-beacon-80094\",\n  \"initial_height\": 1,\n  \"app_hash\": null,\n  \"app_state\": {\n    \"beacon\": {\n      \"fork_version\": \"0x04000000\",\n      \"deposits\": [\n        {\n          \"pubkey\": \"0x98111a6ee569f1be005551d8c76e042aabcb5bf4c491d177445a2b5fb30dedc7bf6db39e387831c6739bde4129c6ada5\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0x1c6bf52634000\",\n          \"signature\": \"0x88a0a6b0cfa3e03b6c33684edbad9062431f5db53b7fe9322a386a335e0e3936c45e886f6bcf228d88c980423c69433e0491a74ff0be6d93657425b1f7146e654f7405a8d956a175657551a6a9e319264b5b2fbc4ad423dfe6308d0ee32411f0\",\n          \"index\": 0\n        },\n        {\n          \"pubkey\": \"0xa14fa37a1d4c65326bf091d3bb0e5607fde8946471ed923e6815077fac7282d89820dd4f8765e4085ca8247fb99ecb6b\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0x1c6bf52634000\",\n          \"signature\": \"0xac2a43306aaad2da1ed72c4171f9b20f9d5cf3e9abffca6868dffedd5b710cd4b972cd662719fffa86870666b1b160390f671dfa22bf32987cf993ef92b72e2fff45af60438998a629037884242255567bea35be7cfe2e2a3317b2a788dc0925\",\n          \"index\": 1\n        },\n        {\n          \"pubkey\": \"0x80305831f81c688a6814ebf9d9b842e28a20b425864c480fab6f52e41541853eab39e77ca68248d096bd4d5499b24b7e\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xb0058439696ffcb4b75add47afce6d4adcc3306f16cae5fe620748bb17cf00899f71bbd348fb3cf32e06799eb435a7c60dc31b9a0179956f2cb77309594e6c3b809e999dbddcf540f7d96f58d3ec4410a847c1cd91ba63384630222d33dc8185\",\n          \"index\": 2\n        },\n        {\n          \"pubkey\": \"0x8148ddb478a291cf6a16fb98195e3076aad319ca8821b4aef69c8d1d45c8ed49d61109a1cbc029b58f22f5bb60854fe4\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0x8c76bcc35b2d7b8fdddcfba02302dedc83f1c0aa69610a3568e3445defc31abd6427d93a60b7cde09b167fffdbfbc49d1916584925214b54339fbd800323a80150bfd7209c7103cda89032232f380716331a3888795eaf5ce031b53d125b7c5a\",\n          \"index\": 3\n        },\n        {\n          \"pubkey\": \"0xa232a81b5e834b817db01d85ee13e36552b48413626287de511b6c89b7b8ff4a448e865713fd21c98f1467a58fe6efe5\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xa3073a0c3f7db231f284cc144b96b53134a5a58e5f72de8d44547ea6e95fc948842963a9dac97b1418e4951e7a7ef8ae0a8b8556c87fef0e29f92b809f20fea424806ef6d2658f357175d1049c2802f233de3f5b9265a1166e8174f1880890c1\",\n          \"index\": 4\n        },\n        {\n          \"pubkey\": \"0xa247c21f73c3327f31f8ee0dbb40110ef0a830af89b83986dddf92d1bd1a68b88f9050bc6a0f1405cb75fbb457e3e83b\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0x1c6bf52634000\",\n          \"signature\": \"0x95930ca76ed1b79a3c7a41d2521efb2d196944b8af0714b35df77a2d55d56a75868d160eea040cad7badc6aab0901bee178e8c26f3d5509fc10c5fbb7bd5d20693e20c5f9f3c817d06f64284abce34f6c11d7ffe2632b7582a7cec569325662b\",\n          \"index\": 5\n        },\n        {\n          \"pubkey\": \"0x832153bf3e09b9cab14414425a0ebaeb889e21d20872ebb990ed9a6102d7dc7f3017d4689f931a8e96d918bdeb184e1b\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0x1c6bf52634000\",\n          \"signature\": \"0x8b9c2cd08c7ea88d6535e7c8dc4d62ba5e4e58049424e79724f5365b8adce2b338e2ec6e6510570e7b9951838975da49189f37ffc3752d906ff14a9b659f05f13188fd34ac0bdb4d24e408ff3dac8e09652099f6b2c76ed4bebb2d9b944d2bc5\",\n          \"index\": 6\n        },\n        {\n          \"pubkey\": \"0xa3539ca28e0fd74d2a3c4c552740be77d6914cad2d8ec16583492cc57e8cfa358c62e31cc9106b1700cc169962855a6f\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0x9978adfbceddc79b472634aacb781060a7d3d4e9c1051325385f1fa75169f10b04d45f7b8dddf1c5a4104e7bcbad450903d80ce7b59a59b8597fd9d72cd7f514336a6e7987e3234ab570195f617a515a08b1e1f52f6eb3f8c7b47d3748f3ce0d\",\n          \"index\": 7\n        },\n        {\n          \"pubkey\": \"0xa3ae000f40c06c1af1c40d713370a5fbf2cc28fdd6a03b36b751a1eb28a5699eea469d7b337981081facc738c326091d\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0x96a4310025bb94b8ce017c67cd87848807a7848b8f936bc230a9796eb73f61da8c3a633cf8430352fa61d0005816b1e405941a1970eefb5d9aa8799a0cd6855302e6fb05e0d8e00d055fd9fce29f01b23b06cf88ca263393a08a1f5f681ff6b5\",\n          \"index\": 8\n        },\n        {\n          \"pubkey\": \"0xa6194b4dc5f7c8bd00666cbe1a9490eae3306ff397c4d198395dd938100fc3828e2d072a1bf6f256299f9cdb8d2b42f0\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xb31e4b01eee9b172b6da62a40eafd3df3e7dd72f24bc90263efbdc18dd585c0fdae77cf10378465d09123989629b6b33039631b107a60bafcb3437d1c36abcee173945669c936036b9eafb6a042fd51b00f526e84bddd1197172fbf06f8100aa\",\n          \"index\": 9\n        },\n        {\n          \"pubkey\": \"0x865a04fc3fb234b69595fc464b00604e8e1f387d47dc6bca2d1503a82d2e20060334ef275c764136f13b87447bd3d0a8\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0x1c6bf52634000\",\n          \"signature\": \"0x8a71c514d75a5506f2cc8e7f4bcd5e67dab6ecba21f6f0adbcb927751b0cbceacce0629991956cab84f1aa2fd23eae7d14ba271adaddf39612769c9b6db4bde9d455158976f6f45319c428f254e9b8704b5d3e6c0e9b8f9f679cc5a9d8a5fdf4\",\n          \"index\": 10\n        },\n        {\n          \"pubkey\": \"0xa769858cabcbe2fa239997e676e378f2037a679a1cf674679c40e410ffa9e72921781c24af7cc79969361559e88615de\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xa3bccffbc3daf7f34f8f1fcad65d32019f56e891341806b2536c457dd65932236be7379cfa36515fe928257506643d6806bd23096abcb5459d8209a315d69f296df5c3a68f8480c7285aec5ca7a8dc4b7cee69177db8cbf254fb91348794db13\",\n          \"index\": 11\n        },\n        {\n          \"pubkey\": \"0xa7f3186065f3f18a4b21b661f40941b942dad39062d9df399d94a18870e0600f1ccab51ee71ca5d6f971b79c2e51d6de\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xaa16f8f87b93cdbeb375fc86b284209b8c0146748b9981dda09548feb44a4cb02b5a09b76d4a5965d053dc20b157ec290b7a0e6b3d353ecec135f0f790fb5061b084392bb4caf2d0e6ed204e3382260ec3692f684dcc1ebf33aa0d3f86d3bfa3\",\n          \"index\": 12\n        },\n        {\n          \"pubkey\": \"0x89233d54cc54e67cbab9493af37bcbedaa9def92c14637694bf88f675b2ccd0a6c98a8dde009d6d80f515f11a8845517\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xaeabb1b459dd7069a0979e70a988734b880087e0e739b49fb461b8900fe8b2d24528469559553d286342960a25187bc611aaf289c6872b9fb3af68326a6cbc92b0e12c85109bd7d656670a7cd64194620b448d6179cd0776a69c369bd62c3f43\",\n          \"index\": 13\n        },\n        {\n          \"pubkey\": \"0x89884fc95abcb82736d768fc8ad4fdf4cb2112496974ae05440d835d0e93216643ae212b365fb6d9d2501d76d0925ef3\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0x1c6bf52634000\",\n          \"signature\": \"0xa3ffd89ca2332fd848489d32d8bc6ab971a745edceac4bd6ad0262a020869c1ebe549c690ad818895fa767d0f111c91a106ad863bc58fcd90724e07baea01adcc8c8be67f2af9a153aea8cbc114b4959c7aaa78f2e13c5e6592b53512733b494\",\n          \"index\": 14\n        },\n        {\n          \"pubkey\": \"0x89c7f0d4cbace56294b624f6fa1b27beaa5afc9dab7072383c5f63f636e9f78f9e868a82e6684a72068199461f1f1c15\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0x84243354ef9365d76a68911f0ce632cdf7b4f02fa201dafe2afa7a09636315bf9417172cd5a503faeffed8da4c6e4ed50c67c119100964080481a41ee6e323db8f8d6e108bcb5b7f9a4b4b1f46edfb7250343a78468a70885ece13cbc2872807\",\n          \"index\": 15\n        },\n        {\n          \"pubkey\": \"0xab98ea73f3afab04154829f8d12a537cbf31a8b08f7f8e3870f4902001f0011234ed8f9218b40b4ed732d11d889f609d\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0x1c6bf52634000\",\n          \"signature\": \"0x84e20df0f06e96fc428d8e3de91f07e2adf2b6cb38b40d27d3fe3bc4cf5c1a8ef70ba7443e6133deda9f5300d19458f907ed03cc8f514a4aacec548cd1d2b113b63143965c83a302f25b00a085ae109ee5dd9393efe2d981bb7c12a9384195fc\",\n          \"index\": 16\n        },\n        {\n          \"pubkey\": \"0x8bca787da4be8b093c0e8bb9e62311ee61459140cd616aad48dbcab233a163da85994869983e74658fa53af595432df4\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xae469d8fad70139a3e646b1fe9277c28c6664b1ebf26b0cc5d6e4b87436c6cc93f707420b4352023bea70ccc6d66b77815831a677a23d8bfd191feaa5e80ec8c79b1a52c4faafc6ef4cc046ac9a6b89dafb3f6299e4b17d05d23aff05c4309d2\",\n          \"index\": 17\n        },\n        {\n          \"pubkey\": \"0xabfb6d9eb0785e57b43ecffddd5d906375dd627e7338137a77c02788ed6d569b1a098ff2c2499a740e382930b39bce48\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0x2aa1efb94e000\",\n          \"signature\": \"0xa3c97804578b6e579a14ad40133520a7c55c19182085ff93d56c188ccb8a7c4f650d28879e4bd9a26b8b35619ad2e46806560e7939c9a2758b4f6e22ca11b7a360e8b92edc6ece33cbb907d87de4846f4757931bec4f262d2c27cddad3d3d9f1\",\n          \"index\": 18\n        },\n        {\n          \"pubkey\": \"0x8d0a94a5a2bb0289ebb24e73233f5ae6508d635022d8a12c69fce99791783bd76ab3fd33b6304a5fe42b85201db12f18\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0x2aa1efb94e000\",\n          \"signature\": \"0xa2d3c4aebd0a19123515b8a03137ab5ffba65d6ae5ebd255d312d42441b35a07ac1cd56ae4e0d93b5858ca81387eed430973c8e20c1f8d34d26e7ffe6930c7b1c09fd8db557945fac57cc57b3047957957f7337ffdfe44ff2357103f6a3532bc\",\n          \"index\": 19\n        },\n        {\n          \"pubkey\": \"0x8db0c2f3475fbe90310e7b2ed608546dae7aa5d0fe7f3d2775c2e18ab0e87368bc8c670de021f7740f2f82e6d54a8131\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xb8ffcdbaad229d6cd0045b10d80d2f35b9d7c47abae43550eae0230861ff8f790b49825462bef4ba629c0526058dcb6803ac176ad5d0397dce1cfba76d754cd8b897a048dc3371932eb036de99bb7445392c7375e8d37bd2e25fb8a21b950036\",\n          \"index\": 20\n        },\n        {\n          \"pubkey\": \"0x8e3b35bd379652019fe8f341c5c854a60f55772016340781e8d3577e2b24e1ac0d5786d45459cd756810281eff8f729c\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xa56d5493a899bd0f7048b911b865329aa60baaac75ac583e471c5c1ef0b217e1e0ac752aef65a554741e71f1e749d9eb0c3a8c470822cc529a2a5ceb95e1bd064812579c08bd4ff6102a961ccd1de81e4afad59c08b7d157058d85f89ef1f62b\",\n          \"index\": 21\n        },\n        {\n          \"pubkey\": \"0xb1580b412431ff7a1cca16045f0996740a5e52ebd1aeff6359415d99886b89a3506b36bd71af132a5dcb989e7a89b58d\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xb93a03089b440b426ed181ce934df4b4683557fee4790b333da2e6e15af58533a177dfa6e30749a5775339000a8e3eab054c4cb2896677a4141abeeeea2a4ab0abd319f1567b13e4c77e80a8fe7b39ccb566654937604df03e0ae5196063386a\",\n          \"index\": 22\n        },\n        {\n          \"pubkey\": \"0xb255e317f7e6415eab053180c8e36b5f6312c1e6ee1e884a26c490aa4121595574656ed89c83e0d6afd5e2b33c00b101\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xada62b2c6a8b20f2e85b82a121c7762b69222108334a9c9ccb0fb48c84f42bc289b74257f28e3e3307bde6273ae2339b08429adad60a5f99d4e4904e03c99acb4a70c8bdfbf6a592d24a706544604d00186c1d47cd655eab8e8604e16c01686a\",\n          \"index\": 23\n        },\n        {\n          \"pubkey\": \"0xb2faa51f9cf1a8c818459034941d965445bda15b212661f74f09394f2febe40c1f8feeba0cedcafd4ad28a944afb2b2c\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0x963e542a648f85bf0e7b261e4fe35a6b8fe843f13dfdad0c6852fc7ad62e01c23834ec062323d0a771d8a430d420e0a817a966768496175fb7c664e929ad7a5a79e529c6867156b7ffa0fe4988c741ccc4e9bb68491504990664a4f3e7965c8b\",\n          \"index\": 24\n        },\n        {\n          \"pubkey\": \"0x93012bdcf6baa87c1737df03c5fac7c8bb447282fbca5d2de42726ec67f237d66a2f867853e32ebd295010f075f22e95\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xb44c9fa4887a02bf109dc10ea87421e27cc466d22efbd46b4044c89e1639a68e07c688ef8b36fd3361699f4554a734570f70975f4d15228e661f067a5ade7b5bd545287ef0c4eafba7b541f315c214cde7623443432313e21e95512eff4b8f5e\",\n          \"index\": 25\n        },\n        {\n          \"pubkey\": \"0xb40cc8701d344c41054a3d028bb5f5f0702f7c228b22bdc9081541808c101808d3db2c130d64359efdd7589365b8f05b\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xb2370b357a6d928c5112dcf86a44027c93e2148cbcb79472cae1b454a671c8daf98c5a05f007b45c940656867ea8358810c735b5a6eca502ff97f83b27f93220df1ff04e81f4ced487abb27a7923a00e29a98c3060ce213daaf5455ea1a6cbc7\",\n          \"index\": 26\n        },\n        {\n          \"pubkey\": \"0xb577aa07f35ba1651b266f7f316ed1cd10907d0064e01dbcb502ec8c39bc1fc01acde07f4755ad0d414832fa2e2b5629\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xacbe459f7949a2d30b652912a2b88faf78bc71f815367252e99ecf3c9a4f160dc3bfaa1ef5357a49e2a9105063757c020609f62d8e7f9794277b95025400ba390bd7b33c211a07f885125383b953e666c6bab3ee33dfa93d4fd87ec948427fd6\",\n          \"index\": 27\n        },\n        {\n          \"pubkey\": \"0x960052c5509caa280218f3ecf3da7ba5bf4ec20b97e6c52700dd93515ef4e963813aa92a8731c9e137b1027dbc77102f\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0x1c6bf52634000\",\n          \"signature\": \"0xadaec61ef0e55cf534648e3b3380618809716efdef669099bf74569281bef837ab7e6f8e4b17c838c9b8adaa3f6a4bdf00676520bac406621dfbd34c6243d95849f6dd3bd88cdb2e5075a3724cb967b811150f05f87c3e8e944416bd4d3e0ba9\",\n          \"index\": 28\n        },\n        {\n          \"pubkey\": \"0x964dd0632d0ed772dd0b5a269e9809be5b742df0ad4463552c7b51beef6baf6021360db60b0428ff1c4c38661c02b283\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0x8727fd93a940faa915d8b506537eb81dd786978892babab26c7c4a4cca6873604e7a1c057b74dcd8a5c4ffed02c43ac20bd17b4e24d66ba5a2ce2ceab21f10d1c8dee2cd566b75cedd37fe1d7868db212903ec66599a4ead0faadd29ff22555d\",\n          \"index\": 29\n        },\n        {\n          \"pubkey\": \"0x97266c94c490662479a9188b070c86e505df4f167016883af4114c8c1a71429e8f270c0c2f1b74375880f81828b768c0\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xa449362a6db71c5444eaa553d0239b148d3086fc3be0cdcb1184b947bd02c834bc9de91a197a61e51d9e1cbc059ca73d07001cca6fa2035fa49a668e6fce040d785e9bce595e8a63a6d26fabb3d65c49e27486ee28a77afed41d9cf2b3c2ed7d\",\n          \"index\": 30\n        },\n        {\n          \"pubkey\": \"0xb77084d2b92baa3e01ec5ce57fbd529d3c8e60941c637bdc7c85d9ca2cc56545c3cbea86879dcbe9402f8a55d0284e7b\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0x1c6bf52634000\",\n          \"signature\": \"0xabc2bd89d64c715cc5ea811b0f42ffffea6feb4e2b3e631834bdeb6d4771bf181d30a659f4733517353c5e7ec4dbc5cf14f5490e1b5c1b0068c155a4c16caf2cb84ea3666b35f711f399faefe63d5cdd99180129cc5f04fec55a96b825c0b641\",\n          \"index\": 31\n        },\n        {\n          \"pubkey\": \"0x98b7240b6aa60283ef2733840dc0996b1a16b68b38f9cbd83e5b7dda516d47b8279449f14c5b6a3d2bd8e74816ce2cae\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xac631262e9de9ce61e3502cb2fae5fdb68f6b173b74cd49707624c7ba0876c8e7d62076daefafea44af5821f32cf72630f91e1eea2a65f821003e80ec80dbb1e1a11d9368de404049f7fceacec0510c3a66748efd32a504ed807de3e68e44786\",\n          \"index\": 32\n        },\n        {\n          \"pubkey\": \"0x98beef4053d097aa1527a70301021a363fd3b92754a446932f5c97e7daa9c8d0bcf2ed315e7a55775a8bbe5ebe134ffb\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0x9187f8f325962f690fe67b497723df3a427e443832dcb7dc54c3019e061be9d15edb03c3644b7c37b6efc8fda915810e048cab47d752d1e04e6906d043e7f901c5e063dd6f3f2122ebb14cbcd4e2ddbaefcc82b06e062b7304511f15af012a41\",\n          \"index\": 33\n        },\n        {\n          \"pubkey\": \"0x83d0f90cdedaac1450c8dc08cfa644ae02f5918572041c2fca7df8b55336682cb5edbccadd6e77129de425844e147d02\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0x2386f26fc10000\",\n          \"signature\": \"0x921e7ea4d25e4904472db0cf2dcada03a776f614ef7c6a322972c1fc67f05ba76589cf577d62d7e7695795ac66242951160efab8200ed98781216ca7a0166e554efd4f3963bdd1f2ede64628be9661e8c406f91a35cf026baae4490878dda27e\",\n          \"index\": 34\n        },\n        {\n          \"pubkey\": \"0xa47aa6bd157dfa6ab6f411384a662c3d4d4f8745217ea8198470d6f3135bd71958fd824256fdbf16b21494ec3080b7ee\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0xa5682983524a9285c9bf6ec1d197d6c7bd87cb0f065d39b811be67527317b691c80dbd0cb4d01e3764675a7a8b36ec040f8e01bd51596ad79436c37ce87eaa1f79a69c7055bb0f4df79860f54f0ba2ba251fcaf24fe80c2e64ffc0421f6cfe37\",\n          \"index\": 35\n        },\n        {\n          \"pubkey\": \"0xa9504e88e6e969bd31a194c7c81df0e44b4644d0db81ad712d55023c5c6e1ac656558f27c8f8bac65c1fe72c597e6578\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0xe35fa931a000\",\n          \"signature\": \"0x8e6ca94997c9cdb616e2a446e82e169cba1cc6428b6e126099fe46b9f13ba01135d20bf54d1f0d84d5df470312bd3ddc045671b983c76bf313377faa68a3761d43196449528fa59b561d6e6c2fd322b8f37251d92ee44f006d5ca653d81f7f6f\",\n          \"index\": 36\n        },\n        {\n          \"pubkey\": \"0x83fd53710b75c2115bd0aac128b739eb9fa9e262603dacdf834030abb1bf4c8a6c00bb72b314c123d77f4ff40cd4d49a\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0x2386f26fc10000\",\n          \"signature\": \"0xaeddc8a422aad2f0a1ed0806211bc5b67ccfb6ffe83f17dce5e589b63861a82c9cc4481bb0bd3f64905eb63b6788a9cc006dda3330aba22248ddc882dde000ed35ac2dda310416f84737fd0951f4e99358fcb9bb3bbbb9576570c60613b8b3f9\",\n          \"index\": 37\n        },\n        {\n          \"pubkey\": \"0x89543c3e50251ae355835484faf7cb38dacfca943b97fef9c9ee1e47248258a7198da417bf8fc6771fa7ef16a8adec0f\",\n          \"credentials\": \"0x0100000000000000000000000b2261d5b8748aaf43e138c0a4a556659150a11a\",\n          \"amount\": \"0x11c37937e08000\",\n          \"signature\": \"0x82d5bd0d24c4db783333cf2f211d3e4c94953ea56c4df989f176d05ebe74b3bf3efdfeafb8152f5c9aa41326c587eb330a9c6d15d6464eb9a278a3a5729c8f9141198d8d5f829deaa9eb99145e449231b8206b07f3f49fec1fbbda832e23e55e\",\n          \"index\": 38\n        }\n      ],\n      \"execution_payload_header\": {\n        \"parentHash\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        \"feeRecipient\": \"0x0000000000000000000000000000000000000000\",\n        \"stateRoot\": \"0x2aace2f233f1ef6ca13e5fd8feae4cb1b0b580fa56c8ee081ab89d861eaf1515\",\n        \"receiptsRoot\": \"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\n        \"logsBloom\": \"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n        \"prevRandao\": \"0x0000000000000000000000000000000000000000000000000000000000000000\",\n        \"blockNumber\": \"0x0\",\n        \"gasLimit\": \"0x1c9c380\",\n        \"gasUsed\": \"0x0\",\n        \"timestamp\": \"0x678e56e0\",\n        \"extraData\": \"0x\",\n        \"baseFeePerGas\": \"1000000000\",\n        \"blockHash\": \"0xd57819422128da1c44339fc7956662378c17e2213e669b427ac91cd11dfcfb38\",\n        \"transactionsRoot\": \"0x7ffe241ea60187fdb0187bfa22de35d1f9bed7ab061d9401fd47e34a54fbede1\",\n        \"withdrawalsRoot\": \"0x792930bbd5baac43bcc798ee49aa8185ef76bb3b44ba62b91d86ae569e4bb535\",\n        \"blobGasUsed\": \"0x0\",\n        \"excessBlobGas\": \"0x0\"\n      }\n    }\n  },\n  \"consensus\": {\n    \"params\": {\n      \"block\": {\n        \"max_bytes\": \"104857600\",\n        \"max_gas\": \"10000000\"\n      },\n      \"evidence\": {\n        \"max_age_num_blocks\": \"100000\",\n        \"max_age_duration\": \"172800000000000\",\n        \"max_bytes\": \"1048576\"\n      },\n      \"validator\": {\n        \"pub_key_types\": [\n          \"bls12_381\"\n        ]\n      },\n      \"version\": {\n        \"app\": \"0\"\n      },\n      \"synchrony\": {\n        \"precision\": \"505000000\",\n        \"message_delay\": \"15000000000\"\n      },\n      \"feature\": {\n        \"vote_extensions_enable_height\": \"0\",\n        \"pbts_enable_height\": \"1\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "testing/networks/80094/kzg-trusted-setup.json",
    "content": "{\n  \"g1_lagrange\": [\n    \"0xa0413c0dcafec6dbc9f47d66785cf1e8c981044f7d13cfe3e4fcbb71b5408dfde6312493cb3c1d30516cb3ca88c03654\",\n    \"0x8b997fb25730d661918371bb41f2a6e899cac23f04fc5365800b75433c0a953250e15e7a98fb5ca5cc56a8cd34c20c57\",\n    \"0x83302852db89424d5699f3f157e79e91dc1380f8d5895c5a772bb4ea3a5928e7c26c07db6775203ce33e62a114adaa99\",\n    \"0xa759c48b7e4a685e735c01e5aa6ef9c248705001f470f9ad856cd87806983e917a8742a3bd5ee27db8d76080269b7c83\",\n    \"0x967f8dc45ebc3be14c8705f43249a30ff48e96205fb02ae28daeab47b72eb3f45df0625928582aa1eb4368381c33e127\",\n    \"0xa418eb1e9fb84cb32b370610f56f3cb470706a40ac5a47c411c464299c45c91f25b63ae3fcd623172aa0f273c0526c13\",\n    \"0x8f44e3f0387293bc7931e978165abbaed08f53acd72a0a23ac85f6da0091196b886233bcee5b4a194db02f3d5a9b3f78\",\n    \"0x97173434b336be73c89412a6d70d416e170ea355bf1956c32d464090b107c090ef2d4e1a467a5632fbc332eeb679bf2d\",\n    \"0xa24052ad8d55ad04bc5d951f78e14213435681594110fd18173482609d5019105b8045182d53ffce4fc29fc8810516c1\",\n    \"0xb950768136b260277590b5bec3f56bbc2f7a8bc383d44ce8600e85bf8cf19f479898bcc999d96dfbd2001ede01d94949\",\n    \"0x92ab8077871037bd3b57b95cbb9fb10eb11efde9191690dcac655356986fd02841d8fdb25396faa0feadfe3f50baf56d\",\n    \"0xa79b096dff98038ac30f91112dd14b78f8ad428268af36d20c292e2b3b6d9ed4fb28480bb04e465071cc67d05786b6d1\",\n    \"0xb9ff71461328f370ce68bf591aa7fb13027044f42a575517f3319e2be4aa4843fa281e756d0aa5645428d6dfa857cef2\",\n    \"0x8d765808c00b3543ff182e2d159c38ae174b12d1314da88ea08e13bd9d1c37184cb515e6bf6420531b5d41767987d7ce\",\n    \"0xb8c9a837d20c3b53e6f578e4a257bb7ef8fc43178614ec2a154915b267ad2be135981d01ed2ee1b5fbd9d9bb27f0800a\",\n    \"0xa9773d92cf23f65f98ef68f6cf95c72b53d0683af2f9bf886bb9036e4a38184b1131b26fd24397910b494fbef856f3aa\",\n    \"0xb41ebe38962d112da4a01bf101cb248d808fbd50aaf749fc7c151cf332032eb3e3bdbd716db899724b734d392f26c412\",\n    \"0x90fbb030167fb47dcc13d604a726c0339418567c1d287d1d87423fa0cb92eec3455fbb46bcbe2e697144a2d3972142e4\",\n    \"0xb11d298bd167464b35fb923520d14832bd9ed50ed841bf6d7618424fd6f3699190af21759e351b89142d355952149da1\",\n    \"0x8bc36066f69dc89f7c4d1e58d67497675050c6aa002244cebd9fc957ec5e364c46bab4735ea3db02b73b3ca43c96e019\",\n    \"0xab7ab92c5d4d773068e485aa5831941ebd63db7118674ca38089635f3b4186833af2455a6fb9ed2b745df53b3ce96727\",\n    \"0xaf191ca3089892cb943cd97cf11a51f38e38bd9be50844a4e8da99f27e305e876f9ed4ab0628e8ae3939066b7d34a15f\",\n    \"0xa3204c1747feabc2c11339a542195e7cb6628fd3964f846e71e2e3f2d6bb379a5e51700682ea1844eba12756adb13216\",\n    \"0x903a29883846b7c50c15968b20e30c471aeac07b872c40a4d19eb1a42da18b649d5bbfde4b4cf6225d215a461b0deb6d\",\n    \"0x8e6e9c15ffbf1e16e5865a5fef7ed751dc81957a9757b535cb38b649e1098cda25d42381dc4f776778573cdf90c3e6e0\",\n    \"0xa8f6dd26100b512a8c96c52e00715c4b2cb9ac457f17aed8ffe1cf1ea524068fe5a1ddf218149845fc1417b789ecfc98\",\n    \"0xa5b0ffc819451ea639cfd1c18cbc9365cc79368d3b2e736c0ae54eba2f0801e6eb0ee14a5f373f4a70ca463bdb696c09\",\n    \"0x879f91ccd56a1b9736fbfd20d8747354da743fb121f0e308a0d298ff0d9344431890e41da66b5009af3f442c636b4f43\",\n    \"0x81bf3a2d9755e206b515a508ac4d1109bf933c282a46a4ae4a1b4cb4a94e1d23642fad6bd452428845afa155742ade7e\",\n    \"0x8de778d4742f945df40004964e165592f9c6b1946263adcdd5a88b00244bda46c7bb49098c8eb6b3d97a0dd46148a8ca\",\n    \"0xb7a57b21d13121907ee28c5c1f80ee2e3e83a3135a8101e933cf57171209a96173ff5037f5af606e9fd6d066de6ed693\",\n    \"0xb0877d1963fd9200414a38753dffd9f23a10eb3198912790d7eddbc9f6b477019d52ddd4ebdcb9f60818db076938a5a9\",\n    \"0x88da2d7a6611bc16adc55fc1c377480c828aba4496c645e3efe0e1a67f333c05a0307f7f1d2df8ac013602c655c6e209\",\n    \"0x95719eb02e8a9dede1a888c656a778b1c69b7716fbe3d1538fe8afd4a1bc972183c7d32aa7d6073376f7701df80116d8\",\n    \"0x8e8a1ca971f2444b35af3376e85dccda3abb8e8e11d095d0a4c37628dfe5d3e043a377c3de68289ef142e4308e9941a0\",\n    \"0xb720caaff02f6d798ac84c4f527203e823ff685869e3943c979e388e1c34c3f77f5c242c6daa7e3b30e511aab917b866\",\n    \"0x86040d55809afeec10e315d1ad950d269d37cfee8c144cd8dd4126459e3b15a53b3e68df5981df3c2346d23c7b4baaf4\",\n    \"0x82d8cabf13ab853db0377504f0aec00dba3a5cd3119787e8ad378ddf2c40b022ecfc67c642b7acc8c1e3dd03ab50993e\",\n    \"0xb8d873927936719d2484cd03a6687d65697e17dcf4f0d5aed6f5e4750f52ef2133d4645894e7ebfc4ef6ce6788d404c8\",\n    \"0xb1235594dbb15b674a419ff2b2deb644ad2a93791ca05af402823f87114483d6aa1689b7a9bea0f547ad12fe270e4344\",\n    \"0xa53fda86571b0651f5affb74312551a082fffc0385cfd24c1d779985b72a5b1cf7c78b42b4f7e51e77055f8e5e915b00\",\n    \"0xb579adcfd9c6ef916a5a999e77a0cb21d378c4ea67e13b7c58709d5da23a56c2e54218691fc4ac39a4a3d74f88cc31f7\",\n    \"0xab79e584011713e8a2f583e483a91a0c2a40771b77d91475825b5acbea82db4262132901cb3e4a108c46d7c9ee217a4e\",\n    \"0xa0fe58ea9eb982d7654c8aaf9366230578fc1362f6faae0594f8b9e659bcb405dff4aac0c7888bbe07f614ecf0d800a6\",\n    \"0x867e50e74281f28ecd4925560e2e7a6f8911b135557b688254623acce0dbc41e23ac3e706a184a45d54c586edc416eb0\",\n    \"0x89f81b61adda20ea9d0b387a36d0ab073dc7c7cbff518501962038be19867042f11fcc7ff78096e5d3b68c6d8dc04d9b\",\n    \"0xa58ee91bb556d43cf01f1398c5811f76dc0f11efdd569eed9ef178b3b0715e122060ec8f945b4dbf6eebfa2b90af6fa6\",\n    \"0xac460be540f4c840def2eef19fc754a9af34608d107cbadb53334cf194cc91138d53b9538fcd0ec970b5d4aa455b224a\",\n    \"0xb09b91f929de52c09d48ca0893be6eb44e2f5210a6c394689dc1f7729d4be4e11d0474b178e80cea8c2ac0d081f0e811\",\n    \"0x8d37a442a76b06a02a4e64c2504aea72c8b9b020ab7bcc94580fe2b9603c7c50d7b1e9d70d2a7daea19c68667e8f8c31\",\n    \"0xa9838d4c4e3f3a0075a952cf7dd623307ec633fcc81a7cf9e52e66c31780de33dbb3d74c320dc7f0a4b72f7a49949515\",\n    \"0xa44766b6251af458fe4f5f9ed1e02950f35703520b8656f09fc42d9a2d38a700c11a7c8a0436ac2e5e9f053d0bb8ff91\",\n    \"0xad78d9481c840f5202546bea0d13c776826feb8b1b7c72e83d99a947622f0bf38a4208551c4c41beb1270d7792075457\",\n    \"0xb619ffa8733b470039451e224b777845021e8dc1125f247a4ff2476cc774657d0ff9c5279da841fc1236047de9d81c60\",\n    \"0xaf760b0a30a1d6af3bc5cd6686f396bd41779aeeb6e0d70a09349bd5da17ca2e7965afc5c8ec22744198fbe3f02fb331\",\n    \"0xa0cc209abdb768b589fcb7b376b6e1cac07743288c95a1cf1a0354b47f0cf91fca78a75c1fcafa6f5926d6c379116608\",\n    \"0x864add673c89c41c754eeb3cd8dcff5cdde1d739fce65c30e474a082bb5d813cba6412e61154ce88fdb6c12c5d9be35b\",\n    \"0xb091443b0ce279327dc37cb484e9a5b69b257a714ce21895d67539172f95ffa326903747b64a3649e99aea7bb10d03f7\",\n    \"0xa8c452b8c4ca8e0a61942a8e08e28f17fb0ef4c5b018b4e6d1a64038280afa2bf1169202f05f14af24a06ca72f448ccd\",\n    \"0xa23c24721d18bc48d5dcf70effcbef89a7ae24e67158d70ae1d8169ee75d9a051d34b14e9cf06488bac324fe58549f26\",\n    \"0x92a730e30eb5f3231feb85f6720489dbb1afd42c43f05a1610c6b3c67bb949ec8fde507e924498f4ffc646f7b07d9123\",\n    \"0x8dbe5abf4031ec9ba6bb06d1a47dd1121fb9e03b652804069250967fd5e9577d0039e233441b7f837a7c9d67ba18c28e\",\n    \"0xaa456bcfef6a21bb88181482b279df260297b3778e84594ebddbdf337e85d9e3d46ca1d0b516622fb0b103df8ec519b7\",\n    \"0xa3b31ae621bd210a2b767e0e6f22eb28fe3c4943498a7e91753225426168b9a26da0e02f1dc5264da53a5ad240d9f51b\",\n    \"0xaa8d66857127e6e71874ce2202923385a7d2818b84cb73a6c42d71afe70972a70c6bdd2aad1a6e8c5e4ca728382a8ea8\",\n    \"0xac7e8e7a82f439127a5e40558d90d17990f8229852d21c13d753c2e97facf077cf59582b603984c3dd3faebd80aff4f5\",\n    \"0x93a8bcf4159f455d1baa73d2ef2450dcd4100420de84169bbe28b8b7a5d1746273f870091a87a057e834f754f34204b1\",\n    \"0x89d0ebb287c3613cdcae7f5acc43f17f09c0213fc40c074660120b755d664109ffb9902ed981ede79e018ddb0c845698\",\n    \"0xa87ccbfad431406aadbee878d9cf7d91b13649d5f7e19938b7dfd32645a43b114eef64ff3a13201398bd9b0337832e5a\",\n    \"0x833c51d0d0048f70c3eefb4e70e4ff66d0809c41838e8d2c21c288dd3ae9d9dfaf26d1742bf4976dab83a2b381677011\",\n    \"0x8bcd6b1c3b02fffead432e8b1680bad0a1ac5a712d4225e220690ee18df3e7406e2769e1f309e2e803b850bc96f0e768\",\n    \"0xb61e3dbd88aaf4ff1401521781e2eea9ef8b66d1fac5387c83b1da9e65c2aa2a56c262dea9eceeb4ad86c90211672db0\",\n    \"0x866d3090db944ecf190dd0651abf67659caafd31ae861bab9992c1e3915cb0952da7c561cc7e203560a610f48fae633b\",\n    \"0xa5e8971543c14274a8dc892b0be188c1b4fbc75c692ed29f166e0ea80874bc5520c2791342b7c1d2fb5dd454b03b8a5b\",\n    \"0x8f2f9fc50471bae9ea87487ebd1bc8576ef844cc42d606af5c4c0969670fdf2189afd643e4de3145864e7773d215f37f\",\n    \"0xb1bb0f2527db6d51f42b9224383c0f96048bbc03d469bf01fe1383173ef8b1cc9455d9dd8ba04d46057f46949bfc92b5\",\n    \"0xaa7c99d906b4d7922296cfe2520473fc50137c03d68b7865c5bfb8adbc316b1034310ec4b5670c47295f4a80fb8d61e9\",\n    \"0xa5d1da4d6aba555919df44cbaa8ff79378a1c9e2cfdfbf9d39c63a4a00f284c5a5724e28ecbc2d9dba27fe4ee5018bd5\",\n    \"0xa8db53224f70af4d991b9aae4ffe92d2aa5b618ad9137784b55843e9f16cefbfd25ada355d308e9bbf55f6d2f7976fb3\",\n    \"0xb6536c4232bb20e22af1a8bb12de76d5fec2ad9a3b48af1f38fa67e0f8504ef60f305a73d19385095bb6a9603fe29889\",\n    \"0x87f7e371a1817a63d6838a8cf4ab3a8473d19ce0d4f40fd013c03d5ddd5f4985df2956531cc9f187928ef54c68f4f9a9\",\n    \"0xae13530b1dbc5e4dced9d909ea61286ec09e25c12f37a1ed2f309b0eb99863d236c3b25ed3484acc8c076ad2fa8cd430\",\n    \"0x98928d850247c6f7606190e687d5c94a627550198dbdbea0161ef9515eacdb1a0f195cae3bb293112179082daccf8b35\",\n    \"0x918528bb8e6a055ad4db6230d3a405e9e55866da15c4721f5ddd1f1f37962d4904aad7a419218fe6d906fe191a991806\",\n    \"0xb71e31a06afe065773dd3f4a6e9ef81c3292e27a3b7fdfdd452d03e05af3b6dd654c355f7516b2a93553360c6681a73a\",\n    \"0x8870b83ab78a98820866f91ac643af9f3ff792a2b7fda34185a9456a63abdce42bfe8ad4dc67f08a6392f250d4062df4\",\n    \"0x91eea1b668e52f7a7a5087fabf1cab803b0316f78d9fff469fbfde2162f660c250e4336a9eea4cb0450bd30ac067bc8b\",\n    \"0x8b74990946de7b72a92147ceac1bd9d55999a8b576e8df68639e40ed5dc2062cfcd727903133de482b6dca19d0aaed82\",\n    \"0x8ebad537fece090ebbab662bdf2618e21ca30cf6329c50935e8346d1217dcbe3c1fe1ea28efca369c6003ce0a94703c1\",\n    \"0xa8640479556fb59ebd1c40c5f368fbd960932fdbb782665e4a0e24e2bdb598fc0164ce8c0726d7759cfc59e60a62e182\",\n    \"0xa9a52a6bf98ee4d749f6d38be2c60a6d54b64d5cbe4e67266633dc096cf28c97fe998596707d31968cbe2064b72256bf\",\n    \"0x847953c48a4ce6032780e9b39d0ed4384e0be202c2bbe2dfda3910f5d87aa5cd3c2ffbfcfae4dddce16d6ab657599b95\",\n    \"0xb6f6e1485d3ec2a06abaecd23028b200b2e4a0096c16144d07403e1720ff8f9ba9d919016b5eb8dc5103880a7a77a1d3\",\n    \"0x98dfc2065b1622f596dbe27131ea60bef7a193b12922cecb27f8c571404f483014f8014572e86ae2e341ab738e4887ef\",\n    \"0xacb0d205566bacc87bbe2e25d10793f63f7a1f27fd9e58f4f653ceae3ffeba511eaf658e068fad289eeb28f9edbeb35b\",\n    \"0xae4411ed5b263673cee894c11fe4abc72a4bf642d94022a5c0f3369380fcdfc1c21e277f2902972252503f91ada3029a\",\n    \"0xac4a7a27ba390a75d0a247d93d4a8ef1f0485f8d373a4af4e1139369ec274b91b3464d9738eeaceb19cd6f509e2f8262\",\n    \"0x87379c3bf231fdafcf6472a79e9e55a938d851d4dd662ab6e0d95fd47a478ed99e2ad1e6e39be3c0fc4f6d996a7dd833\",\n    \"0x81316904b035a8bcc2041199a789a2e6879486ba9fddcba0a82c745cc8dd8374a39e523b91792170cd30be7aa3005b85\",\n    \"0xb8206809c6cd027ed019f472581b45f7e12288f89047928ba32b4856b6560ad30395830d71e5e30c556f6f182b1fe690\",\n    \"0x88d76c028f534a62e019b4a52967bb8642ede6becfa3807be68fdd36d366fc84a4ac8dc176e80a68bc59eb62caf5dff9\",\n    \"0x8c3b8be685b0f8aad131ee7544d0e12f223f08a6f8edaf464b385ac644e0ddc9eff7cc7cb5c1b50ab5d71ea0f41d2213\",\n    \"0x8d91410e004f76c50fdc05784157b4d839cb5090022c629c7c97a5e0c3536eeafee17a527b54b1165c3cd81774bb54ce\",\n    \"0xb25c2863bc28ec5281ce800ddf91a7e1a53f4c6d5da1e6c86ef4616e93bcf55ed49e297216d01379f5c6e7b3c1e46728\",\n    \"0x865f7b09ac3ca03f20be90c48f6975dd2588838c2536c7a3532a6aa5187ed0b709cd03d91ff4048061c10d0aa72b69ce\",\n    \"0xb3f7477c90c11596eb4f8bbf34adbcb832638c4ff3cdd090d4d477ee50472ac9ddaf5be9ad7eca3f148960d362bbd098\",\n    \"0x8db35fd53fca04faecd1c76a8227160b3ab46ac1af070f2492445a19d8ff7c25bbaef6c9fa0c8c088444561e9f7e4eb2\",\n    \"0xa478b6e9d058a2e01d2fc053b739092e113c23a6a2770a16afbef044a3709a9e32f425ace9ba7981325f02667c3f9609\",\n    \"0x98caa6bd38916c08cf221722a675a4f7577f33452623de801d2b3429595f988090907a7e99960fff7c076d6d8e877b31\",\n    \"0xb79aaaacefc49c3038a14d2ac468cfec8c2161e88bdae91798d63552cdbe39e0e02f9225717436b9b8a40a022c633c6e\",\n    \"0x845a31006c680ee6a0cc41d3dc6c0c95d833fcf426f2e7c573fa15b2c4c641fbd6fe5ebb0e23720cc3467d6ee1d80dc4\",\n    \"0xa1bc287e272cf8b74dbf6405b3a5190883195806aa351f1dc8e525aa342283f0a35ff687e3b434324dedee74946dd185\",\n    \"0xa4fd2dc8db75d3783a020856e2b3aa266dc6926e84f5c491ef739a3bddd46dc8e9e0fc1177937839ef1b18d062ffbb9e\",\n    \"0xacbf0d3c697f57c202bb8c5dc4f3fc341b8fc509a455d44bd86acc67cad2a04495d5537bcd3e98680185e8aa286f2587\",\n    \"0xa5caf423a917352e1b8e844f5968a6da4fdeae467d10c6f4bbd82b5eea46a660b82d2f5440d3641c717b2c3c9ed0be52\",\n    \"0x8a39d763c08b926599ab1233219c49c825368fad14d9afc7c0c039224d37c00d8743293fd21645bf0b91eaf579a99867\",\n    \"0xb2b53a496def0ba06e80b28f36530fbe0fb5d70a601a2f10722e59abee529369c1ae8fd0f2db9184dd4a2519bb832d94\",\n    \"0xa73980fcef053f1b60ebbb5d78ba6332a475e0b96a0c724741a3abf3b59dd344772527f07203cf4c9cb5155ebed81fa0\",\n    \"0xa070d20acce42518ece322c9db096f16aed620303a39d8d5735a0df6e70fbeceb940e8d9f5cc38f3314b2240394ec47b\",\n    \"0xa50cf591f522f19ca337b73089557f75929d9f645f3e57d4f241e14cdd1ea3fb48d84bcf05e4f0377afbb789fbdb5d20\",\n    \"0x82a5ffce451096aca8eeb0cd2ae9d83db3ed76da3f531a80d9a70a346359bf05d74863ce6a7c848522b526156a5e20cd\",\n    \"0x88e0e84d358cbb93755a906f329db1537c3894845f32b9b0b691c29cbb455373d9452fadd1e77e20a623f6eaf624de6f\",\n    \"0xaa07ac7b84a6d6838826e0b9e350d8ec75e398a52e9824e6b0da6ae4010e5943fec4f00239e96433f291fef9d1d1e609\",\n    \"0xac8887bf39366034bc63f6cc5db0c26fd27307cbc3d6cce47894a8a019c22dd51322fb5096edc018227edfafc053a8f6\",\n    \"0xb7d26c26c5b33f77422191dca94977588ab1d4b9ce7d0e19c4a3b4cd1c25211b78c328dbf81e755e78cd7d1d622ad23e\",\n    \"0x99a676d5af49f0ba44047009298d8474cabf2d5bca1a76ba21eff7ee3c4691a102fdefea27bc948ccad8894a658abd02\",\n    \"0xb0d09a91909ab3620c183bdf1d53d43d39eb750dc7a722c661c3de3a1a5d383ad221f71bae374f8a71867505958a3f76\",\n    \"0x84681a883de8e4b93d68ac10e91899c2bbb815ce2de74bb48a11a6113b2a3f4df8aceabda1f5f67bc5aacac8c9da7221\",\n    \"0x9470259957780fa9b43521fab3644f555f5343281c72582b56d2efd11991d897b3b481cafa48681c5aeb80c9663b68f7\",\n    \"0xab1b29f7ece686e6fa968a4815da1d64f3579fed3bc92e1f3e51cd13a3c076b6cf695ed269d373300a62463dc98a4234\",\n    \"0x8ab415bfcd5f1061f7687597024c96dd9c7cb4942b5989379a7a3b5742f7d394337886317659cbeacaf030234a24f972\",\n    \"0xb9b524aad924f9acc63d002d617488f31b0016e0f0548f050cada285ce7491b74a125621638f19e9c96eabb091d945be\",\n    \"0x8c4c373e79415061837dd0def4f28a2d5d74d21cb13a76c9049ad678ca40228405ab0c3941df49249847ecdefc1a5b78\",\n    \"0xa8edf4710b5ab2929d3db6c1c0e3e242261bbaa8bcec56908ddadd7d2dad2dca9d6eb9de630b960b122ebeea41040421\",\n    \"0x8d66bb3b50b9df8f373163629f9221b3d4b6980a05ea81dc3741bfe9519cf3ebba7ab98e98390bae475e8ede5821bd5c\",\n    \"0x8d3c21bae7f0cfb97c56952bb22084b58e7bb718890935b73103f33adf5e4d99cd262f929c6eeab96209814f0dbae50a\",\n    \"0xa5c66cfab3d9ebf733c4af24bebc97070e7989fe3c73e79ac85fb0e4d40ae44fb571e0fad4ad72560e13ed453900d14f\",\n    \"0x9362e6b50b43dbefbc3254471372297b5dcce809cd3b60bf74a1268ab68bdb50e46e462cbd78f0d6c056330e982846af\",\n    \"0x854630d08e3f0243d570cc2e856234cb4c1a158d9c1883bf028a76525aaa34be897fe918d5f6da9764a3735fa9ebd24a\",\n    \"0x8c7d246985469ff252c3f4df6c7c9196fc79f05c1c66a609d84725c78001d0837c7a7049394ba5cf7e863e2d58af8417\",\n    \"0xae050271e01b528925302e71903f785b782f7bf4e4e7a7f537140219bc352dc7540c657ed03d3a297ad36798ecdb98cd\",\n    \"0x8d2ae9179fcf2b0c69850554580b52c1f4a5bd865af5f3028f222f4acad9c1ad69a8ef6c7dc7b03715ee5c506b74325e\",\n    \"0xb8ef8de6ce6369a8851cd36db0ccf00a85077e816c14c4e601f533330af9e3acf0743a95d28962ed8bfcfc2520ef3cfe\",\n    \"0xa6ecad6fdfb851b40356a8b1060f38235407a0f2706e7b8bb4a13465ca3f81d4f5b99466ac2565c60af15f022d26732e\",\n    \"0x819ff14cdea3ab89d98e133cd2d0379361e2e2c67ad94eeddcdb9232efd509f51d12f4f03ebd4dd953bd262a886281f7\",\n    \"0x8561cd0f7a6dbcddd83fcd7f472d7dbcba95b2d4fb98276f48fccf69f76d284e626d7e41314b633352df8e6333fd52a1\",\n    \"0xb42557ccce32d9a894d538c48712cb3e212d06ac05cd5e0527ccd2db1078ee6ae399bf6a601ffdab1f5913d35fc0b20c\",\n    \"0x89b4008d767aad3c6f93c349d3b956e28307311a5b1cec237e8d74bb0dee7e972c24f347fd56afd915a2342bd7bc32f0\",\n    \"0x877487384b207e53f5492f4e36c832c2227f92d1bb60542cfeb35e025a4a7afc2b885fae2528b33b40ab09510398f83e\",\n    \"0x8c411050b63c9053dd0cd81dacb48753c3d7f162028098e024d17cd6348482703a69df31ad6256e3d25a8bbf7783de39\",\n    \"0xa8506b54a88d17ac10fb1b0d1fe4aa40eae7553a064863d7f6b52ccc4236dd4b82d01dca6ba87da9a239e3069ba879fb\",\n    \"0xb1a24caef9df64750c1350789bb8d8a0db0f39474a1c74ea9ba064b1516db6923f00af8d57c632d58844fb8786c3d47a\",\n    \"0x959d6e255f212b0708c58a2f75cb1fe932248c9d93424612c1b8d1e640149656059737e4db2139afd5556bcdacf3eda2\",\n    \"0x84525af21a8d78748680b6535bbc9dc2f0cf9a1d1740d12f382f6ecb2e73811d6c1da2ad9956070b1a617c61fcff9fe5\",\n    \"0xb74417d84597a485d0a8e1be07bf78f17ebb2e7b3521b748f73935b9afbbd82f34b710fb7749e7d4ab55b0c7f9de127d\",\n    \"0xa4a9aecb19a6bab167af96d8b9d9aa5308eab19e6bfb78f5a580f9bf89bdf250a7b52a09b75f715d651cb73febd08e84\",\n    \"0x9777b30be2c5ffe7d29cc2803a562a32fb43b59d8c3f05a707ab60ec05b28293716230a7d264d7cd9dd358fc031cc13e\",\n    \"0x95dce7a3d4f23ac0050c510999f5fbf8042f771e8f8f94192e17bcbfa213470802ebdbe33a876cb621cf42e275cbfc8b\",\n    \"0xb0b963ebcbbee847ab8ae740478544350b3ac7e86887e4dfb2299ee5096247cd2b03c1de74c774d9bde94ae2ee2dcd59\",\n    \"0xa4ab20bafa316030264e13f7ef5891a2c3b29ab62e1668fcb5881f50a9acac6adbe3d706c07e62f2539715db768f6c43\",\n    \"0x901478a297669d608e406fe4989be75264b6c8be12169aa9e0ad5234f459ca377f78484ffd2099a2fe2db5e457826427\",\n    \"0x88c76e5c250810c057004a03408b85cd918e0c8903dc55a0dd8bb9b4fc2b25c87f9b8cf5943eb19fbbe99d36490050c5\",\n    \"0x91607322bbad4a4f03fc0012d0821eff5f8c516fda45d1ec1133bface6f858bf04b25547be24159cab931a7aa08344d4\",\n    \"0x843203e07fce3c6c81f84bc6dc5fb5e9d1c50c8811ace522dc66e8658433a0ef9784c947e6a62c11bf705307ef05212e\",\n    \"0x91dd8813a5d6dddcda7b0f87f672b83198cd0959d8311b2b26fb1fae745185c01f796fbd03aad9db9b58482483fdadd8\",\n    \"0x8d15911aacf76c8bcd7136e958febd6963104addcd751ce5c06b6c37213f9c4fb0ffd4e0d12c8e40c36d658999724bfd\",\n    \"0x8a36c5732d3f1b497ebe9250610605ee62a78eaa9e1a45f329d09aaa1061131cf1d9df00f3a7d0fe8ad614a1ff9caaae\",\n    \"0xa407d06affae03660881ce20dab5e2d2d6cddc23cd09b95502a9181c465e57597841144cb34d22889902aff23a76d049\",\n    \"0xb5fd856d0578620a7e25674d9503be7d97a2222900e1b4738c1d81ff6483b144e19e46802e91161e246271f90270e6cf\",\n    \"0x91b7708869cdb5a7317f88c0312d103f8ce90be14fb4f219c2e074045a2a83636fdc3e69e862049fc7c1ef000e832541\",\n    \"0xb64719cc5480709d1dae958f1d3082b32a43376da446c8f9f64cb02a301effc9c34d9102051733315a8179aed94d53cc\",\n    \"0x94347a9542ff9d18f7d9eaa2f4d9b832d0e535fe49d52aa2de08aa8192400eddabdb6444a2a78883e27c779eed7fdf5a\",\n    \"0x840ef44a733ff1376466698cd26f82cf56bb44811e196340467f932efa3ae1ef9958a0701b3b032f50fd9c1d2aed9ab5\",\n    \"0x90ab3f6f67688888a31ffc2a882bb37adab32d1a4b278951a21646f90d03385fc976715fc639a785d015751171016f10\",\n    \"0xb56f35d164c24b557dbcbc8a4bfa681ec916f8741ffcb27fb389c164f4e3ed2be325210ef5bdaeae7a172ca9599ab442\",\n    \"0xa7921a5a80d7cf6ae81ba9ee05e0579b18c20cd2852762c89d6496aa4c8ca9d1ca2434a67b2c16d333ea8e382cdab1e3\",\n    \"0xa506bcfbd7e7e5a92f68a1bd87d07ad5fe3b97aeee40af2bf2cae4efcd77fff03f872732c5b7883aa6584bee65d6f8cb\",\n    \"0xa8c46cff58931a1ce9cbe1501e1da90b174cddd6d50f3dfdfb759d1d4ad4673c0a8feed6c1f24c7af32865a7d6c984e5\",\n    \"0xb45686265a83bff69e312c5149db7bb70ac3ec790dc92e392b54d9c85a656e2bf58596ce269f014a906eafc97461aa5f\",\n    \"0x8d4009a75ccb2f29f54a5f16684b93202c570d7a56ec1a8b20173269c5f7115894f210c26b41e8d54d4072de2d1c75d0\",\n    \"0xaef8810af4fc676bf84a0d57b189760ddc3375c64e982539107422e3de2580b89bd27aa6da44e827b56db1b5555e4ee8\",\n    \"0x888f0e1e4a34f48eb9a18ef4de334c27564d72f2cf8073e3d46d881853ac1424d79e88d8ddb251914890588937c8f711\",\n    \"0xb64b0aa7b3a8f6e0d4b3499fe54e751b8c3e946377c0d5a6dbb677be23736b86a7e8a6be022411601dd75012012c3555\",\n    \"0x8d57776f519f0dd912ea14f79fbab53a30624e102f9575c0bad08d2dc754e6be54f39b11278c290977d9b9c7c0e1e0ad\",\n    \"0xa018fc00d532ceb2e4de908a15606db9b6e0665dd77190e2338da7c87a1713e6b9b61554e7c1462f0f6d4934b960b15c\",\n    \"0x8c932be83ace46f65c78e145b384f58e41546dc0395270c1397874d88626fdeda395c8a289d602b4c312fe98c1311856\",\n    \"0x89174838e21639d6bdd91a0621f04dc056907b88e305dd66e46a08f6d65f731dea72ae87ca5e3042d609e8de8de9aa26\",\n    \"0xb7b7f508bb74f7a827ac8189daa855598ff1d96fa3a02394891fd105d8f0816224cd50ac4bf2ed1cf469ace516c48184\",\n    \"0xb31877ad682583283baadd68dc1bebd83f5748b165aadd7fe9ef61a343773b88bcd3a022f36d6c92f339b7bfd72820a9\",\n    \"0xb79d77260b25daf9126dab7a193df2d7d30542786fa1733ffaf6261734770275d3ca8bae1d9915d1181a78510b3439db\",\n    \"0x91894fb94cd4c1dd2ceaf9c53a7020c5799ba1217cf2d251ea5bc91ed26e1159dd758e98282ebe35a0395ef9f1ed15a0\",\n    \"0xab59895cdafd33934ceedfc3f0d5d89880482cba6c99a6db93245f9e41987efd76e0640e80aef31782c9a8c7a83fccec\",\n    \"0xaa22ea63654315e033e09d4d4432331904a6fc5fb1732557987846e3c564668ca67c60a324b4af01663a23af11a9ce4b\",\n    \"0xb53ba3ef342601467e1f71aa280e100fbabbd38518fa0193e0099505036ee517c1ac78e96e9baeb549bb6879bb698fb0\",\n    \"0x943fd69fd656f37487cca3605dc7e5a215fddd811caf228595ec428751fc1de484a0cb84c667fe4d7c35599bfa0e5e34\",\n    \"0x9353128b5ebe0dddc555093cf3e5942754f938173541033e8788d7331fafc56f68d9f97b4131e37963ab7f1c8946f5f1\",\n    \"0xa76cd3c566691f65cfb86453b5b31dbaf3cab8f84fe1f795dd1e570784b9b01bdd5f0b3c1e233942b1b5838290e00598\",\n    \"0x983d84b2e53ffa4ae7f3ba29ef2345247ea2377686b74a10479a0ef105ecf90427bf53b74c96dfa346d0f842b6ffb25b\",\n    \"0x92e0fe9063306894a2c6970c001781cff416c87e87cb5fbac927a3192655c3da4063e6fa93539f6ff58efac6adcc5514\",\n    \"0xb00a81f03c2b8703acd4e2e4c21e06973aba696415d0ea1a648ace2b0ea19b242fede10e4f9d7dcd61c546ab878bc8f9\",\n    \"0xb0d08d880f3b456a10bf65cff983f754f545c840c413aea90ce7101a66eb0a0b9b1549d6c4d57725315828607963f15a\",\n    \"0x90cb64d03534f913b411375cce88a9e8b1329ce67a9f89ca5df8a22b8c1c97707fec727dbcbb9737f20c4cf751359277\",\n    \"0x8327c2d42590dfcdb78477fc18dcf71608686ad66c49bce64d7ee874668be7e1c17cc1042a754bbc77c9daf50b2dae07\",\n    \"0x8532171ea13aa7e37178e51a6c775da469d2e26ec854eb16e60f3307db4acec110d2155832c202e9ba525fc99174e3b0\",\n    \"0x83ca44b15393d021de2a511fa5511c5bd4e0ac7d67259dce5a5328f38a3cce9c3a269405959a2486016bc27bb140f9ff\",\n    \"0xb1d36e8ca812be545505c8214943b36cabee48112cf0de369957afa796d37f86bf7249d9f36e8e990f26f1076f292b13\",\n    \"0x9803abf45be5271e2f3164c328d449efc4b8fc92dfc1225d38e09630909fe92e90a5c77618daa5f592d23fc3ad667094\",\n    \"0xb268ad68c7bf432a01039cd889afae815c3e120f57930d463aece10af4fd330b5bd7d8869ef1bcf6b2e78e4229922edc\",\n    \"0xa4c91a0d6f16b1553264592b4cbbbf3ca5da32ab053ffbdd3dbb1aed1afb650fb6e0dc5274f71a51d7160856477228db\",\n    \"0xad89d043c2f0f17806277ffdf3ecf007448e93968663f8a0b674254f36170447b7527d5906035e5e56f4146b89b5af56\",\n    \"0x8b6964f757a72a22a642e4d69102951897e20c21449184e44717bd0681d75f7c5bfa5ee5397f6e53febf85a1810d6ed1\",\n    \"0xb08f5cdaabec910856920cd6e836c830b863eb578423edf0b32529488f71fe8257d90aed4a127448204df498b6815d79\",\n    \"0xaf26bb3358be9d280d39b21d831bb53145c4527a642446073fee5a86215c4c89ff49a3877a7a549486262f6f57a0f476\",\n    \"0xb4010b37ec4d7c2af20800e272539200a6b623ae4636ecbd0e619484f4ab9240d02bc5541ace3a3fb955dc0a3d774212\",\n    \"0x82752ab52bdcc3cc2fc405cb05a2e694d3df4a3a68f2179ec0652536d067b43660b96f85f573f26fbd664a9ef899f650\",\n    \"0x96d392dde067473a81faf2d1fea55b6429126b88b160e39b4210d31d0a82833ffd3a80e07d24d495aea2d96be7251547\",\n    \"0xa76d8236d6671204d440c33ac5b8deb71fa389f6563d80e73be8b043ec77d4c9b06f9a586117c7f957f4af0331cbc871\",\n    \"0xb6c90961f68b5e385d85c9830ec765d22a425f506904c4d506b87d8944c2b2c09615e740ed351df0f9321a7b93979cae\",\n    \"0xa6ec5ea80c7558403485b3b1869cdc63bde239bafdf936d9b62a37031628402a36a2cfa5cfbb8e26ac922cb0a209b3ba\",\n    \"0x8c3195bbdbf9bc0fc95fa7e3d7f739353c947f7767d1e3cb24d8c8602d8ea0a1790ac30b815be2a2ba26caa5227891e2\",\n    \"0xa7f8a63d809f1155722c57f375ea00412b00147776ae4444f342550279ef4415450d6f400000a326bf11fea6c77bf941\",\n    \"0x97fa404df48433a00c85793440e89bb1af44c7267588ae937a1f5d53e01e1c4d4fc8e4a6d517f3978bfdd6c2dfde012f\",\n    \"0xa984a0a3836de3d8d909c4629a2636aacb85393f6f214a2ef68860081e9db05ad608024762db0dc35e895dc00e2d4cdd\",\n    \"0x9526cf088ab90335add1db4d3a4ac631b58cbfbe88fa0845a877d33247d1cfeb85994522e1eb8f8874651bfb1df03e2a\",\n    \"0xac83443fd0afe99ad49de9bf8230158c118e2814c9c89db5ac951c240d6c2ce45e7677221279d9e97848ec466b99aafe\",\n    \"0xaeeefdbaba612e971697798ceaf63b247949dc823a0ad771ae5b988a5e882b338a98d3d0796230f49d533ec5ba411b39\",\n    \"0xae3f248b5a7b0f92b7820a6c5ae21e5bd8f4265d4f6e21a22512079b8ee9be06393fd3133ce8ebac0faf23f4f8517e36\",\n    \"0xa64a831b908eee784b8388b45447d2885ec0551b26b0c2b15e5f417d0a12c79e867fb7bd3d008d0af98b44336f8ec1ad\",\n    \"0xb242238cd8362b6e440ba21806905714dd55172db25ec7195f3fc4937b2aba146d5cbf3cf691a1384b4752dc3b54d627\",\n    \"0x819f97f337eea1ffb2a678cc25f556f1aab751c6b048993a1d430fe1a3ddd8bb411c152e12ca60ec6e057c190cd1db9a\",\n    \"0xb9d7d187407380df54ee9fef224c54eec1bfabf17dc8abf60765b7951f538f59aa26fffd5846cfe05546c35f59b573f4\",\n    \"0xaa6e3c14efa6a5962812e3f94f8ce673a433f4a82d07a67577285ea0eaa07f8be7115853122d12d6d4e1fdf64c504be1\",\n    \"0x82268bee9c1662d3ddb5fb785abfae6fb8b774190f30267f1d47091d2cd4b3874db4372625aa36c32f27b0eee986269b\",\n    \"0xb236459565b7b966166c4a35b2fa71030b40321821b8e96879d95f0e83a0baf33fa25721f30af4a631df209e25b96061\",\n    \"0x8708d752632d2435d2d5b1db4ad1fa2558d776a013655f88e9a3556d86b71976e7dfe5b8834fdec97682cd94560d0d0d\",\n    \"0xae1424a68ae2dbfb0f01211f11773732a50510b5585c1fb005cb892b2c6a58f4a55490b5c5b4483c6fce40e9d3236a52\",\n    \"0xb3f5f722af9dddb07293c871ce97abbccba0093ca98c8d74b1318fa21396fc1b45b69c15084f63d728f9908442024506\",\n    \"0x9606f3ce5e63886853ca476dc0949e7f1051889d529365c0cb0296fdc02abd088f0f0318ecd2cf36740a3634132d36f6\",\n    \"0xb11a833a49fa138db46b25ff8cdda665295226595bc212c0931b4931d0a55c99da972c12b4ef753f7e37c6332356e350\",\n    \"0xafede34e7dab0a9e074bc19a7daddb27df65735581ca24ad70c891c98b1349fcebbcf3ba6b32c2617fe06a5818dabc2d\",\n    \"0x97993d456e459e66322d01f8eb13918979761c3e8590910453944bdff90b24091bb018ac6499792515c9923be289f99f\",\n    \"0x977e3e967eff19290a192cd11df3667d511b398fb3ac9a5114a0f3707e25a0edcb56105648b1b85a8b7519fc529fc6f6\",\n    \"0xb873a7c88bf58731fe1bf61ff6828bf114cf5228f254083304a4570e854e83748fc98683ddba62d978fff7909f2c5c47\",\n    \"0xad4b2691f6f19da1d123aaa23cca3e876247ed9a4ab23c599afdbc0d3aa49776442a7ceaa996ac550d0313d9b9a36cee\",\n    \"0xb9210713c78e19685608c6475bfa974b57ac276808a443f8b280945c5d5f9c39da43effa294bfb1a6c6f7b6b9f85bf6c\",\n    \"0xa65152f376113e61a0e468759de38d742caa260291b4753391ee408dea55927af08a4d4a9918600a3bdf1df462dffe76\",\n    \"0x8bf8c27ad5140dde7f3d2280fd4cc6b29ab76537e8d7aa7011a9d2796ee3e56e9a60c27b5c2da6c5e14fc866301dc195\",\n    \"0x92fde8effc9f61393a2771155812b863cff2a0c5423d7d40aa04d621d396b44af94ddd376c28e7d2f53c930aea947484\",\n    \"0x97a01d1dd9ee30553ce676011aea97fa93d55038ada95f0057d2362ae9437f3ed13de8290e2ff21e3167dd7ba10b9c3f\",\n    \"0x89affffaa63cb2df3490f76f0d1e1d6ca35c221dd34057176ba739fa18d492355e6d2a5a5ad93a136d3b1fed0bb8aa19\",\n    \"0x928b8e255a77e1f0495c86d3c63b83677b4561a5fcbbe5d3210f1e0fc947496e426d6bf3b49394a5df796c9f25673fc4\",\n    \"0x842a0af91799c9b533e79ee081efe2a634cac6c584c2f054fb7d1db67dde90ae36de36cbf712ec9cd1a0c7ee79e151ea\",\n    \"0xa65b946cf637e090baf2107c9a42f354b390e7316beb8913638130dbc67c918926eb87bec3b1fe92ef72bc77a170fa3b\",\n    \"0xaafc0f19bfd71ab5ae4a8510c7861458b70ad062a44107b1b1dbacbfa44ba3217028c2824bd7058e2fa32455f624040b\",\n    \"0x95269dc787653814e0be899c95dba8cfa384f575a25e671c0806fd80816ad6797dc819d30ae06e1d0ed9cb01c3950d47\",\n    \"0xa1e760f7fa5775a1b2964b719ff961a92083c5c617f637fc46e0c9c20ab233f8686f7f38c3cb27d825c54dd95e93a59b\",\n    \"0xac3b8a7c2317ea967f229eddc3e23e279427f665c4705c7532ed33443f1243d33453c1088f57088d2ab1e3df690a9cc9\",\n    \"0xb787beeddfbfe36dd51ec4efd9cf83e59e84d354c3353cc9c447be53ae53d366ed1c59b686e52a92f002142c8652bfe0\",\n    \"0xb7a64198300cb6716aa7ac6b25621f8bdec46ad5c07a27e165b3f774cdf65bcfdbf31e9bae0c16b44de4b00ada7a4244\",\n    \"0xb8ae9f1452909e0c412c7a7fe075027691ea8df1347f65a5507bc8848f1d2c833d69748076db1129e5b4fb912f65c86c\",\n    \"0x9682e41872456b9fa67def89e71f06d362d6c8ca85c9c48536615bc401442711e1c9803f10ab7f8ab5feaec0f9df20a6\",\n    \"0x88889ff4e271dc1c7e21989cc39f73cde2f0475acd98078281591ff6c944fadeb9954e72334319050205d745d4df73df\",\n    \"0x8f79b5b8159e7fd0d93b0645f3c416464f39aec353b57d99ecf24f96272df8a068ad67a6c90c78d82c63b40bb73989bb\",\n    \"0x838c01a009a3d8558a3f0bdd5e22de21af71ca1aefc8423c91dc577d50920e9516880e87dce3e6d086e11cd45c9052d9\",\n    \"0xb97f1c6eee8a78f137c840667cc288256e39294268a3009419298a04a1d0087c9c9077b33c917c65caf76637702dda8a\",\n    \"0x972284ce72f96a61c899260203dfa06fc3268981732bef74060641c1a5068ead723e3399431c247ca034b0dae861e8df\",\n    \"0x945a8d52d6d3db6663dbd3110c6587f9e9c44132045eeffba15621576d178315cb52870fa5861669f84f0bee646183fe\",\n    \"0xa0a547b5f0967b1c3e5ec6c6a9a99f0578521489180dfdfbb5561f4d166baac43a2f06f950f645ce991664e167537eed\",\n    \"0xa0592cda5cdddf1340033a745fd13a6eff2021f2e26587116c61c60edead067e0f217bc2bef4172a3c9839b0b978ab35\",\n    \"0xb9c223b65a3281587fa44ec829e609154b32f801fd1de6950e01eafb07a8324243b960d5735288d0f89f0078b2c42b5b\",\n    \"0x99ebfc3b8f9f98249f4d37a0023149ed85edd7a5abe062c8fb30c8c84555258b998bdcdd1d400bc0fa2a4aaa8b224466\",\n    \"0x955b68526e6cb3937b26843270f4e60f9c6c8ece2fa9308fe3e23afa433309c068c66a4bc16ee2cf04220f095e9afce4\",\n    \"0xb766caeafcc00378135ae53397f8a67ed586f5e30795462c4a35853de6681b1f17401a1c40958de32b197c083b7279c1\",\n    \"0x921bf87cad947c2c33fa596d819423c10337a76fe5a63813c0a9dc78a728207ae7b339407a402fc4d0f7cba3af6da6fc\",\n    \"0xa74ba1f3bc3e6c025db411308f49b347ec91da1c916bda9da61e510ec8d71d25e0ac0f124811b7860e5204f93099af27\",\n    \"0xa29b4d144e0bf17a7e8353f2824cef0ce85621396babe8a0b873ca1e8a5f8d508b87866cf86da348470649fceefd735c\",\n    \"0xa8040e12ffc3480dd83a349d06741d1572ef91932c46f5cf03aee8454254156ee95786fd013d5654725e674c920cec32\",\n    \"0x8c4cf34ca60afd33923f219ffed054f90cd3f253ffeb2204a3b61b0183417e366c16c07fae860e362b0f2bfe3e1a1d35\",\n    \"0x8195eede4ddb1c950459df6c396b2e99d83059f282b420acc34220cadeed16ab65c856f2c52568d86d3c682818ed7b37\",\n    \"0x91fff19e54c15932260aa990c7fcb3c3c3da94845cc5aa8740ef56cf9f58d19b4c3c55596f8d6c877f9f4d22921d93aa\",\n    \"0xa3e0bf7e5d02a80b75cf75f2db7e66cb625250c45436e3c136d86297d652590ec97c2311bafe407ad357c79ab29d107b\",\n    \"0x81917ff87e5ed2ae4656b481a63ced9e6e5ff653b8aa6b7986911b8bc1ee5b8ef4f4d7882c3f250f2238e141b227e510\",\n    \"0x915fdbe5e7de09c66c0416ae14a8750db9412e11dc576cf6158755fdcaf67abdbf0fa79b554cac4fe91c4ec245be073f\",\n    \"0x8df27eafb5c3996ba4dc5773c1a45ca77e626b52e454dc1c4058aa94c2067c18332280630cc3d364821ee53bf2b8c130\",\n    \"0x934f8a17c5cbb827d7868f5c8ca00cb027728a841000a16a3428ab16aa28733f16b52f58c9c4fbf75ccc45df72d9c4df\",\n    \"0xb83f4da811f9183c25de8958bc73b504cf790e0f357cbe74ef696efa7aca97ad3b7ead1faf76e9f982c65b6a4d888fc2\",\n    \"0x87188213c8b5c268dc2b6da413f0501c95749e953791b727450af3e43714149c115b596b33b63a2f006a1a271b87efd0\",\n    \"0x83e9e888ab9c3e30761de635d9aabd31248cdd92f7675fc43e4b21fd96a03ec1dc4ad2ec94fec857ffb52683ac98e360\",\n    \"0xb4b9a1823fe2d983dc4ec4e3aaea297e581c3fc5ab4b4af5fa1370caa37af2d1cc7fc6bfc5e7da60ad8fdce27dfe4b24\",\n    \"0x856388bc78aef465dbcdd1f559252e028c9e9a2225c37d645c138e78f008f764124522705822a61326a6d1c79781e189\",\n    \"0xa6431b36db93c3b47353ba22e7c9592c9cdfb9cbdd052ecf2cc3793f5b60c1e89bc96e6bae117bfd047f2308da00dd2f\",\n    \"0xb619972d48e7e4291542dcde08f7a9cdc883c892986ded2f23ccb216e245cd8d9ad1d285347b0f9d7611d63bf4cee2bc\",\n    \"0x8845cca6ff8595955f37440232f8e61d5351500bd016dfadd182b9d39544db77a62f4e0102ff74dd4173ae2c181d24ef\",\n    \"0xb2f5f7fa26dcd3b6550879520172db2d64ee6aaa213cbef1a12befbce03f0973a22eb4e5d7b977f466ac2bf8323dcedd\",\n    \"0x858b7f7e2d44bdf5235841164aa8b4f3d33934e8cb122794d90e0c1cac726417b220529e4f896d7b77902ab0ccd35b3a\",\n    \"0x80b0408a092dae2b287a5e32ea1ad52b78b10e9c12f49282976cd738f5d834e03d1ad59b09c5ccaccc39818b87d06092\",\n    \"0xb996b0a9c6a2d14d984edcd6ab56bc941674102980d65b3ad9733455f49473d3f587c8cbf661228a7e125ddbe07e3198\",\n    \"0x90224fcebb36865293bd63af786e0c5ade6b67c4938d77eb0cbae730d514fdd0fe2d6632788e858afd29d46310cf86df\",\n    \"0xb71351fdfff7168b0a5ec48397ecc27ac36657a8033d9981e97002dcca0303e3715ce6dd3f39423bc8ef286fa2e9e669\",\n    \"0xae2a3f078b89fb753ce4ed87e0c1a58bb19b4f0cfb6586dedb9fcab99d097d659a489fb40e14651741e1375cfc4b6c5f\",\n    \"0x8ef476b118e0b868caed297c161f4231bbeb863cdfa5e2eaa0fc6b6669425ce7af50dc374abceac154c287de50c22307\",\n    \"0x92e46ab472c56cfc6458955270d3c72b7bde563bb32f7d4ab4d959db6f885764a3d864e1aa19802fefaa5e16b0cb0b54\",\n    \"0x96a3f68323d1c94e73d5938a18a377af31b782f56212de3f489d22bc289cf24793a95b37f1d6776edf88114b5c1fa695\",\n    \"0x962cc068cfce6faaa27213c4e43e44eeff0dfbb6d25b814e82c7da981fb81d7d91868fa2344f05fb552362f98cfd4a72\",\n    \"0x895d4e4c4ad670abf66d43d59675b1add7afad7438ada8f42a0360c704cee2060f9ac15b4d27e9b9d0996bb801276fe3\",\n    \"0xb3ad18d7ece71f89f2ef749b853c45dc56bf1c796250024b39a1e91ed11ca32713864049c9aaaea60cde309b47486bbf\",\n    \"0x8f05404e0c0258fdbae50e97ccb9b72ee17e0bd2400d9102c0dad981dac8c4c71585f03e9b5d50086d0a2d3334cb55d1\",\n    \"0x8bd877e9d4591d02c63c6f9fc9976c109de2d0d2df2bfa5f6a3232bab5b0b8b46e255679520480c2d7a318545efa1245\",\n    \"0x8d4c16b5d98957c9da13d3f36c46f176e64e5be879f22be3179a2c0e624fe4758a82bf8c8027410002f973a3b84cd55a\",\n    \"0x86e2a8dea86427b424fa8eada881bdff896907084a495546e66556cbdf070b78ba312bf441eb1be6a80006d25d5097a3\",\n    \"0x8608b0c117fd8652fdab0495b08fadbeba95d9c37068e570de6fddfef1ba4a1773b42ac2be212836141d1bdcdef11a17\",\n    \"0xa13d6febf5fb993ae76cae08423ca28da8b818d6ef0fde32976a4db57839cd45b085026b28ee5795f10a9a8e3098c683\",\n    \"0x8e261967fa6de96f00bc94a199d7f72896a6ad8a7bbb1d6187cca8fad824e522880e20f766620f4f7e191c53321d70f9\",\n    \"0x8b8e8972ac0218d7e3d922c734302803878ad508ca19f5f012bc047babd8a5c5a53deb5fe7c15a4c00fd6d1cb9b1dbd0\",\n    \"0xb5616b233fb3574a2717d125a434a2682ff68546dccf116dd8a3b750a096982f185614b9fb6c7678107ff40a451f56fa\",\n    \"0xaa6adf9b0c3334b0d0663f583a4914523b2ac2e7adffdb026ab9109295ff6af003ef8357026dbcf789896d2afded8d73\",\n    \"0xacb72df56a0b65496cd534448ed4f62950bb1e11e50873b6ed349c088ee364441821294ce0f7c61bd7d38105bea3b442\",\n    \"0xabae12df83e01ec947249fedd0115dc501d2b03ff7232092979eda531dbbca29ace1d46923427c7dde4c17bdf3fd7708\",\n    \"0x820b4fc2b63a9fda7964acf5caf19a2fc4965007cb6d6b511fcafcb1f71c3f673a1c0791d3f86e3a9a1eb6955b191cc0\",\n    \"0xaf277259d78c6b0f4f030a10c53577555df5e83319ddbad91afbd7c30bc58e7671c56d00d66ec3ab5ef56470cd910cee\",\n    \"0xad4a861c59f1f5ca1beedd488fb3d131dea924fffd8e038741a1a7371fad7370ca5cf80dc01f177fbb9576713bb9a5b3\",\n    \"0xb67a5162982ce6a55ccfb2f177b1ec26b110043cf18abd6a6c451cf140b5af2d634591eb4f28ad92177d8c7e5cd0a5e8\",\n    \"0x96176d0a83816330187798072d449cbfccff682561e668faf6b1220c9a6535b32a6e4f852e8abb00f79abb87493df16b\",\n    \"0xb0afe6e7cb672e18f0206e4423f51f8bd0017bf464c4b186d46332c5a5847647f89ff7fa4801a41c1b0b42f6135bcc92\",\n    \"0x8fc5e7a95ef20c1278c645892811f6fe3f15c431ebc998a32ec0da44e7213ea934ed2be65239f3f49b8ec471e9914160\",\n    \"0xb7793e41adda6c82ba1f2a31f656f6205f65bf8a3d50d836ee631bc7ce77c153345a2d0fc5c60edf8b37457c3729c4ec\",\n    \"0xa504dd7e4d6b2f4379f22cc867c65535079c75ccc575955f961677fa63ecb9f74026fa2f60c9fb6323c1699259e5e9c8\",\n    \"0xab899d00ae693649cc1afdf30fb80d728973d2177c006e428bf61c7be01e183866614e05410041bc82cb14a33330e69c\",\n    \"0x8a3bd8b0b1be570b65c4432a0f6dc42f48a2000e30ab089cf781d38f4090467b54f79c0d472fcbf18ef6a00df69cc6f3\",\n    \"0xb4d7028f7f76a96a3d7803fca7f507ae11a77c5346e9cdfccb120a833a59bda1f4264e425aa588e7a16f8e7638061d84\",\n    \"0xb9c7511a76ea5fb105de905d44b02edb17008335766ee357ed386b7b3cf19640a98b38785cb14603c1192bee5886c9b6\",\n    \"0x8563afb12e53aed71ac7103ab8602bfa8371ae095207cb0d59e8fd389b6ad1aff0641147e53cb6a7ca16c7f37c9c5e6b\",\n    \"0x8e108be614604e09974a9ed90960c28c4ea330a3d9a0cb4af6dd6f193f84ab282b243ecdf549b3131036bebc8905690c\",\n    \"0xb794d127fbedb9c5b58e31822361706ffac55ce023fbfe55716c3c48c2fd2f2c7660a67346864dfe588812d369cb50b6\",\n    \"0xb797a3442fc3b44f41baefd30346f9ac7f96e770d010d53c146ce74ce424c10fb62758b7e108b8abfdc5fafd89d745cb\",\n    \"0x993bb71e031e8096442e6205625e1bfddfe6dd6a83a81f3e2f84fafa9e5082ab4cad80a099f21eff2e81c83457c725c3\",\n    \"0x8711ab833fc03e37acf2e1e74cfd9133b101ff4144fe30260654398ae48912ab46549d552eb9d15d2ea57760d35ac62e\",\n    \"0xb21321fd2a12083863a1576c5930e1aecb330391ef83326d9d92e1f6f0d066d1394519284ddab55b2cb77417d4b0292f\",\n    \"0x877d98f731ffe3ee94b0b5b72d127630fa8a96f6ca4f913d2aa581f67732df6709493693053b3e22b0181632ac6c1e3b\",\n    \"0xae391c12e0eb8c145103c62ea64f41345973311c3bf7281fa6bf9b7faafac87bcf0998e5649b9ef81e288c369c827e07\",\n    \"0xb83a2842f36998890492ab1cd5a088d9423d192681b9a3a90ec518d4c541bce63e6c5f4df0f734f31fbfdd87785a2463\",\n    \"0xa21b6a790011396e1569ec5b2a423857b9bec16f543e63af28024e116c1ea24a3b96e8e4c75c6537c3e4611fd265e896\",\n    \"0xb4251a9c4aab3a495da7a42e684ba4860dbcf940ad1da4b6d5ec46050cbe8dab0ab9ae6b63b5879de97b905723a41576\",\n    \"0x8222f70aebfe6ac037f8543a08498f4cadb3edaac00336fc00437eb09f2cba758f6c38e887cc634b4d5b7112b6334836\",\n    \"0x86f05038e060594c46b5d94621a1d9620aa8ba59a6995baf448734e21f58e23c1ea2993d3002ad5250d6edd5ba59b34f\",\n    \"0xa7c0c749baef811ab31b973c39ceb1d94750e2bc559c90dc5eeb20d8bb6b78586a2b363c599ba2107d6be65cd435f24e\",\n    \"0x861d46a5d70b38d6c1cd72817a2813803d9f34c00320c8b62f8b9deb67f5b5687bc0b37c16d28fd017367b92e05da9ca\",\n    \"0xb3365d3dab639bffbe38e35383686a435c8c88b397b717cd4aeced2772ea1053ceb670f811f883f4e02975e5f1c4ac58\",\n    \"0xa5750285f61ab8f64cd771f6466e2c0395e01b692fd878f2ef2d5c78bdd8212a73a3b1dfa5e4c8d9e1afda7c84857d3b\",\n    \"0x835a10809ccf939bc46cf950a33b36d71be418774f51861f1cd98a016ade30f289114a88225a2c11e771b8b346cbe6ef\",\n    \"0xa4f59473a037077181a0a62f1856ec271028546ca9452b45cedfcb229d0f4d1aabfc13062b07e536cc8a0d4b113156a2\",\n    \"0x95cd14802180b224d44a73cc1ed599d6c4ca62ddcaa503513ccdc80aaa8be050cc98bd4b4f3b639549beb4587ac6caf9\",\n    \"0x973b731992a3e69996253d7f36dd7a0af1982b5ed21624b77a7965d69e9a377b010d6dabf88a8a97eec2a476259859cc\",\n    \"0xaf8a1655d6f9c78c8eb9a95051aa3baaf9c811adf0ae8c944a8d3fcba87b15f61021f3baf6996fa0aa51c81b3cb69de1\",\n    \"0x835aad5c56872d2a2d6c252507b85dd742bf9b8c211ccb6b25b52d15c07245b6d89b2a40f722aeb5083a47cca159c947\",\n    \"0xabf4e970b02bef8a102df983e22e97e2541dd3650b46e26be9ee394a3ea8b577019331857241d3d12b41d4eacd29a3ac\",\n    \"0xa13c32449dbedf158721c13db9539ae076a6ce5aeaf68491e90e6ad4e20e20d1cdcc4a89ed9fd49cb8c0dd50c17633c1\",\n    \"0x8c8f78f88b7e22dd7e9150ab1c000f10c28e696e21d85d6469a6fe315254740f32e73d81ab1f3c1cf8f544c86df506e8\",\n    \"0xb4b77f2acfe945abf81f2605f906c10b88fb4d28628487fb4feb3a09f17f28e9780445dfcee4878349d4c6387a9d17d4\",\n    \"0x8d255c235f3812c6ecc646f855fa3832be5cb4dbb9c9e544989fafdf3f69f05bfd370732eaf954012f0044aa013fc9c6\",\n    \"0xb982efd3f34b47df37c910148ac56a84e8116647bea24145a49e34e0a6c0176e3284d838dae6230cb40d0be91c078b85\",\n    \"0x983f365aa09bd85df2a6a2ad8e4318996b1e27d02090755391d4486144e40d80b1fbfe1c798d626db92f52e33aa634da\",\n    \"0x95fd1981271f3ea3a41d654cf497e6696730d9ff7369f26bc4d7d15c7adb4823dd0c42e4a005a810af12d234065e5390\",\n    \"0xa9f5219bd4b913c186ef30c02f995a08f0f6f1462614ea5f236964e02bdaa33db9d9b816c4aee5829947840a9a07ba60\",\n    \"0x9210e6ceb05c09b46fd09d036287ca33c45124ab86315e5d6911ff89054f1101faaa3e83d123b7805056d388bcec6664\",\n    \"0x8ed9cbf69c6ff3a5c62dd9fe0d7264578c0f826a29e614bc2fb4d621d90c8c9992438accdd7a614b1dca5d1bb73dc315\",\n    \"0x85cf2a8cca93e00da459e3cecd22c342d697eee13c74d5851634844fc215f60053cf84b0e03c327cb395f48d1c71a8a4\",\n    \"0x8818a18e9a2ec90a271b784400c1903089ffb0e0b40bc5abbbe12fbebe0f731f91959d98c5519ef1694543e31e2016d4\",\n    \"0x8dabc130f296fa7a82870bf9a8405aaf542b222ed9276bba9bd3c3555a0f473acb97d655ee7280baff766a827a8993f0\",\n    \"0xac7952b84b0dc60c4d858f034093b4d322c35959605a3dad2b806af9813a4680cb038c6d7f4485b4d6b2ff502aaeca25\",\n    \"0xad65cb6d57b48a2602568d2ec8010baed0eb440eec7638c5ec8f02687d764e9de5b5d42ad5582934e592b48471c22d26\",\n    \"0xa02ab8bd4c3d114ea23aebdd880952f9495912817da8c0c08eabc4e6755439899d635034413d51134c72a6320f807f1c\",\n    \"0x8319567764b8295402ec1ebef4c2930a138480b37e6d7d01c8b4c9cd1f2fc3f6e9a44ae6e380a0c469b25b06db23305f\",\n    \"0xafec53b2301dc0caa8034cd9daef78c48905e6068d692ca23d589b84a6fa9ddc2ed24a39480597e19cb3e83eec213b3f\",\n    \"0xac0b4ffdb5ae08e586a9cdb98f9fe56f4712af3a97065e89e274feacfb52b53c839565aee93c4cfaaccfe51432c4fab0\",\n    \"0x8972cbf07a738549205b1094c5987818124144bf187bc0a85287c94fdb22ce038c0f11df1aa16ec5992e91b44d1af793\",\n    \"0xb7267aa6f9e3de864179b7da30319f1d4cb2a3560f2ea980254775963f1523b44c680f917095879bebfa3dc2b603efcf\",\n    \"0x80f68f4bfc337952e29504ee5149f15093824ea7ab02507efd1317a670f6cbc3611201848560312e3e52e9d9af72eccf\",\n    \"0x8897fee93ce8fc1e1122e46b6d640bba309384dbd92e46e185e6364aa8210ebf5f9ee7e5e604b6ffba99aa80a10dd7d0\",\n    \"0xb58ea6c02f2360be60595223d692e82ee64874fda41a9f75930f7d28586f89be34b1083e03bbc1575bbfdda2d30db1ea\",\n    \"0x85a523a33d903280d70ac5938770453a58293480170c84926457ac2df45c10d5ff34322ab130ef4a38c916e70d81af53\",\n    \"0xa2cbf045e1bed38937492c1f2f93a5ba41875f1f262291914bc1fc40c60bd0740fb3fea428faf6da38b7c180fe8ac109\",\n    \"0x8c09328770ed8eb17afc6ac7ddd87bb476de18ed63cab80027234a605806895959990c47bd10d259d7f3e2ecb50074c9\",\n    \"0xb4b9e19edb4a33bde8b7289956568a5b6b6557404e0a34584b5721fe6f564821091013fbb158e2858c6d398293bb4b59\",\n    \"0x8a47377df61733a2aa5a0e945fce00267f8e950f37e109d4487d92d878fb8b573317bb382d902de515b544e9e233458d\",\n    \"0xb5804c9d97efeff5ca94f3689b8088c62422d92a1506fd1d8d3b1b30e8a866ad0d6dad4abfa051dfc4471250cac4c5d9\",\n    \"0x9084a6ee8ec22d4881e9dcc8a9eb3c2513523d8bc141942370fd191ad2601bf9537a0b1e84316f3209b3d8a54368051e\",\n    \"0x85447eea2fa26656a649f8519fa67279183044791d61cf8563d0783d46d747d96af31d0a93507bbb2242666aa87d3720\",\n    \"0x97566a84481027b60116c751aec552adfff2d9038e68d48c4db9811fb0cbfdb3f1d91fc176a0b0d988a765f8a020bce1\",\n    \"0xae87e5c1b9e86c49a23dceda4ecfd1dcf08567f1db8e5b6ec752ebd45433c11e7da4988573cdaebbb6f4135814fc059e\",\n    \"0xabee05cf9abdbc52897ac1ce9ed157f5466ed6c383d6497de28616238d60409e5e92619e528af8b62cc552bf09970dc2\",\n    \"0xae6d31cd7bf9599e5ee0828bab00ceb4856d829bba967278a73706b5f388465367aa8a6c7da24b5e5f1fdd3256ef8e63\",\n    \"0xac33e7b1ee47e1ee4af472e37ab9e9175260e506a4e5ce449788075da1b53c44cb035f3792d1eea2aa24b1f688cc6ed3\",\n    \"0x80f65b205666b0e089bb62152251c48c380a831e5f277f11f3ef4f0d52533f0851c1b612267042802f019ec900dc0e8f\",\n    \"0x858520ad7aa1c9fed738e3b583c84168f2927837ad0e1d326afe9935c26e9b473d7f8c382e82ef1fe37d2b39bb40a1ee\",\n    \"0xb842dd4af8befe00a97c2d0f0c33c93974761e2cb9e5ab8331b25170318ddd5e4bdbc02d8f90cbfdd5f348f4f371c1f7\",\n    \"0x8bf2cb79bc783cb57088aae7363320cbeaabd078ffdec9d41bc74ff49e0043d0dad0086a30e5112b689fd2f5a606365d\",\n    \"0x982eb03bbe563e8850847cd37e6a3306d298ab08c4d63ab6334e6b8c1fa13fce80cf2693b09714c7621d74261a0ff306\",\n    \"0xb143edb113dec9f1e5105d4a93fbe502b859e587640d3db2f628c09a17060e6aec9e900e2c8c411cda99bc301ff96625\",\n    \"0xaf472d9befa750dcebc5428fe1a024f18ec1c07bca0f95643ce6b5f4189892a910285afb03fd7ed7068fbe614e80d33c\",\n    \"0xa97e3bc57ede73ecd1bbf02de8f51b4e7c1a067da68a3cd719f4ba26a0156cbf1cef2169fd35a18c5a4cced50d475998\",\n    \"0xa862253c937cf3d75d7183e5f5be6a4385d526aeda5171c1c60a8381fea79f88f5f52a4fab244ecc70765d5765e6dfd5\",\n    \"0x90cb776f8e5a108f1719df4a355bebb04bf023349356382cae55991b31720f0fd03206b895fa10c56c98f52453be8778\",\n    \"0xa7614e8d0769dccd520ea4b46f7646e12489951efaef5176bc889e9eb65f6e31758df136b5bf1e9107e68472fa9b46ec\",\n    \"0xac3a9b80a3254c42e5ed3a090a0dd7aee2352f480de96ad187027a3bb6c791eddfc3074b6ffd74eea825188f107cda4d\",\n    \"0x82a01d0168238ef04180d4b6e0a0e39024c02c2d75b065017c2928039e154d093e1af4503f4d1f3d8a948917abb5d09f\",\n    \"0x8fab000a2b0eef851a483aec8d2dd85fe60504794411a2f73ed82e116960547ac58766cb73df71aea71079302630258d\",\n    \"0x872451a35c6db61c63e9b8bb9f16b217f985c20be4451c14282c814adb29d7fb13f201367c664435c7f1d4d9375d7a58\",\n    \"0x887d9ff54cc96b35d562df4a537ff972d7c4b3fd91ab06354969a4cfede0b9fc68bbffb61d0dbf1a58948dc701e54f5a\",\n    \"0x8cb5c2a6bd956875d88f41ae24574434f1308514d44057b55c9c70f13a3366ed054150eed0955a38fda3f757be73d55f\",\n    \"0x89ad0163cad93e24129d63f8e38422b7674632a8d0a9016ee8636184cab177659a676c4ee7efba3abe1a68807c656d60\",\n    \"0xb9ec01c7cab6d00359b5a0b4a1573467d09476e05ca51a9227cd16b589a9943d161eef62dcc73f0de2ec504d81f4d252\",\n    \"0x8031d17635d39dfe9705c485d2c94830b6fc9bc67b91300d9d2591b51e36a782e77ab5904662effa9382d9cca201f525\",\n    \"0x8be5a5f6bc8d680e5092d6f9a6585acbaaaa2ddc671da560dcf5cfa4472f4f184b9597b5b539438accd40dda885687cc\",\n    \"0xb1fc0f052fae038a2e3de3b3a96b0a1024b009de8457b8b3adb2d315ae68a89af905720108a30038e5ab8d0d97087785\",\n    \"0x8b8bdc77bd3a6bc7ca5492b6f8c614852c39a70d6c8a74916eaca0aeb4533b11898b8820a4c2620a97bf35e275480029\",\n    \"0xaf35f4dc538d4ad5cdf710caa38fd1eb496c3fa890a047b6a659619c5ad3054158371d1e88e0894428282eed9f47f76b\",\n    \"0x8166454a7089cc07758ad78724654f4e7a1a13e305bbf88ddb86f1a4b2904c4fc8ab872d7da364cdd6a6c0365239e2ad\",\n    \"0xab287c7d3addce74ce40491871c768abe01daaa0833481276ff2e56926b38a7c6d2681ffe837d2cc323045ad1a4414f9\",\n    \"0xb90317f4505793094d89365beb35537f55a6b5618904236258dd04ca61f21476837624a2f45fef8168acf732cab65579\",\n    \"0x98ae5ea27448e236b6657ab5ef7b1cccb5372f92ab25f5fa651fbac97d08353a1dae1b280b1cd42b17d2c6a70a63ab9d\",\n    \"0xadcf54e752d32cbaa6cb98fbca48d8cd087b1db1d131d465705a0d8042c8393c8f4d26b59006eb50129b21e6240f0c06\",\n    \"0xb591a3e4db18a7345fa935a8dd7994bbac5cc270b8ebd84c8304c44484c7a74afb45471fdbe4ab22156a30fae1149b40\",\n    \"0x806b53ac049a42f1dcc1d6335505371da0bf27c614f441b03bbf2e356be7b2fb4eed7117eabcce9e427a542eaa2bf7d8\",\n    \"0x800482e7a772d49210b81c4a907f5ce97f270b959e745621ee293cf8c71e8989363d61f66a98f2d16914439544ca84c7\",\n    \"0x99de9eafdad3617445312341644f2bb888680ff01ce95ca9276b1d2e5ef83fa02dab5e948ebf66c17df0752f1bd37b70\",\n    \"0x961ee30810aa4c93ae157fbe9009b8e443c082192bd36a73a6764ff9b2ad8b0948fe9a73344556e01399dd77badb4257\",\n    \"0xae0a361067c52efbe56c8adf982c00432cd478929459fc7f74052c8ee9531cd031fe1335418fde53f7c2ef34254eb7ac\",\n    \"0xa3503d16b6b27eb20c1b177bcf90d13706169220523a6271b85b2ce35a9a2b9c5bed088540031c0a4ebfdae3a4c6ab04\",\n    \"0x909420122c3e723289ca4e7b81c2df5aff312972a2203f4c45821b176e7c862bf9cac7f7df3adf1d59278f02694d06e7\",\n    \"0x989f42380ae904b982f85d0c6186c1aef5d6bcba29bcfbb658e811b587eb2749c65c6e4a8cc6409c229a107499a4f5d7\",\n    \"0x8037a6337195c8e26a27ea4ef218c6e7d79a9720aaab43932d343192abc2320fe72955f5e431c109093bda074103330a\",\n    \"0xb312e168663842099b88445e940249cc508f080ab0c94331f672e7760258dbd86be5267e4cf25ea25facb80bff82a7e9\",\n    \"0xaaa3ff8639496864fcdbfdda1ac97edc4f08e3c9288b768f6c8073038c9fbbf7e1c4bea169b4d45c31935cdf0680d45e\",\n    \"0x97dbd3df37f0b481a311dfc5f40e59227720f367912200d71908ef6650f32cc985cb05b981e3eea38958f7e48d10a15d\",\n    \"0xa89d49d1e267bb452d6cb621b9a90826fe55e9b489c0427b94442d02a16f390eed758e209991687f73f6b5a032321f42\",\n    \"0x9530dea4e0e19d6496f536f2e75cf7d814d65fde567055eb20db48fd8d20d501cd2a22fb506db566b94c9ee10f413d43\",\n    \"0x81a7009b9e67f1965fa7da6a57591c307de91bf0cd35ab4348dc4a98a4961e096d004d7e7ad318000011dc4342c1b809\",\n    \"0x83440a9402b766045d7aca61a58bba2aa29cac1cf718199e472ba086f5d48093d9dda4d135292ba51d049a23964eceae\",\n    \"0xa06c9ce5e802df14f6b064a3d1a0735d429b452f0e2e276042800b0a4f16df988fd94cf3945921d5dd3802ab2636f867\",\n    \"0xb1359e358b89936dee9e678a187aad3e9ab14ac40e96a0a68f70ee2583cdcf467ae03bef4215e92893f4e12f902adec8\",\n    \"0x835304f8619188b4d14674d803103d5a3fa594d48e96d9699e653115dd05fdc2dda6ba3641cf7ad53994d448da155f02\",\n    \"0x8327cba5a9ff0d3f5cd0ae55e77167448926d5fcf76550c0ad978092a14122723090c51c415e88e42a2b62eb07cc3981\",\n    \"0xb373dcdaea85f85ce9978b1426a7ef4945f65f2d3467a9f1cc551a99766aac95df4a09e2251d3f89ca8c9d1a7cfd7b0e\",\n    \"0xab1422dc41af2a227b973a6fd124dfcb2367e2a11a21faa1d381d404f51b7257e5bc82e9cf20cd7fe37d7ae761a2ab37\",\n    \"0xa93774a03519d2f20fdf2ef46547b0a5b77c137d6a3434b48d56a2cbef9e77120d1b85d0092cf8842909213826699477\",\n    \"0x8eb967a495a38130ea28711580b7e61bcd1d051cd9e4f2dbf62f1380bd86e0d60e978d72f6f31e909eb97b3b9a2b867c\",\n    \"0xae8213378da1287ba1fe4242e1acaec19b877b6fe872400013c6eac1084b8d03156792fa3020201725b08228a1e80f49\",\n    \"0xb143daf6893d674d607772b3b02d8ac48f294237e2f2c87963c0d4e26d9227d94a2a13512457c3d5883544bbc259f0ef\",\n    \"0xb343bd2aca8973888e42542218924e2dda2e938fd1150d06878af76f777546213912b7c7a34a0f94186817d80ffa185c\",\n    \"0xb188ebc6a8c3007001aa347ae72cc0b15d09bc6c19a80e386ee4b334734ec0cc2fe8b493c2422f38d1e6d133cc3db6fe\",\n    \"0xb795f6a8b9b826aaeee18ccd6baf6c5adeeec85f95eb5b6d19450085ec7217e95a2d9e221d77f583b297d0872073ba0e\",\n    \"0xb1c7dbd998ad32ae57bfa95deafa147024afd57389e98992c36b6e52df915d3d5a39db585141ec2423173e85d212fed8\",\n    \"0x812bcdeb9fe5f12d0e1df9964798056e1f1c3de3b17b6bd2919b6356c4b86d8e763c01933efbe0224c86a96d5198a4be\",\n    \"0xb19ebeda61c23d255cbf472ef0b8a441f4c55b70f0d8ed47078c248b1d3c7c62e076b43b95c00a958ec8b16d5a7cb0d7\",\n    \"0xb02adc9aaa20e0368a989c2af14ff48b67233d28ebee44ff3418bb0473592e6b681af1cc45450bd4b175df9051df63d9\",\n    \"0x8d87f0714acee522eb58cec00360e762adc411901dba46adc9227124fa70ee679f9a47e91a6306d6030dd4eb8de2f3c1\",\n    \"0x8be54cec21e74bcc71de29dc621444263737db15f16d0bb13670f64e42f818154e04b484593d19ef95f2ee17e4b3fe21\",\n    \"0xab8e20546c1db38d31493b5d5f535758afb17e459645c1b70813b1cf7d242fd5d1f4354a7c929e8f7259f6a25302e351\",\n    \"0x89f035a1ed8a1e302ac893349ba8ddf967580fcb6e73d44af09e3929cde445e97ff60c87dafe489e2c0ab9c9986cfa00\",\n    \"0x8b2b0851a795c19191a692af55f7e72ad2474efdc5401bc3733cfdd910e34c918aaebe69d5ea951bdddf3c01cabbfc67\",\n    \"0xa4edb52c2b51495ccd1ee6450fc14b7b3ede8b3d106808929d02fb31475bacb403e112ba9c818d2857651e508b3a7dd1\",\n    \"0x9569341fded45d19f00bcf3cbf3f20eb2b4d82ef92aba3c8abd95866398438a2387437e580d8b646f17cf6fde8c5af23\",\n    \"0xaa4b671c6d20f72f2f18a939a6ff21cc37e0084b44b4a717f1be859a80b39fb1be026b3205adec2a66a608ec2bcd578f\",\n    \"0x94902e980de23c4de394ad8aec91b46f888d18f045753541492bfbb92c59d3daa8de37ae755a6853744af8472ba7b72b\",\n    \"0xaf651ef1b2a0d30a7884557edfad95b6b5d445a7561caebdc46a485aedd25932c62c0798465c340a76f6feaa196dd712\",\n    \"0xb7b669b8e5a763452128846dd46b530dca4893ace5cc5881c7ddcd3d45969d7e73fbebdb0e78aa81686e5f7b22ec5759\",\n    \"0x82507fd4ebe9fa656a7f2e084d64a1fa6777a2b0bc106d686e2d9d2edafc58997e58cb6bfd0453b2bf415704aa82ae62\",\n    \"0xb40bce2b42b88678400ecd52955bbdadd15f8b9e1b3751a1a3375dc0efb5ca3ee258cf201e1140b3c09ad41217d1d49e\",\n    \"0xb0210d0cbb3fbf3b8cdb39e862f036b0ff941cd838e7aaf3a8354e24246e64778d22f3de34572e6b2a580614fb6425be\",\n    \"0x876693cba4301b251523c7d034108831df3ce133d8be5a514e7a2ca494c268ca0556fa2ad8310a1d92a16b55bcd99ea9\",\n    \"0x8660281406d22a4950f5ef050bf71dd3090edb16eff27fa29ef600cdea628315e2054211ed2cc6eaf8f2a1771ef689fd\",\n    \"0xa610e7e41e41ab66955b809ba4ade0330b8e9057d8efc9144753caed81995edeb1a42a53f93ce93540feca1fae708dac\",\n    \"0xa49e2c176a350251daef1218efaccc07a1e06203386ede59c136699d25ca5cb2ac1b800c25b28dd05678f14e78e51891\",\n    \"0x83e0915aa2b09359604566080d411874af8c993beba97d4547782fdbe1a68e59324b800ff1f07b8db30c71adcbd102a8\",\n    \"0xa19e84e3541fb6498e9bb8a099c495cbfcad113330e0262a7e4c6544495bb8a754b2208d0c2d895c93463558013a5a32\",\n    \"0x87f2bd49859a364912023aca7b19a592c60214b8d6239e2be887ae80b69ebdeb59742bdebcfa73a586ab23b2c945586c\",\n    \"0xb8e8fdddae934a14b57bc274b8dcd0d45ebb95ddbaabef4454e0f6ce7d3a5a61c86181929546b3d60c447a15134d08e1\",\n    \"0x87e0c31dcb736ea4604727e92dc1d9a3cf00adcff79df3546e02108355260f3dd171531c3c0f57be78d8b28058fcc8c0\",\n    \"0x9617d74e8f808a4165a8ac2e30878c349e1c3d40972006f0787b31ea62d248c2d9f3fc3da83181c6e57e95feedfd0e8c\",\n    \"0x8949e2cee582a2f8db86e89785a6e46bc1565c2d8627d5b6bf43ba71ffadfab7e3c5710f88dcb5fb2fc6edf6f4fae216\",\n    \"0xad3fa7b0edceb83118972a2935a09f409d09a8db3869f30be3a76f67aa9fb379cabb3a3aff805ba023a331cad7d7eb64\",\n    \"0x8c95718a4112512c4efbd496be38bf3ca6cdcaad8a0d128f32a3f9aae57f3a57bdf295a3b372a8c549fda8f4707cffed\",\n    \"0x88f3261d1e28a58b2dee3fcc799777ad1c0eb68b3560f9b4410d134672d9533532a91ea7be28a041784872632d3c9d80\",\n    \"0xb47472a41d72dd2e8b72f5c4f8ad626737dde3717f63d6bc776639ab299e564cbad0a2ad5452a07f02ff49a359c437e5\",\n    \"0x9896d21dc2e8aad87b76d6df1654f10cd7bceed4884159d50a818bea391f8e473e01e14684814c7780235f28e69dca6e\",\n    \"0x82d47c332bbd31bbe83b5eb44a23da76d4a7a06c45d7f80f395035822bc27f62f59281d5174e6f8e77cc9b5c3193d6f0\",\n    \"0x95c74cd46206e7f70c9766117c34c0ec45c2b0f927a15ea167901a160e1530d8522943c29b61e03568aa0f9c55926c53\",\n    \"0xa89d7757825ae73a6e81829ff788ea7b3d7409857b378ebccd7df73fdbe62c8d9073741cf038314971b39af6c29c9030\",\n    \"0x8c1cd212d0b010905d560688cfc036ae6535bc334fa8b812519d810b7e7dcf1bb7c5f43deaa40f097158358987324a7f\",\n    \"0xb86993c383c015ed8d847c6b795164114dd3e9efd25143f509da318bfba89389ea72a420699e339423afd68b6512fafb\",\n    \"0x8d06bd379c6d87c6ed841d8c6e9d2d0de21653a073725ff74be1934301cc3a79b81ef6dd0aad4e7a9dc6eac9b73019bc\",\n    \"0x81af4d2d87219985b9b1202d724fe39ef988f14fef07dfe3c3b11714e90ffba2a97250838e8535eb63f107abfe645e96\",\n    \"0x8c5e0af6330a8becb787e4b502f34f528ef5756e298a77dc0c7467433454347f3a2e0bd2641fbc2a45b95e231c6e1c02\",\n    \"0x8e2a8f0f04562820dc8e7da681d5cad9fe2e85dd11c785fb6fba6786c57a857e0b3bd838fb849b0376c34ce1665e4837\",\n    \"0xa39be8269449bfdfc61b1f62077033649f18dae9bef7c6163b9314ca8923691fb832f42776f0160b9e8abd4d143aa4e1\",\n    \"0x8c154e665706355e1cc98e0a4cabf294ab019545ba9c4c399d666e6ec5c869ca9e1faf8fb06cd9c0a5c2f51a7d51b70a\",\n    \"0xa046a7d4de879d3ebd4284f08f24398e9e3bf006cd4e25b5c67273ade248689c69affff92ae810c07941e4904296a563\",\n    \"0xafd94c1cb48758e5917804df03fb38a6da0e48cd9b6262413ea13b26973f9e266690a1b7d9d24bbaf7e82718e0e594b0\",\n    \"0x859e21080310c8d6a38e12e2ac9f90a156578cdeb4bb2e324700e97d9a5511cd6045dc39d1d0de3f94aeed043a24119d\",\n    \"0xa219fb0303c379d0ab50893264919f598e753aac9065e1f23ef2949abc992577ab43c636a1d2c089203ec9ddb941e27d\",\n    \"0xb0fdb639d449588a2ca730afcba59334e7c387342d56defdfb7ef79c493f7fd0e5277eff18e7203e756c7bdda5803047\",\n    \"0x87f9c3b7ed01f54368aca6dbcf2f6e06bff96e183c4b2c65f8baa23b377988863a0a125d5cdd41a072da8462ced4c070\",\n    \"0x99ef7a5d5ac2f1c567160e1f8c95f2f38d41881850f30c461a205f7b1b9fb181277311333839b13fb3ae203447e17727\",\n    \"0xaeaca9b1c2afd24e443326cc68de67b4d9cedb22ad7b501a799d30d39c85bb2ea910d4672673e39e154d699e12d9b3dc\",\n    \"0xa11675a1721a4ba24dd3d0e4c3c33a6edf4cd1b9f6b471070b4386c61f77452266eae6e3f566a40cfc885eada9a29f23\",\n    \"0xb228334445e37b9b49cb4f2cc56b454575e92173ddb01370a553bba665adadd52df353ad74470d512561c2c3473c7bb9\",\n    \"0xa18177087c996572d76f81178d18ed1ceebc8362a396348ce289f1d8bd708b9e99539be6fccd4acb1112381cfc5749b4\",\n    \"0x8e7b8bf460f0d3c99abb19803b9e43422e91507a1c0c22b29ee8b2c52d1a384da4b87c292e28eff040db5be7b1f8641f\",\n    \"0xb03d038d813e29688b6e6f444eb56fec3abba64c3d6f890a6bcf2e916507091cdb2b9d2c7484617be6b26552ed1c56cb\",\n    \"0xa1c88ccd30e934adfc5494b72655f8afe1865a84196abfb376968f22ddc07761210b6a9fb7638f1413d1b4073d430290\",\n    \"0x961b714faebf172ad2dbc11902461e286e4f24a99a939152a53406117767682a571057044decbeb3d3feef81f4488497\",\n    \"0xa03dc4059b46effdd786a0a03cc17cfee8585683faa35bb07936ded3fa3f3a097f518c0b8e2db92fd700149db1937789\",\n    \"0xadf60180c99ca574191cbcc23e8d025b2f931f98ca7dfcebfc380226239b6329347100fcb8b0fcb12db108c6ad101c07\",\n    \"0x805d4f5ef24d46911cbf942f62cb84b0346e5e712284f82b0db223db26d51aabf43204755eb19519b00e665c7719fcaa\",\n    \"0x8dea7243e9c139662a7fe3526c6c601eee72fd8847c54c8e1f2ad93ef7f9e1826b170afe58817dac212427164a88e87f\",\n    \"0xa2ba42356606d651b077983de1ad643650997bb2babb188c9a3b27245bb65d2036e46667c37d4ce02cb1be5ae8547abe\",\n    \"0xaf2ae50b392bdc013db2d12ce2544883472d72424fc767d3f5cb0ca2d973fc7d1f425880101e61970e1a988d0670c81b\",\n    \"0x98e6bec0568d3939b31d00eb1040e9b8b2a35db46ddf4369bdaee41bbb63cc84423d29ee510a170fb5b0e2df434ba589\",\n    \"0x822ff3cd12fbef4f508f3ca813c04a2e0b9b799c99848e5ad3563265979e753ee61a48f6adc2984a850f1b46c1a43d35\",\n    \"0x891e8b8b92a394f36653d55725ef514bd2e2a46840a0a2975c76c2a935577f85289026aaa74384da0afe26775cbddfb9\",\n    \"0xb2a3131a5d2fe7c8967047aa66e4524babae941d90552171cc109527f345f42aa0df06dcbb2fa01b33d0043917bbed69\",\n    \"0x80c869469900431f3eeefafdbe07b8afd8cee7739e659e6d0109b397cacff85a88247698f87dc4e2fe39a592f250ac64\",\n    \"0x9091594f488b38f9d2bb5df49fd8b4f8829d9c2f11a197dd1431ed5abbc5c954bbde3387088f9ee3a5a834beb7619bce\",\n    \"0xb472e241e6956146cca57b97a8a204668d050423b4e76f857bad5b47f43b203a04c8391ba9d9c3e95093c071f9d376a1\",\n    \"0xb7dd2de0284844392f7dfb56fe7ca3ede41e27519753ffc579a0a8d2d65ceb8108d06b6b0d4c3c1a2588951297bd1a1e\",\n    \"0x902116ce70d0a079ac190321c1f48701318c05f8e69ee09694754885d33a835a849cafe56f499a2f49f6cda413ddf9a7\",\n    \"0xb18105cc736787fafaf7c3c11c448bce9466e683159dff52723b7951dff429565e466e4841d982e3aaa9ee2066838666\",\n    \"0x97ab9911f3f659691762d568ae0b7faa1047b0aed1009c319fa79d15d0db8db9f808fc385dc9a68fa388c10224985379\",\n    \"0xb2a2cba65f5b927e64d2904ba412e2bac1cf18c9c3eda9c72fb70262497ecf505b640827e2afebecf10eebbcf48ccd3e\",\n    \"0xb36a3fd677baa0d3ef0dac4f1548ff50a1730286b8c99d276a0a45d576e17b39b3cbadd2fe55e003796d370d4be43ce3\",\n    \"0xa5dfec96ca3c272566e89dc453a458909247e3895d3e44831528130bc47cc9d0a0dac78dd3cad680a4351d399d241967\",\n    \"0x8029382113909af6340959c3e61db27392531d62d90f92370a432aec3eb1e4c36ae1d4ef2ba8ec6edb4d7320c7a453f6\",\n    \"0x971d85121ea108e6769d54f9c51299b0381ece8b51d46d49c89f65bedc123bab4d5a8bc14d6f67f4f680077529cbae4c\",\n    \"0x98ff6afc01d0bec80a278f25912e1b1ebff80117adae72e31d5b9fa4d9624db4ba2065b444df49b489b0607c45e26c4c\",\n    \"0x8fa29be10fb3ab30ce25920fec0187e6e91e458947009dabb869aade7136c8ba23602682b71e390c251f3743164cbdaa\",\n    \"0xb3345c89eb1653418fe3940cf3e56a9a9c66526389b98f45ca02dd62bfb37baa69a4baaa7132d7320695f8ea6ad1fd94\",\n    \"0xb72c7f5541c9ac6b60a7ec9f5415e7fb14da03f7164ea529952a29399f3a071576608dbbcc0d45994f21f92ddbeb1e19\",\n    \"0xaa3450bb155a5f9043d0ef95f546a2e6ade167280bfb75c9f09c6f9cdb1fffb7ce8181436161a538433afa3681c7a141\",\n    \"0x92a18fecaded7854b349f441e7102b638ababa75b1b0281dd0bded6541abe7aa37d96693595be0b01fe0a2e2133d50f9\",\n    \"0x980756ddf9d2253cfe6c94960b516c94889d09e612810935150892627d2ecee9a2517e04968eea295d0106850c04ca44\",\n    \"0xae68c6ccc454318cdd92f32b11d89116a3b8350207a36d22a0f626718cad671d960090e054c0c77ac3162ae180ecfd4b\",\n    \"0x99f31f66eaaa551749ad91d48a0d4e3ff4d82ef0e8b28f3184c54e852422ba1bdafd53b1e753f3a070f3b55f3c23b6a2\",\n    \"0xa44eaeaa6589206069e9c0a45ff9fc51c68da38d4edff1d15529b7932e6f403d12b9387019c44a1488a5d5f27782a51f\",\n    \"0xb80b5d54d4b344840e45b79e621bd77a3f83fb4ce6d8796b7d6915107b3f3c34d2e7d95bdafd120f285669e5acf2437a\",\n    \"0xb36c069ec085a612b5908314d6b84c00a83031780261d1c77a0384c406867c9847d5b0845deddfa512cc04a8df2046fb\",\n    \"0xb09dbe501583220f640d201acea7ee3e39bf9eda8b91aa07b5c50b7641d86d71acb619b38d27835ce97c3759787f08e9\",\n    \"0x87403d46a2bf63170fff0b857acacf42ee801afe9ccba8e5b4aea967b68eac73a499a65ca46906c2eb4c8f27bc739faa\",\n    \"0x82b93669f42a0a2aa5e250ffe6097269da06a9c02fcd1801abbad415a7729a64f830754bafc702e64600ba47671c2208\",\n    \"0x8e3a3029be7edb8dd3ab1f8216664c8dc50d395f603736061d802cef77627db7b859ef287ed850382c13b4d22d6a2d80\",\n    \"0x968e9ec7194ff424409d182ce0259acd950c384c163c04463bc8700a40b79beba6146d22b7fa7016875a249b7b31c602\",\n    \"0x8b42c984bbe4996e0c20862059167c6bdc5164b1ffcd928f29512664459212d263e89f0f0e30eed4e672ffa5ed0b01b5\",\n    \"0x96bac54062110dada905363211133f1f15dc7e4fd80a4c6e4a83bc9a0bcbbaba11cd2c7a13debcf0985e1a954c1da66b\",\n    \"0xa16dc8a653d67a7cd7ae90b2fffac0bf1ca587005430fe5ba9403edd70ca33e38ba5661d2ed6e9d2864400d997626a62\",\n    \"0xa68ab11a570a27853c8d67e491591dcba746bfbee08a2e75ae0790399130d027ed387f41ef1d7de8df38b472df309161\",\n    \"0x92532b74886874447c0300d07eda9bbe4b41ed25349a3da2e072a93fe32c89d280f740d8ff70d5816793d7f2b97373cc\",\n    \"0x88e35711b471e89218fd5f4d0eadea8a29405af1cd81974427bc4a5fb26ed60798daaf94f726c96e779b403a2cd82820\",\n    \"0xb5c72aa4147c19f8c4f3a0a62d32315b0f4606e0a7025edc5445571eaf4daff64f4b7a585464821574dd50dbe1b49d08\",\n    \"0x9305d9b4095258e79744338683fd93f9e657367b3ab32d78080e51d54eec331edbc224fad5093ebf8ee4bd4286757eb8\",\n    \"0xb2a17abb3f6a05bcb14dc7b98321fa8b46d299626c73d7c6eb12140bf4c3f8e1795250870947af817834f033c88a59d6\",\n    \"0xb3477004837dbd8ba594e4296f960fc91ab3f13551458445e6c232eb04b326da803c4d93e2e8dcd268b4413305ff84da\",\n    \"0x924b4b2ebaafdcfdfedb2829a8bf46cd32e1407d8d725a5bd28bdc821f1bafb3614f030ea4352c671076a63494275a3f\",\n    \"0x8b81b9ef6125c82a9bece6fdcb9888a767ac16e70527753428cc87c56a1236e437da8be4f7ecfe57b9296dc3ae7ba807\",\n    \"0x906e19ec8b8edd58bdf9ae05610a86e4ea2282b1bbc1e8b00b7021d093194e0837d74cf27ac9916bdb8ec308b00da3da\",\n    \"0xb41c5185869071760ac786078a57a2ab4e2af60a890037ac0c0c28d6826f15c2cf028fddd42a9b6de632c3d550bfbc14\",\n    \"0xa646e5dec1b713ae9dfdf7bdc6cd474d5731a320403c7dfcfd666ffc9ae0cff4b5a79530e8df3f4aa9cb80568cb138e9\",\n    \"0xb0efad22827e562bd3c3e925acbd0d9425d19057868608d78c2209a531cccd0f2c43dc5673acf9822247428ffa2bb821\",\n    \"0xa94c19468d14b6f99002fc52ac06bbe59e5c472e4a0cdb225144a62f8870b3f10593749df7a2de0bd3c9476ce682e148\",\n    \"0x803864a91162f0273d49271dafaab632d93d494d1af935aefa522768af058fce52165018512e8d6774976d52bd797e22\",\n    \"0xa08711c2f7d45c68fb340ac23597332e1bcaec9198f72967b9921204b9d48a7843561ff318f87908c05a44fc35e3cc9d\",\n    \"0x91c3cad94a11a3197ae4f9461faab91a669e0dddb0371d3cab3ed9aeb1267badc797d8375181130e461eadd05099b2a2\",\n    \"0x81bdaaf48aae4f7b480fc13f1e7f4dd3023a41439ba231760409ce9292c11128ab2b0bdbbf28b98af4f97b3551f363af\",\n    \"0x8d60f9df9fd303f625af90e8272c4ecb95bb94e6efc5da17b8ab663ee3b3f673e9f6420d890ccc94acf4d2cae7a860d8\",\n    \"0xa7b75901520c06e9495ab983f70b61483504c7ff2a0980c51115d11e0744683ce022d76e3e09f4e99e698cbd21432a0d\",\n    \"0x82956072df0586562fda7e7738226f694e1c73518dd86e0799d2e820d7f79233667192c9236dcb27637e4c65ef19d493\",\n    \"0xa586beb9b6ffd06ad200957490803a7cd8c9bf76e782734e0f55e04a3dc38949de75dc607822ec405736c576cf83bca3\",\n    \"0xa179a30d00def9b34a7e85607a447eea0401e32ab5abeee1a281f2acd1cf6ec81a178020666f641d9492b1bdf66f05a3\",\n    \"0x83e129705c538787ed8e0fdc1275e6466a3f4ee21a1e6abedd239393b1df72244723b92f9d9d9339a0cab6ebf28f5a16\",\n    \"0x811bd8d1e3722b64cd2f5b431167e7f91456e8bba2cc669d3fbbce7d553e29c3c19f629fcedd2498bc26d33a24891d17\",\n    \"0xa243c030c858f1f60cccd26b45b024698cc6d9d9e6198c1ed4964a235d9f8d0baf9cde10c8e63dfaa47f8e74e51a6e85\",\n    \"0xab839eb82e23ca52663281f863b55b0a3d6d4425c33ffb4eeb1d7979488ab068bf99e2a60e82cea4dc42c56c26cbfebe\",\n    \"0x8b896f9bb21d49343e67aec6ad175b58c0c81a3ca73d44d113ae4354a0065d98eb1a5cafedaf232a2bb9cdc62152f309\",\n    \"0xaf6230340cc0b66f5bf845540ed4fc3e7d6077f361d60762e488d57834c3e7eb7eacc1b0ed73a7d134f174a01410e50c\",\n    \"0x88975e1b1af678d1b5179f72300a30900736af580dd748fd9461ef7afccc91ccd9bed33f9da55c8711a7635b800e831f\",\n    \"0xa97486bb9047391661718a54b8dd5a5e363964e495eae6c692730264478c927cf3e66dd3602413189a3699fbeae26e15\",\n    \"0xa5973c161ab38732885d1d2785fd74bf156ba34881980cba27fe239caef06b24a533ffe6dbbbeca5e6566682cc00300a\",\n    \"0xa24776e9a840afda0003fa73b415d5bd6ecd9b5c2cc842b643ee51b8c6087f4eead4d0bfbd987eb174c489a7b952ff2a\",\n    \"0xa8a6ee06e3af053b705a12b59777267c546f33ba8a0f49493af8e6df4e15cf8dd2d4fb4daf7e84c6b5d3a7363118ff03\",\n    \"0xa28e59ce6ad02c2ce725067c0123117e12ac5a52c8f5af13eec75f4a9efc4f696777db18a374fa33bcae82e0734ebd16\",\n    \"0x86dfc3b78e841c708aff677baa8ee654c808e5d257158715097c1025d46ece94993efe12c9d188252ad98a1e0e331fec\",\n    \"0xa88d0275510f242eab11fdb0410ff6e1b9d7a3cbd3658333539815f1b450a84816e6613d15aa8a8eb15d87cdad4b27a2\",\n    \"0x8440acea2931118a5b481268ff9f180ee4ede85d14a52c026adc882410825b8275caa44aff0b50c2b88d39f21b1a0696\",\n    \"0xa7c3182eab25bd6785bacf12079d0afb0a9b165d6ed327814e2177148539f249eb9b5b2554538f54f3c882d37c0a8abe\",\n    \"0x85291fbe10538d7da38efdd55a7acebf03b1848428a2f664c3ce55367aece60039f4f320b1771c9c89a35941797f717c\",\n    \"0xa2c6414eeb1234728ab0de94aa98fc06433a58efa646ca3fcbd97dbfb8d98ae59f7ce6d528f669c8149e1e13266f69c9\",\n    \"0x840c8462785591ee93aee2538d9f1ec44ba2ca61a569ab51d335ac873f5d48099ae8d7a7efa0725d9ff8f9475bfa4f56\",\n    \"0xa7065a9d02fb3673acf7702a488fbc01aa69580964932f6f40b6c2d1c386b19e50b0e104fcac24ea26c4e723611d0238\",\n    \"0xb72db6d141267438279e032c95e6106c2ccb3164b842ba857a2018f3a35f4b040da92680881eb17cd61d0920d5b8f006\",\n    \"0xa8005d6c5960e090374747307ef0be2871a7a43fa4e76a16c35d2baab808e9777b496e9f57a4218b23390887c33a0b55\",\n    \"0x8e152cea1e00a451ca47c20a1e8875873419700af15a5f38ee2268d3fbc974d4bd5f4be38008fa6f404dbdedd6e6e710\",\n    \"0xa3391aed1fcd68761f06a7d1008ec62a09b1cb3d0203cd04e300a0c91adfed1812d8bc1e4a3fd7976dc0aae0e99f52f1\",\n    \"0x967eb57bf2aa503ee0c6e67438098149eac305089c155f1762cf5e84e31f0fbf27c34a9af05621e34645c1ec96afaec8\",\n    \"0x88af97ddc4937a95ec0dcd25e4173127260f91c8db2f6eac84afb789b363705fb3196235af631c70cafd09411d233589\",\n    \"0xa32df75b3f2c921b8767638fd289bcfc61e08597170186637a7128ffedd52c798c434485ac2c7de07014f9e895c2c3d8\",\n    \"0xb0a783832153650aa0d766a3a73ec208b6ce5caeb40b87177ffc035ab03c7705ecdd1090b6456a29f5fb7e90e2fa8930\",\n    \"0xb59c8e803b4c3486777d15fc2311b97f9ded1602fa570c7b0200bada36a49ee9ef4d4c1474265af8e1c38a93eb66b18b\",\n    \"0x982f2c85f83e852022998ff91bafbb6ff093ef22cf9d5063e083a48b29175ccbd51b9c6557151409e439096300981a6c\",\n    \"0x939e3b5989fefebb9d272a954659a4eb125b98c9da6953f5e628d26266bd0525ec38304b8d56f08d65abc4d6da4a8dbb\",\n    \"0x8898212fe05bc8de7d18503cb84a1c1337cc2c09d1eeef2b475aa79185b7322bf1f8e065f1bf871c0c927dd19faf1f6d\",\n    \"0x94b0393a41cd00f724aee2d4bc72103d626a5aecb4b5486dd1ef8ac27528398edf56df9db5c3d238d8579af368afeb09\",\n    \"0x96ac564450d998e7445dd2ea8e3fc7974d575508fa19e1c60c308d83b645864c029f2f6b7396d4ff4c1b24e92e3bac37\",\n    \"0x8adf6638e18aff3eb3b47617da696eb6c4bdfbecbbc3c45d3d0ab0b12cbad00e462fdfbe0c35780d21aa973fc150285e\",\n    \"0xb53f94612f818571b5565bbb295e74bada9b5f9794b3b91125915e44d6ddcc4da25510eab718e251a09c99534d6042d9\",\n    \"0x8b96462508d77ee083c376cd90807aebad8de96bca43983c84a4a6f196d5faf6619a2351f43bfeec101864c3bf255519\",\n    \"0xaeadf34657083fc71df33bd44af73bf5281c9ca6d906b9c745536e1819ea90b56107c55e2178ebad08f3ba75b3f81c86\",\n    \"0x9784ba29b2f0057b5af1d3ab2796d439b8753f1f749c73e791037461bdfc3f7097394283105b8ab01788ea5255a96710\",\n    \"0x8756241bda159d4a33bf74faba0d4594d963c370fb6a18431f279b4a865b070b0547a6d1613cf45b8cfb5f9236bbf831\",\n    \"0xb03ebfd6b71421dfd49a30460f9f57063eebfe31b9ceaa2a05c37c61522b35bdc09d7db3ad75c76c253c00ba282d3cd2\",\n    \"0xb34e7e6341fa9d854b2d3153bdda0c4ae2b2f442ab7af6f99a0975d45725aa48e36ae5f7011edd249862e91f499687d4\",\n    \"0xb462ee09dc3963a14354244313e3444de5cc37ea5ccfbf14cd9aca8027b59c4cb2a949bc30474497cab8123e768460e6\",\n    \"0xaea753290e51e2f6a21a9a0ee67d3a2713f95c2a5c17fe41116c87d3aa77b1683761264d704df1ac34f8b873bc88ef7b\",\n    \"0x98430592afd414394f98ddfff9f280fcb1c322dbe3510f45e1e9c4bb8ee306b3e0cf0282c0ee73ebb8ba087d4d9e0858\",\n    \"0xb95d3b5aaf54ffca11f4be8d57f76e14afdb20afc859dc7c7471e0b42031e8f3d461b726ecb979bdb2f353498dfe95ea\",\n    \"0x984d17f9b11a683132e0b5a9ee5945e3ff7054c2d5c716be73b29078db1d36f54c6e652fd2f52a19da313112e97ade07\",\n    \"0xab232f756b3fff3262be418a1af61a7e0c95ceebbc775389622a8e10610508cd6784ab7960441917a83cc191c58829ea\",\n    \"0xa28f41678d6e60de76b0e36ab10e4516e53e02e9c77d2b5af3cfeee3ce94cfa30c5797bd1daab20c98e1cad83ad0f633\",\n    \"0xb55395fca84dd3ccc05dd480cb9b430bf8631ff06e24cb51d54519703d667268c2f8afcde4ba4ed16bece8cc7bc8c6e0\",\n    \"0x8a8a5392a0e2ea3c7a8c51328fab11156004e84a9c63483b64e8f8ebf18a58b6ffa8fe8b9d95af0a2f655f601d096396\",\n    \"0xab480000fe194d23f08a7a9ec1c392334e9c687e06851f083845121ce502c06b54dda8c43092bcc1035df45cc752fe9b\",\n    \"0xb265644c29f628d1c7e8e25a5e845cabb21799371814730a41a363e1bda8a7be50fee7c3996a365b7fcba4642add10db\",\n    \"0xb8a915a3c685c2d4728f6931c4d29487cad764c5ce23c25e64b1a3259ac27235e41b23bfe7ae982921b4cb84463097df\",\n    \"0x8efa7338442a4b6318145a5440fc213b97869647eeae41b9aa3c0a27ee51285b73e3ae3b4a9423df255e6add58864aa9\",\n    \"0x9106d65444f74d217f4187dfc8fcf3810b916d1e4275f94f6a86d1c4f3565b131fd6cde1fa708bc05fe183c49f14941a\",\n    \"0x948252dac8026bbbdb0a06b3c9d66ec4cf9532163bab68076fda1bd2357b69e4b514729c15aaa83b5618b1977bbc60c4\",\n    \"0xae6596ccfdf5cbbc5782efe3bb0b101bb132dbe1d568854ca24cacc0b2e0e9fabcb2ca7ab42aecec412efd15cf8cb7a2\",\n    \"0x84a0b6c198ff64fd7958dfd1b40eac9638e8e0b2c4cd8cf5d8cdf80419baee76a05184bce6c5b635f6bf2d30055476a7\",\n    \"0x8893118be4a055c2b3da593dbca51b1ae2ea2469911acfb27ee42faf3e6c3ad0693d3914c508c0b05b36a88c8b312b76\",\n    \"0xb097479e967504deb6734785db7e60d1d8034d6ca5ba9552887e937f5e17bb413fccac2c1d1082154ed76609127860ad\",\n    \"0xa0294e6b9958f244d29943debf24b00b538b3da1116269b6e452bb12dc742226712fd1a15b9c88195afeb5d2415f505c\",\n    \"0xb3cc15f635080bc038f61b615f62b5b5c6f2870586191f59476e8368a73641d6ac2f7d0c1f54621982defdb318020230\",\n    \"0x99856f49b9fe1604d917c94d09cc0ed753d13d015d30587a94e6631ffd964b214e607deb8a69a8b5e349a7edf4309206\",\n    \"0xa8571e113ea22b4b4fce41a094da8c70de37830ae32e62c65c2fa5ad06a9bc29e884b945e73d448c72b176d6ecebfb58\",\n    \"0xa9e9c6e52beb0013273c29844956b3ce291023678107cdc785f7b44eff5003462841ad8780761b86aefc6b734adde7cf\",\n    \"0x80a784b0b27edb51ef2bad3aee80e51778dcaa0f3f5d3dcb5dc5d4f4b2cf7ae35b08de6680ea9dac53f8438b92eb09ef\",\n    \"0x827b543e609ea328e97e373f70ad72d4915a2d1daae0c60d44ac637231070e164c43a2a58db80a64df1c624a042b38f9\",\n    \"0xb449c65e8195202efdcb9bdb4e869a437313b118fef8b510cbbf8b79a4e99376adb749b37e9c20b51b31ed3310169e27\",\n    \"0x8ea3028f4548a79a94c717e1ed28ad4d8725b8d6ab18b021063ce46f665c79da3c49440c6577319dab2d036b7e08f387\",\n    \"0x897798431cfb17fe39f08f5f854005dc37b1c1ec1edba6c24bc8acb3b88838d0534a75475325a5ea98b326ad47dbad75\",\n    \"0x89cf232e6303b0751561960fd4dea5754a28c594daf930326b4541274ffb03c7dd75938e411eb9a375006a70ce38097f\",\n    \"0x9727c6ae7f0840f0b6c8bfb3a1a5582ceee705e0b5c59b97def7a7a2283edd4d3f47b7971e902a3a2079e40b53ff69b8\",\n    \"0xb76ed72b122c48679d221072efc0eeea063cb205cbf5f9ef0101fd10cb1075b8628166c83577cced654e1c001c7882f7\",\n    \"0xae908c42d208759da5ee9b405df85a6532ea35c6f0f6a1288d22870f59d98edc896841b8ac890a538e6c8d1e8b02d359\",\n    \"0x809d12fe4039a0ec80dc9be6a89acaab7797e5f7f9b163378f52f9a75a1d73b2e9ae6e3dd49e32ced439783c1cabbef5\",\n    \"0xa4149530b7f85d1098ba534d69548c6c612c416e8d35992fc1f64f4deeb41e09e49c6cf7aadbed7e846b91299358fe2d\",\n    \"0xa49342eacd1ec1148b8df1e253b1c015f603c39de11fa0a364ccb86ea32d69c34fd7aa6980a1fadcd8e785a57fa46f60\",\n    \"0x87d43eff5a006dc4dddcf76cc96c656a1f3a68f19f124181feab86c6cc9a52cb9189cdbb423414defdd9bb0ca8ff1ddc\",\n    \"0x861367e87a9aa2f0f68296ba50aa5dbc5713008d260cc2c7e62d407c2063064749324c4e8156dc21b749656cfebce26b\",\n    \"0xb5303c2f72e84e170e66ae1b0fbd51b8c7a6f27476eaf5694b64e8737d5c84b51fe90100b256465a4c4156dd873cddb0\",\n    \"0xb62849a4f891415d74f434cdc1d23c4a69074487659ca96e1762466b2b7a5d8525b056b891d0feea6fe6845cba8bc7fb\",\n    \"0x923dd9e0d6590a9307e8c4c23f13bae3306b580e297a937711a8b13e8de85e41a61462f25b7d352b682e8437bf2b4ab3\",\n    \"0x9147379860cd713cd46c94b8cdf75125d36c37517fbecf81ace9680b98ce6291cd1c3e472f84249cc3b2b445e314b1b6\",\n    \"0xa808a4f17ac21e3fb5cfef404e61fae3693ca3e688d375f99b6116779696059a146c27b06de3ac36da349b0649befd56\",\n    \"0x87787e9322e1b75e66c1f0d9ea0915722a232770930c2d2a95e9478c4b950d15ab767e30cea128f9ed65893bfc2d0743\",\n    \"0x9036a6ee2577223be105defe1081c48ea7319e112fff9110eb9f61110c319da25a6cea0464ce65e858635b079691ef1f\",\n    \"0xaf5548c7c24e1088c23b57ee14d26c12a83484c9fd9296edf1012d8dcf88243f20039b43c8c548c265ef9a1ffe9c1c88\",\n    \"0xa0fff520045e14065965fb8accd17e878d3fcaf9e0af2962c8954e50be6683d31fa0bf4816ab68f08630dbac6bfce52a\",\n    \"0xb4c1b249e079f6ae1781af1d97a60b15855f49864c50496c09c91fe1946266915b799f0406084d7783f5b1039116dd8b\",\n    \"0x8b0ffa5e7c498cb3879dddca34743b41eee8e2dea3d4317a6e961b58adb699ef0c92400c068d5228881a2b08121226bf\",\n    \"0x852ae8b19a1d80aa8ae5382e7ee5c8e7670ceb16640871c56b20b96b66b3b60e00015a3dde039446972e57b49a999ddd\",\n    \"0xa49942f04234a7d8492169da232cfff8051df86e8e1ba3db46aede02422c689c87dc1d99699c25f96cb763f5ca0983e5\",\n    \"0xb04b597b7760cf5dcf411ef896d1661e6d5b0db3257ac2cf64b20b60c6cc18fa10523bb958a48d010b55bac7b02ab3b1\",\n    \"0xa494591b51ea8285daecc194b5e5bd45ae35767d0246ac94fae204d674ee180c8e97ff15f71f28b7aeb175b8aea59710\",\n    \"0x97d2624919e78406e7460730680dea8e71c8571cf988e11441aeea54512b95bd820e78562c99372d535d96f7e200d20d\",\n    \"0xac693ddb00e48f76e667243b9b6a7008424043fb779e4f2252330285232c3fccac4da25cbd6d95fe9ad959ff305a91f6\",\n    \"0x8d20ca0a71a64a3f702a0825bb46bd810d03bebfb227683680d474a52f965716ff99e19a165ebaf6567987f4f9ee3c94\",\n    \"0xa5c516a438f916d1d68ca76996404792e0a66e97b7f18fc54c917bf10cf3211b62387932756e39e67e47b0bd6e88385a\",\n    \"0xb089614d830abc0afa435034cec7f851f2f095d479cacf1a3fb57272da826c499a52e7dcbc0eb85f4166fb94778e18e9\",\n    \"0xa8dacc943765d930848288192f4c69e2461c4b9bc6e79e30eeef9a543318cf9ae9569d6986c65c5668a89d49993f8e07\",\n    \"0xab5a9361fa339eec8c621bdad0a58078983abd8942d4282b22835d7a3a47e132d42414b7c359694986f7db39386c2e19\",\n    \"0x94230517fb57bd8eb26c6f64129b8b2abd0282323bf7b94b8bac7fab27b4ecc2c4290c294275e1a759de19f2216134f3\",\n    \"0xb8f158ea5006bc3b90b285246625faaa6ac9b5f5030dc69701b12f3b79a53ec7e92eeb5a63bbd1f9509a0a3469ff3ffc\",\n    \"0x8b6944fd8cb8540957a91a142fdcda827762aa777a31e8810ca6d026e50370ee1636fc351724767e817ca38804ebe005\",\n    \"0x82d1ee40fe1569c29644f79fa6c4033b7ed45cd2c3b343881f6eb0de2e79548fded4787fae19bed6ee76ed76ff9f2f11\",\n    \"0xa8924c7035e99eaed244ca165607e7e568b6c8085510dcdbaf6ebdbed405af2e6c14ee27d94ffef10d30aa52a60bf66d\",\n    \"0x956f82a6c2ae044635e85812581e4866c5fa2f427b01942047d81f6d79a14192f66fbbe77c9ffeaef4e6147097fdd2b5\",\n    \"0xb1100255a1bcf5e05b6aff1dfeb6e1d55b5d68d43a7457ba10cc76b61885f67f4d0d5179abda786e037ae95deb8eea45\",\n    \"0x99510799025e3e5e8fbf06dedb14c060c6548ba2bda824f687d3999dc395e794b1fb6514b9013f3892b6cf65cb0d65aa\",\n    \"0x8f9091cebf5e9c809aab415942172258f894e66e625d7388a05289183f01b8d994d52e05a8e69f784fba41db9ea357f0\",\n    \"0xa13d2eeb0776bdee9820ecb6693536720232848c51936bb4ef4fe65588d3f920d08a21907e1fdb881c1ad70b3725e726\",\n    \"0xa68b8f18922d550284c5e5dc2dda771f24c21965a6a4d5e7a71678178f46df4d8a421497aad8fcb4c7e241aba26378a0\",\n    \"0x8b7601f0a3c6ad27f03f2d23e785c81c1460d60100f91ea9d1cab978aa03b523150206c6d52ce7c7769c71d2c8228e9e\",\n    \"0xa8e02926430813caa851bb2b46de7f0420f0a64eb5f6b805401c11c9091d3b6d67d841b5674fa2b1dce0867714124cd8\",\n    \"0xb7968ecba568b8193b3058400af02c183f0a6df995a744450b3f7e0af7a772454677c3857f99c140bbdb2a09e832e8e0\",\n    \"0x8f20b1e9ba87d0a3f35309b985f3c18d2e8800f1ca7f0c52cadef773f1496b6070c936eea48c4a1cae83fd2524e9d233\",\n    \"0x88aef260042db0d641a51f40639dbeeefa9e9811df30bee695f3791f88a2f84d318f04e8926b7f47bf25956cb9e3754f\",\n    \"0x9725345893b647e9ba4e6a29e12f96751f1ae25fcaec2173e9a259921a1a7edb7a47159b3c8767e44d9e2689f5aa0f72\",\n    \"0x8c281e6f72752cb11e239e4df9341c45106eb7993c160e54423c2bffe10bc39d42624b45a1f673936ef2e1a02fc92f1a\",\n    \"0x90aba2f68bddb2fcce6c51430dacdfeec43ea8dc379660c99095df11017691ccf5faa27665cf4b9f0eea7728ae53c327\",\n    \"0xb7022695c16521c5704f49b7ddbdbec9b5f57ce0ceebe537bc0ebb0906d8196cc855a9afeb8950a1710f6a654464d93f\",\n    \"0x8fe1b9dd3c6a258116415d36e08374e094b22f0afb104385a5da48be17123e86fb8327baacc4f0d9ebae923d55d99bb5\",\n    \"0x817e85d8e3d19a4cbc1dec31597142c2daa4871bda89c2177fa719c00eda3344eb08b82eb92d4aa91a9eaacb3fc09783\",\n    \"0xb59053e1081d2603f1ca0ba553804d6fa696e1fd996631db8f62087b26a40dfef02098b0326bb75f99ec83b9267ca738\",\n    \"0x990a173d857d3ba81ff3789b931bfc9f5609cde0169b7f055fa3cb56451748d593d62d46ba33f80f9cafffe02b68dd14\",\n    \"0xb0c538dbba4954b809ab26f9f94a3cf1dcb77ce289eaec1d19f556c0ae4be1fa03af4a9b7057837541c3cc0a80538736\",\n    \"0xac3ba42f5f44f9e1fc453ce49c4ab79d0e1d5c42d3b30b1e098f3ab3f414c4c262fa12fb2be249f52d4aaf3c5224beb9\",\n    \"0xaf47467eb152e59870e21f0d4da2f43e093daf40180ab01438030684b114d025326928eaab12c41b81a066d94fce8436\",\n    \"0x98d1b58ba22e7289b1c45c79a24624f19b1d89e00f778eef327ec4856a9a897278e6f1a9a7e673844b31dde949153000\",\n    \"0x97ccb15dfadc7c59dca08cfe0d22df2e52c684cf97de1d94bc00d7ba24e020025130b0a39c0f4d46e4fc872771ee7875\",\n    \"0xb699e4ed9a000ff96ca296b2f09dce278832bc8ac96851ff3cff99ed3f6f752cfc0fea8571be28cd9b5a7ec36f1a08ee\",\n    \"0xb9f49f0edb7941cc296435ff0a912e3ad16848ee8765ab5f60a050b280d6ea585e5b34051b15f6b8934ef01ceb85f648\",\n    \"0xac3893df7b4ceab23c6b9054e48e8ba40d6e5beda8fbe90b814f992f52494186969b35d8c4cdc3c99890a222c9c09008\",\n    \"0xa41293ad22fae81dea94467bc1488c3707f3d4765059173980be93995fa4fcc3c9340796e3eed0beeb0ba0d9bb4fa3aa\",\n    \"0xa0543e77acd2aeecde13d18d258aeb2c7397b77f17c35a1992e8666ea7abcd8a38ec6c2741bd929abba2f766138618cc\",\n    \"0x92e79b22bc40e69f6527c969500ca543899105837b6b1075fa1796755c723462059b3d1b028e0b3df2559fa440e09175\",\n    \"0xa1fa1eac8f41a5197a6fb4aa1eae1a031c89f9c13ff9448338b222780cf9022e0b0925d930c37501a0ef7b2b00fdaf83\",\n    \"0xb3cb29ff73229f0637335f28a08ad8c5f166066f27c6c175164d0f26766a927f843b987ee9b309ed71cbf0a65d483831\",\n    \"0x84d4ab787f0ac00f104f4a734dc693d62d48c2aeb03913153da62c2ae2c27d11b1110dcef8980368dd84682ea2c1a308\",\n    \"0xab6a8e4bbc78d4a7b291ad3e9a8fe2d65f640524ba3181123b09d2d18a9e300e2509ccf7000fe47e75b65f3e992a2e7e\",\n    \"0xb7805ebe4f1a4df414003dc10bca805f2ab86ca75820012653e8f9b79c405196b0e2cab099f2ab953d67f0d60d31a0f9\",\n    \"0xb12c582454148338ea605d22bd00a754109063e22617f1f8ac8ddf5502c22a181c50c216c3617b9852aa5f26af56b323\",\n    \"0x86333ad9f898947e31ce747728dc8c887479e18d36ff3013f69ebef807d82c6981543b5c3788af93c4d912ba084d3cba\",\n    \"0xb514efa310dc4ad1258add138891e540d8c87142a881b5f46563cc58ecd1488e6d3a2fca54c0b72a929f3364ca8c333e\",\n    \"0xaa0a30f92843cf2f484066a783a1d75a7aa6f41f00b421d4baf20a6ac7886c468d0eea7ca8b17dd22f4f74631b62b640\",\n    \"0xb3b7dc63baec9a752e8433c0cdee4d0f9bc41f66f2b8d132faf925eef9cf89aae756fc132c45910f057122462605dc10\",\n    \"0xb9b8190dac5bfdeb59fd44f4da41a57e7f1e7d2c21faba9da91fa45cbeca06dcf299c9ae22f0c89ece11ac46352d619f\",\n    \"0x89f8cf36501ad8bdfeab863752a9090e3bfda57cf8fdeca2944864dc05925f501e252c048221bcc57136ab09a64b64b2\",\n    \"0xb0cbfaf317f05f97be47fc9d69eda2dd82500e00d42612f271a1fe24626408c28881f171e855bd5bd67409f9847502b4\",\n    \"0xa7c21a8fcede581bfd9847b6835eda62ba250bea81f1bb17372c800a19c732abe03064e64a2f865d974fb636cab4b859\",\n    \"0x95f9df524ba7a4667351696c4176b505d8ea3659f5ff2701173064acc624af69a0fad4970963736383b979830cb32260\",\n    \"0x856a74fe8b37a2e3afeac858c8632200485d438422a16ae3b29f359e470e8244995c63ad79c7e007ed063f178d0306fd\",\n    \"0xb37faa4d78fdc0bb9d403674dbea0176c2014a171c7be8527b54f7d1a32a76883d3422a3e7a5f5fcc5e9b31b57822eeb\",\n    \"0x8d37234d8594ec3fe75670b5c9cc1ec3537564d4739b2682a75b18b08401869a4264c0f264354219d8d896cded715db4\",\n    \"0xb5289ee5737f0e0bde485d32096d23387d68dab8f01f47821ab4f06cc79a967afe7355e72dc0c751d96b2747b26f6255\",\n    \"0x9085e1fdf9f813e9c3b8232d3c8863cd84ab30d45e8e0d3d6a0abd9ebc6fd70cdf749ff4d04390000e14c7d8c6655fc7\",\n    \"0x93a388c83630331eca4da37ea4a97b3b453238af474817cc0a0727fd3138dcb4a22de38c04783ec829c22cb459cb4e8e\",\n    \"0xa5377116027c5d061dbe24c240b891c08cdd8cd3f0899e848d682c873aff5b8132c1e7cfe76d2e5ed97ee0eb1d42cb68\",\n    \"0xa274c84b04338ed28d74683e2a7519c2591a3ce37c294d6f6e678f7d628be2db8eff253ede21823e2df7183e6552f622\",\n    \"0x8bc201147a842453a50bec3ac97671397bc086d6dfc9377fa38c2124cdc286abda69b7324f47d64da094ae011d98d9d9\",\n    \"0x9842d0c066c524592b76fbec5132bc628e5e1d21c424bec4555efca8619cc1fd8ea3161febcb8b9e8ab54702f4e815e2\",\n    \"0xa19191b713a07efe85c266f839d14e25660ee74452e6c691cd9997d85ae4f732052d802d3deb018bdd847caa298a894b\",\n    \"0xa24f71fc0db504da4e287dd118a4a74301cbcd16033937ba2abc8417956fcb4ae19b8e63b931795544a978137eff51cb\",\n    \"0xa90eec4a6a3a4b8f9a5b93d978b5026fcf812fe65585b008d7e08c4aaf21195a1d0699f12fc16f79b6a18a369af45771\",\n    \"0x8b551cf89737d7d06d9b3b9c4c1c73b41f2ea0af4540999c70b82dabff8580797cf0a3caf34c86c59a7069eb2e38f087\",\n    \"0xb8d312e6c635e7a216a1cda075ae77ba3e1d2fd501dc31e83496e6e81ed5d9c7799f8e578869c2e0e256fb29f5de10a7\",\n    \"0x8d144bdb8cae0b2cdb5b33d44bbc96984a5925202506a8cc65eb67ac904b466f5a7fe3e1cbf04aa785bbb7348c4bb73c\",\n    \"0xa101b3d58b7a98659244b88de0b478b3fb87dc5fc6031f6e689b99edf498abd43e151fd32bd4bbd240e0b3e59c440359\",\n    \"0x907453abca7d8e7151a05cc3d506c988007692fe7401395dc93177d0d07d114ab6cca0cc658eb94c0223fe8658295cad\",\n    \"0x825329ffbe2147ddb68f63a0a67f32d7f309657b8e5d9ab5bb34b3730bfa2c77a23eaaadb05def7d9f94a9e08fdc1e96\",\n    \"0x88ee923c95c1dac99ae7ed6067906d734d793c5dc5d26339c1bb3314abe201c5dccb33b9007351885eb2754e9a8ea06c\",\n    \"0x98bc9798543f5f1adc9f2cfcfa72331989420e9c3f6598c45269f0dc9b7c8607bbeaf03faa0aea2ddde2b8f17fdceff5\",\n    \"0x8ee87877702a79aef923ab970db6fa81561b3c07d5bf1a072af0a7bad765b4cbaec910afe1a91703feacc7822fa38a94\",\n    \"0x8060b9584aa294fe8adc2b22f67e988bc6da768eae91e429dcc43ddc53cfcc5d6753fdc1b420b268c7eb2fb50736a970\",\n    \"0xb344a5524d80a2f051870c7001f74fcf348a70fcf78dbd20c6ff9ca85d81567d2318c8b8089f2c4f195d6aec9fc15fa6\",\n    \"0x8f5a5d893e1936ed062149d20eb73d98b62b7f50ab5d93a6429c03656b36688d1c80cb5010e4977491e51fa0d7dd35d5\",\n    \"0x86fa32ebbf97328c5f5f15564e1238297e289ec3219b9a741724e9f3ae8d5c15277008f555863a478b247ba5dc601d44\",\n    \"0x9557e55377e279f4b6b5e0ffe01eca037cc13aac242d67dfcd0374a1e775c5ed5cb30c25fe21143fee54e3302d34a3ea\",\n    \"0x8cb6bcbc39372d23464a416ea7039f57ba8413cf3f00d9a7a5b356ab20dcb8ed11b3561f7bce372b8534d2870c7ee270\",\n    \"0xb5d59075cb5abde5391f64b6c3b8b50adc6e1f654e2a580b6d6d6eff3f4fbdd8fffc92e06809c393f5c8eab37f774c4b\",\n    \"0xafcfb6903ef13e493a1f7308675582f15af0403b6553e8c37afb8b2808ad21b88b347dc139464367dc260df075fea1ad\",\n    \"0x810fbbe808375735dd22d5bc7fc3828dc49fdd22cc2d7661604e7ac9c4535c1df578780affb3b895a0831640a945bcad\",\n    \"0x8056b0c678803b416f924e09a6299a33cf9ad7da6fe1ad7accefe95c179e0077da36815fde3716711c394e2c5ea7127f\",\n    \"0x8b67403702d06979be19f1d6dc3ec73cc2e81254d6b7d0cc49cd4fdda8cd51ab0835c1d2d26fc0ecab5df90585c2f351\",\n    \"0x87f97f9e6d4be07e8db250e5dd2bffdf1390665bc5709f2b631a6fa69a7fca958f19bd7cc617183da1f50ee63e9352b5\",\n    \"0xae151310985940471e6803fcf37600d7fa98830613e381e00dab943aec32c14162d51c4598e8847148148000d6e5af5c\",\n    \"0x81eb537b35b7602c45441cfc61b27fa9a30d3998fad35a064e05bc9479e9f10b62eba2b234b348219eea3cadcaac64bb\",\n    \"0x8a441434934180ab6f5bc541f86ebd06eadbee01f438836d797e930fa803a51510e005c9248cecc231a775b74d12b5e9\",\n    \"0x81f3c250a27ba14d8496a5092b145629eb2c2e6a5298438670375363f57e2798207832c8027c3e9238ad94ecdadfc4df\",\n    \"0xa6217c311f2f3db02ceaa5b6096849fe92b6f4b6f1491535ef8525f6ccee6130bed2809e625073ecbaddd4a3eb3df186\",\n    \"0x82d1c396f0388b942cf22b119d7ef1ad03d3dad49a74d9d01649ee284f377c8daddd095d596871669e16160299a210db\",\n    \"0xa40ddf7043c5d72a7246bd727b07f7fff1549f0e443d611de6f9976c37448b21664c5089c57f20105102d935ab82f27b\",\n    \"0xb6c03c1c97adf0c4bf4447ec71366c6c1bff401ba46236cd4a33d39291e7a1f0bb34bd078ba3a18d15c98993b153a279\",\n    \"0x8a94f5f632068399c359c4b3a3653cb6df2b207379b3d0cdace51afdf70d6d5cce6b89a2b0fee66744eba86c98fb21c2\",\n    \"0xb2f19e78ee85073f680c3bba1f07fd31b057c00b97040357d97855b54a0b5accb0d3b05b2a294568fcd6a4be6f266950\",\n    \"0xa74632d13bbe2d64b51d7a9c3ae0a5a971c19f51cf7596a807cea053e6a0f3719700976d4e394b356c0329a2dced9aa2\",\n    \"0xafef616d341a9bc94393b8dfba68ff0581436aa3a3adb7c26a1bbf2cf19fa877066191681f71f17f3cd6f9cf6bf70b5a\",\n    \"0x8ce96d93ae217408acf7eb0f9cbb9563363e5c7002e19bbe1e80760bc9d449daee2118f3878b955163ed664516b97294\",\n    \"0x8414f79b496176bc8b8e25f8e4cfee28f4f1c2ddab099d63d2aca1b6403d26a571152fc3edb97794767a7c4686ad557c\",\n    \"0xb6c61d01fd8ce087ef9f079bf25bf10090db483dd4f88c4a786d31c1bdf52065651c1f5523f20c21e75cea17df69ab73\",\n    \"0xa5790fd629be70545093631efadddc136661f63b65ec682609c38ef7d3d7fa4e56bdf94f06e263bc055b90cb1c6bcefe\",\n    \"0xb515a767e95704fb7597bca9e46f1753abacdc0e56e867ee3c6f4cd382643c2a28e65312c05ad040eaa3a8cbe7217a65\",\n    \"0x8135806a02ead6aa92e9adb6fefb91349837ab73105aaa7be488ef966aa8dfaafdfa64bbae30fcbfa55dd135a036a863\",\n    \"0x8f22435702716d76b1369750694540742d909d5e72b54d0878245fab7c269953b1c6f2b29c66f08d5e0263ca3a731771\",\n    \"0x8e0f8a8e8753e077dac95848212aeffd51c23d9b6d611df8b102f654089401954413ecbedc6367561ca599512ae5dda7\",\n    \"0x815a9084e3e2345f24c5fa559deec21ee1352fb60f4025c0779be65057f2d528a3d91593bd30d3a185f5ec53a9950676\",\n    \"0x967e6555ccba395b2cc1605f8484c5112c7b263f41ce8439a99fd1c71c5ed14ad02684d6f636364199ca48afbbde13be\",\n    \"0x8cd0ccf17682950b34c796a41e2ea7dd5367aba5e80a907e01f4cdc611e4a411918215e5aebf4292f8b24765d73314a6\",\n    \"0xa58bf1bbb377e4b3915df6f058a0f53b8fb8130fdec8c391f6bc82065694d0be59bb67ffb540e6c42cc8b380c6e36359\",\n    \"0x92af3151d9e6bfb3383d85433e953c0160859f759b0988431ec5893542ba40288f65db43c78a904325ef8d324988f09d\",\n    \"0x8011bbb05705167afb47d4425065630f54cb86cd462095e83b81dfebf348f846e4d8fbcf1c13208f5de1931f81da40b9\",\n    \"0x81c743c104fc3cb047885c9fa0fb9705c3a83ee24f690f539f4985509c3dafd507af3f6a2128276f45d5939ef70c167f\",\n    \"0xa2c9679b151c041aaf5efeac5a737a8f70d1631d931609fca16be1905682f35e291292874cb3b03f14994f98573c6f44\",\n    \"0xa4949b86c4e5b1d5c82a337e5ce6b2718b1f7c215148c8bfb7e7c44ec86c5c9476048fc5c01f57cb0920876478c41ad6\",\n    \"0x86c2495088bd1772152e527a1da0ef473f924ea9ab0e5b8077df859c28078f73c4e22e3a906b507fdf217c3c80808b5c\",\n    \"0x892e0a910dcf162bcea379763c3e2349349e4cda9402949255ac4a78dd5a47e0bf42f5bd0913951576b1d206dc1e536a\",\n    \"0xa7009b2c6b396138afe4754b7cc10dee557c51c7f1a357a11486b3253818531f781ea8107360c8d4c3b1cd96282353c0\",\n    \"0x911763ef439c086065cc7b4e57484ed6d693ea44acee4b18c9fd998116da55fbe7dcb8d2a0f0f9b32132fca82d73dff6\",\n    \"0xa722000b95a4a2d40bed81870793f15ba2af633f9892df507f2842e52452e02b5ea8dea6a043c2b2611d82376e33742a\",\n    \"0x9387ac49477bd719c2f92240d0bdfcf9767aad247ca93dc51e56106463206bc343a8ec855eb803471629a66fffb565d6\",\n    \"0x92819a1fa48ab4902939bb72a0a4e6143c058ea42b42f9bc6cea5df45f49724e2530daf3fc4f097cceefa2a8b9db0076\",\n    \"0x98eac7b04537653bc0f4941aae732e4b1f84bd276c992c64a219b8715eb1fb829b5cbd997d57feb15c7694c468f95f70\",\n    \"0xb275e7ba848ce21bf7996e12dbeb8dadb5d0e4f1cb5a0248a4f8f9c9fe6c74e3c93f4b61edbcb0a51af5a141e1c14bc7\",\n    \"0x97243189285aba4d49c53770c242f2faf5fd3914451da4931472e3290164f7663c726cf86020f8f181e568c72fd172d1\",\n    \"0x839b0b3c25dd412bee3dc24653b873cc65454f8f16186bb707bcd58259c0b6765fa4c195403209179192a4455c95f3b8\",\n    \"0x8689d1a870514568a074a38232e2ceb4d7df30fabeb76cff0aed5b42bf7f02baea12c5fadf69f4713464dbd52aafa55f\",\n    \"0x8958ae7b290f0b00d17c3e9fdb4dbf168432b457c7676829299dd428984aba892de1966fc106cfc58a772862ecce3976\",\n    \"0xa422bc6bd68b8870cfa5bc4ce71781fd7f4368b564d7f1e0917f6013c8bbb5b240a257f89ecfdbecb40fe0f3aa31d310\",\n    \"0xaa61f78130cebe09bc9a2c0a37f0dd57ed2d702962e37d38b1df7f17dc554b1d4b7a39a44182a452ce4c5eb31fa4cfcc\",\n    \"0xb7918bd114f37869bf1a459023386825821bfadce545201929d13ac3256d92a431e34f690a55d944f77d0b652cefeffc\",\n    \"0x819bba35fb6ace1510920d4dcff30aa682a3c9af9022e287751a6a6649b00c5402f14b6309f0aeef8fce312a0402915e\",\n    \"0x8b7c9ad446c6f63c11e1c24e24014bd570862b65d53684e107ba9ad381e81a2eaa96731b4b33536efd55e0f055071274\",\n    \"0x8fe79b53f06d33386c0ec7d6d521183c13199498594a46d44a8a716932c3ec480c60be398650bbfa044fa791c4e99b65\",\n    \"0x9558e10fb81250b9844c99648cf38fa05ec1e65d0ccbb18aa17f2d1f503144baf59d802c25be8cc0879fff82ed5034ad\",\n    \"0xb538a7b97fbd702ba84645ca0a63725be1e2891c784b1d599e54e3480e4670d0025526674ef5cf2f87dddf2290ba09f0\",\n    \"0x92eafe2e869a3dd8519bbbceb630585c6eb21712b2f31e1b63067c0acb5f9bdbbcbdb612db4ea7f9cc4e7be83d31973f\",\n    \"0xb40d21390bb813ab7b70a010dff64c57178418c62685761784e37d327ba3cb9ef62df87ecb84277c325a637fe3709732\",\n    \"0xb349e6fbf778c4af35fbed33130bd8a7216ed3ba0a79163ebb556e8eb8e1a7dad3456ddd700dad9d08d202491c51b939\",\n    \"0xa8fdaedecb251f892b66c669e34137f2650509ade5d38fbe8a05d9b9184bb3b2d416186a3640429bd1f3e4b903c159dd\",\n    \"0xac6167ebfee1dbab338eff7642f5e785fc21ef0b4ddd6660333fe398068cbd6c42585f62e81e4edbb72161ce852a1a4f\",\n    \"0x874b1fbf2ebe140c683bd7e4e0ab017afa5d4ad38055aaa83ee6bbef77dbc88a6ce8eb0dcc48f0155244af6f86f34c2d\",\n    \"0x903c58e57ddd9c446afab8256a6bb6c911121e6ccfb4f9b4ed3e2ed922a0e500a5cb7fa379d5285bc16e11dac90d1fda\",\n    \"0x8dae7a0cffa2fd166859cd1bf10ff82dd1932e488af377366b7efc0d5dec85f85fe5e8150ff86a79a39cefc29631733a\",\n    \"0xaa047857a47cc4dfc08585f28640420fcf105b881fd59a6cf7890a36516af0644d143b73f3515ab48faaa621168f8c31\",\n    \"0x864508f7077c266cc0cb3f7f001cb6e27125ebfe79ab57a123a8195f2e27d3799ff98413e8483c533b46a816a3557f1f\",\n    \"0x8bcd45ab1f9cbab36937a27e724af819838f66dfeb15923f8113654ff877bd8667c54f6307aaf0c35027ca11b6229bfd\",\n    \"0xb21aa34da9ab0a48fcfdd291df224697ce0c1ebc0e9b022fdee8750a1a4b5ba421c419541ed5c98b461eecf363047471\",\n    \"0xa9a18a2ab2fae14542dc336269fe612e9c1af6cf0c9ac933679a2f2cb77d3c304114f4d219ca66fe288adde30716775b\",\n    \"0xb5205989b92c58bdda71817f9a897e84100b5c4e708de1fced5c286f7a6f01ae96b1c8d845f3a320d77c8e2703c0e8b1\",\n    \"0xa364059412bbcc17b8907d43ac8e5df90bc87fd1724b5f99832d0d24559fae6fa76a74cff1d1eac8cbac6ec80b44af20\",\n    \"0xae709f2c339886b31450834cf29a38b26eb3b0779bd77c9ac269a8a925d1d78ea3837876c654b61a8fe834b3b6940808\",\n    \"0x8802581bba66e1952ac4dab36af371f66778958f4612901d95e5cac17f59165e6064371d02de8fb6fccf89c6dc8bd118\",\n    \"0xa313252df653e29c672cbcfd2d4f775089cb77be1077381cf4dc9533790e88af6cedc8a119158e7da5bf6806ad9b91a1\",\n    \"0x992a065b4152c7ef11515cd54ba9d191fda44032a01aed954acff3443377ee16680c7248d530b746b8c6dee2d634e68c\",\n    \"0xb627b683ee2b32c1ab4ccd27b9f6cce2fe097d96386fa0e5c182ad997c4c422ab8dfc03870cd830b8c774feb66537282\",\n    \"0xb823cf8a9aee03dadd013eb9efe40a201b4b57ef67efaae9f99683005f5d1bf55e950bf4af0774f50859d743642d3fea\",\n    \"0xb8a7449ffac0a3f206677097baf7ce00ca07a4d2bd9b5356fbcb83f3649b0fda07cfebad220c1066afba89e5a52abf4b\",\n    \"0xb2dd1a2f986395bb4e3e960fbbe823dbb154f823284ebc9068502c19a7609790ec0073d08bfa63f71e30c7161b6ef966\",\n    \"0x98e5236de4281245234f5d40a25b503505af140b503a035fc25a26159a9074ec81512b28f324c56ea2c9a5aa7ce90805\",\n    \"0x89070847dc8bbf5bc4ed073aa2e2a1f699cf0c2ca226f185a0671cecc54e7d3e14cd475c7752314a7a8e7476829da4bc\",\n    \"0xa9402dc9117fdb39c4734c0688254f23aed3dce94f5f53f5b7ef2b4bf1b71a67f85ab1a38ec224a59691f3bee050aeb3\",\n    \"0x957288f9866a4bf56a4204218ccc583f717d7ce45c01ea27142a7e245ad04a07f289cc044f8cf1f21d35e67e39299e9c\",\n    \"0xb2fb31ccb4e69113763d7247d0fc8edaae69b550c5c56aecacfd780c7217dc672f9fb7496edf4aba65dacf3361268e5b\",\n    \"0xb44a4526b2f1d6eb2aa8dba23bfa385ff7634572ab2afddd0546c3beb630fbfe85a32f42dd287a7fec069041411537f7\",\n    \"0x8db5a6660c3ac7fd7a093573940f068ee79a82bc17312af900b51c8c439336bc86ca646c6b7ab13aaaa008a24ca508ab\",\n    \"0x8f9899a6d7e8eb4367beb5c060a1f8e94d8a21099033ae582118477265155ba9e72176a67f7f25d7bad75a152b56e21a\",\n    \"0xa67de0e91ade8d69a0e00c9ff33ee2909b8a609357095fa12319e6158570c232e5b6f4647522efb7345ce0052aa9d489\",\n    \"0x82eb2414898e9c3023d57907a2b17de8e7eea5269029d05a94bfd7bf5685ac4a799110fbb375eb5e0e2bd16acf6458ae\",\n    \"0x94451fc7fea3c5a89ba701004a9693bab555cb622caf0896b678faba040409fdfd14a978979038b2a81e8f0abc4994d2\",\n    \"0xac879a5bb433998e289809a4a966bd02b4bf6a9c1cc276454e39c886efcf4fc68baebed575826bde577ab5aa71d735a9\",\n    \"0x880c0f8f49c875dfd62b4ddedde0f5c8b19f5687e693717f7e5c031bc580e58e13ab497d48b4874130a18743c59fdce3\",\n    \"0xb582af8d8ff0bf76f0a3934775e0b54c0e8fed893245d7d89cae65b03c8125b7237edc29dc45b4fe1a3fe6db45d280ee\",\n    \"0x89f337882ed3ae060aaee98efa20d79b6822bde9708c1c5fcee365d0ec9297f694cae37d38fd8e3d49717c1e86f078e7\",\n    \"0x826d2c1faea54061848b484e288a5f4de0d221258178cf87f72e14baaa4acc21322f8c9eab5dde612ef497f2d2e1d60b\",\n    \"0xa5333d4f227543e9cd741ccf3b81db79f2f03ca9e649e40d6a6e8ff9073e06da83683566d3b3c8d7b258c62970fb24d1\",\n    \"0xa28f08c473db06aaf4c043a2fae82b3c8cfaa160bce793a4c208e4e168fb1c65115ff8139dea06453c5963d95e922b94\",\n    \"0x8162546135cc5e124e9683bdfaa45833c18553ff06a0861c887dc84a5b12ae8cd4697f6794c7ef6230492c32faba7014\",\n    \"0xb23f0d05b74c08d6a7df1760792be83a761b36e3f8ae360f3c363fb196e2a9dd2de2e492e49d36561366e14daa77155c\",\n    \"0xb6f70d6c546722d3907c708d630dbe289771d2c8bf059c2e32b77f224696d750b4dda9b3a014debda38e7d02c9a77585\",\n    \"0x83bf4c4a9f3ca022c631017e7a30ea205ba97f7f5927cba8fc8489a4646eac6712cb821c5668c9ffe94d69d524374a27\",\n    \"0xb0371475425a8076d0dd5f733f55aabbe42d20a7c8ea7da352e736d4d35a327b2beb370dfcb05284e22cfd69c5f6c4cc\",\n    \"0xa0031ba7522c79211416c2cca3aa5450f96f8fee711552a30889910970ba13608646538781a2c08b834b140aadd7166f\",\n    \"0x99d273c80c7f2dc6045d4ed355d9fc6f74e93549d961f4a3b73cd38683f905934d359058cd1fc4da8083c7d75070487f\",\n    \"0xb0e4b0efa3237793e9dcce86d75aafe9879c5fa23f0d628649aef2130454dcf72578f9bf227b9d2b9e05617468e82588\",\n    \"0xa5ab076fa2e1c5c51f3ae101afdd596ad9d106bba7882b359c43d8548b64f528af19afa76cd6f40da1e6c5fca4def3fa\",\n    \"0x8ce2299e570331d60f6a6eff1b271097cd5f1c0e1113fc69b89c6a0f685dabea3e5bc2ac6bd789aa492ab189f89be494\",\n    \"0x91b829068874d911a310a5f9dee001021f97471307b5a3de9ec336870ec597413e1d92010ce320b619f38bed7c4f7910\",\n    \"0xb14fe91f4b07bf33b046e9285b66cb07927f3a8da0af548ac2569b4c4fb1309d3ced76d733051a20814e90dd5b75ffd1\",\n    \"0xabaab92ea6152d40f82940277c725aa768a631ee0b37f5961667f82fb990fc11e6d3a6a2752b0c6f94563ed9bb28265c\",\n    \"0xb7fe28543eca2a716859a76ab9092f135337e28109544f6bd2727728d0a7650428af5713171ea60bfc273d1c821d992c\",\n    \"0x8a4917b2ab749fc7343fc64bdf51b6c0698ff15d740cc7baf248c030475c097097d5a473bcc00d8c25817563fe0447b4\",\n    \"0xaa96156d1379553256350a0a3250166add75948fb9cde62aa555a0a9dc0a9cb7f2f7b8428aff66097bf6bfedaf14bbe2\",\n    \"0xae4ffeb9bdc76830d3eca2b705f30c1bdede6412fa064260a21562c8850c7fb611ec62bc68479fe48f692833e6f66d8d\",\n    \"0xb96543caaba9d051600a14997765d49e4ab10b07c7a92cccf0c90b309e6da334fdd6d18c96806cbb67a7801024fbd3c7\",\n    \"0x97b2b9ad76f19f500fcc94ca8e434176249f542ac66e5881a3dccd07354bdab6a2157018b19f8459437a68d8b86ba8e0\",\n    \"0xa8d206f6c5a14c80005849474fde44b1e7bcf0b2d52068f5f97504c3c035b09e65e56d1cf4b5322791ae2c2fdbd61859\",\n    \"0x936bad397ad577a70cf99bf9056584a61bd7f02d2d5a6cf219c05d770ae30a5cd902ba38366ce636067fc1dd10108d31\",\n    \"0xa77e30195ee402b84f3882e2286bf5380c0ed374a112dbd11e16cef6b6b61ab209d4635e6f35cdaaa72c1a1981d5dabe\",\n    \"0xa46ba4d3947188590a43c180757886a453a0503f79cc435322d92490446f37419c7b999fdf868a023601078070e03346\",\n    \"0x80d8d4c5542f223d48240b445d4d8cf6a75d120b060bc08c45e99a13028b809d910b534d2ac47fb7068930c54efd8da9\",\n    \"0x803be9c68c91b42b68e1f55e58917a477a9a6265e679ca44ee30d3eb92453f8c89c64eafc04c970d6831edd33d066902\",\n    \"0xb14b2b3d0dfe2bb57cee4cd72765b60ac33c1056580950be005790176543826c1d4fbd737f6cfeada6c735543244ab57\",\n    \"0xa9e480188bba1b8fb7105ff12215706665fd35bf1117bacfb6ab6985f4dbc181229873b82e5e18323c2b8f5de03258e0\",\n    \"0xa66a0f0779436a9a3999996d1e6d3000f22c2cac8e0b29cddef9636393c7f1457fb188a293b6c875b05d68d138a7cc4a\",\n    \"0x848397366300ab40c52d0dbbdafbafef6cd3dadf1503bb14b430f52bb9724188928ac26f6292a2412bc7d7aa620763c8\",\n    \"0x95466cc1a78c9f33a9aaa3829a4c8a690af074916b56f43ae46a67a12bb537a5ac6dbe61590344a25b44e8512355a4a7\",\n    \"0x8b5f7a959f818e3baf0887f140f4575cac093d0aece27e23b823cf421f34d6e4ff4bb8384426e33e8ec7b5eed51f6b5c\",\n    \"0x8d5e1368ec7e3c65640d216bcc5d076f3d9845924c734a34f3558ac0f16e40597c1a775a25bf38b187213fbdba17c93b\",\n    \"0xb4647c1b823516880f60d20c5cc38c7f80b363c19d191e8992226799718ee26b522a12ecb66556ed3d483aa4824f3326\",\n    \"0xac3abaea9cd283eb347efda4ed9086ea3acf495043e08d0d19945876329e8675224b685612a6badf8fd72fb6274902b1\",\n    \"0x8eae1ce292d317aaa71bcf6e77e654914edd5090e2e1ebab78b18bb41b9b1bc2e697439f54a44c0c8aa0d436ebe6e1a9\",\n    \"0x94dc7d1aec2c28eb43d93b111fa59aaa0d77d5a09501220bd411768c3e52208806abf973c6a452fd8292ff6490e0c9e2\",\n    \"0x8fd8967f8e506fef27d17b435d6b86b232ec71c1036351f12e6fb8a2e12daf01d0ee04451fb944d0f1bf7fd20e714d02\",\n    \"0x824e6865be55d43032f0fec65b3480ea89b0a2bf860872237a19a54bc186a85d2f8f9989cc837fbb325b7c72d9babe2c\",\n    \"0x8bd361f5adb27fd6f4e3f5de866e2befda6a8454efeb704aacc606f528c03f0faae888f60310e49440496abd84083ce2\",\n    \"0xb098a3c49f2aaa28b6b3e85bc40ce6a9cdd02134ee522ae73771e667ad7629c8d82c393fba9f27f5416986af4c261438\",\n    \"0xb385f5ca285ff2cfe64dcaa32dcde869c28996ed091542600a0b46f65f3f5a38428cca46029ede72b6cf43e12279e3d3\",\n    \"0x8196b03d011e5be5288196ef7d47137d6f9237a635ab913acdf9c595fa521d9e2df722090ec7eb0203544ee88178fc5f\",\n    \"0x8ed1270211ef928db18e502271b7edf24d0bbd11d97f2786aee772d70c2029e28095cf8f650b0328cc8a4c38d045316d\",\n    \"0xa52ab60e28d69b333d597a445884d44fd2a7e1923dd60f763951e1e45f83e27a4dac745f3b9eff75977b3280e132c15d\",\n    \"0x91e9fe78cdac578f4a4687f71b800b35da54b824b1886dafec073a3c977ce7a25038a2f3a5b1e35c2c8c9d1a7312417c\",\n    \"0xa42832173f9d9491c7bd93b21497fbfa4121687cd4d2ab572e80753d7edcbb42cfa49f460026fbde52f420786751a138\",\n    \"0x97b947126d84dcc70c97be3c04b3de3f239b1c4914342fa643b1a4bb8c4fe45c0fcb585700d13a7ed50784790c54bef9\",\n    \"0x860e407d353eac070e2418ef6cb80b96fc5f6661d6333e634f6f306779651588037be4c2419562c89c61f9aa2c4947f5\",\n    \"0xb2c9d93c3ba4e511b0560b55d3501bf28a510745fd666b3cb532db051e6a8617841ea2f071dda6c9f15619c7bfd2737f\",\n    \"0x8596f4d239aeeac78311207904d1bd863ef68e769629cc379db60e019aaf05a9d5cd31dc8e630b31e106a3a93e47cbc5\",\n    \"0x8b26e14e2e136b65c5e9e5c2022cee8c255834ea427552f780a6ca130a6446102f2a6f334c3f9a0308c53df09e3dba7e\",\n    \"0xb54724354eb515a3c8bed0d0677ff1db94ac0a07043459b4358cb90e3e1aa38ac23f2caa3072cf9647275d7cd61d0e80\",\n    \"0xb7ce9fe0e515e7a6b2d7ddcb92bc0196416ff04199326aea57996eef8c5b1548bd8569012210da317f7c0074691d01b7\",\n    \"0xa1a13549c82c877253ddefa36a29ea6a23695ee401fdd48e65f6f61e5ebd956d5e0edeff99484e9075cb35071fec41e2\",\n    \"0x838ba0c1e5bd1a6da05611ff1822b8622457ebd019cb065ece36a2d176bd2d889511328120b8a357e44569e7f640c1e6\",\n    \"0xb916eccff2a95519400bbf76b5f576cbe53cf200410370a19d77734dc04c05b585cfe382e8864e67142d548cd3c4c2f4\",\n    \"0xa610447cb7ca6eea53a6ff1f5fe562377dcb7f4aaa7300f755a4f5e8eba61e863c51dc2aa9a29b35525b550fbc32a0fe\",\n    \"0x9620e8f0f0ee9a4719aa9685eeb1049c5c77659ba6149ec4c158f999cfd09514794b23388879931fe26fea03fa471fd3\",\n    \"0xa9dcf8b679e276583cf5b9360702a185470d09aea463dc474ee9c8aee91ef089dacb073e334e47fbc78ec5417c90465c\",\n    \"0x8c9adee8410bdd99e5b285744cee61e2593b6300ff31a8a83b0ec28da59475a5c6fb9346fe43aadea2e6c3dad2a8e30a\",\n    \"0x97d5afe9b3897d7b8bb628b7220cf02d8ee4e9d0b78f5000d500aaf4c1df9251aaaabfd1601626519f9d66f00a821d4e\",\n    \"0x8a382418157b601ce4c3501d3b8409ca98136a4ef6abcbf62885e16e215b76b035c94d149cc41ff92e42ccd7c43b9b3d\",\n    \"0xb64b8d11fb3b01abb2646ac99fdb9c02b804ce15d98f9fe0fbf1c9df8440c71417487feb6cdf51e3e81d37104b19e012\",\n    \"0x849d7d044f9d8f0aab346a9374f0b3a5d14a9d1faa83dbacccbdc629ad1ef903a990940255564770537f8567521d17f0\",\n    \"0x829dbb0c76b996c2a91b4cbbe93ba455ca0d5729755e5f0c92aaee37dff7f36fcdc06f33aca41f1b609c784127b67d88\",\n    \"0x85a7c0069047b978422d264d831ab816435f63938015d2e977222b6b5746066c0071b7f89267027f8a975206ed25c1b0\",\n    \"0x84b9fbc1cfb302df1acdcf3dc5d66fd1edfe7839f7a3b2fb3a0d5548656249dd556104d7c32b73967bccf0f5bdcf9e3b\",\n    \"0x972220ac5b807f53eac37dccfc2ad355d8b21ea6a9c9b011c09fe440ddcdf7513e0b43d7692c09ded80d7040e26aa28f\",\n    \"0x855885ed0b21350baeca890811f344c553cf9c21024649c722453138ba29193c6b02c4b4994cd414035486f923472e28\",\n    \"0x841874783ae6d9d0e59daea03e96a01cbbe4ecaced91ae4f2c8386e0d87b3128e6d893c98d17c59e4de1098e1ad519dd\",\n    \"0x827e50fc9ce56f97a4c3f2f4cbaf0b22f1c3ce6f844ff0ef93a9c57a09b8bf91ebfbd2ba9c7f83c442920bffdaf288cc\",\n    \"0xa441f9136c7aa4c08d5b3534921b730e41ee91ab506313e1ba5f7c6f19fd2d2e1594e88c219834e92e6fb95356385aa7\",\n    \"0x97d75b144471bf580099dd6842b823ec0e6c1fb86dd0da0db195e65524129ea8b6fd4a7a9bbf37146269e938a6956596\",\n    \"0xa4b6fa87f09d5a29252efb2b3aaab6b3b6ea9fab343132a651630206254a25378e3e9d6c96c3d14c150d01817d375a8e\",\n    \"0xa31a671876d5d1e95fe2b8858dc69967231190880529d57d3cab7f9f4a2b9b458ac9ee5bdaa3289158141bf18f559efb\",\n    \"0x90bee6fff4338ba825974021b3b2a84e36d617e53857321f13d2b3d4a28954e6de3b3c0e629d61823d18a9763313b3bf\",\n    \"0x96b622a63153f393bb419bfcf88272ea8b3560dbd46b0aa07ada3a6223990d0abdd6c2adb356ef4be5641688c8d83941\",\n    \"0x84c202adeaff9293698022bc0381adba2cd959f9a35a4e8472288fd68f96f6de8be9da314c526d88e291c96b1f3d6db9\",\n    \"0x8ca01a143b8d13809e5a8024d03e6bc9492e22226073ef6e327edf1328ef4aff82d0bcccee92cb8e212831fa35fe1204\",\n    \"0xb2f970dbad15bfbefb38903c9bcc043d1367055c55dc1100a850f5eb816a4252c8c194b3132c929105511e14ea10a67d\",\n    \"0xa5e36556472a95ad57eb90c3b6623671b03eafd842238f01a081997ffc6e2401f76e781d049bb4aa94d899313577a9cf\",\n    \"0x8d1057071051772f7c8bedce53a862af6fd530dd56ae6321eaf2b9fc6a68beff5ed745e1c429ad09d5a118650bfd420a\",\n    \"0x8aadc4f70ace4fcb8d93a78610779748dcffc36182d45b932c226dc90e48238ea5daa91f137c65ed532352c4c4d57416\",\n    \"0xa2ea05ae37e673b4343232ae685ee14e6b88b867aef6dfac35db3589cbcd76f99540fed5c2641d5bb5a4a9f808e9bf0d\",\n    \"0x947f1abad982d65648ae4978e094332b4ecb90f482c9be5741d5d1cf5a28acf4680f1977bf6e49dd2174c37f11e01296\",\n    \"0xa27b144f1565e4047ba0e3f4840ef19b5095d1e281eaa463c5358f932114cbd018aa6dcf97546465cf2946d014d8e6d6\",\n    \"0x8574e1fc3acade47cd4539df578ce9205e745e161b91e59e4d088711a7ab5aa3b410d517d7304b92109924d9e2af8895\",\n    \"0xa48ee6b86b88015d6f0d282c1ae01d2a5b9e8c7aa3d0c18b35943dceb1af580d08a65f54dc6903cde82fd0d73ce94722\",\n    \"0x8875650cec543a7bf02ea4f2848a61d167a66c91ffaefe31a9e38dc8511c6a25bde431007eefe27a62af3655aca208dc\",\n    \"0x999b0a6e040372e61937bf0d68374e230346b654b5a0f591a59d33a4f95bdb2f3581db7c7ccb420cd7699ed709c50713\",\n    \"0x878c9e56c7100c5e47bbe77dc8da5c5fe706cec94d37fa729633bca63cace7c40102eee780fcdabb655f5fa47a99600e\",\n    \"0x865006fb5b475ada5e935f27b96f9425fc2d5449a3c106aa366e55ebed3b4ee42adc3c3f0ac19fd129b40bc7d6bc4f63\",\n    \"0xb7a7da847f1202e7bc1672553e68904715e84fd897d529243e3ecda59faa4e17ba99c649a802d53f6b8dfdd51f01fb74\",\n    \"0x8b2fb4432c05653303d8c8436473682933a5cb604da10c118ecfcd2c8a0e3132e125afef562bdbcc3df936164e5ce4f2\",\n    \"0x808d95762d33ddfa5d0ee3d7d9f327de21a994d681a5f372e2e3632963ea974da7f1f9e5bac8ccce24293509d1f54d27\",\n    \"0x932946532e3c397990a1df0e94c90e1e45133e347a39b6714c695be21aeb2d309504cb6b1dde7228ff6f6353f73e1ca2\",\n    \"0x9705e7c93f0cdfaa3fa96821f830fe53402ad0806036cd1b48adc2f022d8e781c1fbdab60215ce85c653203d98426da3\",\n    \"0xaa180819531c3ec1feb829d789cb2092964c069974ae4faad60e04a6afcce5c3a59aec9f11291e6d110a788d22532bc6\",\n    \"0x88f755097f7e25cb7dd3c449520c89b83ae9e119778efabb54fbd5c5714b6f37c5f9e0346c58c6ab09c1aef2483f895d\",\n    \"0x99fc03ab7810e94104c494f7e40b900f475fde65bdec853e60807ffd3f531d74de43335c3b2646b5b8c26804a7448898\",\n    \"0xaf2dea9683086bed1a179110efb227c9c00e76cd00a2015b089ccbcee46d1134aa18bda5d6cab6f82ae4c5cd2461ac21\",\n    \"0xa500f87ba9744787fdbb8e750702a3fd229de6b8817594348dec9a723b3c4240ddfa066262d002844b9e38240ce55658\",\n    \"0x924d0e45c780f5bc1c1f35d15dfc3da28036bdb59e4c5440606750ecc991b85be18bc9a240b6c983bc5430baa4c68287\",\n    \"0x865b11e0157b8bf4c5f336024b016a0162fc093069d44ac494723f56648bc4ded13dfb3896e924959ea11c96321afefc\",\n    \"0x93672d8607d4143a8f7894f1dcca83fb84906dc8d6dd7dd063bb0049cfc20c1efd933e06ca7bd03ea4cb5a5037990bfe\",\n    \"0x826891efbdff0360446825a61cd1fa04326dd90dae8c33dfb1ed97b045e165766dd070bd7105560994d0b2044bdea418\",\n    \"0x93c4a4a8bcbc8b190485cc3bc04175b7c0ed002c28c98a540919effd6ed908e540e6594f6db95cd65823017258fb3b1c\",\n    \"0xaeb2a0af2d2239fda9aa6b8234b019708e8f792834ff0dd9c487fa09d29800ddceddd6d7929faa9a3edcb9e1b3aa0d6b\",\n    \"0x87f11de7236d387863ec660d2b04db9ac08143a9a2c4dfff87727c95b4b1477e3bc473a91e5797313c58754905079643\",\n    \"0x80dc1db20067a844fe8baceca77f80db171a5ca967acb24e2d480eae9ceb91a3343c31ad1c95b721f390829084f0eae6\",\n    \"0x9825c31f1c18da0de3fa84399c8b40f8002c3cae211fb6a0623c76b097b4d39f5c50058f57a16362f7a575909d0a44a2\",\n    \"0xa99fc8de0c38dbf7b9e946de83943a6b46a762167bafe2a603fb9b86f094da30d6de7ed55d639aafc91936923ee414b3\",\n    \"0xad594678b407db5d6ea2e90528121f84f2b96a4113a252a30d359a721429857c204c1c1c4ff71d8bb5768c833f82e80e\",\n    \"0xb33d985e847b54510b9b007e31053732c8a495e43be158bd2ffcea25c6765bcbc7ca815f7c60b36ad088b955dd6e9350\",\n    \"0x815f8dfc6f90b3342ca3fbd968c67f324dae8f74245cbf8bc3bef10e9440c65d3a2151f951e8d18959ba01c1b50b0ec1\",\n    \"0x94c608a362dd732a1abc56e338637c900d59013db8668e49398b3c7a0cae3f7e2f1d1bf94c0299eeafe6af7f76c88618\",\n    \"0x8ebd8446b23e5adfcc393adc5c52fe172f030a73e63cd2d515245ca0dd02782ceed5bcdd9ccd9c1b4c5953dfac9c340c\",\n    \"0x820437f3f6f9ad0f5d7502815b221b83755eb8dc56cd92c29e9535eb0b48fb8d08c9e4fcc26945f9c8cca60d89c44710\",\n    \"0x8910e4e8a56bf4be9cc3bbf0bf6b1182a2f48837a2ed3c2aaec7099bfd7f0c83e14e608876b17893a98021ff4ab2f20d\",\n    \"0x9633918fde348573eec15ce0ad53ac7e1823aac86429710a376ad661002ae6d049ded879383faaa139435122f64047c6\",\n    \"0xa1f5e3fa558a9e89318ca87978492f0fb4f6e54a9735c1b8d2ecfb1d1c57194ded6e0dd82d077b2d54251f3bee1279e1\",\n    \"0xb208e22d04896abfd515a95c429ff318e87ff81a5d534c8ac2c33c052d6ffb73ef1dccd39c0bbe0734b596c384014766\",\n    \"0x986d5d7d2b5bde6d16336f378bd13d0e671ad23a8ec8a10b3fc09036faeeb069f60662138d7a6df3dfb8e0d36180f770\",\n    \"0xa2d4e6c5f5569e9cef1cddb569515d4b6ace38c8aed594f06da7434ba6b24477392cc67ba867c2b079545ca0c625c457\",\n    \"0xb5ac32b1d231957d91c8b7fc43115ce3c5c0d8c13ca633374402fa8000b6d9fb19499f9181844f0c10b47357f3f757ce\",\n    \"0x96b8bf2504b4d28fa34a4ec378e0e0b684890c5f44b7a6bb6e19d7b3db2ab27b1e2686389d1de9fbd981962833a313ea\",\n    \"0x953bfd7f6c3a0469ad432072b9679a25486f5f4828092401eff494cfb46656c958641a4e6d0d97d400bc59d92dba0030\",\n    \"0x876ab3cea7484bbfd0db621ec085b9ac885d94ab55c4bb671168d82b92e609754b86aaf472c55df3d81421d768fd108a\",\n    \"0x885ff4e67d9ece646d02dd425aa5a087e485c3f280c3471b77532b0db6145b69b0fbefb18aa2e3fa5b64928b43a94e57\",\n    \"0xb91931d93f806d0b0e6cc62a53c718c099526140f50f45d94b8bbb57d71e78647e06ee7b42aa5714aed9a5c05ac8533f\",\n    \"0xa0313eeadd39c720c9c27b3d671215331ab8d0a794e71e7e690f06bcd87722b531d6525060c358f35f5705dbb7109ccb\",\n    \"0x874c0944b7fedc6701e53344100612ddcb495351e29305c00ec40a7276ea5455465ffb7bded898886c1853139dfb1fc7\",\n    \"0x8dc31701a01ee8137059ca1874a015130d3024823c0576aa9243e6942ec99d377e7715ed1444cd9b750a64b85dcaa3e5\",\n    \"0x836d2a757405e922ec9a2dfdcf489a58bd48b5f9683dd46bf6047688f778c8dee9bc456de806f70464df0b25f3f3d238\",\n    \"0xb30b0a1e454a503ea3e2efdec7483eaf20b0a5c3cefc42069e891952b35d4b2c955cf615f3066285ed8fafd9fcfbb8f6\",\n    \"0x8e6d4044b55ab747e83ec8762ea86845f1785cc7be0279c075dadf08aca3ccc5a096c015bb3c3f738f647a4eadea3ba5\",\n    \"0xad7735d16ab03cbe09c029610aa625133a6daecfc990b297205b6da98eda8c136a7c50db90f426d35069708510d5ae9c\",\n    \"0x8d62d858bbb59ec3c8cc9acda002e08addab4d3ad143b3812098f3d9087a1b4a1bb255dcb1635da2402487d8d0249161\",\n    \"0x805beec33238b832e8530645a3254aeef957e8f7ea24bcfc1054f8b9c69421145ebb8f9d893237e8a001c857fedfc77e\",\n    \"0xb1005644be4b085e3f5775aa9bd3e09a283e87ddada3082c04e7a62d303dcef3b8cf8f92944c200c7ae6bb6bdf63f832\",\n    \"0xb4ba0e0790dc29063e577474ffe3b61f5ea2508169f5adc1e394934ebb473e356239413a17962bc3e5d3762d72cce8c2\",\n    \"0xa157ba9169c9e3e6748d9f1dd67fbe08b9114ade4c5d8fc475f87a764fb7e6f1d21f66d7905cd730f28a1c2d8378682a\",\n    \"0x913e52b5c93989b5d15e0d91aa0f19f78d592bc28bcfdfddc885a9980c732b1f4debb8166a7c4083c42aeda93a702898\",\n    \"0x90fbfc1567e7cd4e096a38433704d3f96a2de2f6ed3371515ccc30bc4dd0721a704487d25a97f3c3d7e4344472702d8d\",\n    \"0x89646043028ffee4b69d346907586fd12c2c0730f024acb1481abea478e61031966e72072ff1d5e65cb8c64a69ad4eb1\",\n    \"0xb125a45e86117ee11d2fb42f680ab4a7894edd67ff927ae2c808920c66c3e55f6a9d4588eee906f33a05d592e5ec3c04\",\n    \"0xaad47f5b41eae9be55fb4f67674ff1e4ae2482897676f964a4d2dcb6982252ee4ff56aac49578b23f72d1fced707525e\",\n    \"0xb9ddff8986145e33851b4de54d3e81faa3352e8385895f357734085a1616ef61c692d925fe62a5ed3be8ca49f5d66306\",\n    \"0xb3cb0963387ed28c0c0adf7fe645f02606e6e1780a24d6cecef5b7c642499109974c81a7c2a198b19862eedcea2c2d8c\",\n    \"0xac9c53c885457aaf5cb36c717a6f4077af701e0098eebd7aa600f5e4b14e6c1067255b3a0bc40e4a552025231be7de60\",\n    \"0x8e1a8d823c4603f6648ec21d064101094f2a762a4ed37dd2f0a2d9aa97b2d850ce1e76f4a4b8cae58819b058180f7031\",\n    \"0xb268b73bf7a179b6d22bd37e5e8cb514e9f5f8968c78e14e4f6d5700ca0d0ca5081d0344bb73b028970eebde3cb4124e\",\n    \"0xa7f57d71940f0edbd29ed8473d0149cae71d921dd15d1ff589774003e816b54b24de2620871108cec1ab9fa956ad6ce6\",\n    \"0x8053e6416c8b120e2b999cc2fc420a6a55094c61ac7f2a6c6f0a2c108a320890e389af96cbe378936132363c0d551277\",\n    \"0xb3823f4511125e5aa0f4269e991b435a0d6ceb523ebd91c04d7add5534e3df5fc951c504b4fd412a309fd3726b7f940b\",\n    \"0xae6eb04674d04e982ca9a6add30370ab90e303c71486f43ed3efbe431af1b0e43e9d06c11c3412651f304c473e7dbf39\",\n    \"0x96ab55e641ed2e677591f7379a3cd126449614181fce403e93e89b1645d82c4af524381ff986cae7f9cebe676878646d\",\n    \"0xb52423b4a8c37d3c3e2eca8f0ddbf7abe0938855f33a0af50f117fab26415fb0a3da5405908ec5fdc22a2c1f2ca64892\",\n    \"0x82a69ce1ee92a09cc709d0e3cd22116c9f69d28ea507fe5901f5676000b5179b9abe4c1875d052b0dd42d39925e186bb\",\n    \"0xa84c8cb84b9d5cfb69a5414f0a5283a5f2e90739e9362a1e8c784b96381b59ac6c18723a4aa45988ee8ef5c1f45cc97d\",\n    \"0xafd7efce6b36813082eb98257aae22a4c1ae97d51cac7ea9c852d4a66d05ef2732116137d8432e3f117119725a817d24\",\n    \"0xa0f5fe25af3ce021b706fcff05f3d825384a272284d04735574ce5fb256bf27100fad0b1f1ba0e54ae9dcbb9570ecad3\",\n    \"0x8751786cb80e2e1ff819fc7fa31c2833d25086534eb12b373d31f826382430acfd87023d2a688c65b5e983927e146336\",\n    \"0x8cf5c4b17fa4f3d35c78ce41e1dc86988fd1135cd5e6b2bb0c108ee13538d0d09ae7102609c6070f39f937b439b31e33\",\n    \"0xa9108967a2fedd7c322711eca8159c533dd561bedcb181b646de98bf5c3079449478eab579731bee8d215ae8852c7e21\",\n    \"0xb54c5171704f42a6f0f4e70767cdb3d96ffc4888c842eece343a01557da405961d53ffdc34d2f902ea25d3e1ed867cad\",\n    \"0xae8d4b764a7a25330ba205bf77e9f46182cd60f94a336bbd96773cf8064e3d39caf04c310680943dc89ed1fbad2c6e0d\",\n    \"0xaa5150e911a8e1346868e1b71c5a01e2a4bb8632c195861fb6c3038a0e9b85f0e09b3822e9283654a4d7bb17db2fc5f4\",\n    \"0x9685d3756ce9069bf8bb716cf7d5063ebfafe37e15b137fc8c3159633c4e006ff4887ddd0ae90360767a25c3f90cba7f\",\n    \"0x82155fd70f107ab3c8e414eadf226c797e07b65911508c76c554445422325e71af8c9a8e77fd52d94412a6fc29417cd3\",\n    \"0xabfae52f53a4b6e00760468d973a267f29321997c3dbb5aee36dc1f20619551229c0c45b9d9749f410e7f531b73378e8\",\n    \"0x81a76d921f8ef88e774fd985e786a4a330d779b93fad7def718c014685ca0247379e2e2a007ad63ee7f729cd9ed6ce1b\",\n    \"0x81947c84bc5e28e26e2e533af5ae8fe10407a7b77436dbf8f1d5b0bbe86fc659eae10f974659dc7c826c6dabd03e3a4b\",\n    \"0x92b8c07050d635b8dd4fd09df9054efe4edae6b86a63c292e73cc819a12a21dd7d104ce51fa56af6539dedf6dbe6f7b6\",\n    \"0xb44c579e3881f32b32d20c82c207307eca08e44995dd2aac3b2692d2c8eb2a325626c80ac81c26eeb38c4137ff95add5\",\n    \"0x97efab8941c90c30860926dea69a841f2dcd02980bf5413b9fd78d85904588bf0c1021798dbc16c8bbb32cce66c82621\",\n    \"0x913363012528b50698e904de0588bf55c8ec5cf6f0367cfd42095c4468fcc64954fbf784508073e542fee242d0743867\",\n    \"0x8ed203cf215148296454012bd10fddaf119203db1919a7b3d2cdc9f80e66729464fdfae42f1f2fc5af1ed53a42b40024\",\n    \"0xab84312db7b87d711e9a60824f4fe50e7a6190bf92e1628688dfcb38930fe87b2d53f9e14dd4de509b2216856d8d9188\",\n    \"0x880726def069c160278b12d2258eac8fa63f729cd351a710d28b7e601c6712903c3ac1e7bbd0d21e4a15f13ca49db5aa\",\n    \"0x980699cd51bac6283959765f5174e543ed1e5f5584b5127980cbc2ef18d984ecabba45042c6773b447b8e694db066028\",\n    \"0xaeb019cb80dc4cb4207430d0f2cd24c9888998b6f21d9bf286cc638449668d2eec0018a4cf3fe6448673cd6729335e2b\",\n    \"0xb29852f6aa6c60effdffe96ae88590c88abae732561d35cc19e82d3a51e26cb35ea00986193e07f90060756240f5346e\",\n    \"0xa0fa855adc5ba469f35800c48414b8921455950a5c0a49945d1ef6e8f2a1881f2e2dfae47de6417270a6bf49deeb091d\",\n    \"0xb6c7332e3b14813641e7272d4f69ecc7e09081df0037d6dab97ce13a9e58510f5c930d300633f208181d9205c5534001\",\n    \"0x85a6c050f42fce560b5a8d54a11c3bbb8407abbadd859647a7b0c21c4b579ec65671098b74f10a16245dc779dff7838e\",\n    \"0x8f3eb34bb68759d53c6677de4de78a6c24dd32c8962a7fb355ed362572ef8253733e6b52bc21c9f92ecd875020a9b8de\",\n    \"0xa17dd44181e5dab4dbc128e1af93ec22624b57a448ca65d2d9e246797e4af7d079e09c6e0dfb62db3a9957ce92f098d5\",\n    \"0xa56a1b854c3183082543a8685bb34cae1289f86cfa8123a579049dbd059e77982886bfeb61bf6e05b4b1fe4e620932e7\",\n    \"0xaedae3033cb2fb7628cb4803435bdd7757370a86f808ae4cecb9a268ad0e875f308c048c80cbcac523de16b609683887\",\n    \"0x9344905376aa3982b1179497fac5a1d74b14b7038fd15e3b002db4c11c8bfc7c39430db492cdaf58b9c47996c9901f28\",\n    \"0xa3bfafdae011a19f030c749c3b071f83580dee97dd6f949e790366f95618ca9f828f1daaeabad6dcd664fcef81b6556d\",\n    \"0x81c03d8429129e7e04434dee2c529194ddb01b414feda3adee2271eb680f6c85ec872a55c9fa9d2096f517e13ed5abcc\",\n    \"0x98205ef3a72dff54c5a9c82d293c3e45d908946fa74bb749c3aabe1ab994ea93c269bcce1a266d2fe67a8f02133c5985\",\n    \"0x85a70aeed09fda24412fadbafbbbf5ba1e00ac92885df329e147bfafa97b57629a3582115b780d8549d07d19b7867715\",\n    \"0xb0fbe81c719f89a57d9ea3397705f898175808c5f75f8eb81c2193a0b555869ba7bd2e6bc54ee8a60cea11735e21c68c\",\n    \"0xb03a0bd160495ee626ff3a5c7d95bc79d7da7e5a96f6d10116600c8fa20bedd1132f5170f25a22371a34a2d763f2d6d0\",\n    \"0xa90ab04091fbca9f433b885e6c1d60ab45f6f1daf4b35ec22b09909d493a6aab65ce41a6f30c98239cbca27022f61a8b\",\n    \"0xb66f92aa3bf2549f9b60b86f99a0bd19cbdd97036d4ae71ca4b83d669607f275260a497208f6476cde1931d9712c2402\",\n    \"0xb08e1fdf20e6a9b0b4942f14fa339551c3175c1ffc5d0ab5b226b6e6a322e9eb0ba96adc5c8d59ca4259e2bdd04a7eb0\",\n    \"0xa2812231e92c1ce74d4f5ac3ab6698520288db6a38398bb38a914ac9326519580af17ae3e27cde26607e698294022c81\",\n    \"0xabfcbbcf1d3b9e84c02499003e490a1d5d9a2841a9e50c7babbef0b2dd20d7483371d4dc629ba07faf46db659459d296\",\n    \"0xb0fe9f98c3da70927c23f2975a9dc4789194d81932d2ad0f3b00843dd9cbd7fb60747a1da8fe5a79f136a601becf279d\",\n    \"0xb130a6dba7645165348cb90f023713bed0eefbd90a976b313521c60a36d34f02032e69a2bdcf5361e343ed46911297ec\",\n    \"0x862f0cffe3020cea7a5fd4703353aa1eb1be335e3b712b29d079ff9f7090d1d8b12013011e1bdcbaa80c44641fd37c9f\",\n    \"0x8c6f11123b26633e1abb9ed857e0bce845b2b3df91cc7b013b2fc77b477eee445da0285fc6fc793e29d5912977f40916\",\n    \"0x91381846126ea819d40f84d3005e9fb233dc80071d1f9bb07f102bf015f813f61e5884ffffb4f5cd333c1b1e38a05a58\",\n    \"0x8add7d908de6e1775adbd39c29a391f06692b936518db1f8fde74eb4f533fc510673a59afb86e3a9b52ade96e3004c57\",\n    \"0x8780e086a244a092206edcde625cafb87c9ab1f89cc3e0d378bc9ee776313836160960a82ec397bc3800c0a0ec3da283\",\n    \"0xa6cb4cd9481e22870fdd757fae0785edf4635e7aacb18072fe8dc5876d0bab53fb99ce40964a7d3e8bcfff6f0ab1332f\",\n    \"0xaf30ff47ecc5b543efba1ba4706921066ca8bb625f40e530fb668aea0551c7647a9d126e8aba282fbcce168c3e7e0130\",\n    \"0x91b0bcf408ce3c11555dcb80c4410b5bc2386d3c05caec0b653352377efdcb6bab4827f2018671fc8e4a0e90d772acc1\",\n    \"0xa9430b975ef138b6b2944c7baded8fe102d31da4cfe3bd3d8778bda79189c99d38176a19c848a19e2d1ee0bddd9a13c1\",\n    \"0xaa5a4eef849d7c9d2f4b018bd01271c1dd83f771de860c4261f385d3bdcc130218495860a1de298f14b703ec32fa235f\",\n    \"0xb0ce79e7f9ae57abe4ff366146c3b9bfb38b0dee09c28c28f5981a5d234c6810ad4d582751948affb480d6ae1c8c31c4\",\n    \"0xb75122748560f73d15c01a8907d36d06dc068e82ce22b84b322ac1f727034493572f7907dec34ebc3ddcc976f2f89ed7\",\n    \"0xb0fc7836369a3e4411d34792d6bd5617c14f61d9bba023dda64e89dc5fb0f423244e9b48ee64869258931daa9753a56f\",\n    \"0x8956d7455ae9009d70c6e4a0bcd7610e55f37494cf9897a8f9e1b904cc8febc3fd2d642ebd09025cfff4609ad7e3bc52\",\n    \"0xad741efe9e472026aa49ae3d9914cb9c1a6f37a54f1a6fe6419bebd8c7d68dca105a751c7859f4389505ede40a0de786\",\n    \"0xb52f418797d719f0d0d0ffb0846788b5cba5d0454a69a2925de4b0b80fa4dd7e8c445e5eac40afd92897ed28ca650566\",\n    \"0xa0ab65fb9d42dd966cd93b1de01d7c822694669dd2b7a0c04d99cd0f3c3de795f387b9c92da11353412f33af5c950e9a\",\n    \"0xa0052f44a31e5741a331f7cac515a08b3325666d388880162d9a7b97598fde8b61f9ff35ff220df224eb5c4e40ef0567\",\n    \"0xa0101cfdc94e42b2b976c0d89612a720e55d145a5ef6ef6f1f78cf6de084a49973d9b5d45915349c34ce712512191e3c\",\n    \"0xa0dd99fcf3f5cead5aaf08e82212df3a8bb543c407a4d6fab88dc5130c1769df3f147e934a46f291d6c1a55d92b86917\",\n    \"0xa5939153f0d1931bbda5cf6bdf20562519ea55fbfa978d6dbc6828d298260c0da7a50c37c34f386e59431301a96c2232\",\n    \"0x9568269f3f5257200f9ca44afe1174a5d3cf92950a7f553e50e279c239e156a9faaa2a67f288e3d5100b4142efe64856\",\n    \"0xb746b0832866c23288e07f24991bbf687cad794e7b794d3d3b79367566ca617d38af586cdc8d6f4a85a34835be41d54f\",\n    \"0xa871ce28e39ab467706e32fec1669fda5a4abba2f8c209c6745df9f7a0fa36bbf1919cf14cb89ea26fa214c4c907ae03\",\n    \"0xa08dacdd758e523cb8484f6bd070642c0c20e184abdf8e2a601f61507e93952d5b8b0c723c34fcbdd70a8485eec29db2\",\n    \"0x85bdb78d501382bb95f1166b8d032941005661aefd17a5ac32df9a3a18e9df2fc5dc2c1f07075f9641af10353cecc0c9\",\n    \"0x98d730c28f6fa692a389e97e368b58f4d95382fad8f0baa58e71a3d7baaea1988ead47b13742ce587456f083636fa98e\",\n    \"0xa557198c6f3d5382be9fb363feb02e2e243b0c3c61337b3f1801c4a0943f18e38ce1a1c36b5c289c8fa2aa9d58742bab\",\n    \"0x89174f79201742220ac689c403fc7b243eed4f8e3f2f8aba0bf183e6f5d4907cb55ade3e238e3623d9885f03155c4d2b\",\n    \"0xb891d600132a86709e06f3381158db300975f73ea4c1f7c100358e14e98c5fbe792a9af666b85c4e402707c3f2db321e\",\n    \"0xb9e5b2529ef1043278c939373fc0dbafe446def52ddd0a8edecd3e4b736de87e63e187df853c54c28d865de18a358bb6\",\n    \"0x8589b2e9770340c64679062c5badb7bbef68f55476289b19511a158a9a721f197da03ece3309e059fc4468b15ac33aa3\",\n    \"0xaad8c6cd01d785a881b446f06f1e9cd71bca74ba98674c2dcddc8af01c40aa7a6d469037498b5602e76e9c91a58d3dbd\",\n    \"0xabaccb1bd918a8465f1bf8dbe2c9ad4775c620b055550b949a399f30cf0d9eb909f3851f5b55e38f9e461e762f88f499\",\n    \"0xae62339d26db46e85f157c0151bd29916d5cc619bd4b832814b3fd2f00af8f38e7f0f09932ffe5bba692005dab2d9a74\",\n    \"0x93a6ff30a5c0edf8058c89aba8c3259e0f1b1be1b80e67682de651e5346f7e1b4b4ac3d87cbaebf198cf779524aff6bf\",\n    \"0x8980a2b1d8f574af45b459193c952400b10a86122b71fca2acb75ee0dbd492e7e1ef5b959baf609a5172115e371f3177\",\n    \"0x8c2f49f3666faee6940c75e8c7f6f8edc3f704cca7a858bbb7ee5e96bba3b0cf0993996f781ba6be3b0821ef4cb75039\",\n    \"0xb14b9e348215b278696018330f63c38db100b0542cfc5be11dc33046e3bca6a13034c4ae40d9cef9ea8b34fef0910c4e\",\n    \"0xb59bc3d0a30d66c16e6a411cb641f348cb1135186d5f69fda8b0a0934a5a2e7f6199095ba319ec87d3fe8f1ec4a06368\",\n    \"0x8874aca2a3767aa198e4c3fec2d9c62d496bc41ff71ce242e9e082b7f38cdf356089295f80a301a3cf1182bde5308c97\",\n    \"0xb1820ebd61376d91232423fc20bf008b2ba37e761199f4ef0648ea2bd70282766799b4de814846d2f4d516d525c8daa7\",\n    \"0xa6b202e5dedc16a4073e04a11af3a8509b23dfe5a1952f899adeb240e75c3f5bde0c424f811a81ea48d343591faffe46\",\n    \"0xa69becee9c93734805523b92150a59a62eed4934f66056b645728740d42223f2925a1ad38359ba644da24d9414f4cdda\",\n    \"0xad72f0f1305e37c7e6b48c272323ee883320994cb2e0d850905d6655fafc9f361389bcb9c66b3ff8d2051dbb58c8aa96\",\n    \"0xb563600bd56fad7c8853af21c6a02a16ed9d8a8bbeea2c31731d63b976d83cb05b9779372d898233e8fd597a75424797\",\n    \"0xb0abb78ce465bf7051f563c62e8be9c57a2cc997f47c82819300f36e301fefd908894bb2053a9d27ce2d0f8c46d88b5b\",\n    \"0xa071a85fb8274bac2202e0cb8e0e2028a5e138a82d6e0374d39ca1884a549c7c401312f00071b91f455c3a2afcfe0cda\",\n    \"0xb931c271513a0f267b9f41444a5650b1918100b8f1a64959c552aff4e2193cc1b9927906c6fa7b8a8c68ef13d79aaa52\",\n    \"0xa6a1bb9c7d32cb0ca44d8b75af7e40479fbce67d216b48a2bb680d3f3a772003a49d3cd675fc64e9e0f8fabeb86d6d61\",\n    \"0xb98d609858671543e1c3b8564162ad828808bb50ded261a9f8690ded5b665ed8368c58f947365ed6e84e5a12e27b423d\",\n    \"0xb3dca58cd69ec855e2701a1d66cad86717ff103ef862c490399c771ad28f675680f9500cb97be48de34bcdc1e4503ffd\",\n    \"0xb34867c6735d3c49865e246ddf6c3b33baf8e6f164db3406a64ebce4768cb46b0309635e11be985fee09ab7a31d81402\",\n    \"0xacb966c554188c5b266624208f31fab250b3aa197adbdd14aee5ab27d7fb886eb4350985c553b20fdf66d5d332bfd3fe\",\n    \"0x943c36a18223d6c870d54c3b051ef08d802b85e9dd6de37a51c932f90191890656c06adfa883c87b906557ae32d09da0\",\n    \"0x81bca7954d0b9b6c3d4528aadf83e4bc2ef9ea143d6209bc45ae9e7ae9787dbcd8333c41f12c0b6deee8dcb6805e826a\",\n    \"0xaba176b92256efb68f574e543479e5cf0376889fb48e3db4ebfb7cba91e4d9bcf19dcfec444c6622d9398f06de29e2b9\",\n    \"0xb9f743691448053216f6ece7cd699871fff4217a1409ceb8ab7bdf3312d11696d62c74b0664ba0a631b1e0237a8a0361\",\n    \"0xa383c2b6276fa9af346b21609326b53fb14fdf6f61676683076e80f375b603645f2051985706d0401e6fbed7eb0666b6\",\n    \"0xa9ef2f63ec6d9beb8f3d04e36807d84bda87bdd6b351a3e4a9bf7edcb5618c46c1f58cfbf89e64b40f550915c6988447\",\n    \"0xa141b2d7a82f5005eaea7ae7d112c6788b9b95121e5b70b7168d971812f3381de8b0082ac1f0a82c7d365922ebd2d26a\",\n    \"0xb1b76ef8120e66e1535c17038b75255a07849935d3128e3e99e56567b842fb1e8d56ef932d508d2fb18b82f7868fe1a9\",\n    \"0x8e2e234684c81f21099f5c54f6bbe2dd01e3b172623836c77668a0c49ce1fe218786c3827e4d9ae2ea25c50a8924fb3c\",\n    \"0xa5caf5ff948bfd3c4ca3ffbdfcd91eec83214a6c6017235f309a0bbf7061d3b0b466307c00b44a1009cf575163898b43\",\n    \"0x986415a82ca16ebb107b4c50b0c023c28714281db0bcdab589f6cb13d80e473a3034b7081b3c358e725833f6d845cb14\",\n    \"0xb94836bf406ac2cbacb10e6df5bcdfcc9d9124ae1062767ca4e322d287fd5e353fdcebd0e52407cb3cd68571258a8900\",\n    \"0x83c6d70a640b33087454a4788dfd9ef3ed00272da084a8d36be817296f71c086b23b576f98178ab8ca6a74f04524b46b\",\n    \"0xad4115182ad784cfe11bcfc5ce21fd56229cc2ce77ac82746e91a2f0aa53ca6593a22efd2dc4ed8d00f84542643d9c58\",\n    \"0xab1434c5e5065da826d10c2a2dba0facccab0e52b506ce0ce42fbe47ced5a741797151d9ecc99dc7d6373cfa1779bbf6\",\n    \"0x8a8b591d82358d55e6938f67ea87a89097ab5f5496f7260adb9f649abb289da12b498c5b2539c2f9614fb4e21b1f66b0\",\n    \"0x964f355d603264bc1f44c64d6d64debca66f37dff39c971d9fc924f2bc68e6c187b48564a6dc82660a98b035f8addb5d\",\n    \"0xb66235eaaf47456bc1dc4bde454a028e2ce494ece6b713a94cd6bf27cf18c717fd0c57a5681caaa2ad73a473593cdd7a\",\n    \"0x9103e3bb74304186fa4e3e355a02da77da4aca9b7e702982fc2082af67127ebb23a455098313c88465bc9b7d26820dd5\",\n    \"0xb6a42ff407c9dd132670cdb83cbad4b20871716e44133b59a932cd1c3f97c7ac8ff7f61acfaf8628372508d8dc8cad7c\",\n    \"0x883a9c21c16a167a4171b0f084565c13b6f28ba7c4977a0de69f0a25911f64099e7bbb4da8858f2e93068f4155d04e18\",\n    \"0x8dbb3220abc6a43220adf0331e3903d3bfd1d5213aadfbd8dfcdf4b2864ce2e96a71f35ecfb7a07c3bbabf0372b50271\",\n    \"0xb4ad08aee48e176bda390b7d9acf2f8d5eb008f30d20994707b757dc6a3974b2902d29cd9b4d85e032810ad25ac49e97\",\n    \"0x865bb0f33f7636ec501bb634e5b65751c8a230ae1fa807a961a8289bbf9c7fe8c59e01fbc4c04f8d59b7f539cf79ddd5\",\n    \"0x86a54d4c12ad1e3605b9f93d4a37082fd26e888d2329847d89afa7802e815f33f38185c5b7292293d788ad7d7da1df97\",\n    \"0xb26c8615c5e47691c9ff3deca3021714662d236c4d8401c5d27b50152ce7e566266b9d512d14eb63e65bc1d38a16f914\",\n    \"0x827639d5ce7db43ba40152c8a0eaad443af21dc92636cc8cc2b35f10647da7d475a1e408901cd220552fddad79db74df\",\n    \"0xa2b79a582191a85dbe22dc384c9ca3de345e69f6aa370aa6d3ff1e1c3de513e30b72df9555b15a46586bd27ea2854d9d\",\n    \"0xae0d74644aba9a49521d3e9553813bcb9e18f0b43515e4c74366e503c52f47236be92dfbd99c7285b3248c267b1de5a0\",\n    \"0x80fb0c116e0fd6822a04b9c25f456bdca704e2be7bdc5d141dbf5d1c5eeb0a2c4f5d80db583b03ef3e47517e4f9a1b10\",\n    \"0xac3a1fa3b4a2f30ea7e0a114cdc479eb51773573804c2a158d603ad9902ae8e39ffe95df09c0d871725a5d7f9ba71a57\",\n    \"0xb56b2b0d601cba7f817fa76102c68c2e518c6f20ff693aad3ff2e07d6c4c76203753f7f91686b1801e8c4659e4d45c48\",\n    \"0x89d50c1fc56e656fb9d3915964ebce703cb723fe411ab3c9eaa88ccc5d2b155a9b2e515363d9c600d3c0cee782c43f41\",\n    \"0xb24207e61462f6230f3cd8ccf6828357d03e725769f7d1de35099ef9ee4dca57dbce699bb49ed994462bee17059d25ce\",\n    \"0xb886f17fcbcbfcd08ac07f04bb9543ef58510189decaccea4b4158c9174a067cb67d14b6be3c934e6e2a18c77efa9c9c\",\n    \"0xb9c050ad9cafd41c6e2e192b70d080076eed59ed38ea19a12bd92fa17b5d8947d58d5546aaf5e8e27e1d3b5481a6ce51\",\n    \"0xaaf7a34d3267e3b1ddbc54c641e3922e89303f7c86ebebc7347ebca4cffad5b76117dac0cbae1a133053492799cd936f\",\n    \"0xa9ee604ada50adef82e29e893070649d2d4b7136cc24fa20e281ce1a07bd736bf0de7c420369676bcbcecff26fb6e900\",\n    \"0x9855315a12a4b4cf80ab90b8bd13003223ba25206e52fd4fe6a409232fbed938f30120a3db23eab9c53f308bd8b9db81\",\n    \"0x8cd488dd7a24f548a3cf03c54dec7ff61d0685cb0f6e5c46c2d728e3500d8c7bd6bba0156f4bf600466fda53e5b20444\",\n    \"0x890ad4942ebac8f5b16c777701ab80c68f56fa542002b0786f8fea0fb073154369920ac3dbfc07ea598b82f4985b8ced\",\n    \"0x8de0cf9ddc84c9b92c59b9b044387597799246b30b9f4d7626fc12c51f6e423e08ee4cbfe9289984983c1f9521c3e19d\",\n    \"0xb474dfb5b5f4231d7775b3c3a8744956b3f0c7a871d835d7e4fd9cc895222c7b868d6c6ce250de568a65851151fac860\",\n    \"0x86433b6135d9ed9b5ee8cb7a6c40e5c9d30a68774cec04988117302b8a02a11a71a1e03fd8e0264ef6611d219f103007\",\n    \"0x80b9ed4adbe9538fb1ef69dd44ec0ec5b57cbfea820054d8d445b4261962624b4c70ac330480594bc5168184378379c3\",\n    \"0x8b2e83562ccd23b7ad2d17f55b1ab7ef5fbef64b3a284e6725b800f3222b8bdf49937f4a873917ada9c4ddfb090938c2\",\n    \"0xabe78cebc0f5a45d754140d1f685e387489acbfa46d297a8592aaa0d676a470654f417a4f7d666fc0b2508fab37d908e\",\n    \"0xa9c5f8ff1f8568e252b06d10e1558326db9901840e6b3c26bbd0cd5e850cb5fb3af3f117dbb0f282740276f6fd84126f\",\n    \"0x975f8dc4fb55032a5df3b42b96c8c0ffecb75456f01d4aef66f973cb7270d4eff32c71520ceefc1adcf38d77b6b80c67\",\n    \"0xb043306ed2c3d8a5b9a056565afd8b5e354c8c4569fda66b0d797a50a3ce2c08cffbae9bbe292da69f39e89d5dc7911e\",\n    \"0x8d2afc36b1e44386ba350c14a6c1bb31ff6ea77128a0c5287584ac3584282d18516901ce402b4644a53db1ed8e7fa581\",\n    \"0x8c294058bed53d7290325c363fe243f6ec4f4ea2343692f4bac8f0cb86f115c069ccb8334b53d2e42c067691ad110dba\",\n    \"0xb92157b926751aaf7ef82c1aa8c654907dccab6376187ee8b3e8c0c82811eae01242832de953faa13ebaff7da8698b3e\",\n    \"0xa780c4bdd9e4ba57254b09d745075cecab87feda78c88ffee489625c5a3cf96aa6b3c9503a374a37927d9b78de9bd22b\",\n    \"0x811f548ef3a2e6a654f7dcb28ac9378de9515ed61e5a428515d9594a83e80b35c60f96a5cf743e6fab0d3cb526149f49\",\n    \"0x85a4dccf6d90ee8e094731eec53bd00b3887aec6bd81a0740efddf812fd35e3e4fe4f983afb49a8588691c202dabf942\",\n    \"0xb152c2da6f2e01c8913079ae2b40a09b1f361a80f5408a0237a8131b429677c3157295e11b365b1b1841924b9efb922e\",\n    \"0x849b9efee8742502ffd981c4517c88ed33e4dd518a330802caff168abae3cd09956a5ee5eda15900243bc2e829016b74\",\n    \"0x955a933f3c18ec0f1c0e38fa931e4427a5372c46a3906ebe95082bcf878c35246523c23f0266644ace1fa590ffa6d119\",\n    \"0x911989e9f43e580c886656377c6f856cdd4ff1bd001b6db3bbd86e590a821d34a5c6688a29b8d90f28680e9fdf03ba69\",\n    \"0xb73b8b4f1fd6049fb68d47cd96a18fcba3f716e0a1061aa5a2596302795354e0c39dea04d91d232aec86b0bf2ba10522\",\n    \"0x90f87456d9156e6a1f029a833bf3c7dbed98ca2f2f147a8564922c25ae197a55f7ea9b2ee1f81bf7383197c4bad2e20c\",\n    \"0x903cba8b1e088574cb04a05ca1899ab00d8960580c884bd3c8a4c98d680c2ad11410f2b75739d6050f91d7208cac33a5\",\n    \"0x9329987d42529c261bd15ecedd360be0ea8966e7838f32896522c965adfc4febf187db392bd441fb43bbd10c38fdf68b\",\n    \"0x8178ee93acf5353baa349285067b20e9bb41aa32d77b5aeb7384fe5220c1fe64a2461bd7a83142694fe673e8bbf61b7c\",\n    \"0xa06a8e53abcff271b1394bcc647440f81fb1c1a5f29c27a226e08f961c3353f4891620f2d59b9d1902bf2f5cc07a4553\",\n    \"0xaaf5fe493b337810889e777980e6bbea6cac39ac66bc0875c680c4208807ac866e9fda9b5952aa1d04539b9f4a4bec57\",\n    \"0xaa058abb1953eceac14ccfa7c0cc482a146e1232905dcecc86dd27f75575285f06bbae16a8c9fe8e35d8713717f5f19f\",\n    \"0x8f15dd732799c879ca46d2763453b359ff483ca33adb1d0e0a57262352e0476c235987dc3a8a243c74bc768f93d3014c\",\n    \"0xa61cc8263e9bc03cce985f1663b8a72928a607121005a301b28a278e9654727fd1b22bc8a949af73929c56d9d3d4a273\",\n    \"0x98d6dc78502d19eb9f921225475a6ebcc7b44f01a2df6f55ccf6908d65b27af1891be2a37735f0315b6e0f1576c1f8d8\",\n    \"0x8bd258b883f3b3793ec5be9472ad1ff3dc4b51bc5a58e9f944acfb927349ead8231a523cc2175c1f98e7e1e2b9f363b8\",\n    \"0xaeacc2ecb6e807ad09bedd99654b097a6f39840e932873ace02eabd64ccfbb475abdcb62939a698abf17572d2034c51e\",\n    \"0xb8ccf78c08ccd8df59fd6eda2e01de328bc6d8a65824d6f1fc0537654e9bc6bf6f89c422dd3a295cce628749da85c864\",\n    \"0x8f91fd8cb253ba2e71cc6f13da5e05f62c2c3b485c24f5d68397d04665673167fce1fc1aec6085c69e87e66ec555d3fd\",\n    \"0xa254baa10cb26d04136886073bb4c159af8a8532e3fd36b1e9c3a2e41b5b2b6a86c4ebc14dbe624ee07b7ccdaf59f9ab\",\n    \"0x94e3286fe5cd68c4c7b9a7d33ae3d714a7f265cf77cd0e9bc19fc51015b1d1c34ad7e3a5221c459e89f5a043ee84e3a9\",\n    \"0xa279da8878af8d449a9539bec4b17cea94f0242911f66fab275b5143ab040825f78c89cb32a793930609415cfa3a1078\",\n    \"0xac846ceb89c9e5d43a2991c8443079dc32298cd63e370e64149cec98cf48a6351c09c856f2632fd2f2b3d685a18bbf8b\",\n    \"0xa847b27995c8a2e2454aaeb983879fb5d3a23105c33175839f7300b7e1e8ec3efd6450e9fa3f10323609dee7b98c6fd5\",\n    \"0xa2f432d147d904d185ff4b2de8c6b82fbea278a2956bc406855b44c18041854c4f0ecccd472d1d0dff1d8aa8e281cb1d\",\n    \"0x94a48ad40326f95bd63dff4755f863a1b79e1df771a1173b17937f9baba57b39e651e7695be9f66a472f098b339364fc\",\n    \"0xa12a0ccd8f96e96e1bc6494341f7ebce959899341b3a084aa1aa87d1c0d489ac908552b7770b887bb47e7b8cbc3d8e66\",\n    \"0x81a1f1681bda923bd274bfe0fbb9181d6d164fe738e54e25e8d4849193d311e2c4253614ed673c98af2c798f19a93468\",\n    \"0xabf71106a05d501e84cc54610d349d7d5eae21a70bd0250f1bebbf412a130414d1c8dbe673ffdb80208fd72f1defa4d4\",\n    \"0x96266dc2e0df18d8136d79f5b59e489978eee0e6b04926687fe389d4293c14f36f055c550657a8e27be4118b64254901\",\n    \"0x8df5dcbefbfb4810ae3a413ca6b4bf08619ca53cd50eb1dde2a1c035efffc7b7ac7dff18d403253fd80104bd83dc029e\",\n    \"0x9610b87ff02e391a43324a7122736876d5b3af2a137d749c52f75d07b17f19900b151b7f439d564f4529e77aa057ad12\",\n    \"0xa90a5572198b40fe2fcf47c422274ff36c9624df7db7a89c0eb47eb48a73a03c985f4ac5016161c76ca317f64339bce1\",\n    \"0x98e5e61a6ab6462ba692124dba7794b6c6bde4249ab4fcc98c9edd631592d5bc2fb5e38466691a0970a38e48d87c2e43\",\n    \"0x918cefb8f292f78d4db81462c633daf73b395e772f47b3a7d2cea598025b1d8c3ec0cbff46cdb23597e74929981cde40\",\n    \"0xa98918a5dc7cf610fe55f725e4fd24ce581d594cb957bb9b4e888672e9c0137003e1041f83e3f1d7b9caab06462c87d4\",\n    \"0xb92b74ac015262ca66c33f2d950221e19d940ba3bf4cf17845f961dc1729ae227aa9e1f2017829f2135b489064565c29\",\n    \"0xa053ee339f359665feb178b4e7ee30a85df37debd17cacc5a27d6b3369d170b0114e67ad1712ed26d828f1df641bcd99\",\n    \"0x8c3c8bad510b35da5ce5bd84b35c958797fbea024ad1c97091d2ff71d9b962e9222f65a9b776e5b3cc29c36e1063d2ee\",\n    \"0xaf99dc7330fe7c37e850283eb47cc3257888e7c197cb0d102edf94439e1e02267b6a56306d246c326c4c79f9dc8c6986\",\n    \"0xafecb2dc34d57a725efbd7eb93d61eb29dbe8409b668ab9ea040791f5b796d9be6d4fc10d7f627bf693452f330cf0435\",\n    \"0x93334fedf19a3727a81a6b6f2459db859186227b96fe7a391263f69f1a0884e4235de64d29edebc7b99c44d19e7c7d7a\",\n    \"0x89579c51ac405ad7e9df13c904061670ce4b38372492764170e4d3d667ed52e5d15c7cd5c5991bbfa3a5e4e3fa16363e\",\n    \"0x9778f3e8639030f7ef1c344014f124e375acb8045bd13d8e97a92c5265c52de9d1ffebaa5bc3e1ad2719da0083222991\",\n    \"0x88f77f34ee92b3d36791bdf3326532524a67d544297dcf1a47ff00b47c1b8219ff11e34034eab7d23b507caa2fd3c6b9\",\n    \"0xa699c1e654e7c484431d81d90657892efeb4adcf72c43618e71ca7bd7c7a7ebbb1db7e06e75b75dc4c74efd306b5df3f\",\n    \"0x81d13153baebb2ef672b5bdb069d3cd669ce0be96b742c94e04038f689ff92a61376341366b286eee6bf3ae85156f694\",\n    \"0x81efb17de94400fdacc1deec2550cbe3eecb27c7af99d8207e2f9be397e26be24a40446d2a09536bb5172c28959318d9\",\n    \"0x989b21ebe9ceab02488992673dc071d4d5edec24bff0e17a4306c8cb4b3c83df53a2063d1827edd8ed16d6e837f0d222\",\n    \"0x8d6005d6536825661b13c5fdce177cb37c04e8b109b7eb2b6d82ea1cb70efecf6a0022b64f84d753d165edc2bba784a3\",\n    \"0xa32607360a71d5e34af2271211652d73d7756d393161f4cf0da000c2d66a84c6826e09e759bd787d4fd0305e2439d342\",\n    \"0xaaad8d6f6e260db45d51b2da723be6fa832e76f5fbcb77a9a31e7f090dd38446d3b631b96230d78208cae408c288ac4e\",\n    \"0xabcfe425255fd3c5cffd3a818af7650190c957b6b07b632443f9e33e970a8a4c3bf79ac9b71f4d45f238a04d1c049857\",\n    \"0xaeabf026d4c783adc4414b5923dbd0be4b039cc7201219f7260d321f55e9a5b166d7b5875af6129c034d0108fdc5d666\",\n    \"0xaf49e740c752d7b6f17048014851f437ffd17413c59797e5078eaaa36f73f0017c3e7da020310cfe7d3c85f94a99f203\",\n    \"0x8854ca600d842566e3090040cd66bb0b3c46dae6962a13946f0024c4a8aca447e2ccf6f240045f1ceee799a88cb9210c\",\n    \"0xb6c03b93b1ab1b88ded8edfa1b487a1ed8bdce8535244dddb558ffb78f89b1c74058f80f4db2320ad060d0c2a9c351cc\",\n    \"0xb5bd7d17372faff4898a7517009b61a7c8f6f0e7ed4192c555db264618e3f6e57fb30a472d169fea01bf2bf0362a19a8\",\n    \"0x96eb1d38319dc74afe7e7eb076fcd230d19983f645abd14a71e6103545c01301b31c47ae931e025f3ecc01fb3d2f31fa\",\n    \"0xb55a8d30d4403067def9b65e16f867299f8f64c9b391d0846d4780bc196569622e7e5b64ce799b5aefac8f965b2a7a7b\",\n    \"0x8356d199a991e5cbbff608752b6291731b6b6771aed292f8948b1f41c6543e4ab1bedc82dd26d10206c907c03508df06\",\n    \"0x97f4137445c2d98b0d1d478049de952610ad698c91c9d0f0e7227d2aae690e9935e914ec4a2ea1fbf3fc1dddfeeacebb\",\n    \"0xaf5621707e0938320b15ddfc87584ab325fbdfd85c30efea36f8f9bd0707d7ec12c344eff3ec21761189518d192df035\",\n    \"0x8ac7817e71ea0825b292687928e349da7140285d035e1e1abff0c3704fa8453faaae343a441b7143a74ec56539687cc4\",\n    \"0x8a5e0a9e4758449489df10f3386029ada828d1762e4fb0a8ffe6b79e5b6d5d713cb64ed95960e126398b0cdb89002bc9\",\n    \"0x81324be4a71208bbb9bca74b77177f8f1abb9d3d5d9db195d1854651f2cf333cd618d35400da0f060f3e1b025124e4b2\",\n    \"0x849971d9d095ae067525b3cbc4a7dfae81f739537ade6d6cec1b42fb692d923176197a8770907c58069754b8882822d6\",\n    \"0x89f830825416802477cc81fdf11084885865ee6607aa15aa4eb28e351c569c49b8a1b9b5e95ddc04fa0ebafe20071313\",\n    \"0x9240aeeaff37a91af55f860b9badd466e8243af9e8c96a7aa8cf348cd270685ab6301bc135b246dca9eda696f8b0e350\",\n    \"0xacf74db78cc33138273127599eba35b0fb4e7b9a69fe02dae18fc6692d748ca332bd00b22afa8e654ed587aab11833f3\",\n    \"0xb091e6d37b157b50d76bd297ad752220cd5c9390fac16dc838f8557aed6d9833fc920b61519df21265406216315e883f\",\n    \"0xa6446c429ebf1c7793c622250e23594c836b2fbcaf6c5b3d0995e1595a37f50ea643f3e549b0be8bbdadd69044d72ab9\",\n    \"0x93e675353bd60e996bf1c914d5267eeaa8a52fc3077987ccc796710ef9becc6b7a00e3d82671a6bdfb8145ee3c80245a\",\n    \"0xa2f731e43251d04ed3364aa2f072d05355f299626f2d71a8a38b6f76cf08c544133f7d72dd0ab4162814b674b9fc7fa6\",\n    \"0x97a8b791a5a8f6e1d0de192d78615d73d0c38f1e557e4e15d15adc663d649e655bc8da3bcc499ef70112eafe7fb45c7a\",\n    \"0x98cd624cbbd6c53a94469be4643c13130916b91143425bcb7d7028adbbfede38eff7a21092af43b12d4fab703c116359\",\n    \"0x995783ce38fd5f6f9433027f122d4cf1e1ff3caf2d196ce591877f4a544ce9113ead60de2de1827eaff4dd31a20d79a8\",\n    \"0x8cf251d6f5229183b7f3fe2f607a90b4e4b6f020fb4ba2459d28eb8872426e7be8761a93d5413640a661d73e34a5b81f\",\n    \"0xb9232d99620652a3aa7880cad0876f153ff881c4ed4c0c2e7b4ea81d5d42b70daf1a56b869d752c3743c6d4c947e6641\",\n    \"0x849716f938f9d37250cccb1bf77f5f9fde53096cdfc6f2a25536a6187029a8f1331cdbed08909184b201f8d9f04b792f\",\n    \"0x80c7c4de098cbf9c6d17b14eba1805e433b5bc905f6096f8f63d34b94734f2e4ebf4bce8a177efd1186842a61204a062\",\n    \"0xb790f410cf06b9b8daadceeb4fd5ff40a2deda820c8df2537e0a7554613ae3948e149504e3e79aa84889df50c8678eeb\",\n    \"0x813aab8bd000299cd37485b73cd7cba06e205f8efb87f1efc0bae8b70f6db2bc7702eb39510ad734854fb65515fe9d0f\",\n    \"0x94f0ab7388ac71cdb67f6b85dfd5945748afb2e5abb622f0b5ad104be1d4d0062b651f134ba22385c9e32c2dfdcccce1\",\n    \"0xab6223dca8bd6a4f969e21ccd9f8106fc5251d321f9e90cc42cea2424b3a9c4e5060a47eeef6b23c7976109b548498e8\",\n    \"0x859c56b71343fce4d5c5b87814c47bf55d581c50fd1871a17e77b5e1742f5af639d0e94d19d909ec7dfe27919e954e0c\",\n    \"0xaae0d632b6191b8ad71b027791735f1578e1b89890b6c22e37de0e4a6074886126988fe8319ae228ac9ef3b3bcccb730\",\n    \"0x8ca9f32a27a024c3d595ecfaf96b0461de57befa3b331ab71dc110ec3be5824fed783d9516597537683e77a11d334338\",\n    \"0xa061df379fb3f4b24816c9f6cd8a94ecb89b4c6dc6cd81e4b8096fa9784b7f97ab3540259d1de9c02eb91d9945af4823\",\n    \"0x998603102ac63001d63eb7347a4bb2bf4cf33b28079bb48a169076a65c20d511ccd3ef696d159e54cc8e772fb5d65d50\",\n    \"0x94444d96d39450872ac69e44088c252c71f46be8333a608a475147752dbb99db0e36acfc5198f158509401959c12b709\",\n    \"0xac1b51b6c09fe055c1d7c9176eea9adc33f710818c83a1fbfa073c8dc3a7eb3513cbdd3f5960b7845e31e3e83181e6ba\",\n    \"0x803d530523fc9e1e0f11040d2412d02baef3f07eeb9b177fa9bfa396af42eea898a4276d56e1db998dc96ae47b644cb2\",\n    \"0x85a3c9fc7638f5bf2c3e15ba8c2fa1ae87eb1ceb44c6598c67a2948667a9dfa41e61f66d535b4e7fda62f013a5a8b885\",\n    \"0xa961cf5654c46a1a22c29baf7a4e77837a26b7f138f410e9d1883480ed5fa42411d522aba32040b577046c11f007388e\",\n    \"0xad1154142344f494e3061ef45a34fab1aaacf5fdf7d1b26adbb5fbc3d795655fa743444e39d9a4119b4a4f82a6f30441\",\n    \"0xb1d6c30771130c77806e7ab893b73d4deb590b2ff8f2f8b5e54c2040c1f3e060e2bd99afc668cf706a2df666a508bbf6\",\n    \"0xa00361fd440f9decabd98d96c575cd251dc94c60611025095d1201ef2dedde51cb4de7c2ece47732e5ed9b3526c2012c\",\n    \"0xa85c5ab4d17d328bda5e6d839a9a6adcc92ff844ec25f84981e4f44a0e8419247c081530f8d9aa629c7eb4ca21affba6\",\n    \"0xa4ddd3eab4527a2672cf9463db38bc29f61460e2a162f426b7852b7a7645fbd62084fd39a8e4d60e1958cce436dd8f57\",\n    \"0x811648140080fe55b8618f4cf17f3c5a250adb0cd53d885f2ddba835d2b4433188e41fc0661faac88e4ff910b16278c0\",\n    \"0xb85c7f1cfb0ed29addccf7546023a79249e8f15ac2d14a20accbfef4dd9dc11355d599815fa09d2b6b4e966e6ea8cff1\",\n    \"0xa10b5d8c260b159043b020d5dd62b3467df2671afea6d480ca9087b7e60ed170c82b121819d088315902842d66c8fb45\",\n    \"0x917e191df1bcf3f5715419c1e2191da6b8680543b1ba41fe84ed07ef570376e072c081beb67b375fca3565a2565bcabb\",\n    \"0x881fd967407390bfd7badc9ab494e8a287559a01eb07861f527207c127eadea626e9bcc5aa9cca2c5112fbac3b3f0e9c\",\n    \"0x959fd71149af82cc733619e0e5bf71760ca2650448c82984b3db74030d0e10f8ab1ce1609a6de6f470fe8b5bd90df5b3\",\n    \"0xa3370898a1c5f33d15adb4238df9a6c945f18b9ada4ce2624fc32a844f9ece4c916a64e9442225b6592afa06d2e015f2\",\n    \"0x817efb8a791435e4236f7d7b278181a5fa34587578c629dbc14fbf9a5c26772290611395eecd20222a4c58649fc256d8\",\n    \"0xa04c9876acf2cfdc8ef96de4879742709270fa1d03fe4c8511fbef2d59eb0aaf0336fa2c7dfe41a651157377fa217813\",\n    \"0x81e15875d7ea7f123e418edf14099f2e109d4f3a6ce0eb65f67fe9fb10d2f809a864a29f60ad3fc949f89e2596b21783\",\n    \"0xb49f529975c09e436e6bc202fdc16e3fdcbe056db45178016ad6fdece9faad4446343e83aed096209690b21a6910724f\",\n    \"0x879e8eda589e1a279f7f49f6dd0580788c040d973748ec4942dbe51ea8fbd05983cc919b78f0c6b92ef3292ae29db875\",\n    \"0x81a2b74b2118923f34139a102f3d95e7eee11c4c2929c2576dee200a5abfd364606158535a6c9e4178a6a83dbb65f3c4\",\n    \"0x8913f281d8927f2b45fc815d0f7104631cb7f5f7278a316f1327d670d15868daadd2a64e3eb98e1f53fe7e300338cc80\",\n    \"0xa6f815fba7ef9af7fbf45f93bc952e8b351f5de6568a27c7c47a00cb39a254c6b31753794f67940fc7d2e9cc581529f4\",\n    \"0xb3722a15c66a0014ce4d082de118def8d39190c15678a472b846225585f3a83756ae1b255b2e3f86a26168878e4773b2\",\n    \"0x817ae61ab3d0dd5b6e24846b5a5364b1a7dc2e77432d9fed587727520ae2f307264ea0948c91ad29f0aea3a11ff38624\",\n    \"0xb3db467464415fcad36dc1de2d6ba7686772a577cc2619242ac040d6734881a45d3b40ed4588db124e4289cfeec4bbf6\",\n    \"0xad66a14f5a54ac69603b16e5f1529851183da77d3cc60867f10aea41339dd5e06a5257982e9e90a352cdd32750f42ee4\",\n    \"0xadafa3681ef45d685555601a25a55cf23358319a17f61e2179e704f63df83a73bdd298d12cf6cef86db89bd17119e11d\",\n    \"0xa379dc44cb6dd3b9d378c07b2ec654fec7ca2f272de6ba895e3d00d20c9e4c5550498a843c8ac67e4221db2115bedc1c\",\n    \"0xb7bf81c267a78efc6b9e5a904574445a6487678d7ef70054e3e93ea6a23f966c2b68787f9164918e3b16d2175459ed92\",\n    \"0xb41d66a13a4afafd5760062b77f79de7e6ab8ccacde9c6c5116a6d886912fb491dc027af435b1b44aacc6af7b3c887f2\",\n    \"0x9904d23a7c1c1d2e4bab85d69f283eb0a8e26d46e8b7b30224438015c936729b2f0af7c7c54c03509bb0500acb42d8a4\",\n    \"0xae30d65e9e20c3bfd603994ae2b175ff691d51f3e24b2d058b3b8556d12ca4c75087809062dddd4aaac81c94d15d8a17\",\n    \"0x9245162fab42ac01527424f6013310c3eb462982518debef6c127f46ba8a06c705d7dc9f0a41e796ba8d35d60ae6cc64\",\n    \"0x87fab853638d7a29a20f3ba2b1a7919d023e9415bfa78ebb27973d8cbc7626f584dc5665d2e7ad71f1d760eba9700d88\",\n    \"0x85aac46ecd330608e5272430970e6081ff02a571e8ea444f1e11785ea798769634a22a142d0237f67b75369d3c484a8a\",\n    \"0x938c85ab14894cc5dfce3d80456f189a2e98eddbc8828f4ff6b1df1dcb7b42b17ca2ff40226a8a1390a95d63dca698dd\",\n    \"0xa18ce1f846e3e3c4d846822f60271eecf0f5d7d9f986385ac53c5ace9589dc7c0188910448c19b91341a1ef556652fa9\",\n    \"0x8611608a9d844f0e9d7584ad6ccf62a5087a64f764caf108db648a776b5390feb51e5120f0ef0e9e11301af3987dd7dc\",\n    \"0x8106333ba4b4de8d1ae43bc9735d3fea047392e88efd6a2fa6f7b924a18a7a265ca6123c3edc0f36307dd7fb7fe89257\",\n    \"0xa91426fa500951ff1b051a248c050b7139ca30dde8768690432d597d2b3c4357b11a577be6b455a1c5d145264dcf81fc\",\n    \"0xb7f9f90e0e450f37b081297f7f651bad0496a8b9afd2a4cf4120a2671aaaa8536dce1af301258bfbfdb122afa44c5048\",\n    \"0x84126da6435699b0c09fa4032dec73d1fca21d2d19f5214e8b0bea43267e9a8dd1fc44f8132d8315e734c8e2e04d7291\",\n    \"0xaff064708103884cb4f1a3c1718b3fc40a238d35cf0a7dc24bdf9823693b407c70da50df585bf5bc4e9c07d1c2d203e8\",\n    \"0xa8b40fc6533752983a5329c31d376c7a5c13ce6879cc7faee648200075d9cd273537001fb4c86e8576350eaac6ba60c2\",\n    \"0xa02db682bdc117a84dcb9312eb28fcbde12d49f4ce915cc92c610bb6965ec3cc38290f8c5b5ec70afe153956692cda95\",\n    \"0x86decd22b25d300508472c9ce75d3e465b737e7ce13bc0fcce32835e54646fe12322ba5bc457be18bfd926a1a6ca4a38\",\n    \"0xa18666ef65b8c2904fd598791f5627207165315a85ee01d5fb0e6b2e10bdd9b00babc447da5bd63445e3337de33b9b89\",\n    \"0x89bb0c06effadefdaf34ffe4b123e1678a90d4451ee856c863df1e752eef41fd984689ded8f0f878bf8916d5dd8e8024\",\n    \"0x97cfcba08ebec05d0073992a66b1d7d6fb9d95871f2cdc36db301f78bf8069294d1c259efef5c93d20dc937eedae3a1a\",\n    \"0xac2643b14ece79dcb2e289c96776a47e2bebd40dd6dc74fd035df5bb727b5596f40e3dd2d2202141e69b0993717ede09\",\n    \"0xa5e6fd88a2f9174d9bd4c6a55d9c30974be414992f22aa852f552c7648f722ed8077acf5aba030abd47939bb451b2c60\",\n    \"0x8ad40a612824a7994487731a40b311b7349038c841145865539c6ada75c56de6ac547a1c23df190e0caaafecddd80ccc\",\n    \"0x953a7cea1d857e09202c438c6108060961f195f88c32f0e012236d7a4b39d840c61b162ec86436e8c38567328bea0246\",\n    \"0x80d8b47a46dae1868a7b8ccfe7029445bbe1009dad4a6c31f9ef081be32e8e1ac1178c3c8fb68d3e536c84990cc035b1\",\n    \"0x81ecd99f22b3766ce0aca08a0a9191793f68c754fdec78b82a4c3bdc2db122bbb9ebfd02fc2dcc6e1567a7d42d0cc16a\",\n    \"0xb1dd0446bccc25846fb95d08c1c9cc52fb51c72c4c5d169ffde56ecfe800f108dc1106d65d5c5bd1087c656de3940b63\",\n    \"0xb87547f0931e164e96de5c550ca5aa81273648fe34f6e193cd9d69cf729cb432e17aa02e25b1c27a8a0d20a3b795e94e\",\n    \"0x820a94e69a927e077082aae66f6b292cfbe4589d932edf9e68e268c9bd3d71ef76cf7d169dd445b93967c25db11f58f1\",\n    \"0xb0d07ddf2595270c39adfa0c8cf2ab1322979b0546aa4d918f641be53cd97f36c879bb75d205e457c011aca3bbd9f731\",\n    \"0x8700b876b35b4b10a8a9372c5230acecd39539c1bb87515640293ad4464a9e02929d7d6a6a11112e8a29564815ac0de4\",\n    \"0xa61a601c5bb27dcb97e37c8e2b9ce479c6b192a5e04d9ed5e065833c5a1017ee5f237b77d1a17be5d48f8e7cc0bcacf6\",\n    \"0x92fb88fe774c1ba1d4a08cae3c0e05467ad610e7a3f1d2423fd47751759235fe0a3036db4095bd6404716aa03820f484\",\n    \"0xb274f140d77a3ce0796f5e09094b516537ccaf27ae1907099bff172e6368ba85e7c3ef8ea2a07457cac48ae334da95b3\",\n    \"0xb2292d9181f16581a9a9142490b2bdcdfb218ca6315d1effc8592100d792eb89d5356996c890441f04f2b4a95763503e\",\n    \"0x8897e73f576d86bc354baa3bd96e553107c48cf5889dcc23c5ba68ab8bcd4e81f27767be2233fdfa13d39f885087e668\",\n    \"0xa29eac6f0829791c728d71abc49569df95a4446ecbfc534b39f24f56c88fe70301838dfc1c19751e7f3c5c1b8c6af6a0\",\n    \"0x9346dc3720adc5df500a8df27fd9c75ef38dc5c8f4e8ed66983304750e66d502c3c59b8e955be781b670a0afc70a2167\",\n    \"0x9566d534e0e30a5c5f1428665590617e95fd05d45f573715f58157854ad596ece3a3cfec61356aee342308d623e029d5\",\n    \"0xa464fb8bffe6bd65f71938c1715c6e296cc6d0311a83858e4e7eb5873b7f2cf0c584d2101e3407b85b64ca78b2ac93ce\",\n    \"0xb54088f7217987c87e9498a747569ac5b2f8afd5348f9c45bf3fd9fbf713a20f495f49c8572d087efe778ac7313ad6d3\",\n    \"0x91fa9f5f8000fe050f5b224d90b59fcce13c77e903cbf98ded752e5b3db16adb2bc1f8c94be48b69f65f1f1ad81d6264\",\n    \"0x92d04a5b0ac5d8c8e313709b432c9434ecd3e73231f01e9b4e7952b87df60cbfa97b5dedd2200bd033b4b9ea8ba45cc1\",\n    \"0xa94b90ad3c3d6c4bbe169f8661a790c40645b40f0a9d1c7220f01cf7fc176e04d80bab0ced9323fcafb93643f12b2760\",\n    \"0x94d86149b9c8443b46196f7e5a3738206dd6f3be7762df488bcbb9f9ee285a64c997ed875b7b16b26604fa59020a8199\",\n    \"0x82efe4ae2c50a2d7645240c173a047f238536598c04a2c0b69c96e96bd18e075a99110f1206bc213f39edca42ba00cc1\",\n    \"0xab8667685f831bc14d4610f84a5da27b4ea5b133b4d991741a9e64dceb22cb64a3ce8f1b6e101d52af6296df7127c9ad\",\n    \"0x83ba433661c05dcc5d562f4a9a261c8110dac44b8d833ae1514b1fc60d8b4ee395b18804baea04cb10adb428faf713c3\",\n    \"0xb5748f6f660cc5277f1211d2b8649493ed8a11085b871cd33a5aea630abd960a740f08c08be5f9c21574600ac9bf5737\",\n    \"0xa5c8dd12af48fb710642ad65ebb97ca489e8206741807f7acfc334f8035d3c80593b1ff2090c9bb7bd138f0c48714ca8\",\n    \"0xa2b382fd5744e3babf454b1d806cc8783efeb4761bc42b6914ea48a46a2eae835efbe0a18262b6bc034379e03cf1262b\",\n    \"0xb3145ffaf603f69f15a64936d32e3219eea5ed49fdfd2f5bf40ea0dfd974b36fb6ff12164d4c2282d892db4cf3ff3ce1\",\n    \"0x87a316fb213f4c5e30c5e3face049db66be4f28821bd96034714ec23d3e97849d7b301930f90a4323c7ccf53de23050c\",\n    \"0xb9de09a919455070fed6220fc179c8b7a4c753062bcd27acf28f5b9947a659c0b364298daf7c85c4ca6fca7f945add1f\",\n    \"0x806fbd98d411b76979464c40ad88bc07a151628a27fcc1012ba1dfbaf5b5cc9d962fb9b3386008978a12515edce934bc\",\n    \"0xa15268877fae0d21610ae6a31061ed7c20814723385955fac09fdc9693a94c33dea11db98bb89fdfe68f933490f5c381\",\n    \"0x8d633fb0c4da86b2e0b37d8fad5972d62bff2ac663c5ec815d095cd4b7e1fe66ebef2a2590995b57eaf941983c7ad7a4\",\n    \"0x8139e5dd9cf405e8ef65f11164f0440827d98389ce1b418b0c9628be983a9ddd6cf4863036ccb1483b40b8a527acd9ed\",\n    \"0x88b15fa94a08eac291d2b94a2b30eb851ff24addf2cc30b678e72e32cfcb3424cf4b33aa395d741803f3e578ddf524de\",\n    \"0xb5eaf0c8506e101f1646bcf049ee38d99ea1c60169730da893fd6020fd00a289eb2f415947e44677af49e43454a7b1be\",\n    \"0x8489822ad0647a7e06aa2aa5595960811858ddd4542acca419dd2308a8c5477648f4dd969a6740bb78aa26db9bfcc555\",\n    \"0xb1e9a7b9f3423c220330d45f69e45fa03d7671897cf077f913c252e3e99c7b1b1cf6d30caad65e4228d5d7b80eb86e5e\",\n    \"0xb28fe9629592b9e6a55a1406903be76250b1c50c65296c10c5e48c64b539fb08fe11f68cf462a6edcbba71b0cee3feb2\",\n    \"0xa41acf96a02c96cd8744ff6577c244fc923810d17ade133587e4c223beb7b4d99fa56eae311a500d7151979267d0895c\",\n    \"0x880798938fe4ba70721be90e666dfb62fcab4f3556fdb7b0dc8ec5bc34f6b4513df965eae78527136eb391889fe2caf9\",\n    \"0x98d4d89d358e0fb7e212498c73447d94a83c1b66e98fc81427ab13acddb17a20f52308983f3a5a8e0aaacec432359604\",\n    \"0x81430b6d2998fc78ba937a1639c6020199c52da499f68109da227882dc26d005b73d54c5bdcac1a04e8356a8ca0f7017\",\n    \"0xa8d906a4786455eb74613aba4ce1c963c60095ffb8658d368df9266fdd01e30269ce10bf984e7465f34b4fd83beba26a\",\n    \"0xaf54167ac1f954d10131d44a8e0045df00d581dd9e93596a28d157543fbe5fb25d213806ed7fb3cba6b8f5b5423562db\",\n    \"0x8511e373a978a12d81266b9afbd55035d7bc736835cfa921903a92969eeba3624437d1346b55382e61415726ab84a448\",\n    \"0x8cf43eea93508ae586fa9a0f1354a1e16af659782479c2040874a46317f9e8d572a23238efa318fdfb87cc63932602b7\",\n    \"0xb0bdd3bacff077173d302e3a9678d1d37936188c7ecc34950185af6b462b7c679815176f3cce5db19aac8b282f2d60ad\",\n    \"0xa355e9b87f2f2672052f5d4d65b8c1c827d24d89b0d8594641fccfb69aef1b94009105f3242058bb31c8bf51caae5a41\",\n    \"0xb8baa9e4b950b72ff6b88a6509e8ed1304bc6fd955748b2e59a523a1e0c5e99f52aec3da7fa9ff407a7adf259652466c\",\n    \"0x840bc3dbb300ea6f27d1d6dd861f15680bd098be5174f45d6b75b094d0635aced539fa03ddbccb453879de77fb5d1fe9\",\n    \"0xb4bc7e7e30686303856472bae07e581a0c0bfc815657c479f9f5931cff208d5c12930d2fd1ff413ebd8424bcd7a9b571\",\n    \"0x89b5d514155d7999408334a50822508b9d689add55d44a240ff2bdde2eee419d117031f85e924e2a2c1ca77db9b91eea\",\n    \"0xa8604b6196f87a04e1350302e8aa745bba8dc162115d22657b37a1d1a98cb14876ddf7f65840b5dbd77e80cd22b4256c\",\n    \"0x83cb7acdb9e03247515bb2ce0227486ccf803426717a14510f0d59d45e998b245797d356f10abca94f7a14e1a2f0d552\",\n    \"0xaeb3266a9f16649210ab2df0e1908ac259f34ce1f01162c22b56cf1019096ee4ea5854c36e30bb2feb06c21a71e8a45c\",\n    \"0x89e72e86edf2aa032a0fc9acf4d876a40865fbb2c8f87cb7e4d88856295c4ac14583e874142fd0c314a49aba68c0aa3c\",\n    \"0x8c3576eba0583c2a7884976b4ed11fe1fda4f6c32f6385d96c47b0e776afa287503b397fa516a455b4b8c3afeedc76db\",\n    \"0xa31e5b633bda9ffa174654fee98b5d5930a691c3c42fcf55673d927dbc8d91c58c4e42e615353145431baa646e8bbb30\",\n    \"0x89f2f3f7a8da1544f24682f41c68114a8f78c86bd36b066e27da13acb70f18d9f548773a16bd8e24789420e17183f137\",\n    \"0xada27fa4e90a086240c9164544d2528621a415a5497badb79f8019dc3dce4d12eb6b599597e47ec6ac39c81efda43520\",\n    \"0x90dc1eb21bf21c0187f359566fc4bf5386abea52799306a0e5a1151c0817c5f5bc60c86e76b1929c092c0f3ff48cedd2\",\n    \"0xb702a53ebcc17ae35d2e735a347d2c700e9cbef8eadbece33cac83df483b2054c126593e1f462cfc00a3ce9d737e2af5\",\n    \"0x9891b06455ec925a6f8eafffba05af6a38cc5e193acaaf74ffbf199df912c5197106c5e06d72942bbb032ce277b6417f\",\n    \"0x8c0ee71eb01197b019275bcf96cae94e81d2cdc3115dbf2d8e3080074260318bc9303597e8f72b18f965ad601d31ec43\",\n    \"0x8aaf580aaf75c1b7a5f99ccf60503506e62058ef43b28b02f79b8536a96be3f019c9f71caf327b4e6730134730d1bef5\",\n    \"0xae6f9fc21dd7dfa672b25a87eb0a41644f7609fab5026d5cedb6e43a06dbbfd6d6e30322a2598c8dedde88c52eaed626\",\n    \"0x8159b953ffece5693edadb2e906ebf76ff080ee1ad22698950d2d3bfc36ac5ea78f58284b2ca180664452d55bd54716c\",\n    \"0xab7647c32ca5e9856ac283a2f86768d68de75ceeba9e58b74c5324f8298319e52183739aba4340be901699d66ac9eb3f\",\n    \"0xa4d85a5701d89bcfaf1572db83258d86a1a0717603d6f24ac2963ffcf80f1265e5ab376a4529ca504f4396498791253c\",\n    \"0x816080c0cdbfe61b4d726c305747a9eb58ac26d9a35f501dd32ba43c098082d20faf3ccd41aad24600aa73bfa453dfac\",\n    \"0x84f3afac024f576b0fd9acc6f2349c2fcefc3f77dbe5a2d4964d14b861b88e9b1810334b908cf3427d9b67a8aee74b18\",\n    \"0x94b390655557b1a09110018e9b5a14490681ade275bdc83510b6465a1218465260d9a7e2a6e4ec700f58c31dc3659962\",\n    \"0xa8c66826b1c04a2dd4c682543242e7a57acae37278bd09888a3d17747c5b5fec43548101e6f46d703638337e2fd3277b\",\n    \"0x86e6f4608a00007fa533c36a5b054c5768ccafe41ad52521d772dcae4c8a4bcaff8f7609be30d8fab62c5988cbbb6830\",\n    \"0x837da4cf09ae8aa0bceb16f8b3bfcc3b3367aecac9eed6b4b56d7b65f55981ef066490764fb4c108792623ecf8cad383\",\n    \"0x941ff3011462f9b5bf97d8cbdb0b6f5d37a1b1295b622f5485b7d69f2cb2bcabc83630dae427f0259d0d9539a77d8424\",\n    \"0xb99e5d6d82aa9cf7d5970e7f710f4039ac32c2077530e4c2779250c6b9b373bc380adb0a03b892b652f649720672fc8c\",\n    \"0xa791c78464b2d65a15440b699e1e30ebd08501d6f2720adbc8255d989a82fcded2f79819b5f8f201bed84a255211b141\",\n    \"0x84af7ad4a0e31fcbb3276ab1ad6171429cf39adcf78dc03750dc5deaa46536d15591e26d53e953dfb31e1622bc0743ab\",\n    \"0xa833e62fe97e1086fae1d4917fbaf09c345feb6bf1975b5cb863d8b66e8d621c7989ab3dbecda36bc9eaffc5eaa6fa66\",\n    \"0xb4ef79a46a2126f53e2ebe62770feb57fd94600be29459d70a77c5e9cc260fa892be06cd60f886bf48459e48eb50d063\",\n    \"0xb43b8f61919ea380bf151c294e54d3a3ff98e20d1ee5efbfe38aa2b66fafbc6a49739793bd5cb1c809f8b30466277c3a\",\n    \"0xab37735af2412d2550e62df9d8b3b5e6f467f20de3890bf56faf1abf2bf3bd1d98dc3fa0ad5e7ab3fce0fa20409eb392\",\n    \"0x82416b74b1551d484250d85bb151fabb67e29cce93d516125533df585bc80779ab057ea6992801a3d7d5c6dcff87a018\",\n    \"0x8145d0787f0e3b5325190ae10c1d6bee713e6765fb6a0e9214132c6f78f4582bb2771aaeae40d3dad4bafb56bf7e36d8\",\n    \"0xb6935886349ecbdd5774e12196f4275c97ec8279fdf28ccf940f6a022ebb6de8e97d6d2173c3fe402cbe9643bed3883b\",\n    \"0x87ef9b4d3dc71ac86369f8ed17e0dd3b91d16d14ae694bc21a35b5ae37211b043d0e36d8ff07dcc513fb9e6481a1f37f\",\n    \"0xae1d0ded32f7e6f1dc8fef495879c1d9e01826f449f903c1e5034aeeabc5479a9e323b162b688317d46d35a42d570d86\",\n    \"0xa40d16497004db4104c6794e2f4428d75bdf70352685944f3fbe17526df333e46a4ca6de55a4a48c02ecf0bde8ba03c0\",\n    \"0x8d45121efba8cc308a498e8ee39ea6fa5cae9fb2e4aab1c2ff9d448aa8494ccbec9a078f978a86fcd97b5d5e7be7522a\",\n    \"0xa8173865c64634ba4ac2fa432740f5c05056a9deaf6427cb9b4b8da94ca5ddbc8c0c5d3185a89b8b28878194de9cdfcd\",\n    \"0xb6ec06a74d690f6545f0f0efba236e63d1fdfba54639ca2617408e185177ece28901c457d02b849fd00f1a53ae319d0a\",\n    \"0xb69a12df293c014a40070e3e760169b6f3c627caf9e50b35a93f11ecf8df98b2bc481b410eecb7ab210bf213bbe944de\",\n    \"0x97e7dc121795a533d4224803e591eef3e9008bab16f12472210b73aaf77890cf6e3877e0139403a0d3003c12c8f45636\",\n    \"0xacdfa6fdd4a5acb7738cc8768f7cba84dbb95c639399b291ae8e4e63df37d2d4096900a84d2f0606bf534a9ccaa4993f\",\n    \"0x86ee253f3a9446a33e4d1169719b7d513c6b50730988415382faaf751988c10a421020609f7bcdef91be136704b906e2\",\n    \"0xaac9438382a856caf84c5a8a234282f71b5fc5f65219103b147e7e6cf565522285fbfd7417b513bdad8277a00f652ca1\",\n    \"0x83f3799d8e5772527930f5dc071a2e0a65471618993ec8990a96ccdeee65270e490bda9d26bb877612475268711ffd80\",\n    \"0x93f28a81ac8c0ec9450b9d762fae9c7f8feaace87a6ee6bd141ef1d2d0697ef1bbd159fe6e1de640dbdab2b0361fca8a\",\n    \"0xa0825c95ba69999b90eac3a31a3fd830ea4f4b2b7409bde5f202b61d741d6326852ce790f41de5cb0eccec7af4db30c1\",\n    \"0x83924b0e66233edd603c3b813d698daa05751fc34367120e3cf384ea7432e256ccee4d4daf13858950549d75a377107d\",\n    \"0x956fd9fa58345277e06ba2ec72f49ed230b8d3d4ff658555c52d6cddeb84dd4e36f1a614f5242d5ca0192e8daf0543c2\",\n    \"0x944869912476baae0b114cced4ff65c0e4c90136f73ece5656460626599051b78802df67d7201c55d52725a97f5f29fe\",\n    \"0x865cb25b64b4531fb6fe4814d7c8cd26b017a6c6b72232ff53defc18a80fe3b39511b23f9e4c6c7249d06e03b2282ed2\",\n    \"0x81e09ff55214960775e1e7f2758b9a6c4e4cd39edf7ec1adfaad51c52141182b79fe2176b23ddc7df9fd153e5f82d668\",\n    \"0xb31006896f02bc90641121083f43c3172b1039334501fbaf1672f7bf5d174ddd185f945adf1a9c6cf77be34c5501483d\",\n    \"0x88b92f6f42ae45e9f05b16e52852826e933efd0c68b0f2418ac90957fd018df661bc47c8d43c2a7d7bfcf669dab98c3c\",\n    \"0x92fc68f595853ee8683930751789b799f397135d002eda244fe63ecef2754e15849edde3ba2f0cc8b865c9777230b712\",\n    \"0x99ca06a49c5cd0bb097c447793fcdd809869b216a34c66c78c7e41e8c22f05d09168d46b8b1f3390db9452d91bc96dea\",\n    \"0xb48b9490a5d65296802431852d548d81047bbefc74fa7dc1d4e2a2878faacdfcb365ae59209cb0ade01901a283cbd15d\",\n    \"0xaff0fdbef7c188b120a02bc9085d7b808e88f73973773fef54707bf2cd772cd066740b1b6f4127b5c349f657bd97e738\",\n    \"0x966fd4463b4f43dd8ccba7ad50baa42292f9f8b2e70da23bb6780e14155d9346e275ef03ddaf79e47020dcf43f3738bd\",\n    \"0x9330c3e1fadd9e08ac85f4839121ae20bbeb0a5103d84fa5aadbd1213805bdcda67bf2fb75fc301349cbc851b5559d20\",\n    \"0x993bb99867bd9041a71a55ad5d397755cfa7ab6a4618fc526179bfc10b7dc8b26e4372fe9a9b4a15d64f2b63c1052dda\",\n    \"0xa29b59bcfab51f9b3c490a3b96f0bf1934265c315349b236012adbd64a56d7f6941b2c8cc272b412044bc7731f71e1dc\",\n    \"0xa65c9cefe1fc35d089fe8580c2e7671ebefdb43014ac291528ff4deefd4883fd4df274af83711dad610dad0d615f9d65\",\n    \"0x944c78c56fb227ae632805d448ca3884cd3d2a89181cead3d2b7835e63297e6d740aa79a112edb1d4727824991636df5\",\n    \"0xa73d782da1db7e4e65d7b26717a76e16dd9fab4df65063310b8e917dc0bc24e0d6755df5546c58504d04d9e68c3b474a\",\n    \"0xaf80f0b87811ae3124f68108b4ca1937009403f87928bbc53480e7c5408d072053ace5eeaf5a5aba814dab8a45502085\",\n    \"0x88aaf1acfc6e2e19b8387c97da707cb171c69812fefdd4650468e9b2c627bd5ccfb459f4d8e56bdfd84b09ddf87e128f\",\n    \"0x92c97276ff6f72bab6e9423d02ad6dc127962dbce15a0dd1e4a393b4510c555df6aa27be0f697c0d847033a9ca8b8dfd\",\n    \"0xa0e07d43d96e2d85b6276b3c60aadb48f0aedf2de8c415756dc597249ea64d2093731d8735231dadc961e5682ac59479\",\n    \"0xadc9e6718a8f9298957d1da3842a7751c5399bbdf56f8de6c1c4bc39428f4aee6f1ba6613d37bf46b9403345e9d6fc81\",\n    \"0x951da434da4b20d949b509ceeba02e24da7ed2da964c2fcdf426ec787779c696b385822c7dbea4df3e4a35921f1e912c\",\n    \"0xa04cbce0d2b2e87bbf038c798a12ec828423ca6aca08dc8d481cf6466e3c9c73d4d4a7fa47df9a7e2e15aae9e9f67208\",\n    \"0x8f855cca2e440d248121c0469de1f94c2a71b8ee2682bbad3a78243a9e03da31d1925e6760dbc48a1957e040fae9abe8\",\n    \"0xb642e5b17c1df4a4e101772d73851180b3a92e9e8b26c918050f51e6dd3592f102d20b0a1e96f0e25752c292f4c903ff\",\n    \"0xa92454c300781f8ae1766dbbb50a96192da7d48ef4cbdd72dd8cbb44c6eb5913c112cc38e9144615fdc03684deb99420\",\n    \"0x8b74f7e6c2304f8e780df4649ef8221795dfe85fdbdaa477a1542d135b75c8be45bf89adbbb6f3ddf54ca40f02e733e9\",\n    \"0x85cf66292cbb30cec5fd835ab10c9fcb3aea95e093aebf123e9a83c26f322d76ebc89c4e914524f6c5f6ee7d74fc917d\",\n    \"0xae0bfe0cdc97c09542a7431820015f2d16067b30dca56288013876025e81daa8c519e5e347268e19aa1a85fa1dc28793\",\n    \"0x921322fc6a47dc091afa0ad6df18ed14cde38e48c6e71550aa513918b056044983aee402de21051235eecf4ce8040fbe\",\n    \"0x96c030381e97050a45a318d307dcb3c8377b79b4dd5daf6337cded114de26eb725c14171b9b8e1b3c08fe1f5ea6b49e0\",\n    \"0x90c23b86b6111818c8baaf53a13eaee1c89203b50e7f9a994bf0edf851919b48edbac7ceef14ac9414cf70c486174a77\",\n    \"0x8bf6c301240d2d1c8d84c71d33a6dfc6d9e8f1cfae66d4d0f7a256d98ae12b0bcebfa94a667735ee89f810bcd7170cff\",\n    \"0xa41a4ffbbea0e36874d65c009ee4c3feffff322f6fc0e30d26ee4dbc1f46040d05e25d9d0ecb378cef0d24a7c2c4b850\",\n    \"0xa8d4cdd423986bb392a0a92c12a8bd4da3437eec6ef6af34cf5310944899287452a2eb92eb5386086d5063381189d10e\",\n    \"0xa81dd26ec057c4032a4ed7ad54d926165273ed51d09a1267b2e477535cf6966835a257c209e4e92d165d74fa75695fa3\",\n    \"0x8d7f708c3ee8449515d94fc26b547303b53d8dd55f177bc3b25d3da2768accd9bc8e9f09546090ebb7f15c66e6c9c723\",\n    \"0x839ba65cffcd24cfffa7ab3b21faabe3c66d4c06324f07b2729c92f15cad34e474b0f0ddb16cd652870b26a756b731d3\",\n    \"0x87f1a3968afec354d92d77e2726b702847c6afcabb8438634f9c6f7766de4c1504317dc4fa9a4a735acdbf985e119564\",\n    \"0x91a8a7fd6542f3e0673f07f510d850864b34ac087eb7eef8845a1d14b2b1b651cbdc27fa4049bdbf3fea54221c5c8549\",\n    \"0xaef3cf5f5e3a2385ead115728d7059e622146c3457d266c612e778324b6e06fbfb8f98e076624d2f3ce1035d65389a07\",\n    \"0x819915d6232e95ccd7693fdd78d00492299b1983bc8f96a08dcb50f9c0a813ed93ae53c0238345d5bea0beda2855a913\",\n    \"0x8e9ba68ded0e94935131b392b28218315a185f63bf5e3c1a9a9dd470944509ca0ba8f6122265f8da851b5cc2abce68f1\",\n    \"0xb28468e9b04ee9d69003399a3cf4457c9bf9d59f36ab6ceeb8e964672433d06b58beeea198fedc7edbaa1948577e9fa2\",\n    \"0xa633005e2c9f2fd94c8bce2dd5bb708fe946b25f1ec561ae65e54e15cdd88dc339f1a083e01f0d39610c8fe24151aaf0\",\n    \"0x841d0031e22723f9328dd993805abd13e0c99b0f59435d2426246996b08d00ce73ab906f66c4eab423473b409e972ce0\",\n    \"0x85758d1b084263992070ec8943f33073a2d9b86a8606672550c17545507a5b3c88d87382b41916a87ee96ff55a7aa535\",\n    \"0x8581b06b0fc41466ef94a76a1d9fb8ae0edca6d018063acf6a8ca5f4b02d76021902feba58972415691b4bdbc33ae3b4\",\n    \"0x83539597ff5e327357ee62bc6bf8c0bcaec2f227c55c7c385a4806f0d37fb461f1690bad5066b8a5370950af32fafbef\",\n    \"0xaee3557290d2dc10827e4791d00e0259006911f3f3fce4179ed3c514b779160613eca70f720bff7804752715a1266ffa\",\n    \"0xb48d2f0c4e90fc307d5995464e3f611a9b0ef5fe426a289071f4168ed5cc4f8770c9332960c2ca5c8c427f40e6bb389f\",\n    \"0x847af8973b4e300bb06be69b71b96183fd1a0b9d51b91701bef6fcfde465068f1eb2b1503b07afda380f18d69de5c9e1\",\n    \"0xa70a6a80ce407f07804c0051ac21dc24d794b387be94eb24e1db94b58a78e1bcfb48cd0006db8fc1f9bedaece7a44fbe\",\n    \"0xb40e942b8fa5336910ff0098347df716bff9d1fa236a1950c16eeb966b3bc1a50b8f7b0980469d42e75ae13ced53cead\",\n    \"0xb208fabaa742d7db3148515330eb7a3577487845abdb7bd9ed169d0e081db0a5816595c33d375e56aeac5b51e60e49d3\",\n    \"0xb7c8194b30d3d6ef5ab66ec88ad7ebbc732a3b8a41731b153e6f63759a93f3f4a537eab9ad369705bd730184bdbbdc34\",\n    \"0x9280096445fe7394d04aa1bc4620c8f9296e991cc4d6c131bd703cb1cc317510e6e5855ac763f4d958c5edfe7eebeed7\",\n    \"0xabc2aa4616a521400af1a12440dc544e3c821313d0ab936c86af28468ef8bbe534837e364598396a81cf8d06274ed5a6\",\n    \"0xb18ca8a3325adb0c8c18a666d4859535397a1c3fe08f95eebfac916a7a99bbd40b3c37b919e8a8ae91da38bc00fa56c0\",\n    \"0x8a40c33109ecea2a8b3558565877082f79121a432c45ec2c5a5e0ec4d1c203a6788e6b69cb37f1fd5b8c9a661bc5476d\",\n    \"0x88c47301dd30998e903c84e0b0f2c9af2e1ce6b9f187dab03528d44f834dc991e4c86d0c474a2c63468cf4020a1e24a0\",\n    \"0x920c832853e6ab4c851eecfa9c11d3acc7da37c823be7aa1ab15e14dfd8beb5d0b91d62a30cec94763bd8e4594b66600\",\n    \"0x98e1addbe2a6b8edc7f12ecb9be81c3250aeeca54a1c6a7225772ca66549827c15f3950d01b8eb44aecb56fe0fff901a\",\n    \"0x8cfb0fa1068be0ec088402f5950c4679a2eb9218c729da67050b0d1b2d7079f3ddf4bf0f57d95fe2a8db04bc6bcdb20c\",\n    \"0xb70f381aafe336b024120453813aeab70baac85b9c4c0f86918797b6aee206e6ed93244a49950f3d8ec9f81f4ac15808\",\n    \"0xa4c8edf4aa33b709a91e1062939512419711c1757084e46f8f4b7ed64f8e682f4e78b7135920c12f0eb0422fe9f87a6a\",\n    \"0xb4817e85fd0752d7ebb662d3a51a03367a84bac74ebddfba0e5af5e636a979500f72b148052d333b3dedf9edd2b4031b\",\n    \"0xa87430169c6195f5d3e314ff2d1c2f050e766fd5d2de88f5207d72dba4a7745bb86d0baca6e9ae156582d0d89e5838c7\",\n    \"0x991b00f8b104566b63a12af4826b61ce7aa40f4e5b8fff3085e7a99815bdb4471b6214da1e480214fac83f86a0b93cc5\",\n    \"0xb39966e3076482079de0678477df98578377a094054960ee518ef99504d6851f8bcd3203e8da5e1d4f6f96776e1fe6eb\",\n    \"0xa448846d9dc2ab7a0995fa44b8527e27f6b3b74c6e03e95edb64e6baa4f1b866103f0addb97c84bef1d72487b2e21796\",\n    \"0x894bec21a453ae84b592286e696c35bc30e820e9c2fd3e63dd4fbe629e07df16439c891056070faa490155f255bf7187\",\n    \"0xa9ec652a491b11f6a692064e955f3f3287e7d2764527e58938571469a1e29b5225b9415bd602a45074dfbfe9c131d6ca\",\n    \"0xb39d37822e6cbe28244b5f42ce467c65a23765bd16eb6447c5b3e942278069793763483dafd8c4dd864f8917aad357fe\",\n    \"0x88dba51133f2019cb266641c56101e3e5987d3b77647a2e608b5ff9113dfc5f85e2b7c365118723131fbc0c9ca833c9c\",\n    \"0xb566579d904b54ecf798018efcb824dccbebfc6753a0fd2128ac3b4bd3b038c2284a7c782b5ca6f310eb7ea4d26a3f0a\",\n    \"0xa97a55c0a492e53c047e7d6f9d5f3e86fb96f3dddc68389c0561515343b66b4bc02a9c0d5722dff1e3445308240b27f7\",\n    \"0xa044028ab4bcb9e1a2b9b4ca4efbf04c5da9e4bf2fff0e8bd57aa1fc12a71e897999c25d9117413faf2f45395dee0f13\",\n    \"0xa78dc461decbeaeed8ebd0909369b491a5e764d6a5645a7dac61d3140d7dc0062526f777b0eb866bff27608429ebbdde\",\n    \"0xb2c2a8991f94c39ca35fea59f01a92cb3393e0eccb2476dfbf57261d406a68bd34a6cff33ed80209991688c183609ef4\",\n    \"0x84189eefb521aff730a4fd3fd5b10ddfd29f0d365664caef63bb015d07e689989e54c33c2141dd64427805d37a7e546e\",\n    \"0x85ac80bd734a52235da288ff042dea9a62e085928954e8eacd2c751013f61904ed110e5b3afe1ab770a7e6485efb7b5e\",\n    \"0x9183a560393dcb22d0d5063e71182020d0fbabb39e32493eeffeb808df084aa243eb397027f150b55a247d1ed0c8513e\",\n    \"0x81c940944df7ecc58d3c43c34996852c3c7915ed185d7654627f7af62abae7e0048dd444a6c09961756455000bd96d09\",\n    \"0xaa8c34e164019743fd8284b84f06c3b449aae7996e892f419ee55d82ad548cb300fd651de329da0384243954c0ef6a60\",\n    \"0x89a7b7bdfc7e300d06a14d463e573d6296d8e66197491900cc9ae49504c4809ff6e61b758579e9091c61085ba1237b83\",\n    \"0x878d21809ba540f50bd11f4c4d9590fb6f3ab9de5692606e6e2ef4ed9d18520119e385be5e1f4b3f2e2b09c319f0e8fc\",\n    \"0x8eb248390193189cf0355365e630b782cd15751e672dc478b39d75dc681234dcd9309df0d11f4610dbb249c1e6be7ef9\",\n    \"0xa1d7fb3aecb896df3a52d6bd0943838b13f1bd039c936d76d03de2044c371d48865694b6f532393b27fd10a4cf642061\",\n    \"0xa34bca58a24979be442238cbb5ece5bee51ae8c0794dd3efb3983d4db713bc6f28a96e976ac3bd9a551d3ed9ba6b3e22\",\n    \"0x817c608fc8cacdd178665320b5a7587ca21df8bdd761833c3018b967575d25e3951cf3d498a63619a3cd2ad4406f5f28\",\n    \"0x86c95707db0495689afd0c2e39e97f445f7ca0edffad5c8b4cacd1421f2f3cc55049dfd504f728f91534e20383955582\",\n    \"0x99c3b0bb15942c301137765d4e19502f65806f3b126dc01a5b7820c87e8979bce6a37289a8f6a4c1e4637227ad5bf3bf\",\n    \"0x8aa1518a80ea8b074505a9b3f96829f5d4afa55a30efe7b4de4e5dbf666897fdd2cf31728ca45921e21a78a80f0e0f10\",\n    \"0x8d74f46361c79e15128ac399e958a91067ef4cec8983408775a87eca1eed5b7dcbf0ddf30e66f51780457413496c7f07\",\n    \"0xa41cde4a786b55387458a1db95171aca4fd146507b81c4da1e6d6e495527c3ec83fc42fad1dfe3d92744084a664fd431\",\n    \"0x8c352852c906fae99413a84ad11701f93f292fbf7bd14738814f4c4ceab32db02feb5eb70bc73898b0bc724a39d5d017\",\n    \"0xa5993046e8f23b71ba87b7caa7ace2d9023fb48ce4c51838813174880d918e9b4d2b0dc21a2b9c6f612338c31a289df8\",\n    \"0x83576d3324bf2d8afbfb6eaecdc5d767c8e22e7d25160414924f0645491df60541948a05e1f4202e612368e78675de8a\",\n    \"0xb43749b8df4b15bc9a3697e0f1c518e6b04114171739ef1a0c9c65185d8ec18e40e6954d125cbc14ebc652cf41ad3109\",\n    \"0xb4eebd5d80a7327a040cafb9ccdb12b2dfe1aa86e6bc6d3ac8a57fadfb95a5b1a7332c66318ff72ba459f525668af056\",\n    \"0x9198be7f1d413c5029b0e1c617bcbc082d21abe2c60ec8ce9b54ca1a85d3dba637b72fda39dae0c0ae40d047eab9f55a\",\n    \"0x8d96a0232832e24d45092653e781e7a9c9520766c3989e67bbe86b3a820c4bf621ea911e7cd5270a4bfea78b618411f6\",\n    \"0x8d7160d0ea98161a2d14d46ef01dff72d566c330cd4fabd27654d300e1bc7644c68dc8eabf2a20a59bfe7ba276545f9b\",\n    \"0xabb60fce29dec7ba37e3056e412e0ec3e05538a1fc0e2c68877378c867605966108bc5742585ab6a405ce0c962b285b6\",\n    \"0x8fabffa3ed792f05e414f5839386f6449fd9f7b41a47595c5d71074bd1bb3784cc7a1a7e1ad6b041b455035957e5b2dc\",\n    \"0x90ff017b4804c2d0533b72461436b10603ab13a55f86fd4ec11b06a70ef8166f958c110519ca1b4cc7beba440729fe2d\",\n    \"0xb340cfd120f6a4623e3a74cf8c32bfd7cd61a280b59dfd17b15ca8fae4d82f64a6f15fbde4c02f424debc72b7db5fe67\",\n    \"0x871311c9c7220c932e738d59f0ecc67a34356d1429fe570ca503d340c9996cb5ee2cd188fad0e3bd16e4c468ec1dbebd\",\n    \"0xa772470262186e7b94239ba921b29f2412c148d6f97c4412e96d21e55f3be73f992f1ad53c71008f0558ec3f84e2b5a7\",\n    \"0xb2a897dcb7ffd6257f3f2947ec966f2077d57d5191a88840b1d4f67effebe8c436641be85524d0a21be734c63ab5965d\",\n    \"0xa044f6eacc48a4a061fa149500d96b48cbf14853469aa4d045faf3dca973be1bd4b4ce01646d83e2f24f7c486d03205d\",\n    \"0x981af5dc2daa73f7fa9eae35a93d81eb6edba4a7f673b55d41f6ecd87a37685d31bb40ef4f1c469b3d72f2f18b925a17\",\n    \"0x912d2597a07864de9020ac77083eff2f15ceb07600f15755aba61251e8ce3c905a758453b417f04d9c38db040954eb65\",\n    \"0x9642b7f6f09394ba5e0805734ef6702c3eddf9eea187ba98c676d5bbaec0e360e3e51dc58433aaa1e2da6060c8659cb7\",\n    \"0x8ab3836e0a8ac492d5e707d056310c4c8e0489ca85eb771bff35ba1d658360084e836a6f51bb990f9e3d2d9aeb18fbb5\",\n    \"0x879e058e72b73bb1f4642c21ffdb90544b846868139c6511f299aafe59c2d0f0b944dffc7990491b7c4edcd6a9889250\",\n    \"0xb9e60b737023f61479a4a8fd253ed0d2a944ea6ba0439bbc0a0d3abf09b0ad1f18d75555e4a50405470ae4990626f390\",\n    \"0xb9c2535d362796dcd673640a9fa2ebdaec274e6f8b850b023153b0a7a30fffc87f96e0b72696f647ebe7ab63099a6963\",\n    \"0x94aeff145386a087b0e91e68a84a5ede01f978f9dd9fe7bebca78941938469495dc30a96bba9508c0d017873aeea9610\",\n    \"0x98b179f8a3d9f0d0a983c30682dd425a2ddc7803be59bd626c623c8951a5179117d1d2a68254c95c9952989877d0ee55\",\n    \"0x889ecf5f0ee56938273f74eb3e9ecfb5617f04fb58e83fe4c0e4aef51615cf345bc56f3f61b17f6eed3249d4afd54451\",\n    \"0xa0f2b2c39bcea4b50883e2587d16559e246248a66ecb4a4b7d9ab3b51fb39fe98d83765e087eee37a0f86b0ba4144c02\",\n    \"0xb2a61e247ed595e8a3830f7973b07079cbda510f28ad8c78c220b26cb6acde4fbb5ee90c14a665f329168ee951b08cf0\",\n    \"0x95bd0fcfb42f0d6d8a8e73d7458498a85bcddd2fb132fd7989265648d82ac2707d6d203fac045504977af4f0a2aca4b7\",\n    \"0x843e5a537c298666e6cf50fcc044f13506499ef83c802e719ff2c90e85003c132024e04711be7234c04d4b0125512d5d\",\n    \"0xa46d1797c5959dcd3a5cfc857488f4d96f74277c3d13b98b133620192f79944abcb3a361d939a100187f1b0856eae875\",\n    \"0xa1c7786736d6707a48515c38660615fcec67eb8a2598f46657855215f804fd72ab122d17f94fcffad8893f3be658dca7\",\n    \"0xb23dc9e610abc7d8bd21d147e22509a0fa49db5be6ea7057b51aae38e31654b3aa044df05b94b718153361371ba2f622\",\n    \"0xb00cc8f257d659c22d30e6d641f79166b1e752ea8606f558e4cad6fc01532e8319ea4ee12265ba4140ac45aa4613c004\",\n    \"0xac7019af65221b0cc736287b32d7f1a3561405715ba9a6a122342e04e51637ba911c41573de53e4781f2230fdcb2475f\",\n    \"0x81a630bc41b3da8b3eb4bf56cba10cd9f93153c3667f009dc332287baeb707d505fb537e6233c8e53d299ec0f013290c\",\n    \"0xa6b7aea5c545bb76df0f230548539db92bc26642572cb7dd3d5a30edca2b4c386f44fc8466f056b42de2a452b81aff5b\",\n    \"0x8271624ff736b7b238e43943c81de80a1612207d32036d820c11fc830c737972ccc9c60d3c2359922b06652311e3c994\",\n    \"0x8a684106458cb6f4db478170b9ad595d4b54c18bf63b9058f095a2fa1b928c15101472c70c648873d5887880059ed402\",\n    \"0xa5cc3c35228122f410184e4326cf61a37637206e589fcd245cb5d0cec91031f8f7586b80503070840fdfd8ce75d3c88b\",\n    \"0x9443fc631aed8866a7ed220890911057a1f56b0afe0ba15f0a0e295ab97f604b134b1ed9a4245e46ee5f9a93aa74f731\",\n    \"0x984b6f7d79835dffde9558c6bb912d992ca1180a2361757bdba4a7b69dc74b056e303adc69fe67414495dd9c2dd91e64\",\n    \"0xb15a5c8cba5de080224c274d31c68ed72d2a7126d347796569aef0c4e97ed084afe3da4d4b590b9dda1a07f0c2ff3dfb\",\n    \"0x991708fe9650a1f9a4e43938b91d45dc68c230e05ee999c95dbff3bf79b1c1b2bb0e7977de454237c355a73b8438b1d9\",\n    \"0xb4f7edc7468b176a4a7c0273700c444fa95c726af6697028bed4f77eee887e3400f9c42ee15b782c0ca861c4c3b8c98a\",\n    \"0x8c60dcc16c51087eb477c13e837031d6c6a3dc2b8bf8cb43c23f48006bc7173151807e866ead2234b460c2de93b31956\",\n    \"0x83ad63e9c910d1fc44bc114accfb0d4d333b7ebe032f73f62d25d3e172c029d5e34a1c9d547273bf6c0fead5c8801007\",\n    \"0x85de73213cc236f00777560756bdbf2b16841ba4b55902cf2cad9742ecaf5d28209b012ceb41f337456dfeca93010cd7\",\n    \"0xa7561f8827ccd75b6686ba5398bb8fc3083351c55a589b18984e186820af7e275af04bcd4c28e1dc11be1e8617a0610b\",\n    \"0x88c0a4febd4068850557f497ea888035c7fc9f404f6cc7794e7cc8722f048ad2f249e7dc62743e7a339eb7473ad3b0cd\",\n    \"0x932b22b1d3e6d5a6409c34980d176feb85ada1bf94332ef5c9fc4d42b907dabea608ceef9b5595ef3feee195151f18d8\",\n    \"0xa2867bb3f5ab88fbdae3a16c9143ab8a8f4f476a2643c505bb9f37e5b1fd34d216cab2204c9a017a5a67b7ad2dda10e8\",\n    \"0xb573d5f38e4e9e8a3a6fd82f0880dc049efa492a946d00283019bf1d5e5516464cf87039e80aef667cb86fdea5075904\",\n    \"0xb948f1b5ab755f3f5f36af27d94f503b070696d793b1240c1bdfd2e8e56890d69e6904688b5f8ff5a4bdf5a6abfe195f\",\n    \"0x917eae95ebc4109a2e99ddd8fec7881d2f7aaa0e25fda44dec7ce37458c2ee832f1829db7d2dcfa4ca0f06381c7fe91d\",\n    \"0x95751d17ed00a3030bce909333799bb7f4ab641acf585807f355b51d6976dceee410798026a1a004ef4dcdff7ec0f5b8\",\n    \"0xb9b7bd266f449a79bbfe075e429613e76c5a42ac61f01c8f0bbbd34669650682efe01ff9dbbc400a1e995616af6aa278\",\n    \"0xac1722d097ce9cd7617161f8ec8c23d68f1fb1c9ca533e2a8b4f78516c2fd8fb38f23f834e2b9a03bb06a9d655693ca9\",\n    \"0xa7ad9e96ffd98db2ecdb6340c5d592614f3c159abfd832fe27ee9293519d213a578e6246aae51672ee353e3296858873\",\n    \"0x989b8814d5de7937c4acafd000eec2b4cd58ba395d7b25f98cafd021e8efa37029b29ad8303a1f6867923f5852a220eb\",\n    \"0xa5bfe6282c771bc9e453e964042d44eff4098decacb89aecd3be662ea5b74506e1357ab26f3527110ba377711f3c9f41\",\n    \"0x8900a7470b656639721d2abbb7b06af0ac4222ab85a1976386e2a62eb4b88bfb5b72cf7921ddb3cf3a395d7eeb192a2e\",\n    \"0x95a71b55cd1f35a438cf5e75f8ff11c5ec6a2ebf2e4dba172f50bfad7d6d5dca5de1b1afc541662c81c858f7604c1163\",\n    \"0x82b5d62fea8db8d85c5bc3a76d68dedd25794cf14d4a7bc368938ffca9e09f7e598fdad2a5aac614e0e52f8112ae62b9\",\n    \"0x997173f07c729202afcde3028fa7f52cefc90fda2d0c8ac2b58154a5073140683e54c49ed1f254481070d119ce0ce02a\",\n    \"0xaeffb91ccc7a72bbd6ffe0f9b99c9e66e67d59cec2e02440465e9636a613ab3017278cfa72ea8bc4aba9a8dc728cb367\",\n    \"0x952743b06e8645894aeb6440fc7a5f62dd3acf96dab70a51e20176762c9751ea5f2ba0b9497ccf0114dc4892dc606031\",\n    \"0x874c63baeddc56fbbca2ff6031f8634b745f6e34ea6791d7c439201aee8f08ef5ee75f7778700a647f3b21068513fce6\",\n    \"0x85128fec9c750c1071edfb15586435cc2f317e3e9a175bb8a9697bcda1eb9375478cf25d01e7fed113483b28f625122d\",\n    \"0x85522c9576fd9763e32af8495ae3928ed7116fb70d4378448926bc9790e8a8d08f98cf47648d7da1b6e40d6a210c7924\",\n    \"0x97d0f37a13cfb723b848099ca1c14d83e9aaf2f7aeb71829180e664b7968632a08f6a85f557d74b55afe6242f2a36e7c\",\n    \"0xabaa472d6ad61a5fccd1a57c01aa1bc081253f95abbcba7f73923f1f11c4e79b904263890eeb66926de3e2652f5d1c70\",\n    \"0xb3c04945ba727a141e5e8aec2bf9aa3772b64d8fd0e2a2b07f3a91106a95cbcb249adcd074cbe498caf76fffac20d4ef\",\n    \"0x82c46781a3d730d9931bcabd7434a9171372dde57171b6180e5516d4e68db8b23495c8ac3ab96994c17ddb1cf249b9fb\",\n    \"0xa202d8b65613c42d01738ccd68ed8c2dbc021631f602d53f751966e04182743ebc8e0747d600b8a8676b1da9ae7f11ab\",\n    \"0xae73e7256e9459db04667a899e0d3ea5255211fb486d084e6550b6dd64ca44af6c6b2d59d7aa152de9f96ce9b58d940d\",\n    \"0xb67d87b176a9722945ec7593777ee461809861c6cfd1b945dde9ee4ff009ca4f19cf88f4bbb5c80c9cbab2fe25b23ac8\",\n    \"0x8f0b7a317a076758b0dac79959ee4a06c08b07d0f10538a4b53d3da2eda16e2af26922feb32c090330dc4d969cf69bd3\",\n    \"0x90b36bf56adbd8c4b6cb32febc3a8d5f714370c2ac3305c10fa6d168dffb2a026804517215f9a2d4ec8310cdb6bb459b\",\n    \"0xaa80c19b0682ead69934bf18cf476291a0beddd8ef4ed75975d0a472e2ab5c70f119722a8574ae4973aceb733d312e57\",\n    \"0xa3fc9abb12574e5c28dcb51750b4339b794b8e558675eef7d26126edf1de920c35e992333bcbffcbf6a5f5c0d383ce62\",\n    \"0xa1573ff23ab972acdcd08818853b111fc757fdd35aa070186d3e11e56b172fb49d840bf297ac0dd222e072fc09f26a81\",\n    \"0x98306f2be4caa92c2b4392212d0cbf430b409b19ff7d5b899986613bd0e762c909fc01999aa94be3bd529d67f0113d7f\",\n    \"0x8c1fc42482a0819074241746d17dc89c0304a2acdae8ed91b5009e9e3e70ff725ba063b4a3e68fdce05b74f5180c545e\",\n    \"0xa6c6113ebf72d8cf3163b2b8d7f3fa24303b13f55752522c660a98cd834d85d8c79214d900fa649499365e2e7641f77a\",\n    \"0xab95eea424f8a2cfd9fb1c78bb724e5b1d71a0d0d1e4217c5d0f98b0d8bbd3f8400a2002abc0a0e4576d1f93f46fefad\",\n    \"0x823c5a4fd8cf4a75fdc71d5f2dd511b6c0f189b82affeacd2b7cfcad8ad1a5551227dcc9bfdb2e34b2097eaa00efbb51\",\n    \"0xb97314dfff36d80c46b53d87a61b0e124dc94018a0bb680c32765b9a2d457f833a7c42bbc90b3b1520c33a182580398d\",\n    \"0xb17566ee3dcc6bb3b004afe4c0136dfe7dd27df9045ae896dca49fb36987501ae069eb745af81ba3fc19ff037e7b1406\",\n    \"0xb0bdc0f55cfd98d331e3a0c4fbb776a131936c3c47c6bffdc3aaf7d8c9fa6803fbc122c2fefbb532e634228687d52174\",\n    \"0xaa5d9e60cc9f0598559c28bb9bdd52aa46605ab4ffe3d192ba982398e72cec9a2a44c0d0d938ce69935693cabc0887ea\",\n    \"0x802b6459d2354fa1d56c592ac1346c428dadea6b6c0a87bf7d309bab55c94e1cf31dd98a7a86bd92a840dd51f218b91b\",\n    \"0xa526914efdc190381bf1a73dd33f392ecf01350b9d3f4ae96b1b1c3d1d064721c7d6eec5788162c933245a3943f5ee51\",\n    \"0xb3b8fcf637d8d6628620a1a99dbe619eabb3e5c7ce930d6efd2197e261bf394b74d4e5c26b96c4b8009c7e523ccfd082\",\n    \"0x8f7510c732502a93e095aba744535f3928f893f188adc5b16008385fb9e80f695d0435bfc5b91cdad4537e87e9d2551c\",\n    \"0x97b90beaa56aa936c3ca45698f79273a68dd3ccd0076eab48d2a4db01782665e63f33c25751c1f2e070f4d1a8525bf96\",\n    \"0xb9fb798324b1d1283fdc3e48288e3861a5449b2ab5e884b34ebb8f740225324af86e4711da6b5cc8361c1db15466602f\",\n    \"0xb6d52b53cea98f1d1d4c9a759c25bf9d8a50b604b144e4912acbdbdc32aab8b9dbb10d64a29aa33a4f502121a6fb481c\",\n    \"0x9174ffff0f2930fc228f0e539f5cfd82c9368d26b074467f39c07a774367ff6cccb5039ac63f107677d77706cd431680\",\n    \"0xa33b6250d4ac9e66ec51c063d1a6a31f253eb29bbaed12a0d67e2eccfffb0f3a52750fbf52a1c2aaba8c7692346426e7\",\n    \"0xa97025fd5cbcebe8ef865afc39cd3ea707b89d4e765ec817fd021d6438e02fa51e3544b1fd45470c58007a08efac6edd\",\n    \"0xb32a78480edd9ff6ba2f1eec4088db5d6ceb2d62d7e59e904ecaef7bb4a2e983a4588e51692b3be76e6ffbc0b5f911a5\",\n    \"0xb5ab590ef0bb77191f00495b33d11c53c65a819f7d0c1f9dc4a2caa147a69c77a4fff7366a602d743ee1f395ce934c1e\",\n    \"0xb3fb0842f9441fb1d0ee0293b6efbc70a8f58d12d6f769b12872db726b19e16f0f65efbc891cf27a28a248b0ef9c7e75\",\n    \"0x9372ad12856fefb928ccb0d34e198df99e2f8973b07e9d417a3134d5f69e12e79ff572c4e03ccd65415d70639bc7c73e\",\n    \"0xaa8d6e83d09ce216bfe2009a6b07d0110d98cf305364d5529c170a23e693aabb768b2016befb5ada8dabdd92b4d012bb\",\n    \"0xa954a75791eeb0ce41c85200c3763a508ed8214b5945a42c79bfdcfb1ec4f86ad1dd7b2862474a368d4ac31911a2b718\",\n    \"0x8e2081cfd1d062fe3ab4dab01f68062bac802795545fede9a188f6c9f802cb5f884e60dbe866710baadbf55dc77c11a4\",\n    \"0xa2f06003b9713e7dd5929501ed485436b49d43de80ea5b15170763fd6346badf8da6de8261828913ee0dacd8ff23c0e1\",\n    \"0x98eecc34b838e6ffd1931ca65eec27bcdb2fdcb61f33e7e5673a93028c5865e0d1bf6d3bec040c5e96f9bd08089a53a4\",\n    \"0x88cc16019741b341060b95498747db4377100d2a5bf0a5f516f7dec71b62bcb6e779de2c269c946d39040e03b3ae12b7\",\n    \"0xad1135ccbc3019d5b2faf59a688eef2500697642be8cfbdf211a1ab59abcc1f24483e50d653b55ff1834675ac7b4978f\",\n    \"0xa946f05ed9972f71dfde0020bbb086020fa35b482cce8a4cc36dd94355b2d10497d7f2580541bb3e81b71ac8bba3c49f\",\n    \"0xa83aeed488f9a19d8cfd743aa9aa1982ab3723560b1cd337fc2f91ad82f07afa412b3993afb845f68d47e91ba4869840\",\n    \"0x95eebe006bfc316810cb71da919e5d62c2cebb4ac99d8e8ef67be420302320465f8b69873470982de13a7c2e23516be9\",\n    \"0xa55f8961295a11e91d1e5deadc0c06c15dacbfc67f04ccba1d069cba89d72aa3b3d64045579c3ea8991b150ac29366ae\",\n    \"0xb321991d12f6ac07a5de3c492841d1a27b0d3446082fbce93e7e1f9e8d8fe3b45d41253556261c21b70f5e189e1a7a6f\",\n    \"0xa0b0822f15f652ce7962a4f130104b97bf9529797c13d6bd8e24701c213cc37f18157bd07f3d0f3eae6b7cd1cb40401f\",\n    \"0x96e2fa4da378aa782cc2d5e6e465fc9e49b5c805ed01d560e9b98abb5c0de8b74a2e7bec3aa5e2887d25cccb12c66f0c\",\n    \"0x97e4ab610d414f9210ed6f35300285eb3ccff5b0b6a95ed33425100d7725e159708ea78704497624ca0a2dcabce3a2f9\",\n    \"0x960a375b17bdb325761e01e88a3ea57026b2393e1d887b34b8fa5d2532928079ce88dc9fd06a728b26d2bb41b12b9032\",\n    \"0x8328a1647398e832aadc05bd717487a2b6fcdaa0d4850d2c4da230c6a2ed44c3e78ec4837b6094f3813f1ee99414713f\",\n    \"0xaa283834ebd18e6c99229ce4b401eda83f01d904f250fedd4e24f1006f8fa0712a6a89a7296a9bf2ce8de30e28d1408e\",\n    \"0xb29e097f2caadae3e0f0ae3473c072b0cd0206cf6d2e9b22c1a5ad3e07d433e32bd09ed1f4e4276a2da4268633357b7f\",\n    \"0x9539c5cbba14538b2fe077ecf67694ef240da5249950baaabea0340718b882a966f66d97f08556b08a4320ceb2cc2629\",\n    \"0xb4529f25e9b42ae8cf8338d2eface6ba5cd4b4d8da73af502d081388135c654c0b3afb3aa779ffc80b8c4c8f4425dd2b\",\n    \"0x95be0739c4330619fbe7ee2249c133c91d6c07eab846c18c5d6c85fc21ac5528c5d56dcb0145af68ed0c6a79f68f2ccd\",\n    \"0xac0c83ea802227bfc23814a24655c9ff13f729619bcffdb487ccbbf029b8eaee709f8bddb98232ef33cd70e30e45ca47\",\n    \"0xb503becb90acc93b1901e939059f93e671900ca52c6f64ae701d11ac891d3a050b505d89324ce267bc43ab8275da6ffe\",\n    \"0x98e3811b55b1bacb70aa409100abb1b870f67e6d059475d9f278c751b6e1e2e2d6f2e586c81a9fb6597fda06e7923274\",\n    \"0xb0b0f61a44053fa6c715dbb0731e35d48dba257d134f851ee1b81fd49a5c51a90ebf5459ec6e489fce25da4f184fbdb1\",\n    \"0xb1d2117fe811720bb997c7c93fe9e4260dc50fca8881b245b5e34f724aaf37ed970cdad4e8fcb68e05ac8cf55a274a53\",\n    \"0xa10f502051968f14b02895393271776dee7a06db9de14effa0b3471825ba94c3f805302bdddac4d397d08456f620999d\",\n    \"0xa3dbad2ef060ae0bb7b02eaa4a13594f3f900450faa1854fc09620b01ac94ab896321dfb1157cf2374c27e5718e8026a\",\n    \"0xb550fdec503195ecb9e079dcdf0cad559d64d3c30818ef369b4907e813e689da316a74ad2422e391b4a8c2a2bef25fc0\",\n    \"0xa25ba865e2ac8f28186cea497294c8649a201732ecb4620c4e77b8e887403119910423df061117e5f03fc5ba39042db1\",\n    \"0xb3f88174e03fdb443dd6addd01303cf88a4369352520187c739fc5ae6b22fa99629c63c985b4383219dab6acc5f6f532\",\n    \"0x97a7503248e31e81b10eb621ba8f5210c537ad11b539c96dfb7cf72b846c7fe81bd7532c5136095652a9618000b7f8d3\",\n    \"0xa8bcdc1ce5aa8bfa683a2fc65c1e79de8ff5446695dcb8620f7350c26d2972a23da22889f9e2b1cacb3f688c6a2953dc\",\n    \"0x8458c111df2a37f5dd91a9bee6c6f4b79f4f161c93fe78075b24a35f9817da8dde71763218d627917a9f1f0c4709c1ed\",\n    \"0xac5f061a0541152b876cbc10640f26f1cc923c9d4ae1b6621e4bb3bf2cec59bbf87363a4eb72fb0e5b6d4e1c269b52d5\",\n    \"0xa9a25ca87006e8a9203cbb78a93f50a36694aa4aad468b8d80d3feff9194455ca559fcc63838128a0ab75ad78c07c13a\",\n    \"0xa450b85f5dfffa8b34dfd8bc985f921318efacf8857cf7948f93884ba09fb831482ee90a44224b1a41e859e19b74962f\",\n    \"0x8ed91e7f92f5c6d7a71708b6132f157ac226ecaf8662af7d7468a4fa25627302efe31e4620ad28719318923e3a59bf82\",\n    \"0xab524165fd4c71b1fd395467a14272bd2b568592deafa039d8492e9ef36c6d3f96927c95c72d410a768dc0b6d1fbbc9b\",\n    \"0xb662144505aa8432c75ffb8d10318526b6d5777ac7af9ebfad87d9b0866c364f7905a6352743bd8fd79ffd9d5dd4f3e6\",\n    \"0xa48f1677550a5cd40663bb3ba8f84caaf8454f332d0ceb1d94dbea52d0412fe69c94997f7749929712fd3995298572f7\",\n    \"0x8391cd6e2f6b0c242de1117a612be99776c3dc95cb800b187685ea5bf7e2722275eddb79fd7dfc8be8e389c4524cdf70\",\n    \"0x875d3acb9af47833b72900bc0a2448999d638f153c5e97e8a14ec02d0c76f6264353a7e275e1f1a5855daced523d243b\",\n    \"0x91f1823657d30b59b2f627880a9a9cb530f5aca28a9fd217fe6f2f5133690dfe7ad5a897872e400512db2e788b3f7628\",\n    \"0xad3564332aa56cea84123fc7ca79ea70bb4fef2009fa131cb44e4b15e8613bd11ca1d83b9d9bf456e4b7fee9f2e8b017\",\n    \"0x8c530b84001936d5ab366c84c0b105241a26d1fb163669f17c8f2e94776895c2870edf3e1bc8ccd04d5e65531471f695\",\n    \"0x932d01fa174fdb0c366f1230cffde2571cc47485f37f23ba5a1825532190cc3b722aeb1f15aed62cf83ccae9403ba713\",\n    \"0x88b28c20585aca50d10752e84b901b5c2d58efef5131479fbbe53de7bce2029e1423a494c0298e1497669bd55be97a5d\",\n    \"0xb914148ca717721144ebb3d3bf3fcea2cd44c30c5f7051b89d8001502f3856fef30ec167174d5b76265b55d70f8716b5\",\n    \"0x81d0173821c6ddd2a068d70766d9103d1ee961c475156e0cbd67d54e668a796310474ef698c7ab55abe6f2cf76c14679\",\n    \"0x8f28e8d78e2fe7fa66340c53718e0db4b84823c8cfb159c76eac032a62fb53da0a5d7e24ca656cf9d2a890cb2a216542\",\n    \"0x8a26360335c73d1ab51cec3166c3cf23b9ea51e44a0ad631b0b0329ef55aaae555420348a544e18d5760969281759b61\",\n    \"0x94f326a32ed287545b0515be9e08149eb0a565025074796d72387cc3a237e87979776410d78339e23ef3172ca43b2544\",\n    \"0xa785d2961a2fa5e70bffa137858a92c48fe749fee91b02599a252b0cd50d311991a08efd7fa5e96b78d07e6e66ffe746\",\n    \"0x94af9030b5ac792dd1ce517eaadcec1482206848bea4e09e55cc7f40fd64d4c2b3e9197027c5636b70d6122c51d2235d\",\n    \"0x9722869f7d1a3992850fe7be405ec93aa17dc4d35e9e257d2e469f46d2c5a59dbd504056c85ab83d541ad8c13e8bcd54\",\n    \"0xb13c4088b61a06e2c03ac9813a75ff1f68ffdfee9df6a8f65095179a475e29cc49119cad2ce05862c3b1ac217f3aace9\",\n    \"0x8c64d51774753623666b10ca1b0fe63ae42f82ed6aa26b81dc1d48c86937c5772eb1402624c52a154b86031854e1fb9f\",\n    \"0xb47e4df18002b7dac3fee945bf9c0503159e1b8aafcce2138818e140753011b6d09ef1b20894e08ba3006b093559061b\",\n    \"0x93cb5970076522c5a0483693f6a35ffd4ea2aa7aaf3730c4eccd6af6d1bebfc1122fc4c67d53898ae13eb6db647be7e2\",\n    \"0xa68873ef80986795ea5ed1a597d1cd99ed978ec25e0abb57fdcc96e89ef0f50aeb779ff46e3dce21dc83ada3157a8498\",\n    \"0x8cab67f50949cc8eee6710e27358aea373aae3c92849f8f0b5531c080a6300cdf2c2094fe6fecfef6148de0d28446919\",\n    \"0x993e932bcb616dbaa7ad18a4439e0565211d31071ef1b85a0627db74a05d978c60d507695eaeea5c7bd9868a21d06923\",\n    \"0xacdadff26e3132d9478a818ef770e9fa0d2b56c6f5f48bd3bd674436ccce9bdfc34db884a73a30c04c5f5e9764cb2218\",\n    \"0xa0d3e64c9c71f84c0eef9d7a9cb4fa184224b969db5514d678e93e00f98b41595588ca802643ea225512a4a272f5f534\",\n    \"0x91c9140c9e1ba6e330cb08f6b2ce4809cd0d5a0f0516f70032bf30e912b0ed684d07b413b326ab531ee7e5b4668c799b\",\n    \"0x87bc2ee7a0c21ba8334cd098e35cb703f9af57f35e091b8151b9b63c3a5b0f89bd7701dbd44f644ea475901fa6d9ef08\",\n    \"0x9325ccbf64bf5d71b303e31ee85d486298f9802c5e55b2c3d75427097bf8f60fa2ab4fcaffa9b60bf922c3e24fbd4b19\",\n    \"0x95d0506e898318f3dc8d28d16dfd9f0038b54798838b3c9be2a2ae3c2bf204eb496166353fc042220b0bd4f6673b9285\",\n    \"0x811de529416331fe9c416726d45df9434c29dcd7e949045eb15740f47e97dde8f31489242200e19922cac2a8b7c6fd1f\",\n    \"0xade632d04a4c8bbab6ca7df370b2213cb9225023e7973f0e29f4f5e52e8aeaabc65171306bbdd12a67b195dfbb96d48f\",\n    \"0x88b7f029e079b6ae956042c0ea75d53088c5d0efd750dd018adaeacf46be21bf990897c58578c491f41afd3978d08073\",\n    \"0x91f477802de507ffd2be3f4319903119225b277ad24f74eb50f28b66c14d32fae53c7edb8c7590704741af7f7f3e3654\",\n    \"0x809838b32bb4f4d0237e98108320d4b079ee16ed80c567e7548bd37e4d7915b1192880f4812ac0e00476d246aec1dbc8\",\n    \"0x84183b5fc4a7997a8ae5afedb4d21dce69c480d5966b5cbdafd6dd10d29a9a6377f3b90ce44da0eb8b176ac3af0253bb\",\n    \"0x8508abbf6d3739a16b9165caf0f95afb3b3ac1b8c38d6d374cf0c91296e2c1809a99772492b539cda184510bce8a0271\",\n    \"0x8722054e59bab2062e6419a6e45fc803af77fde912ef2cd23055ad0484963de65a816a2debe1693d93c18218d2b8e81a\",\n    \"0x8e895f80e485a7c4f56827bf53d34b956281cdc74856c21eb3b51f6288c01cc3d08565a11cc6f3e2604775885490e8c5\",\n    \"0xafc92714771b7aa6e60f3aee12efd9c2595e9659797452f0c1e99519f67c8bc3ac567119c1ddfe82a3e961ee9defea9a\",\n    \"0x818ff0fd9cefd32db87b259e5fa32967201016fc02ef44116cdca3c63ce5e637756f60477a408709928444a8ad69c471\",\n    \"0x8251e29af4c61ae806fc5d032347fb332a94d472038149225298389495139ce5678fae739d02dfe53a231598a992e728\",\n    \"0xa0ea39574b26643f6f1f48f99f276a8a64b5481989cfb2936f9432a3f8ef5075abfe5c067dc5512143ce8bf933984097\",\n    \"0xaf67a73911b372bf04e57e21f289fc6c3dfac366c6a01409b6e76fea4769bdb07a6940e52e8d7d3078f235c6d2f632c6\",\n    \"0xb5291484ef336024dd2b9b4cf4d3a6b751133a40656d0a0825bcc6d41c21b1c79cb50b0e8f4693f90c29c8f4358641f9\",\n    \"0x8bc0d9754d70f2cb9c63f991902165a87c6535a763d5eece43143b5064ae0bcdce7c7a8f398f2c1c29167b2d5a3e6867\",\n    \"0x8d7faff53579ec8f6c92f661c399614cc35276971752ce0623270f88be937c414eddcb0997e14724a783905a026c8883\",\n    \"0x9310b5f6e675fdf60796f814dbaa5a6e7e9029a61c395761e330d9348a7efab992e4e115c8be3a43d08e90d21290c892\",\n    \"0xb5eb4f3eb646038ad2a020f0a42202532d4932e766da82b2c1002bf9c9c2e5336b54c8c0ffcc0e02d19dde2e6a35b6cc\",\n    \"0x91dabfd30a66710f1f37a891136c9be1e23af4abf8cb751f512a40c022a35f8e0a4fb05b17ec36d4208de02d56f0d53a\",\n    \"0xb3ded14e82d62ac7a5a036122a62f00ff8308498f3feae57d861babaff5a6628d43f0a0c5fc903f10936bcf4e2758ceb\",\n    \"0xa88e8348fed2b26acca6784d19ef27c75963450d99651d11a950ea81d4b93acd2c43e0ecce100eaf7e78508263d5baf3\",\n    \"0xb1f5bbf7c4756877b87bb42163ac570e08c6667c4528bf68b5976680e19beeff7c5effd17009b0718797077e2955457a\",\n    \"0xad2e7b516243f915d4d1415326e98b1a7390ae88897d0b03b66c2d9bd8c3fba283d7e8fe44ed3333296a736454cef6d8\",\n    \"0x8f82eae096d5b11f995de6724a9af895f5e1c58d593845ad16ce8fcae8507e0d8e2b2348a0f50a1f66a17fd6fac51a5c\",\n    \"0x890e4404d0657c6c1ee14e1aac132ecf7a568bb3e04137b85ac0f84f1d333bd94993e8750f88eee033a33fb00f85dcc7\",\n    \"0x82ac7d3385e035115f1d39a99fc73e5919de44f5e6424579776d118d711c8120b8e5916372c6f27bed4cc64cac170b6c\",\n    \"0x85ee16d8901c272cfbbe966e724b7a891c1bd5e68efd5d863043ad8520fc409080af61fd726adc680b3f1186fe0ac8b8\",\n    \"0x86dc564c9b545567483b43a38f24c41c6551a49cabeebb58ce86404662a12dbfafd0778d30d26e1c93ce222e547e3898\",\n    \"0xa29f5b4522db26d88f5f95f18d459f8feefab02e380c2edb65aa0617a82a3c1a89474727a951cef5f15050bcf7b380fb\",\n    \"0xa1ce039c8f6cac53352899edb0e3a72c76da143564ad1a44858bd7ee88552e2fe6858d1593bbd74aeee5a6f8034b9b9d\",\n    \"0x97f10d77983f088286bd7ef3e7fdd8fa275a56bec19919adf33cf939a90c8f2967d2b1b6fc51195cb45ad561202a3ed7\",\n    \"0xa25e2772e8c911aaf8712bdac1dd40ee061c84d3d224c466cfaae8e5c99604053f940cde259bd1c3b8b69595781dbfec\",\n    \"0xb31bb95a0388595149409c48781174c340960d59032ab2b47689911d03c68f77a2273576fbe0c2bf4553e330656058c7\",\n    \"0xb8b2e9287ad803fb185a13f0d7456b397d4e3c8ad5078f57f49e8beb2e85f661356a3392dbd7bcf6a900baa5582b86a1\",\n    \"0xa3d0893923455eb6e96cc414341cac33d2dbc88fba821ac672708cce131761d85a0e08286663a32828244febfcae6451\",\n    \"0x82310cb42f647d99a136014a9f881eb0b9791efd2e01fc1841907ad3fc8a9654d3d1dab6689c3607214b4dc2aca01cee\",\n    \"0x874022d99c16f60c22de1b094532a0bc6d4de700ad01a31798fac1d5088b9a42ad02bef8a7339af7ed9c0d4f16b186ee\",\n    \"0x94981369e120265aed40910eebc37eded481e90f4596b8d57c3bec790ab7f929784bd33ddd05b7870aad6c02e869603b\",\n    \"0xa4f1f50e1e2a73f07095e0dd31cb45154f24968dae967e38962341c1241bcd473102fff1ff668b20c6547e9732d11701\",\n    \"0xae2328f3b0ad79fcda807e69a1b5278145225083f150f67511dafc97e079f860c3392675f1752ae7e864c056e592205b\",\n    \"0x875d8c971e593ca79552c43d55c8c73b17cd20c81ff2c2fed1eb19b1b91e4a3a83d32df150dbfd5db1092d0aebde1e1f\",\n    \"0xadd2e80aa46aae95da73a11f130f4bda339db028e24c9b11e5316e75ba5e63bc991d2a1da172c7c8e8fee038baae3433\",\n    \"0xb46dbe1cb3424002aa7de51e82f600852248e251465c440695d52538d3f36828ff46c90ed77fc1d11534fe3c487df8ef\",\n    \"0xa5e5045d28b4e83d0055863c30c056628c58d4657e6176fd0536f5933f723d60e851bb726d5bf3c546b8ce4ac4a57ef8\",\n    \"0x91fec01e86dd1537e498fff7536ea3ca012058b145f29d9ada49370cd7b7193ac380e116989515df1b94b74a55c45df3\",\n    \"0xa7428176d6918cd916a310bdc75483c72de660df48cac4e6e7478eef03205f1827ea55afc0df5d5fa7567d14bbea7fc9\",\n    \"0x851d89bef45d9761fe5fdb62972209335193610015e16a675149519f9911373bac0919add226ef118d9f3669cfdf4734\",\n    \"0xb74acf5c149d0042021cb2422ea022be4c4f72a77855f42393e71ffd12ebb3eec16bdf16f812159b67b79a9706e7156d\",\n    \"0x99f35dce64ec99aa595e7894b55ce7b5a435851b396e79036ffb249c28206087db4c85379df666c4d95857db02e21ff9\",\n    \"0xb6b9a384f70db9e298415b8ab394ee625dafff04be2886476e59df8d052ca832d11ac68a9b93fba7ab055b7bc36948a4\",\n    \"0x898ee4aefa923ffec9e79f2219c7389663eb11eb5b49014e04ed4a336399f6ea1691051d86991f4c46ca65bcd4fdf359\",\n    \"0xb0f948217b0d65df7599a0ba4654a5e43c84db477936276e6f11c8981efc6eaf14c90d3650107ed4c09af4cc8ec11137\",\n    \"0xaa6286e27ac54f73e63dbf6f41865dd94d24bc0cf732262fcaff67319d162bb43af909f6f8ee27b1971939cfbba08141\",\n    \"0x8bca7cdf730cf56c7b2c8a2c4879d61361a6e1dba5a3681a1a16c17a56e168ace0e99cf0d15826a1f5e67e6b8a8a049a\",\n    \"0xa746d876e8b1ce225fcafca603b099b36504846961526589af977a88c60d31ba2cc56e66a3dec8a77b3f3531bf7524c9\",\n    \"0xa11e2e1927e6704cdb8874c75e4f1842cef84d7d43d7a38e339e61dc8ba90e61bbb20dd3c12e0b11d2471d58eed245be\",\n    \"0xa36395e22bc1d1ba8b0459a235203177737397da5643ce54ded3459d0869ff6d8d89f50c73cb62394bf66a959cde9b90\",\n    \"0x8b49f12ba2fdf9aca7e5f81d45c07d47f9302a2655610e7634d1e4bd16048381a45ef2c95a8dd5b0715e4b7cf42273af\",\n    \"0x91cffa2a17e64eb7f76bccbe4e87280ee1dd244e04a3c9eac12e15d2d04845d876eb24fe2ec6d6d266cce9efb281077f\",\n    \"0xa6b8afabf65f2dee01788114e33a2f3ce25376fb47a50b74da7c3c25ff1fdc8aa9f41307534abbf48acb6f7466068f69\",\n    \"0x8d13db896ccfea403bd6441191995c1a65365cab7d0b97fbe9526da3f45a877bd1f4ef2edef160e8a56838cd1586330e\",\n    \"0x98c717de9e01bef8842c162a5e757fe8552d53269c84862f4d451e7c656ae6f2ae473767b04290b134773f63be6fdb9d\",\n    \"0x8c2036ace1920bd13cf018e82848c49eb511fad65fd0ff51f4e4b50cf3bfc294afb63cba682c16f52fb595a98fa84970\",\n    \"0xa3520fdff05dbad9e12551b0896922e375f9e5589368bcb2cc303bde252743b74460cb5caf99629325d3620f13adc796\",\n    \"0x8d4f83a5bfec05caf5910e0ce538ee9816ee18d0bd44c1d0da2a87715a23cd2733ad4d47552c6dc0eb397687d611dd19\",\n    \"0xa7b39a0a6a02823452d376533f39d35029867b3c9a6ad6bca181f18c54132d675613a700f9db2440fb1b4fa13c8bf18a\",\n    \"0x80bcb114b2544b80f404a200fc36860ed5e1ad31fe551acd4661d09730c452831751baa9b19d7d311600d267086a70bc\",\n    \"0x90dcce03c6f88fc2b08f2b42771eedde90cc5330fe0336e46c1a7d1b5a6c1641e5fcc4e7b3d5db00bd8afca9ec66ed81\",\n    \"0xaec15f40805065c98e2965b1ae12a6c9020cfdb094c2d0549acfc7ea2401a5fb48d3ea7d41133cf37c4e096e7ff53eb9\",\n    \"0x80e129b735dba49fa627a615d6c273119acec8e219b2f2c4373a332b5f98d66cbbdd688dfbe72a8f8bfefaccc02c50c1\",\n    \"0xa9b596da3bdfe23e6799ece5f7975bf7a1979a75f4f546deeaf8b34dfe3e0d623217cb4cf4ccd504cfa3625b88cd53f1\",\n    \"0xabcbbb70b16f6e517c0ab4363ab76b46e4ff58576b5f8340e5c0e8cc0e02621b6e23d742d73b015822a238b17cfd7665\",\n    \"0xa046937cc6ea6a2e1adae543353a9fe929c1ae4ad655be1cc051378482cf88b041e28b1e9a577e6ccff2d3570f55e200\",\n    \"0x831279437282f315e65a60184ef158f0a3dddc15a648dc552bdc88b3e6fe8288d3cfe9f0031846d81350f5e7874b4b33\",\n    \"0x993d7916fa213c6d66e7c4cafafc1eaec9a2a86981f91c31eb8a69c5df076c789cbf498a24c84e0ee77af95b42145026\",\n    \"0x823907a3b6719f8d49b3a4b7c181bd9bb29fcf842d7c70660c4f351852a1e197ca46cf5e879b47fa55f616fa2b87ce5e\",\n    \"0x8d228244e26132b234930ee14c75d88df0943cdb9c276a8faf167d259b7efc1beec2a87c112a6c608ad1600a239e9aae\",\n    \"0xab6e55766e5bfb0cf0764ed909a8473ab5047d3388b4f46faeba2d1425c4754c55c6daf6ad4751e634c618b53e549529\",\n    \"0xab0cab6860e55a84c5ad2948a7e0989e2b4b1fd637605634b118361497332df32d9549cb854b2327ca54f2bcb85eed8f\",\n    \"0xb086b349ae03ef34f4b25a57bcaa5d1b29bd94f9ebf87e22be475adfe475c51a1230c1ebe13506cb72c4186192451658\",\n    \"0x8a0b49d8a254ca6d91500f449cbbfbb69bb516c6948ac06808c65595e46773e346f97a5ce0ef7e5a5e0de278af22709c\",\n    \"0xac49de11edaaf04302c73c578cc0824bdd165c0d6321be1c421c1950e68e4f3589aa3995448c9699e93c6ebae8803e27\",\n    \"0x884f02d841cb5d8f4c60d1402469216b114ab4e93550b5bc1431756e365c4f870a9853449285384a6fa49e12ce6dc654\",\n    \"0xb75f3a28fa2cc8d36b49130cb7448a23d73a7311d0185ba803ad55c8219741d451c110f48b786e96c728bc525903a54f\",\n    \"0x80ae04dbd41f4a35e33f9de413b6ad518af0919e5a30cb0fa1b061b260420780bb674f828d37fd3b52b5a31673cbd803\",\n    \"0xb9a8011eb5fcea766907029bf743b45262db3e49d24f84503687e838651ed11cb64c66281e20a0ae9f6aa51acc552263\",\n    \"0x90bfdd75e2dc9cf013e22a5d55d2d2b8a754c96103a17524488e01206e67f8b6d52b1be8c4e3d5307d4fe06d0e51f54c\",\n    \"0xb4af353a19b06203a815ec43e79a88578cc678c46f5a954b85bc5c53b84059dddba731f3d463c23bfd5273885c7c56a4\",\n    \"0xaa125e96d4553b64f7140e5453ff5d2330318b69d74d37d283e84c26ad672fa00e3f71e530eb7e28be1e94afb9c4612e\",\n    \"0xa18e060aee3d49cde2389b10888696436bb7949a79ca7d728be6456a356ea5541b55492b2138da90108bd1ce0e6f5524\",\n    \"0x93e55f92bdbccc2de655d14b1526836ea2e52dba65eb3f87823dd458a4cb5079bf22ce6ef625cb6d6bfdd0995ab9a874\",\n    \"0x89f5a683526b90c1c3ceebbb8dc824b21cff851ce3531b164f6626e326d98b27d3e1d50982e507d84a99b1e04e86a915\",\n    \"0x83d1c38800361633a3f742b1cb2bfc528129496e80232611682ddbe403e92c2ac5373aea0bca93ecb5128b0b2b7a719e\",\n    \"0x8ecba560ac94905e19ce8d9c7af217bf0a145d8c8bd38e2db82f5e94cc3f2f26f55819176376b51f154b4aab22056059\",\n    \"0xa7e2a4a002b60291924850642e703232994acb4cfb90f07c94d1e0ecd2257bb583443283c20fc6017c37e6bfe85b7366\",\n    \"0x93ed7316fa50b528f1636fc6507683a672f4f4403e55e94663f91221cc198199595bd02eef43d609f451acc9d9b36a24\",\n    \"0xa1220a8ebc5c50ceed76a74bc3b7e0aa77f6884c71b64b67c4310ac29ce5526cb8992d6abc13ef6c8413ce62486a6795\",\n    \"0xb2f6eac5c869ad7f4a25161d3347093e2f70e66cd925032747e901189355022fab3038bca4d610d2f68feb7e719c110b\",\n    \"0xb703fa11a4d511ca01c7462979a94acb40b5d933759199af42670eb48f83df202fa0c943f6ab3b4e1cc54673ea3aab1e\",\n    \"0xb5422912afbfcb901f84791b04f1ddb3c3fbdc76d961ee2a00c5c320e06d3cc5b5909c3bb805df66c5f10c47a292b13d\",\n    \"0xad0934368da823302e1ac08e3ede74b05dfdbfffca203e97ffb0282c226814b65c142e6e15ec1e754518f221f01b30f7\",\n    \"0xa1dd302a02e37df15bf2f1147efe0e3c06933a5a767d2d030e1132f5c3ce6b98e216b6145eb39e1e2f74e76a83165b8d\",\n    \"0xa346aab07564432f802ae44738049a36f7ca4056df2d8f110dbe7fef4a3e047684dea609b2d03dc6bf917c9c2a47608f\",\n    \"0xb96c5f682a5f5d02123568e50f5d0d186e4b2c4c9b956ec7aabac1b3e4a766d78d19bd111adb5176b898e916e49be2aa\",\n    \"0x8a96676d56876fc85538db2e806e1cba20fd01aeb9fa3cb43ca6ca94a2c102639f65660db330e5d74a029bb72d6a0b39\",\n    \"0xab0048336bd5c3def1a4064eadd49e66480c1f2abb4df46e03afbd8a3342c2c9d74ee35d79f08f4768c1646681440984\",\n    \"0x888427bdf76caec90814c57ee1c3210a97d107dd88f7256f14f883ad0f392334b82be11e36dd8bfec2b37935177c7831\",\n    \"0xb622b282becf0094a1916fa658429a5292ba30fb48a4c8066ce1ddcefb71037948262a01c95bab6929ed3a76ba5db9fe\",\n    \"0xb5b9e005c1f456b6a368a3097634fb455723abe95433a186e8278dceb79d4ca2fbe21f8002e80027b3c531e5bf494629\",\n    \"0xa3c6707117a1e48697ed41062897f55d8119403eea6c2ee88f60180f6526f45172664bfee96bf61d6ec0b7fbae6aa058\",\n    \"0xb02a9567386a4fbbdb772d8a27057b0be210447348efe6feb935ceec81f361ed2c0c211e54787dc617cdffed6b4a6652\",\n    \"0xa9b8364e40ef15c3b5902e5534998997b8493064fa2bea99600def58279bb0f64574c09ba11e9f6f669a8354dd79dc85\",\n    \"0x9998a2e553a9aa9a206518fae2bc8b90329ee59ab23005b10972712389f2ec0ee746033c733092ffe43d73d33abbb8ef\",\n    \"0x843a4b34d9039bf79df96d79f2d15e8d755affb4d83d61872daf540b68c0a3888cf8fc00d5b8b247b38524bcb3b5a856\",\n    \"0x84f7128920c1b0bb40eee95701d30e6fc3a83b7bb3709f16d97e72acbb6057004ee7ac8e8f575936ca9dcb7866ab45f7\",\n    \"0x918d3e2222e10e05edb34728162a899ad5ada0aaa491aeb7c81572a9c0d506e31d5390e1803a91ff3bd8e2bb15d47f31\",\n    \"0x9442d18e2489613a7d47bb1cb803c8d6f3259d088cd079460976d87f7905ee07dea8f371b2537f6e1d792d36d7e42723\",\n    \"0xb491976970fe091995b2ed86d629126523ccf3e9daf8145302faca71b5a71a5da92e0e05b62d7139d3efac5c4e367584\",\n    \"0xaa628006235dc77c14cef4c04a308d66b07ac92d377df3de1a2e6ecfe3144f2219ad6d7795e671e1cb37a3641910b940\",\n    \"0x99d386adaea5d4981d7306feecac9a555b74ffdc218c907c5aa7ac04abaead0ec2a8237300d42a3fbc464673e417ceed\",\n    \"0x8f78e8b1556f9d739648ea3cab9606f8328b52877fe72f9305545a73b74d49884044ba9c1f1c6db7d9b7c7b7c661caba\",\n    \"0x8fb357ae49932d0babdf74fc7aa7464a65d3b6a2b3acf4f550b99601d3c0215900cfd67f2b6651ef94cfc323bac79fae\",\n    \"0x9906f2fa25c0290775aa001fb6198113d53804262454ae8b83ef371b5271bde189c0460a645829cb6c59f9ee3a55ce4d\",\n    \"0x8f4379b3ebb50e052325b27655ca6a82e6f00b87bf0d2b680d205dd2c7afdc9ff32a9047ae71a1cdf0d0ce6b9474d878\",\n    \"0xa85534e88c2bd43c043792eaa75e50914b21741a566635e0e107ae857aed0412035f7576cf04488ade16fd3f35fdbb87\",\n    \"0xb4ce93199966d3c23251ca7f28ec5af7efea1763d376b0385352ffb2e0a462ef95c69940950278cf0e3dafd638b7bd36\",\n    \"0xb10cb3d0317dd570aa73129f4acf63c256816f007607c19b423fb42f65133ce21f2f517e0afb41a5378cccf893ae14d0\",\n    \"0xa9b231c9f739f7f914e5d943ed9bff7eba9e2c333fbd7c34eb1648a362ee01a01af6e2f7c35c9fe962b11152cddf35de\",\n    \"0x99ff6a899e156732937fb81c0cced80ae13d2d44c40ba99ac183aa246103b31ec084594b1b7feb96da58f4be2dd5c0ed\",\n    \"0x8748d15d18b75ff2596f50d6a9c4ce82f61ecbcee123a6ceae0e43cab3012a29b6f83cf67b48c22f6f9d757c6caf76b2\",\n    \"0xb88ab05e4248b7fb634cf640a4e6a945d13e331237410f7217d3d17e3e384ddd48897e7a91e4516f1b9cbd30f35f238b\",\n    \"0x8d826deaeeb84a3b2d2c04c2300ca592501f992810582d6ae993e0d52f6283a839dba66c6c72278cff5871802b71173b\",\n    \"0xb36fed027c2f05a5ef625ca00b0364b930901e9e4420975b111858d0941f60e205546474bb25d6bfa6928d37305ae95f\",\n    \"0xaf2fcfc6b87967567e8b8a13a4ed914478185705724e56ce68fb2df6d1576a0cf34a61e880997a0d35dc2c3276ff7501\",\n    \"0xac351b919cd1fbf106feb8af2c67692bfcddc84762d18cea681cfa7470a5644839caace27efee5f38c87d3df306f4211\",\n    \"0x8d6665fb1d4d8d1fa23bd9b8a86e043b8555663519caac214d1e3e3effbc6bee7f2bcf21e645f77de0ced279d69a8a8b\",\n    \"0xa9fc1c2061756b2a1a169c1b149f212ff7f0d2488acd1c5a0197eba793cffa593fc6d1d1b40718aa75ca3ec77eff10e1\",\n    \"0xaff64f0fa009c7a6cf0b8d7a22ddb2c8170c3cb3eec082e60d5aadb00b0040443be8936d728d99581e33c22178c41c87\",\n    \"0x82e0b181adc5e3b1c87ff8598447260e839d53debfae941ebea38265575546c3a74a14b4325a030833a62ff6c52d9365\",\n    \"0xb7ad43cbb22f6f892c2a1548a41dc120ab1f4e1b8dea0cb6272dd9cb02054c542ecabc582f7e16de709d48f5166cae86\",\n    \"0x985e0c61094281532c4afb788ecb2dfcba998e974b5d4257a22040a161883908cdd068fe80f8eb49b8953cfd11acf43a\",\n    \"0xae46895c6d67ea6d469b6c9c07b9e5d295d9ae73b22e30da4ba2c973ba83a130d7eef39717ec9d0f36e81d56bf742671\",\n    \"0x8600177ea1f7e7ef90514b38b219a37dedfc39cb83297e4c7a5b479817ef56479d48cf6314820960c751183f6edf8b0e\",\n    \"0xb9208ec1c1d7a1e99b59c62d3e4e61dfb706b0e940d09d3abfc3454c19749083260614d89cfd7e822596c3cdbcc6bb95\",\n    \"0xa1e94042c796c2b48bc724352d2e9f3a22291d9a34705993357ddb6adabd76da6fc25dac200a8cb0b5bbd99ecddb7af6\",\n    \"0xb29c3adedd0bcad8a930625bc4dfdc3552a9afd5ca6dd9c0d758f978068c7982b50b711aa0eb5b97f2b84ee784637835\",\n    \"0xaf0632a238bb1f413c7ea8e9b4c3d68f2827bd2e38cd56024391fba6446ac5d19a780d0cfd4a78fe497d537b766a591a\",\n    \"0xaaf6e7f7d54f8ef5e2e45dd59774ecbeecf8683aa70483b2a75be6a6071b5981bbaf1627512a65d212817acdfab2e428\",\n    \"0x8c751496065da2e927cf492aa5ca9013b24f861d5e6c24b30bbf52ec5aaf1905f40f9a28175faef283dd4ed4f2182a09\",\n    \"0x8952377d8e80a85cf67d6b45499f3bad5fd452ea7bcd99efc1b066c4720d8e5bff1214cea90fd1f972a7f0baac3d29be\",\n    \"0xa1946ee543d1a6e21f380453be4d446e4130950c5fc3d075794eb8260f6f52d0a795c1ff91d028a648dc1ce7d9ab6b47\",\n    \"0x89f3fefe37af31e0c17533d2ca1ce0884cc1dc97c15cbfab9c331b8debd94781c9396abef4bb2f163d09277a08d6adf0\",\n    \"0xa2753f1e6e1a154fb117100a5bd9052137add85961f8158830ac20541ab12227d83887d10acf7fd36dcaf7c2596d8d23\",\n    \"0x814955b4198933ee11c3883863b06ff98c7eceb21fc3e09df5f916107827ccf3323141983e74b025f46ae00284c9513b\",\n    \"0x8cc5c6bb429073bfef47cae7b3bfccb0ffa076514d91a1862c6bda4d581e0df87db53cc6c130bf8a7826304960f5a34e\",\n    \"0x909f22c1f1cdc87f7be7439c831a73484a49acbf8f23d47087d7cf867c64ef61da3bde85dc57d705682b4c3fc710d36e\",\n    \"0x8048fee7f276fcd504aed91284f28e73693615e0eb3858fa44bcf79d7285a9001c373b3ef71d9a3054817ba293ebe28c\",\n    \"0x94400e5cf5d2700ca608c5fe35ce14623f71cc24959f2bc27ca3684092850f76b67fb1f07ca9e5b2ca3062cf8ad17bd4\",\n    \"0x81c2ae7d4d1b17f8b6de6a0430acc0d58260993980fe48dc2129c4948269cdc74f9dbfbf9c26b19360823fd913083d48\",\n    \"0x8c41fe765128e63f6889d6a979f6a4342300327c8b245a8cfe3ecfbcac1e09c3da30e2a1045b24b78efc6d6d50c8c6ac\",\n    \"0xa5dd4ae51ae48c8be4b218c312ade226cffce671cf121cb77810f6c0990768d6dd767badecb5c69921d5574d5e8433d3\",\n    \"0xb7642e325f4ba97ae2a39c1c9d97b35aafd49d53dba36aed3f3cb0ca816480b3394079f46a48252d46596559c90f4d58\",\n    \"0xae87375b40f35519e7bd4b1b2f73cd0b329b0c2cb9d616629342a71c6c304338445eda069b78ea0fbe44087f3de91e09\",\n    \"0xb08918cb6f736855e11d3daca1ddfbdd61c9589b203b5493143227bf48e2c77c2e8c94b0d1aa2fab2226e0eae83f2681\",\n    \"0xac36b84a4ac2ebd4d6591923a449c564e3be8a664c46092c09e875c2998eba16b5d32bfd0882fd3851762868e669f0b1\",\n    \"0xa44800a3bb192066fa17a3f29029a23697240467053b5aa49b9839fb9b9b8b12bcdcbfc557f024b61f4f51a9aacdefcb\",\n    \"0x9064c688fec23441a274cdf2075e5a449caf5c7363cc5e8a5dc9747183d2e00a0c69f2e6b3f6a7057079c46014c93b3b\",\n    \"0xaa367b021469af9f5b764a79bb3afbe2d87fe1e51862221672d1a66f954b165778b7c27a705e0f93841fab4c8468344d\",\n    \"0xa1a8bfc593d4ab71f91640bc824de5c1380ab2591cfdafcbc78a14b32de3c0e15f9d1b461d85c504baa3d4232c16bb53\",\n    \"0x97df48da1799430f528184d30b6baa90c2a2f88f34cdfb342d715339c5ebd6d019aa693cea7c4993daafc9849063a3aa\",\n    \"0xabd923831fbb427e06e0dd335253178a9e5791395c84d0ab1433c07c53c1209161097e9582fb8736f8a60bde62d8693e\",\n    \"0x84cd1a43f1a438b43dc60ffc775f646937c4f6871438163905a3cebf1115f814ccd38a6ccb134130bff226306e412f32\",\n    \"0x91426065996b0743c5f689eb3ca68a9f7b9e4d01f6c5a2652b57fa9a03d8dc7cd4bdbdab0ca5a891fee1e97a7f00cf02\",\n    \"0xa4bee50249db3df7fd75162b28f04e57c678ba142ce4d3def2bc17bcb29e4670284a45f218dad3969af466c62a903757\",\n    \"0x83141ebcc94d4681404e8b67a12a46374fded6df92b506aff3490d875919631408b369823a08b271d006d5b93136f317\",\n    \"0xa0ea1c8883d58d5a784da3d8c8a880061adea796d7505c1f903d07c287c5467f71e4563fc0faafbc15b5a5538b0a7559\",\n    \"0x89d9d480574f201a87269d26fb114278ed2c446328df431dc3556e3500e80e4cd01fcac196a2459d8646361ebda840df\",\n    \"0x8bf302978973632dd464bec819bdb91304712a3ec859be071e662040620422c6e75eba6f864f764cffa2799272efec39\",\n    \"0x922f666bc0fd58b6d7d815c0ae4f66d193d32fc8382c631037f59eeaeae9a8ca6c72d08e72944cf9e800b8d639094e77\",\n    \"0x81ad8714f491cdff7fe4399f2eb20e32650cff2999dd45b9b3d996d54a4aba24cc6c451212e78c9e5550368a1a38fb3f\",\n    \"0xb58fcf4659d73edb73175bd9139d18254e94c3e32031b5d4b026f2ed37aa19dca17ec2eb54c14340231615277a9d347e\",\n    \"0xb365ac9c2bfe409b710928c646ea2fb15b28557e0f089d39878e365589b9d1c34baf5566d20bb28b33bb60fa133f6eff\",\n    \"0x8fcae1d75b53ab470be805f39630d204853ca1629a14158bac2f52632277d77458dec204ff84b7b2d77e641c2045be65\",\n    \"0xa03efa6bebe84f4f958a56e2d76b5ba4f95dd9ed7eb479edc7cc5e646c8d4792e5b0dfc66cc86aa4b4afe2f7a4850760\",\n    \"0xaf1c823930a3638975fb0cc5c59651771b2719119c3cd08404fbd4ce77a74d708cefbe3c56ea08c48f5f10e6907f338f\",\n    \"0x8260c8299b17898032c761c325ac9cabb4c5b7e735de81eacf244f647a45fb385012f4f8df743128888c29aefcaaad16\",\n    \"0xab2f37a573c82e96a8d46198691cd694dfa860615625f477e41f91b879bc58a745784fccd8ffa13065834ffd150d881d\",\n    \"0x986c746c9b4249352d8e5c629e8d7d05e716b3c7aab5e529ca969dd1e984a14b5be41528baef4c85d2369a42d7209216\",\n    \"0xb25e32da1a8adddf2a6080725818b75bc67240728ad1853d90738485d8924ea1e202df0a3034a60ffae6f965ec55cf63\",\n    \"0xa266e627afcebcefea6b6b44cbc50f5c508f7187e87d047b0450871c2a030042c9e376f3ede0afcf9d1952f089582f71\",\n    \"0x86c3bbca4c0300606071c0a80dbdec21ce1dd4d8d4309648151c420854032dff1241a1677d1cd5de4e4de4385efda986\",\n    \"0xb9a21a1fe2d1f3273a8e4a9185abf2ff86448cc98bfa435e3d68306a2b8b4a6a3ea33a155be3cb62a2170a86f77679a5\",\n    \"0xb117b1ea381adce87d8b342cba3a15d492ff2d644afa28f22424cb9cbc820d4f7693dfc1a4d1b3697046c300e1c9b4c8\",\n    \"0x9004c425a2e68870d6c69b658c344e3aa3a86a8914ee08d72b2f95c2e2d8a4c7bb0c6e7e271460c0e637cec11117bf8e\",\n    \"0x86a18aa4783b9ebd9131580c8b17994825f27f4ac427b0929a1e0236907732a1c8139e98112c605488ee95f48bbefbfc\",\n    \"0x84042243b955286482ab6f0b5df4c2d73571ada00716d2f737ca05a0d2e88c6349e8ee9e67934cfee4a1775dbf7f4800\",\n    \"0x92c2153a4733a62e4e1d5b60369f3c26777c7d01cd3c8679212660d572bd3bac9b8a8a64e1f10f7dbf5eaa7579c4e423\",\n    \"0x918454b6bb8e44a2afa144695ba8d48ae08d0cdfef4ad078f67709eddf3bb31191e8b006f04e82ea45a54715ef4d5817\",\n    \"0xacf0b54f6bf34cf6ed6c2b39cf43194a40d68de6bcf1e4b82c34c15a1343e9ac3737885e1a30b78d01fa3a5125463db8\",\n    \"0xa7d60dbe4b6a7b054f7afe9ee5cbbfeca0d05dc619e6041fa2296b549322529faddb8a11e949562309aecefb842ac380\",\n    \"0x91ffb53e6d7e5f11159eaf13e783d6dbdfdb1698ed1e6dbf3413c6ea23492bbb9e0932230a9e2caac8fe899a17682795\",\n    \"0xb6e8d7be5076ee3565d5765a710c5ecf17921dd3cf555c375d01e958a365ae087d4a88da492a5fb81838b7b92bf01143\",\n    \"0xa8c6b763de2d4b2ed42102ef64eccfef31e2fb2a8a2776241c82912fa50fc9f77f175b6d109a97ede331307c016a4b1a\",\n    \"0x99839f86cb700c297c58bc33e28d46b92931961548deac29ba8df91d3e11721b10ea956c8e16984f9e4acf1298a79b37\",\n    \"0x8c2e2c338f25ea5c25756b7131cde0d9a2b35abf5d90781180a00fe4b8e64e62590dc63fe10a57fba3a31c76d784eb01\",\n    \"0x9687d7df2f41319ca5469d91978fed0565a5f11f829ebadaa83db92b221755f76c6eacd7700735e75c91e257087512e3\",\n    \"0x8795fdfb7ff8439c58b9bf58ed53873d2780d3939b902b9ddaaa4c99447224ced9206c3039a23c2c44bcc461e2bb637f\",\n    \"0xa803697b744d2d087f4e2307218d48fa88620cf25529db9ce71e2e3bbcc65bac5e8bb9be04777ef7bfb5ed1a5b8e6170\",\n    \"0x80f3d3efbbb9346ddd413f0a8e36b269eb5d7ff6809d5525ff9a47c4bcab2c01b70018b117f6fe05253775612ff70c6b\",\n    \"0x9050e0e45bcc83930d4c505af35e5e4d7ca01cd8681cba92eb55821aececcebe32bb692ebe1a4daac4e7472975671067\",\n    \"0x8d206812aac42742dbaf233e0c080b3d1b30943b54b60283515da005de05ea5caa90f91fedcfcba72e922f64d7040189\",\n    \"0xa2d44faaeb2eff7915c83f32b13ca6f31a6847b1c1ce114ea240bac3595eded89f09b2313b7915ad882292e2b586d5b4\",\n    \"0x961776c8576030c39f214ea6e0a3e8b3d32f023d2600958c098c95c8a4e374deeb2b9dc522adfbd6bda5949bdc09e2a2\",\n    \"0x993fa7d8447407af0fbcd9e6d77f815fa5233ab00674efbcf74a1f51c37481445ae291cc7b76db7c178f9cb0e570e0fc\",\n    \"0xabd5b1c78e05f9d7c8cc99bdaef8b0b6a57f2daf0f02bf492bec48ea4a27a8f1e38b5854da96efff11973326ff980f92\",\n    \"0x8f15af4764bc275e6ccb892b3a4362cacb4e175b1526a9a99944e692fe6ccb1b4fc19abf312bb2a089cb1f344d91a779\",\n    \"0xa09b27ccd71855512aba1d0c30a79ffbe7f6707a55978f3ced50e674b511a79a446dbc6d7946add421ce111135a460af\",\n    \"0x94b2f98ce86a9271fbd4153e1fc37de48421fe3490fb3840c00f2d5a4d0ba8810c6a32880b002f6374b59e0a7952518b\",\n    \"0x8650ac644f93bbcb88a6a0f49fee2663297fd4bc6fd47b6a89b9d8038d32370438ab3a4775ec9b58cb10aea8a95ef7b6\",\n    \"0x95e5c2f2e84eed88c6980bbba5a1c0bb375d5a628bff006f7516d45bb7d723da676add4fdd45956f312e7bab0f052644\",\n    \"0xb3278a3fa377ac93af7cfc9453f8cb594aae04269bbc99d2e0e45472ff4b6a2f97a26c4c57bf675b9d86f5e77a5d55d1\",\n    \"0xb4bcbe6eb666a206e2ea2f877912c1d3b5bdbd08a989fc4490eb06013e1a69ad1ba08bcdac048bf29192312be399077b\",\n    \"0xa76d70b78c99fffcbf9bb9886eab40f1ea4f99a309710b660b64cbf86057cbcb644d243f6e341711bb7ef0fedf0435a7\",\n    \"0xb2093c1ee945dca7ac76ad5aed08eae23af31dd5a77c903fd7b6f051f4ab84425d33a03c3d45bf2907bc93c02d1f3ad8\",\n    \"0x904b1f7534e053a265b22d20be859912b9c9ccb303af9a8d6f1d8f6ccdc5c53eb4a45a1762b880d8444d9be0cd55e7f9\",\n    \"0x8f664a965d65bc730c9ef1ec7467be984d4b8eb46bd9b0d64e38e48f94e6e55dda19aeac82cbcf4e1473440e64c4ca18\",\n    \"0x8bcee65c4cc7a7799353d07b114c718a2aae0cd10a3f22b7eead5185d159dafd64852cb63924bf87627d176228878bce\",\n    \"0x8c78f2e3675096fef7ebaa898d2615cd50d39ca3d8f02b9bdfb07e67da648ae4be3da64838dffc5935fd72962c4b96c7\",\n    \"0x8c40afd3701629421fec1df1aac4e849384ef2e80472c0e28d36cb1327acdf2826f99b357f3d7afdbc58a6347fc40b3c\",\n    \"0xa197813b1c65a8ea5754ef782522a57d63433ef752215ecda1e7da76b0412ee619f58d904abd2e07e0c097048b6ae1dd\",\n    \"0xa670542629e4333884ad7410f9ea3bd6f988df4a8f8a424ca74b9add2312586900cf9ae8bd50411f9146e82626b4af56\",\n    \"0xa19875cc07ab84e569d98b8b67fb1dbbdfb59093c7b748fae008c8904a6fd931a63ca8d03ab5fea9bc8d263568125a9b\",\n    \"0xb57e7f68e4eb1bd04aafa917b1db1bdab759a02aa8a9cdb1cba34ba8852b5890f655645c9b4e15d5f19bf37e9f2ffe9f\",\n    \"0x8abe4e2a4f6462b6c64b3f10e45db2a53c2b0d3c5d5443d3f00a453e193df771eda635b098b6c8604ace3557514027af\",\n    \"0x8459e4fb378189b22b870a6ef20183deb816cefbf66eca1dc7e86d36a2e011537db893729f500dc154f14ce24633ba47\",\n    \"0x930851df4bc7913c0d8c0f7bd3b071a83668987ed7c397d3d042fdc0d9765945a39a3bae83da9c88cb6b686ed8aeeb26\",\n    \"0x8078c9e5cd05e1a8c932f8a1d835f61a248b6e7133fcbb3de406bf4ffc0e584f6f9f95062740ba6008d98348886cf76b\",\n    \"0xaddff62bb29430983fe578e3709b0949cdc0d47a13a29bc3f50371a2cb5c822ce53e2448cfaa01bcb6e0aa850d5a380e\",\n    \"0x9433add687b5a1e12066721789b1db2edf9b6558c3bdc0f452ba33b1da67426abe326e9a34d207bfb1c491c18811bde1\",\n    \"0x822beda3389963428cccc4a2918fa9a8a51cf0919640350293af70821967108cded5997adae86b33cb917780b097f1ca\",\n    \"0xa7a9f52bda45e4148ed56dd176df7bd672e9b5ed18888ccdb405f47920fdb0844355f8565cefb17010b38324edd8315f\",\n    \"0xb35c3a872e18e607b2555c51f9696a17fa18da1f924d503b163b4ec9fe22ed0c110925275cb6c93ce2d013e88f173d6a\",\n    \"0xadf34b002b2b26ab84fc1bf94e05bd8616a1d06664799ab149363c56a6e0c807fdc473327d25632416e952ea327fcd95\",\n    \"0xae4a6b9d22a4a3183fac29e2551e1124a8ce4a561a9a2afa9b23032b58d444e6155bb2b48f85c7b6d70393274e230db7\",\n    \"0xa2ea3be4fc17e9b7ce3110284038d46a09e88a247b6971167a7878d9dcf36925d613c382b400cfa4f37a3ebea3699897\",\n    \"0x8e5863786b641ce3140fbfe37124d7ad3925472e924f814ebfc45959aaf3f61dc554a597610b5defaecc85b59a99b50f\",\n    \"0xaefde3193d0f700d0f515ab2aaa43e2ef1d7831c4f7859f48e52693d57f97fa9e520090f3ed700e1c966f4b76048e57f\",\n    \"0x841a50f772956622798e5cd208dc7534d4e39eddee30d8ce133383d66e5f267e389254a0cdae01b770ecd0a9ca421929\",\n    \"0x8fbc2bfd28238c7d47d4c03b1b910946c0d94274a199575e5b23242619b1de3497784e646a92aa03e3e24123ae4fcaba\",\n    \"0x926999579c8eec1cc47d7330112586bdca20b4149c8b2d066f527c8b9f609e61ce27feb69db67eea382649c6905efcf9\",\n    \"0xb09f31f305efcc65589adf5d3690a76cf339efd67cd43a4e3ced7b839507466e4be72dd91f04e89e4bbef629d46e68c0\",\n    \"0xb917361f6b95f759642638e0b1d2b3a29c3bdef0b94faa30de562e6078c7e2d25976159df3edbacbf43614635c2640b4\",\n    \"0x8e7e8a1253bbda0e134d62bfe003a2669d471b47bd2b5cde0ff60d385d8e62279d54022f5ac12053b1e2d3aaa6910b4c\",\n    \"0xb69671a3c64e0a99d90b0ed108ce1912ff8ed983e4bddd75a370e9babde25ee1f5efb59ec707edddd46793207a8b1fe7\",\n    \"0x910b2f4ebd37b7ae94108922b233d0920b4aba0bd94202c70f1314418b548d11d8e9caa91f2cd95aff51b9432d122b7f\",\n    \"0x82f645c90dfb52d195c1020346287c43a80233d3538954548604d09fbab7421241cde8593dbc4acc4986e0ea39a27dd9\",\n    \"0x8fee895f0a140d88104ce442fed3966f58ff9d275e7373483f6b4249d64a25fb5374bbdc6bce6b5ab0270c2847066f83\",\n    \"0x84f5bd7aab27b2509397aeb86510dd5ac0a53f2c8f73799bf720f2f87a52277f8d6b0f77f17bc80739c6a7119b7eb062\",\n    \"0x9903ceced81099d7e146e661bcf01cbaccab5ba54366b85e2177f07e2d8621e19d9c9c3eee14b9266de6b3f9b6ea75ae\",\n    \"0xb9c16ea2a07afa32dd6c7c06df0dec39bca2067a9339e45475c98917f47e2320f6f235da353fd5e15b477de97ddc68dd\",\n    \"0x9820a9bbf8b826bec61ebf886de2c4f404c1ebdc8bab82ee1fea816d9de29127ce1852448ff717a3fe8bbfe9e92012e5\",\n    \"0x817224d9359f5da6f2158c2c7bf9165501424f063e67ba9859a07ab72ee2ee62eb00ca6da821cfa19065c3282ca72c74\",\n    \"0x94b95c465e6cb00da400558a3c60cfec4b79b27e602ca67cbc91aead08de4b6872d8ea096b0dc06dca4525c8992b8547\",\n    \"0xa2b539a5bccd43fa347ba9c15f249b417997c6a38c63517ca38394976baa08e20be384a360969ff54e7e721db536b3e5\",\n    \"0x96caf707e34f62811ee8d32ccf28d8d6ec579bc33e424d0473529af5315c456fd026aa910c1fed70c91982d51df7d3ca\",\n    \"0x8a77b73e890b644c6a142bdbac59b22d6a676f3b63ddafb52d914bb9d395b8bf5aedcbcc90429337df431ebd758a07a6\",\n    \"0x8857830a7351025617a08bc44caec28d2fae07ebf5ffc9f01d979ce2a53839a670e61ae2783e138313929129790a51a1\",\n    \"0xaa3e420321ed6f0aa326d28d1a10f13facec6f605b6218a6eb9cbc074801f3467bf013a456d1415a5536f12599efa3d3\",\n    \"0x824aed0951957b00ea2f3d423e30328a3527bf6714cf9abbae84cf27e58e5c35452ba89ccc011de7c68c75d6e021d8f1\",\n    \"0xa2e87cc06bf202e953fb1081933d8b4445527dde20e38ed1a4f440144fd8fa464a2b73e068b140562e9045e0f4bd3144\",\n    \"0xae3b8f06ad97d7ae3a5e5ca839efff3e4824dc238c0c03fc1a8d2fc8aa546cdfd165b784a31bb4dec7c77e9305b99a4b\",\n    \"0xb30c3e12395b1fb8b776f3ec9f87c70e35763a7b2ddc68f0f60a4982a84017f27c891a98561c830038deb033698ed7fc\",\n    \"0x874e507757cd1177d0dff0b0c62ce90130324442a33da3b2c8ee09dbca5d543e3ecfe707e9f1361e7c7db641c72794bb\",\n    \"0xb53012dd10b5e7460b57c092eaa06d6502720df9edbbe3e3f61a9998a272bf5baaac4a5a732ad4efe35d6fac6feca744\",\n    \"0x85e6509d711515534d394e6cacbed6c81da710074d16ef3f4950bf2f578d662a494d835674f79c4d6315bced4defc5f0\",\n    \"0xb6132b2a34b0905dcadc6119fd215419a7971fe545e52f48b768006944b4a9d7db1a74b149e2951ea48c083b752d0804\",\n    \"0x989867da6415036d19b4bacc926ce6f4df7a556f50a1ba5f3c48eea9cefbb1c09da81481c8009331ee83f0859185e164\",\n    \"0x960a6c36542876174d3fbc1505413e29f053ed87b8d38fef3af180491c7eff25200b45dd5fe5d4d8e63c7e8c9c00f4c8\",\n    \"0x9040b59bd739d9cc2e8f6e894683429e4e876a8106238689ff4c22770ae5fdae1f32d962b30301fa0634ee163b524f35\",\n    \"0xaf3fcd0a45fe9e8fe256dc7eab242ef7f582dd832d147444483c62787ac820fafc6ca55d639a73f76bfa5e7f5462ab8f\",\n    \"0xb934c799d0736953a73d91e761767fdb78454355c4b15c680ce08accb57ccf941b13a1236980001f9e6195801cffd692\",\n    \"0x8871e8e741157c2c326b22cf09551e78da3c1ec0fc0543136f581f1550f8bab03b0a7b80525c1e99812cdbf3a9698f96\",\n    \"0xa8a977f51473a91d178ee8cfa45ffef8d6fd93ab1d6e428f96a3c79816d9c6a93cd70f94d4deda0125fd6816e30f3bea\",\n    \"0xa7688b3b0a4fc1dd16e8ba6dc758d3cfe1b7cf401c31739484c7fa253cce0967df1b290769bcefc9d23d3e0cb19e6218\",\n    \"0x8ae84322662a57c6d729e6ff9d2737698cc2da2daeb1f39e506618750ed23442a6740955f299e4a15dda6db3e534d2c6\",\n    \"0xa04a961cdccfa4b7ef83ced17ab221d6a043b2c718a0d6cc8e6f798507a31f10bf70361f70a049bc8058303fa7f96864\",\n    \"0xb463e39732a7d9daec8a456fb58e54b30a6e160aa522a18b9a9e836488cce3342bcbb2e1deab0f5e6ec0a8796d77197d\",\n    \"0xb1434a11c6750f14018a2d3bcf94390e2948f4f187e93bb22070ca3e5393d339dc328cbfc3e48815f51929465ffe7d81\",\n    \"0x84ff81d73f3828340623d7e3345553610aa22a5432217ef0ebd193cbf4a24234b190c65ca0873c22d10ea7b63bd1fbed\",\n    \"0xb6fe2723f0c47757932c2ddde7a4f8434f665612f7b87b4009c2635d56b6e16b200859a8ade49276de0ef27a2b6c970a\",\n    \"0x9742884ed7cd52b4a4a068a43d3faa02551a424136c85a9313f7cb58ea54c04aa83b0728fd741d1fe39621e931e88f8f\",\n    \"0xb7d2d65ea4d1ad07a5dee39e40d6c03a61264a56b1585b4d76fc5b2a68d80a93a42a0181d432528582bf08d144c2d6a9\",\n    \"0x88c0f66bada89f8a43e5a6ead2915088173d106c76f724f4a97b0f6758aed6ae5c37c373c6b92cdd4aea8f6261f3a374\",\n    \"0x81f9c43582cb42db3900747eb49ec94edb2284999a499d1527f03315fd330e5a509afa3bff659853570e9886aab5b28b\",\n    \"0x821f9d27d6beb416abf9aa5c79afb65a50ed276dbda6060103bc808bcd34426b82da5f23e38e88a55e172f5c294b4d40\",\n    \"0x8ba307b9e7cb63a6c4f3851b321aebfdb6af34a5a4c3bd949ff7d96603e59b27ff4dc4970715d35f7758260ff942c9e9\",\n    \"0xb142eb6c5f846de33227d0bda61d445a7c33c98f0a8365fe6ab4c1fabdc130849be597ef734305894a424ea715372d08\",\n    \"0xa732730ae4512e86a741c8e4c87fee8a05ee840fec0e23b2e037d58dba8dde8d10a9bc5191d34d00598941becbbe467f\",\n    \"0xadce6f7c30fd221f6b10a0413cc76435c4bb36c2d60bca821e5c67409fe9dbb2f4c36ef85eb3d734695e4be4827e9fd3\",\n    \"0xa74f00e0f9b23aff7b2527ce69852f8906dab9d6abe62ecd497498ab21e57542e12af9918d4fd610bb09e10b0929c510\",\n    \"0xa593b6b0ef26448ce4eb3ab07e84238fc020b3cb10d542ff4b16d4e2be1bcde3797e45c9cf753b8dc3b0ffdb63984232\",\n    \"0xaed3913afccf1aa1ac0eb4980eb8426d0baccebd836d44651fd72af00d09fac488a870223c42aca3ceb39752070405ae\",\n    \"0xb2c44c66a5ea7fde626548ba4cef8c8710191343d3dadfd3bb653ce715c0e03056a5303a581d47dde66e70ea5a2d2779\",\n    \"0x8e5029b2ccf5128a12327b5103f7532db599846e422531869560ceaff392236434d87159f597937dbf4054f810c114f4\",\n    \"0x82beed1a2c4477e5eb39fc5b0e773b30cfec77ef2b1bf17eadaf60eb35b6d0dd9d8cf06315c48d3546badb3f21cd0cca\",\n    \"0x90077bd6cc0e4be5fff08e5d07a5a158d36cebd1d1363125bc4fae0866ffe825b26f933d4ee5427ba5cd0c33c19a7b06\",\n    \"0xa7ec0d8f079970e8e34f0ef3a53d3e0e45428ddcef9cc776ead5e542ef06f3c86981644f61c5a637e4faf001fb8c6b3e\",\n    \"0xae6d4add6d1a6f90b22792bc9d40723ee6850c27d0b97eefafd5b7fd98e424aa97868b5287cc41b4fbd7023bca6a322c\",\n    \"0x831aa917533d077da07c01417feaa1408846363ba2b8d22c6116bb858a95801547dd88b7d7fa1d2e3f0a02bdeb2e103d\",\n    \"0x96511b860b07c8a5ed773f36d4aa9d02fb5e7882753bf56303595bcb57e37ccc60288887eb83bef08c657ec261a021a2\",\n    \"0x921d2a3e7e9790f74068623de327443666b634c8443aba80120a45bba450df920b2374d96df1ce3fb1b06dd06f8cf6e3\",\n    \"0xaa74451d51fe82b4581ead8e506ec6cd881010f7e7dd51fc388eb9a557db5d3c6721f81c151d08ebd9c2591689fbc13e\",\n    \"0xa972bfbcf4033d5742d08716c927c442119bdae336bf5dff914523b285ccf31953da2733759aacaa246a9af9f698342c\",\n    \"0xad1fcd0cae0e76840194ce4150cb8a56ebed728ec9272035f52a799d480dfc85840a4d52d994a18b6edb31e79be6e8ad\",\n    \"0xa2c69fe1d36f235215432dad48d75887a44c99dfa0d78149acc74087da215a44bdb5f04e6eef88ff7eff80a5a7decc77\",\n    \"0xa94ab2af2b6ee1bc6e0d4e689ca45380d9fbd3c5a65b9bd249d266a4d4c07bf5d5f7ef2ae6000623aee64027892bf8fe\",\n    \"0x881ec1fc514e926cdc66480ac59e139148ff8a2a7895a49f0dff45910c90cdda97b66441a25f357d6dd2471cddd99bb3\",\n    \"0x884e6d3b894a914c8cef946a76d5a0c8351843b2bffa2d1e56c6b5b99c84104381dd1320c451d551c0b966f4086e60f9\",\n    \"0x817c6c10ce2677b9fc5223500322e2b880583254d0bb0d247d728f8716f5e05c9ff39f135854342a1afecd9fbdcf7c46\",\n    \"0xaaf4a9cb686a14619aa1fc1ac285dd3843ac3dd99f2b2331c711ec87b03491c02f49101046f3c5c538dc9f8dba2a0ac2\",\n    \"0x97ecea5ce53ca720b5d845227ae61d70269a2f53540089305c86af35f0898bfd57356e74a8a5e083fa6e1ea70080bd31\",\n    \"0xa22d811e1a20a75feac0157c418a4bfe745ccb5d29466ffa854dca03e395b6c3504a734341746b2846d76583a780b32e\",\n    \"0x940cbaa0d2b2db94ae96b6b9cf2deefbfd059e3e5745de9aec4a25f0991b9721e5cd37ef71c631575d1a0c280b01cd5b\",\n    \"0xae33cb4951191258a11044682de861bf8d92d90ce751b354932dd9f3913f542b6a0f8a4dc228b3cd9244ac32c4582832\",\n    \"0xa580df5e58c4274fe0f52ac2da1837e32f5c9db92be16c170187db4c358f43e5cfdda7c5911dcc79d77a5764e32325f5\",\n    \"0x81798178cb9d8affa424f8d3be67576ba94d108a28ccc01d330c51d5a63ca45bb8ca63a2f569b5c5fe1303cecd2d777f\",\n    \"0x89975b91b94c25c9c3660e4af4047a8bacf964783010820dbc91ff8281509379cb3b24c25080d5a01174dd9a049118d5\",\n    \"0xa7327fcb3710ed3273b048650bde40a32732ef40a7e58cf7f2f400979c177944c8bc54117ba6c80d5d4260801dddab79\",\n    \"0x92b475dc8cb5be4b90c482f122a51bcb3b6c70593817e7e2459c28ea54a7845c50272af38119406eaadb9bcb993368d0\",\n    \"0x9645173e9ecefc4f2eae8363504f7c0b81d85f8949a9f8a6c01f2d49e0a0764f4eacecf3e94016dd407fc14494fce9f9\",\n    \"0x9215fd8983d7de6ae94d35e6698226fc1454977ae58d42d294be9aad13ac821562ad37d5e7ee5cdfe6e87031d45cd197\",\n    \"0x810360a1c9b88a9e36f520ab5a1eb8bed93f52deefbe1312a69225c0a08edb10f87cc43b794aced9c74220cefcc57e7d\",\n    \"0xad7e810efd61ed4684aeda9ed8bb02fb9ae4b4b63fda8217d37012b94ff1b91c0087043bfa4e376f961fff030c729f3b\",\n    \"0x8b07c95c6a06db8738d10bb03ec11b89375c08e77f0cab7e672ce70b2685667ca19c7e1c8b092821d31108ea18dfd4c7\",\n    \"0x968825d025ded899ff7c57245250535c732836f7565eab1ae23ee7e513201d413c16e1ba3f5166e7ac6cf74de8ceef4f\",\n    \"0x908243370c5788200703ade8164943ad5f8c458219186432e74dbc9904a701ea307fd9b94976c866e6c58595fd891c4b\",\n    \"0x959969d16680bc535cdc6339e6186355d0d6c0d53d7bbfb411641b9bf4b770fd5f575beef5deec5c4fa4d192d455c350\",\n    \"0xad177f4f826a961adeac76da40e2d930748effff731756c797eddc4e5aa23c91f070fb69b19221748130b0961e68a6bb\",\n    \"0x82f8462bcc25448ef7e0739425378e9bb8a05e283ce54aae9dbebaf7a3469f57833c9171672ad43a79778366c72a5e37\",\n    \"0xa28fb275b1845706c2814d9638573e9bc32ff552ebaed761fe96fdbce70395891ca41c400ae438369264e31a2713b15f\",\n    \"0x8a9c613996b5e51dadb587a787253d6081ea446bf5c71096980bf6bd3c4b69905062a8e8a3792de2d2ece3b177a71089\",\n    \"0x8d5aefef9f60cb27c1db2c649221204dda48bb9bf8bf48f965741da051340e8e4cab88b9d15c69f3f84f4c854709f48a\",\n    \"0x93ebf2ca6ad85ab6deace6de1a458706285b31877b1b4d7dcb9d126b63047efaf8c06d580115ec9acee30c8a7212fa55\",\n    \"0xb3ee46ce189956ca298057fa8223b7fd1128cf52f39159a58bca03c71dd25161ac13f1472301f72aef3e1993fe1ab269\",\n    \"0xa24d7a8d066504fc3f5027ccb13120e2f22896860e02c45b5eba1dbd512d6a17c28f39155ea581619f9d33db43a96f92\",\n    \"0xae9ceacbfe12137db2c1a271e1b34b8f92e4816bad1b3b9b6feecc34df0f8b3b0f7ed0133acdf59c537d43d33fc8d429\",\n    \"0x83967e69bf2b361f86361bd705dce0e1ad26df06da6c52b48176fe8dfcbeb03c462c1a4c9e649eff8c654b18c876fdef\",\n    \"0x9148e6b814a7d779c19c31e33a068e97b597de1f8100513db3c581190513edc4d544801ce3dd2cf6b19e0cd6daedd28a\",\n    \"0x94ccdafc84920d320ed22de1e754adea072935d3c5f8c2d1378ebe53d140ea29853f056fb3fb1e375846061a038cc9bc\",\n    \"0xafb43348498c38b0fa5f971b8cdd3a62c844f0eb52bc33daf2f67850af0880fce84ecfb96201b308d9e6168a0d443ae3\",\n    \"0x86d5736520a83538d4cd058cc4b4e84213ed00ebd6e7af79ae787adc17a92ba5359e28ba6c91936d967b4b28d24c3070\",\n    \"0xb5210c1ff212c5b1e9ef9126e08fe120a41e386bb12c22266f7538c6d69c7fd8774f11c02b81fd4e88f9137b020801fe\",\n    \"0xb78cfd19f94d24e529d0f52e18ce6185cb238edc6bd43086270fd51dd99f664f43dd4c7d2fe506762fbd859028e13fcf\",\n    \"0xa6e7220598c554abdcc3fdc587b988617b32c7bb0f82c06205467dbedb58276cc07cae317a190f19d19078773f4c2bbb\",\n    \"0xb88862809487ee430368dccd85a5d72fa4d163ca4aad15c78800e19c1a95be2192719801e315d86cff7795e0544a77e4\",\n    \"0x87ecb13a03921296f8c42ceb252d04716f10e09c93962239fcaa0a7fef93f19ab3f2680bc406170108bc583e9ff2e721\",\n    \"0xa810cd473832b6581c36ec4cb403f2849357ba2d0b54df98ef3004b8a530c078032922a81d40158f5fb0043d56477f6e\",\n    \"0xa247b45dd85ca7fbb718b328f30a03f03c84aef2c583fbdc9fcc9eb8b52b34529e8c8f535505c10598b1b4dac3d7c647\",\n    \"0x96ee0b91313c68bac4aa9e065ce9e1d77e51ca4cff31d6a438718c58264dee87674bd97fc5c6b8008be709521e4fd008\",\n    \"0x837567ad073e42266951a9a54750919280a2ac835a73c158407c3a2b1904cf0d17b7195a393c71a18ad029cbd9cf79ee\",\n    \"0xa6a469c44b67ebf02196213e7a63ad0423aab9a6e54acc6fcbdbb915bc043586993454dc3cd9e4be8f27d67c1050879b\",\n    \"0x8712d380a843b08b7b294f1f06e2f11f4ad6bcc655fdde86a4d8bc739c23916f6fad2b902fe47d6212f03607907e9f0e\",\n    \"0x920adfb644b534789943cdae1bdd6e42828dda1696a440af2f54e6b97f4f97470a1c6ea9fa6a2705d8f04911d055acd1\",\n    \"0xa161c73adf584a0061e963b062f59d90faac65c9b3a936b837a10d817f02fcabfa748824607be45a183dd40f991fe83f\",\n    \"0x874f4ecd408c76e625ea50bc59c53c2d930ee25baf4b4eca2440bfbffb3b8bc294db579caa7c68629f4d9ec24187c1ba\",\n    \"0x8bff18087f112be7f4aa654e85c71fef70eee8ae480f61d0383ff6f5ab1a0508f966183bb3fc4d6f29cb7ca234aa50d3\",\n    \"0xb03b46a3ca3bc743a173cbc008f92ab1aedd7466b35a6d1ca11e894b9482ea9dc75f8d6db2ddd1add99bfbe7657518b7\",\n    \"0x8b4f3691403c3a8ad9e097f02d130769628feddfa8c2b3dfe8cff64e2bed7d6e5d192c1e2ba0ac348b8585e94acd5fa1\",\n    \"0xa0d9ca4a212301f97591bf65d5ef2b2664766b427c9dd342e23cb468426e6a56be66b1cb41fea1889ac5d11a8e3c50a5\",\n    \"0x8c93ed74188ca23b3df29e5396974b9cc135c91fdefdea6c0df694c8116410e93509559af55533a3776ac11b228d69b1\",\n    \"0x82dd331fb3f9e344ebdeeb557769b86a2cc8cc38f6c298d7572a33aea87c261afa9dbd898989139b9fc16bc1e880a099\",\n    \"0xa65faedf326bcfd8ef98a51410c78b021d39206704e8291cd1f09e096a66b9b0486be65ff185ca224c45918ac337ddeb\",\n    \"0xa188b37d363ac072a766fd5d6fa27df07363feff1342217b19e3c37385e42ffde55e4be8355aceaa2f267b6d66b4ac41\",\n    \"0x810fa3ba3e96d843e3bafd3f2995727f223d3567c8ba77d684c993ba1773c66551eb5009897c51b3fe9b37196984f5ec\",\n    \"0x87631537541852da323b4353af45a164f68b304d24c01183bf271782e11687f3fcf528394e1566c2a26cb527b3148e64\",\n    \"0xb721cb2b37b3c477a48e3cc0044167d51ff568a5fd2fb606e5aec7a267000f1ddc07d3db919926ae12761a8e017c767c\",\n    \"0x904dfad4ba2cc1f6e60d1b708438a70b1743b400164cd981f13c064b8328d5973987d4fb9cf894068f29d3deaf624dfb\",\n    \"0xa70491538893552c20939fae6be2f07bfa84d97e2534a6bbcc0f1729246b831103505e9f60e97a8fa7d2e6c1c2384579\",\n    \"0x8726cf1b26b41f443ff7485adcfddc39ace2e62f4d65dd0bb927d933e262b66f1a9b367ded5fbdd6f3b0932553ac1735\",\n    \"0xae8a11cfdf7aa54c08f80cb645e3339187ab3886babe9fae5239ba507bb3dd1c0d161ca474a2df081dcd3d63e8fe445e\",\n    \"0x92328719e97ce60e56110f30a00ac5d9c7a2baaf5f8d22355d53c1c77941e3a1fec7d1405e6fbf8959665fe2ba7a8cad\",\n    \"0x8d9d6255b65798d0018a8cccb0b6343efd41dc14ff2058d3eed9451ceaad681e4a0fa6af67b0a04318aa628024e5553d\",\n    \"0xb70209090055459296006742d946a513f0cba6d83a05249ee8e7a51052b29c0ca9722dc4af5f9816a1b7938a5dac7f79\",\n    \"0xaab7b766b9bf91786dfa801fcef6d575dc6f12b77ecc662eb4498f0312e54d0de9ea820e61508fc8aeee5ab5db529349\",\n    \"0xa8104b462337748b7f086a135d0c3f87f8e51b7165ca6611264b8fb639d9a2f519926cb311fa2055b5fadf03da70c678\",\n    \"0xb0d2460747d5d8b30fc6c6bd0a87cb343ddb05d90a51b465e8f67d499cfc5e3a9e365da05ae233bbee792cdf90ec67d5\",\n    \"0xaa55f5bf3815266b4a149f85ed18e451c93de9163575e3ec75dd610381cc0805bb0a4d7c4af5b1f94d10231255436d2c\",\n    \"0x8d4c6a1944ff94426151909eb5b99cfd92167b967dabe2bf3aa66bb3c26c449c13097de881b2cfc1bf052862c1ef7b03\",\n    \"0x8862296162451b9b6b77f03bf32e6df71325e8d7485cf3335d66fd48b74c2a8334c241db8263033724f26269ad95b395\",\n    \"0x901aa96deb26cda5d9321190ae6624d357a41729d72ef1abfd71bebf6139af6d690798daba53b7bc5923462115ff748a\",\n    \"0x96c195ec4992728a1eb38cdde42d89a7bce150db43adbc9e61e279ea839e538deec71326b618dd39c50d589f78fc0614\",\n    \"0xb6ff8b8aa0837b99a1a8b46fb37f20ad4aecc6a98381b1308697829a59b8442ffc748637a88cb30c9b1f0f28a926c4f6\",\n    \"0x8d807e3dca9e7bef277db1d2cfb372408dd587364e8048b304eff00eacde2c723bfc84be9b98553f83cba5c7b3cba248\",\n    \"0x8800c96adb0195c4fc5b24511450dee503c32bf47044f5e2e25bd6651f514d79a2dd9b01cd8c09f3c9d3859338490f57\",\n    \"0x89fe366096097e38ec28dd1148887112efa5306cc0c3da09562aafa56f4eb000bf46ff79bf0bdd270cbde6bf0e1c8957\",\n    \"0xaf409a90c2776e1e7e3760b2042507b8709e943424606e31e791d42f17873a2710797f5baaab4cc4a19998ef648556b0\",\n    \"0x8d761863c9b6edbd232d35ab853d944f5c950c2b643f84a1a1327ebb947290800710ff01dcfa26dc8e9828481240e8b1\",\n    \"0x90b95e9be1e55c463ed857c4e0617d6dc3674e99b6aa62ed33c8e79d6dfcf7d122f4f4cc2ee3e7c5a49170cb617d2e2e\",\n    \"0xb3ff381efefabc4db38cc4727432e0301949ae4f16f8d1dea9b4f4de611cf5a36d84290a0bef160dac4e1955e516b3b0\",\n    \"0xa8a84564b56a9003adcadb3565dc512239fc79572762cda7b5901a255bc82656bb9c01212ad33d6bef4fbbce18dacc87\",\n    \"0x90a081890364b222eef54bf0075417f85e340d2fec8b7375995f598aeb33f26b44143ebf56fca7d8b4ebb36b5747b0eb\",\n    \"0xade6ee49e1293224ddf2d8ab7f14bb5be6bc6284f60fd5b3a1e0cf147b73cff57cf19763b8a36c5083badc79c606b103\",\n    \"0xb2fa99806dd2fa3de09320b615a2570c416c9bcdb052e592b0aead748bbe407ec9475a3d932ae48b71c2627eb81986a6\",\n    \"0x91f3b7b73c8ccc9392542711c45fe6f236057e6efad587d661ad5cb4d6e88265f86b807bb1151736b1009ab74fd7acb4\",\n    \"0x8800e2a46af96696dfbdcbf2ca2918b3dcf28ad970170d2d1783b52b8d945a9167d052beeb55f56c126da7ffa7059baa\",\n    \"0x9862267a1311c385956b977c9aa08548c28d758d7ba82d43dbc3d0a0fd1b7a221d39e8399997fea9014ac509ff510ac4\",\n    \"0xb7d24f78886fd3e2d283e18d9ad5a25c1a904e7d9b9104bf47da469d74f34162e27e531380dbbe0a9d051e6ffd51d6e7\",\n    \"0xb0f445f9d143e28b9df36b0f2c052da87ee2ca374d9d0fbe2eff66ca6fe5fe0d2c1951b428d58f7314b7e74e45d445ea\",\n    \"0xb63fc4083eabb8437dafeb6a904120691dcb53ce2938b820bb553da0e1eecd476f72495aacb72600cf9cad18698fd3db\",\n    \"0xb9ffd8108eaebd582d665f8690fe8bb207fd85185e6dd9f0b355a09bac1bbff26e0fdb172bc0498df025414e88fe2eda\",\n    \"0x967ed453e1f1a4c5b7b6834cc9f75c13f6889edc0cc91dc445727e9f408487bbf05c337103f61397a10011dfbe25d61d\",\n    \"0x98ceb673aff36e1987d5521a3984a07079c3c6155974bb8b413e8ae1ce84095fe4f7862fba7aefa14753eb26f2a5805f\",\n    \"0x85f01d28603a8fdf6ce6a50cb5c44f8a36b95b91302e3f4cd95c108ce8f4d212e73aec1b8d936520d9226802a2bd9136\",\n    \"0x88118e9703200ca07910345fbb789e7a8f92bd80bbc79f0a9e040e8767d33df39f6eded403a9b636eabf9101e588482a\",\n    \"0x90833a51eef1b10ed74e8f9bbd6197e29c5292e469c854eed10b0da663e2bceb92539710b1858bbb21887bd538d28d89\",\n    \"0xb513b905ec19191167c6193067b5cfdf5a3d3828375360df1c7e2ced5815437dfd37f0c4c8f009d7fb29ff3c8793f560\",\n    \"0xb1b6d405d2d18f9554b8a358cc7e2d78a3b34269737d561992c8de83392ac9a2857be4bf15de5a6c74e0c9d0f31f393c\",\n    \"0xb828bd3e452b797323b798186607849f85d1fb20c616833c0619360dfd6b3e3aa000fd09dafe4b62d74abc41072ff1a9\",\n    \"0x8efde67d0cca56bb2c464731879c9ac46a52e75bac702a63200a5e192b4f81c641f855ca6747752b84fe469cb7113b6c\",\n    \"0xb2762ba1c89ac3c9a983c242e4d1c2610ff0528585ed5c0dfc8a2c0253551142af9b59f43158e8915a1da7cc26b9df67\",\n    \"0x8a3f1157fb820d1497ef6b25cd70b7e16bb8b961b0063ad340d82a79ee76eb2359ca9e15e6d42987ed7f154f5eeaa2da\",\n    \"0xa75e29f29d38f09c879f971c11beb5368affa084313474a5ecafa2896180b9e47ea1995c2733ec46f421e395a1d9cffe\",\n    \"0x8e8c3dd3e7196ef0b4996b531ec79e4a1f211db5d5635e48ceb80ff7568b2ff587e845f97ee703bb23a60945ad64314a\",\n    \"0x8e7f32f4a3e3c584af5e3d406924a0aa34024c42eca74ef6cc2a358fd3c9efaf25f1c03aa1e66bb94b023a2ee2a1cace\",\n    \"0xab7dce05d59c10a84feb524fcb62478906b3fa045135b23afbede3bb32e0c678d8ebe59feabccb5c8f3550ea76cae44b\",\n    \"0xb38bb4b44d827f6fd3bd34e31f9186c59e312dbfadd4a7a88e588da10146a78b1f8716c91ad8b806beb8da65cab80c4c\",\n    \"0x9490ce9442bbbd05438c7f5c4dea789f74a7e92b1886a730544b55ba377840740a3ae4f2f146ee73f47c9278b0e233bc\",\n    \"0x83c003fab22a7178eed1a668e0f65d4fe38ef3900044e9ec63070c23f2827d36a1e73e5c2b883ec6a2afe2450171b3b3\",\n    \"0x9982f02405978ddc4fca9063ebbdb152f524c84e79398955e66fe51bc7c1660ec1afc3a86ec49f58d7b7dde03505731c\",\n    \"0xab337bd83ccdd2322088ffa8d005f450ced6b35790f37ab4534313315ee84312adc25e99cce052863a8bedee991729ed\",\n    \"0x8312ce4bec94366d88f16127a17419ef64285cd5bf9e5eda010319b48085966ed1252ed2f5a9fd3e0259b91bb65f1827\",\n    \"0xa60d5a6327c4041b0c00a1aa2f0af056520f83c9ce9d9ccd03a0bd4d9e6a1511f26a422ea86bd858a1f77438adf07e6c\",\n    \"0xb84a0a0b030bdad83cf5202aa9afe58c9820e52483ab41f835f8c582c129ee3f34aa096d11c1cd922eda02ea1196a882\",\n    \"0x8077d105317f4a8a8f1aadeb05e0722bb55f11abcb490c36c0904401107eb3372875b0ac233144829e734f0c538d8c1d\",\n    \"0x9202503bd29a6ec198823a1e4e098f9cfe359ed51eb5174d1ca41368821bfeebcbd49debfd02952c41359d1c7c06d2b1\",\n    \"0xabc28c155e09365cb77ffead8dc8f602335ef93b2f44e4ef767ce8fc8ef9dd707400f3a722e92776c2e0b40192c06354\",\n    \"0xb0f6d1442533ca45c9399e0a63a11f85ff288d242cea6cb3b68c02e77bd7d158047cae2d25b3bcd9606f8f66d9b32855\",\n    \"0xb01c3d56a0db84dc94575f4b6ee2de4beca3230e86bed63e2066beb22768b0a8efb08ebaf8ac3dedb5fe46708b084807\",\n    \"0x8c8634b0432159f66feaabb165842d1c8ac378f79565b1b90c381aa8450eb4231c3dad11ec9317b9fc2b155c3a771e32\",\n    \"0x8e67f623d69ecd430c9ee0888520b6038f13a2b6140525b056dc0951f0cfed2822e62cf11d952a483107c5c5acac4826\",\n    \"0x9590bb1cba816dd6acd5ac5fba5142c0a19d53573e422c74005e0bcf34993a8138c83124cad35a3df65879dba6134edd\",\n    \"0x801cd96cde0749021a253027118d3ea135f3fcdbe895db08a6c145641f95ebd368dd6a1568d995e1d0084146aebe224a\",\n    \"0x848b5d196427f6fc1f762ee3d36e832b64a76ec1033cfedc8b985dea93932a7892b8ef1035c653fb9dcd9ab2d9a44ac8\",\n    \"0xa1017eb83d5c4e2477e7bd2241b2b98c4951a3b391081cae7d75965cadc1acaec755cf350f1f3d29741b0828e36fedea\",\n    \"0x8d6d2785e30f3c29aad17bd677914a752f831e96d46caf54446d967cb2432be2c849e26f0d193a60bee161ea5c6fe90a\",\n    \"0x935c0ba4290d4595428e034b5c8001cbd400040d89ab00861108e8f8f4af4258e41f34a7e6b93b04bc253d3b9ffc13bf\",\n    \"0xaac02257146246998477921cef2e9892228590d323b839f3e64ea893b991b463bc2f47e1e5092ddb47e70b2f5bce7622\",\n    \"0xb921fde9412970a5d4c9a908ae8ce65861d06c7679af577cf0ad0d5344c421166986bee471fd6a6cecb7d591f06ec985\",\n    \"0x8ef4c37487b139d6756003060600bb6ebac7ea810b9c4364fc978e842f13ac196d1264fbe5af60d76ff6d9203d8e7d3f\",\n    \"0x94b65e14022b5cf6a9b95f94be5ace2711957c96f4211c3f7bb36206bd39cfbd0ea82186cab5ad0577a23214a5c86e9e\",\n    \"0xa31c166d2a2ca1d5a75a5920fef7532681f62191a50d8555fdaa63ba4581c3391cc94a536fc09aac89f64eafceec3f90\",\n    \"0x919a8cc128de01e9e10f5d83b08b52293fdd41bde2b5ae070f3d95842d4a16e5331cf2f3d61c765570c8022403610fa4\",\n    \"0xb23d6f8331eef100152d60483cfa14232a85ee712c8538c9b6417a5a7c5b353c2ac401390c6c215cb101f5cee6b5f43e\",\n    \"0xab357160c08a18319510a571eafff154298ce1020de8e1dc6138a09fcb0fcbcdd8359f7e9386bda00b7b9cdea745ffdc\",\n    \"0xab55079aea34afa5c0bd1124b9cdfe01f325b402fdfa017301bf87812eaa811ea5798c3aaf818074d420d1c782b10ada\",\n    \"0xade616010dc5009e7fc4f8d8b00dc716686a5fa0a7816ad9e503e15839d3b909b69d9dd929b7575376434ffec0d2bea8\",\n    \"0x863997b97ed46898a8a014599508fa3079f414b1f4a0c4fdc6d74ae8b444afa350f327f8bfc2a85d27f9e2d049c50135\",\n    \"0x8d602ff596334efd4925549ed95f2aa762b0629189f0df6dbb162581657cf3ea6863cd2287b4d9c8ad52813d87fcd235\",\n    \"0xb70f68c596dcdeed92ad5c6c348578b26862a51eb5364237b1221e840c47a8702f0fbc56eb520a22c0eed99795d3903e\",\n    \"0x9628088f8e0853cefadee305a8bf47fa990c50fa96a82511bbe6e5dc81ef4b794e7918a109070f92fc8384d77ace226f\",\n    \"0x97e26a46e068b605ce96007197ecd943c9a23881862f4797a12a3e96ba2b8d07806ad9e2a0646796b1889c6b7d75188c\",\n    \"0xb1edf467c068cc163e2d6413cc22b16751e78b3312fe47b7ea82b08a1206d64415b2c8f2a677fa89171e82cc49797150\",\n    \"0xa44d15ef18745b251429703e3cab188420e2d974de07251501799b016617f9630643fcd06f895634d8ecdd579e1bf000\",\n    \"0xabd126df3917ba48c618ee4dbdf87df506193462f792874439043fa1b844466f6f4e0ff2e42516e63b5b23c0892b2695\",\n    \"0xa2a67f57c4aa3c2aa1eeddbfd5009a89c26c2ce8fa3c96a64626aba19514beb125f27df8559506f737de3eae0f1fc18f\",\n    \"0xa633e0132197e6038197304b296ab171f1d8e0d0f34dcf66fe9146ac385b0239232a8470b9205a4802ab432389f4836d\",\n    \"0xa914b3a28509a906c3821463b936455d58ff45dcbe158922f9efb2037f2eb0ce8e92532d29b5d5a3fcd0d23fa773f272\",\n    \"0xa0e1412ce4505daf1a2e59ce4f0fc0e0023e335b50d2b204422f57cd65744cc7a8ed35d5ef131a42c70b27111d3115b7\",\n    \"0xa2339e2f2b6072e88816224fdd612c04d64e7967a492b9f8829db15367f565745325d361fd0607b0def1be384d010d9e\",\n    \"0xa7309fc41203cb99382e8193a1dcf03ac190a7ce04835304eb7e341d78634e83ea47cb15b885601956736d04cdfcaa01\",\n    \"0x81f3ccd6c7f5b39e4e873365f8c37b214e8ab122d04a606fbb7339dc3298c427e922ec7418002561d4106505b5c399ee\",\n    \"0x92c121cf914ca549130e352eb297872a63200e99b148d88fbc9506ad882bec9d0203d65f280fb5b0ba92e336b7f932e8\",\n    \"0xa4b330cf3f064f5b131578626ad7043ce2a433b6f175feb0b52d36134a454ca219373fd30d5e5796410e005b69082e47\",\n    \"0x86fe5774112403ad83f9c55d58317eeb17ad8e1176d9f2f69c2afb7ed83bc718ed4e0245ceab4b377f5f062dcd4c00e7\",\n    \"0x809d152a7e2654c7fd175b57f7928365a521be92e1ed06c05188a95864ddb25f7cab4c71db7d61bbf4cae46f3a1d96ce\",\n    \"0xb82d663e55c2a5ada7e169e9b1a87bc1c0177baf1ec1c96559b4cb1c5214ce1ddf2ab8d345014cab6402f3774235cf5a\",\n    \"0x86580af86df1bd2c385adb8f9a079e925981b7184db66fc5fe5b14cddb82e7d836b06eaeef14924ac529487b23dae111\",\n    \"0xb5f5f4c5c94944ecc804df6ab8687d64e27d988cbfeae1ba7394e0f6adbf778c5881ead7cd8082dd7d68542b9bb4ecd5\",\n    \"0xa6016916146c2685c46e8fdd24186394e2d5496e77e08c0c6a709d4cd7dfa97f1efcef94922b89196819076a91ad37b5\",\n    \"0xb778e7367ded3b6eab53d5fc257f7a87e8faf74a593900f2f517220add2125be3f6142022660d8181df8d164ad9441ce\",\n    \"0x8581b2d36abe6f553add4d24be761bec1b8efaa2929519114346615380b3c55b59e6ad86990e312f7e234d0203bdf59b\",\n    \"0x9917e74fd45c3f71a829ff5498a7f6b5599b48c098dda2339bf04352bfc7f368ccf1a407f5835901240e76452ae807d7\",\n    \"0xafd196ce6f9335069138fd2e3d133134da253978b4ce373152c0f26affe77a336505787594022e610f8feb722f7cc1fb\",\n    \"0xa477491a1562e329764645e8f24d8e228e5ef28c9f74c6b5b3abc4b6a562c15ffb0f680d372aed04d9e1bf944dece7be\",\n    \"0x9767440d58c57d3077319d3a330e5322b9ba16981ec74a5a14d53462eab59ae7fd2b14025bfc63b268862094acb444e6\",\n    \"0x80986d921be3513ef69264423f351a61cb48390c1be8673aee0f089076086aaebea7ebe268fd0aa7182695606116f679\",\n    \"0xa9554c5c921c07b450ee04e34ec58e054ac1541b26ce2ce5a393367a97348ba0089f53db6660ad76b60278b66fd12e3e\",\n    \"0x95097e7d2999b3e84bf052c775581cf361325325f4a50192521d8f4693c830bed667d88f482dc1e3f833aa2bd22d2cbf\",\n    \"0x9014c91d0f85aefd28436b5228c12f6353c055a9326c7efbf5e071e089e2ee7c070fcbc84c5fafc336cbb8fa6fec1ca1\",\n    \"0x90f57ba36ee1066b55d37384942d8b57ae00f3cf9a3c1d6a3dfee1d1af42d4b5fa9baeb0cd7e46687d1d6d090ddb931d\",\n    \"0x8e4b1db12fd760a17214c9e47f1fce6e43c0dbb4589a827a13ac61aaae93759345697bb438a00edab92e0b7b62414683\",\n    \"0x8022a959a513cdc0e9c705e0fc04eafd05ff37c867ae0f31f6d01cddd5df86138a426cab2ff0ac8ff03a62e20f7e8f51\",\n    \"0x914e9a38829834c7360443b8ed86137e6f936389488eccf05b4b4db7c9425611705076ecb3f27105d24b85c852be7511\",\n    \"0x957fb10783e2bd0db1ba66b18e794df710bc3b2b05776be146fa5863c15b1ebdd39747b1a95d9564e1772cdfc4f37b8a\",\n    \"0xb6307028444daed8ed785ac9d0de76bc3fe23ff2cc7e48102553613bbfb5afe0ebe45e4212a27021c8eb870721e62a1f\",\n    \"0x8f76143597777d940b15a01b39c5e1b045464d146d9a30a6abe8b5d3907250e6c7f858ff2308f8591e8b0a7b3f3c568a\",\n    \"0x96163138ac0ce5fd00ae9a289648fd9300a0ca0f63a88481d703ecd281c06a52a3b5178e849e331f9c85ca4ba398f4cc\",\n    \"0xa63ef47c3e18245b0482596a09f488a716df3cbd0f9e5cfabed0d742843e65db8961c556f45f49762f3a6ac8b627b3ef\",\n    \"0x8cb595466552e7c4d42909f232d4063e0a663a8ef6f6c9b7ce3a0542b2459cde04e0e54c7623d404acb5b82775ac04f6\",\n    \"0xb47fe69960eb45f399368807cff16d941a5a4ebad1f5ec46e3dc8a2e4d598a7e6114d8f0ca791e9720fd786070524e2b\",\n    \"0x89eb5ff83eea9df490e5beca1a1fbbbbcf7184a37e2c8c91ede7a1e654c81e8cd41eceece4042ea7918a4f4646b67fd6\",\n    \"0xa84f5d155ed08b9054eecb15f689ba81e44589e6e7207a99790c598962837ca99ec12344105b16641ca91165672f7153\",\n    \"0xa6cc8f25c2d5b2d2f220ec359e6a37a52b95fa6af6e173c65e7cd55299eff4aa9e6d9e6f2769e6459313f1f2aecb0fab\",\n    \"0xafcde944411f017a9f7979755294981e941cc41f03df5e10522ef7c7505e5f1babdd67b3bf5258e8623150062eb41d9b\",\n    \"0x8fab39f39c0f40182fcd996ade2012643fe7731808afbc53f9b26900b4d4d1f0f5312d9d40b3df8baa4739970a49c732\",\n    \"0xae193af9726da0ebe7df1f9ee1c4846a5b2a7621403baf8e66c66b60f523e719c30c6b4f897bb14b27d3ff3da8392eeb\",\n    \"0x8ac5adb82d852eba255764029f42e6da92dcdd0e224d387d1ef94174038db9709ac558d90d7e7c57ad4ce7f89bbfc38c\",\n    \"0xa2066b3458fdf678ee487a55dd5bfb74fde03b54620cb0e25412a89ee28ad0d685e309a51e3e4694be2fa6f1593a344c\",\n    \"0x88d031745dd0ae07d61a15b594be5d4b2e2a29e715d081649ad63605e3404b0c3a5353f0fd9fad9c05c18e93ce674fa1\",\n    \"0x8283cfb0ef743a043f2b77ecaeba3005e2ca50435585b5dd24777ee6bce12332f85e21b446b536da38508807f0f07563\",\n    \"0xb376de22d5f6b0af0b59f7d9764561f4244cf8ffe22890ecd3dcf2ff1832130c9b821e068c9d8773136f4796721e5963\",\n    \"0xae3afc50c764f406353965363840bf28ee85e7064eb9d5f0bb3c31c64ab10f48c853e942ee2c9b51bae59651eaa08c2f\",\n    \"0x948b204d103917461a01a6c57a88f2d66b476eae5b00be20ec8c747650e864bc8a83aee0aff59cb7584b7a3387e0ee48\",\n    \"0x81ab098a082b07f896c5ffd1e4446cb7fb44804cbbf38d125208b233fc82f8ec9a6a8d8dd1c9a1162dc28ffeec0dde50\",\n    \"0xa149c6f1312821ced2969268789a3151bdda213451760b397139a028da609c4134ac083169feb0ee423a0acafd10eceb\",\n    \"0xb0ac9e27a5dadaf523010f730b28f0ebac01f460d3bbbe277dc9d44218abb5686f4fac89ae462682fef9edbba663520a\",\n    \"0x8d0e0073cca273daaaa61b6fc54bfe5a009bc3e20ae820f6c93ba77b19eca517d457e948a2de5e77678e4241807157cb\",\n    \"0xad61d3a2edf7c7533a04964b97499503fd8374ca64286dba80465e68fe932e96749b476f458c6fc57cb1a7ca85764d11\",\n    \"0x90eb5e121ae46bc01a30881eaa556f46bd8457a4e80787cf634aab355082de34ac57d7f497446468225f7721e68e2a47\",\n    \"0x8cdac557de7c42d1f3780e33dec1b81889f6352279be81c65566cdd4952d4c15d79e656cbd46035ab090b385e90245ef\",\n    \"0x82b67e61b88b84f4f4d4f65df37b3e3dcf8ec91ea1b5c008fdccd52da643adbe6468a1cfdb999e87d195afe2883a3b46\",\n    \"0x8503b467e8f5d6048a4a9b78496c58493a462852cab54a70594ae3fd064cfd0deb4b8f336a262155d9fedcaa67d2f6fd\",\n    \"0x8db56c5ac763a57b6ce6832930c57117058e3e5a81532b7d19346346205e2ec614eb1a2ee836ef621de50a7bc9b7f040\",\n    \"0xad344699198f3c6e8c0a3470f92aaffc805b76266734414c298e10b5b3797ca53578de7ccb2f458f5e0448203f55282b\",\n    \"0x80602032c43c9e2a09154cc88b83238343b7a139f566d64cb482d87436b288a98f1ea244fd3bff8da3c398686a900c14\",\n    \"0xa6385bd50ecd548cfb37174cdbb89e10025b5cadaf3cff164c95d7aef5a33e3d6a9bf0c681b9e11db9ef54ebeee2a0c1\",\n    \"0xabf2d95f4aa34b0581eb9257a0cc8462b2213941a5deb8ba014283293e8b36613951b61261cc67bbd09526a54cbbff76\",\n    \"0xa3d5de52f48df72c289ff713e445991f142390798cd42bd9d9dbefaee4af4f5faf09042d126b975cf6b98711c3072553\",\n    \"0x8e627302ff3d686cff8872a1b7c2a57b35f45bf2fc9aa42b049d8b4d6996a662b8e7cbac6597f0cb79b0cc4e29fbf133\",\n    \"0x8510702e101b39a1efbf4e504e6123540c34b5689645e70d0bac1ecc1baf47d86c05cef6c4317a4e99b4edaeb53f2d00\",\n    \"0xaa173f0ecbcc6088f878f8726d317748c81ebf501bba461f163b55d66099b191ec7c55f7702f351a9c8eb42cfa3280e2\",\n    \"0xb560a697eafab695bcef1416648a0a664a71e311ecbe5823ae903bd0ed2057b9d7574b9a86d3fe22aa3e6ddce38ea513\",\n    \"0x8df6304a3d9cf40100f3f687575419c998cd77e5cc27d579cf4f8e98642de3609af384a0337d145dd7c5635172d26a71\",\n    \"0x8105c7f3e4d30a29151849673853b457c1885c186c132d0a98e63096c3774bc9deb956cf957367e633d0913680bda307\",\n    \"0x95373fc22c0917c3c2044ac688c4f29a63ed858a45c0d6d2d0fe97afd6f532dcb648670594290c1c89010ecc69259bef\",\n    \"0x8c2fae9bcadab341f49b55230310df93cac46be42d4caa0d42e45104148a91e527af1b4209c0d972448162aed28fab64\",\n    \"0xb05a77baab70683f76209626eaefdda2d36a0b66c780a20142d23c55bd479ddd4ad95b24579384b6cf62c8eb4c92d021\",\n    \"0x8e6bc6a7ea2755b4aaa19c1c1dee93811fcde514f03485fdc3252f0ab7f032c315614f6336e57cea25dcfb8fb6084eeb\",\n    \"0xb656a27d06aade55eadae2ad2a1059198918ea6cc3fd22c0ed881294d34d5ac7b5e4700cc24350e27d76646263b223aa\",\n    \"0xa296469f24f6f56da92d713afcd4dd606e7da1f79dc4e434593c53695847eefc81c7c446486c4b3b8c8d00c90c166f14\",\n    \"0x87a326f57713ac2c9dffeb3af44b9f3c613a8f952676fc46343299122b47ee0f8d792abaa4b5db6451ced5dd153aabd0\",\n    \"0xb689e554ba9293b9c1f6344a3c8fcb6951d9f9eac4a2e2df13de021aade7c186be27500e81388e5b8bcab4c80f220a31\",\n    \"0x87ae0aa0aa48eac53d1ca5a7b93917de12db9e40ceabf8fdb40884ae771cfdf095411deef7c9f821af0b7070454a2608\",\n    \"0xa71ffa7eae8ace94e6c3581d4cb2ad25d48cbd27edc9ec45baa2c8eb932a4773c3272b2ffaf077b40f76942a1f3af7f2\",\n    \"0x94c218c91a9b73da6b7a495b3728f3028df8ad9133312fc0c03e8c5253b7ccb83ed14688fd4602e2fd41f29a0bc698bd\",\n    \"0xae1e77b90ca33728af07a4c03fb2ef71cd92e2618e7bf8ed4d785ce90097fc4866c29999eb84a6cf1819d75285a03af2\",\n    \"0xb7a5945b277dab9993cf761e838b0ac6eaa903d7111fca79f9fde3d4285af7a89bf6634a71909d095d7619d913972c9c\",\n    \"0x8c43b37be02f39b22029b20aca31bff661abce4471dca88aa3bddefd9c92304a088b2dfc8c4795acc301ca3160656af2\",\n    \"0xb32e5d0fba024554bd5fe8a793ebe8003335ddd7f585876df2048dcf759a01285fecb53daae4950ba57f3a282a4d8495\",\n    \"0x85ea7fd5e10c7b659df5289b2978b2c89e244f269e061b9a15fcab7983fc1962b63546e82d5731c97ec74b6804be63ef\",\n    \"0x96b89f39181141a7e32986ac02d7586088c5a9662cec39843f397f3178714d02f929af70630c12cbaba0268f8ba2d4fa\",\n    \"0x929ab1a2a009b1eb37a2817c89696a06426529ebe3f306c586ab717bd34c35a53eca2d7ddcdef36117872db660024af9\",\n    \"0xa696dccf439e9ca41511e16bf3042d7ec0e2f86c099e4fc8879d778a5ea79e33aa7ce96b23dc4332b7ba26859d8e674d\",\n    \"0xa8fe69a678f9a194b8670a41e941f0460f6e2dbc60470ab4d6ae2679cc9c6ce2c3a39df2303bee486dbfde6844e6b31a\",\n    \"0x95f58f5c82de2f2a927ca99bf63c9fc02e9030c7e46d0bf6b67fe83a448d0ae1c99541b59caf0e1ccab8326231af09a5\",\n    \"0xa57badb2c56ca2c45953bd569caf22968f76ed46b9bac389163d6fe22a715c83d5e94ae8759b0e6e8c2f27bff7748f3f\",\n    \"0x868726fd49963b24acb5333364dffea147e98f33aa19c7919dc9aca0fd26661cfaded74ede7418a5fadbe7f5ae67b67b\",\n    \"0xa8d8550dcc64d9f1dd7bcdab236c4122f2b65ea404bb483256d712c7518f08bb028ff8801f1da6aed6cbfc5c7062e33b\",\n    \"0x97e25a87dae23155809476232178538d4bc05d4ff0882916eb29ae515f2a62bfce73083466cc0010ca956aca200aeacc\",\n    \"0xb4ea26be3f4bd04aa82d7c4b0913b97bcdf5e88b76c57eb1a336cbd0a3eb29de751e1bc47c0e8258adec3f17426d0c71\",\n    \"0x99ee555a4d9b3cf2eb420b2af8e3bc99046880536116d0ce7193464ac40685ef14e0e3c442f604e32f8338cb0ef92558\",\n    \"0x8c64efa1da63cd08f319103c5c7a761221080e74227bbc58b8fb35d08aa42078810d7af3e60446cbaff160c319535648\",\n    \"0x8d9fd88040076c28420e3395cbdfea402e4077a3808a97b7939d49ecbcf1418fe50a0460e1c1b22ac3f6e7771d65169a\",\n    \"0xae3c19882d7a9875d439265a0c7003c8d410367627d21575a864b9cb4918de7dbdb58a364af40c5e045f3df40f95d337\",\n    \"0xb4f7bfacab7b2cafe393f1322d6dcc6f21ffe69cd31edc8db18c06f1a2b512c27bd0618091fd207ba8df1808e9d45914\",\n    \"0x94f134acd0007c623fb7934bcb65ef853313eb283a889a3ffa79a37a5c8f3665f3d5b4876bc66223610c21dc9b919d37\",\n    \"0xaa15f74051171daacdc1f1093d3f8e2d13da2833624b80a934afec86fc02208b8f55d24b7d66076444e7633f46375c6a\",\n    \"0xa32d6bb47ef9c836d9d2371807bafbbbbb1ae719530c19d6013f1d1f813c49a60e4fa51d83693586cba3a840b23c0404\",\n    \"0xb61b3599145ea8680011aa2366dc511a358b7d67672d5b0c5be6db03b0efb8ca5a8294cf220ea7409621f1664e00e631\",\n    \"0x859cafc3ee90b7ececa1ed8ef2b2fc17567126ff10ca712d5ffdd16aa411a5a7d8d32c9cab1fbf63e87dce1c6e2f5f53\",\n    \"0xa2fef1b0b2874387010e9ae425f3a9676d01a095d017493648bcdf3b31304b087ccddb5cf76abc4e1548b88919663b6b\",\n    \"0x939e18c73befc1ba2932a65ede34c70e4b91e74cc2129d57ace43ed2b3af2a9cc22a40fbf50d79a63681b6d98852866d\",\n    \"0xb3b4259d37b1b14aee5b676c9a0dd2d7f679ab95c120cb5f09f9fbf10b0a920cb613655ddb7b9e2ba5af4a221f31303c\",\n    \"0x997255fe51aaca6e5a9cb3359bcbf25b2bb9e30649bbd53a8a7c556df07e441c4e27328b38934f09c09d9500b5fabf66\",\n    \"0xabb91be2a2d860fd662ed4f1c6edeefd4da8dc10e79251cf87f06029906e7f0be9b486462718f0525d5e049472692cb7\",\n    \"0xb2398e593bf340a15f7801e1d1fbda69d93f2a32a889ec7c6ae5e8a37567ac3e5227213c1392ee86cfb3b56ec2787839\",\n    \"0x8ddf10ccdd72922bed36829a36073a460c2118fc7a56ff9c1ac72581c799b15c762cb56cb78e3d118bb9f6a7e56cb25e\",\n    \"0x93e6bc0a4708d16387cacd44cf59363b994dc67d7ada7b6d6dbd831c606d975247541b42b2a309f814c1bfe205681fc6\",\n    \"0xb93fc35c05998cffda2978e12e75812122831523041f10d52f810d34ff71944979054b04de0117e81ddf5b0b4b3e13c0\",\n    \"0x92221631c44d60d68c6bc7b287509f37ee44cbe5fdb6935cee36b58b17c7325098f98f7910d2c3ca5dc885ad1d6dabc7\",\n    \"0xa230124424a57fad3b1671f404a94d7c05f4c67b7a8fbacfccea28887b78d7c1ed40b92a58348e4d61328891cd2f6cee\",\n    \"0xa6a230edb8518a0f49d7231bc3e0bceb5c2ac427f045819f8584ba6f3ae3d63ed107a9a62aad543d7e1fcf1f20605706\",\n    \"0x845be1fe94223c7f1f97d74c49d682472585d8f772762baad8a9d341d9c3015534cc83d102113c51a9dea2ab10d8d27b\",\n    \"0xb44262515e34f2db597c8128c7614d33858740310a49cdbdf9c8677c5343884b42c1292759f55b8b4abc4c86e4728033\",\n    \"0x805592e4a3cd07c1844bc23783408310accfdb769cca882ad4d07d608e590a288b7370c2cb327f5336e72b7083a0e30f\",\n    \"0x95153e8b1140df34ee864f4ca601cb873cdd3efa634af0c4093fbaede36f51b55571ab271e6a133020cd34db8411241f\",\n    \"0x82878c1285cfa5ea1d32175c9401f3cc99f6bb224d622d3fd98cc7b0a27372f13f7ab463ce3a33ec96f9be38dbe2dfe3\",\n    \"0xb7588748f55783077c27fc47d33e20c5c0f5a53fc0ac10194c003aa09b9f055d08ec971effa4b7f760553997a56967b3\",\n    \"0xb36b4de6d1883b6951f59cfae381581f9c6352fcfcf1524fccdab1571a20f80441d9152dc6b48bcbbf00371337ca0bd5\",\n    \"0x89c5523f2574e1c340a955cbed9c2f7b5fbceb260cb1133160dabb7d41c2f613ec3f6e74bbfab3c4a0a6f0626dbe068f\",\n    \"0xa52f58cc39f968a9813b1a8ddc4e83f4219e4dd82c7aa1dd083bea7edf967151d635aa9597457f879771759b876774e4\",\n    \"0x8300a67c2e2e123f89704abfde095463045dbd97e20d4c1157bab35e9e1d3d18f1f4aaba9cbe6aa2d544e92578eaa1b6\",\n    \"0xac6a7f2918768eb6a43df9d3a8a04f8f72ee52f2e91c064c1c7d75cad1a3e83e5aba9fe55bb94f818099ac91ccf2e961\",\n    \"0x8d64a2b0991cf164e29835c8ddef6069993a71ec2a7de8157bbfa2e00f6367be646ed74cbaf524f0e9fe13fb09fa15fd\",\n    \"0x8b2ffe5a545f9f680b49d0a9797a4a11700a2e2e348c34a7a985fc278f0f12def6e06710f40f9d48e4b7fbb71e072229\",\n    \"0x8ab8f71cd337fa19178924e961958653abf7a598e3f022138b55c228440a2bac4176cea3aea393549c03cd38a13eb3fc\",\n    \"0x8419d28318c19ea4a179b7abb43669fe96347426ef3ac06b158d79c0acf777a09e8e770c2fb10e14b3a0421705990b23\",\n    \"0x8bacdac310e1e49660359d0a7a17fe3d334eb820e61ae25e84cb52f863a2f74cbe89c2e9fc3283745d93a99b79132354\",\n    \"0xb57ace3fa2b9f6b2db60c0d861ace7d7e657c5d35d992588aeed588c6ce3a80b6f0d49f8a26607f0b17167ab21b675e4\",\n    \"0x83e265cde477f2ecc164f49ddc7fb255bb05ff6adc347408353b7336dc3a14fdedc86d5a7fb23f36b8423248a7a67ed1\",\n    \"0xa60ada971f9f2d79d436de5d3d045f5ab05308cae3098acaf5521115134b2a40d664828bb89895840db7f7fb499edbc5\",\n    \"0xa63eea12efd89b62d3952bf0542a73890b104dd1d7ff360d4755ebfa148fd62de668edac9eeb20507967ea37fb220202\",\n    \"0xa0275767a270289adc991cc4571eff205b58ad6d3e93778ddbf95b75146d82517e8921bd0d0564e5b75fa0ccdab8e624\",\n    \"0xb9b03fd3bf07201ba3a039176a965d736b4ef7912dd9e9bf69fe1b57c330a6aa170e5521fe8be62505f3af81b41d7806\",\n    \"0xa95f640e26fb1106ced1729d6053e41a16e4896acac54992279ff873e5a969aad1dcfa10311e28b8f409ac1dab7f03bb\",\n    \"0xb144778921742418053cb3c70516c63162c187f00db2062193bb2c14031075dbe055d020cde761b26e8c58d0ea6df2c1\",\n    \"0x8432fbb799e0435ef428d4fefc309a05dd589bce74d7a87faf659823e8c9ed51d3e42603d878e80f439a38be4321c2fa\",\n    \"0xb08ddef14e42d4fd5d8bf39feb7485848f0060d43b51ed5bdda39c05fe154fb111d29719ee61a23c392141358c0cfcff\",\n    \"0x8ae3c5329a5e025b86b5370e06f5e61177df4bda075856fade20a17bfef79c92f54ed495f310130021ba94fb7c33632b\",\n    \"0x92b6d3c9444100b4d7391febfc1dddaa224651677c3695c47a289a40d7a96d200b83b64e6d9df51f534564f272a2c6c6\",\n    \"0xb432bc2a3f93d28b5e506d68527f1efeb2e2570f6be0794576e2a6ef9138926fdad8dd2eabfa979b79ab7266370e86bc\",\n    \"0x8bc315eacedbcfc462ece66a29662ca3dcd451f83de5c7626ef8712c196208fb3d8a0faf80b2e80384f0dd9772f61a23\",\n    \"0xa72375b797283f0f4266dec188678e2b2c060dfed5880fc6bb0c996b06e91a5343ea2b695adaab0a6fd183b040b46b56\",\n    \"0xa43445036fbaa414621918d6a897d3692fdae7b2961d87e2a03741360e45ebb19fcb1703d23f1e15bb1e2babcafc56ac\",\n    \"0xb9636b2ffe305e63a1a84bd44fb402442b1799bd5272638287aa87ca548649b23ce8ce7f67be077caed6aa2dbc454b78\",\n    \"0x99a30bf0921d854c282b83d438a79f615424f28c2f99d26a05201c93d10378ab2cd94a792b571ddae5d4e0c0013f4006\",\n    \"0x8648e3c2f93d70b392443be116b48a863e4b75991bab5db656a4ef3c1e7f645e8d536771dfe4e8d1ceda3be8d32978b0\",\n    \"0xab50dc9e6924c1d2e9d2e335b2d679fc7d1a7632e84964d3bac0c9fe57e85aa5906ec2e7b0399d98ddd022e9b19b5904\",\n    \"0xab729328d98d295f8f3272afaf5d8345ff54d58ff9884da14f17ecbdb7371857fdf2f3ef58080054e9874cc919b46224\",\n    \"0x83fa5da7592bd451cad3ad7702b4006332b3aae23beab4c4cb887fa6348317d234bf62a359e665b28818e5410c278a09\",\n    \"0x8bdbff566ae9d368f114858ef1f009439b3e9f4649f73efa946e678d6c781d52c69af195df0a68170f5f191b2eac286b\",\n    \"0x91245e59b4425fd4edb2a61d0d47c1ccc83d3ced8180de34887b9655b5dcda033d48cde0bdc3b7de846d246c053a02e8\",\n    \"0xa2cb00721e68f1cad8933947456f07144dc69653f96ceed845bd577d599521ba99cdc02421118971d56d7603ed118cbf\",\n    \"0xaf8cd66d303e808b22ec57860dd909ca64c27ec2c60e26ffecfdc1179d8762ffd2739d87b43959496e9fee4108df71df\",\n    \"0x9954136812dffcd5d3f167a500e7ab339c15cfc9b3398d83f64b0daa3dd5b9a851204f424a3493b4e326d3de81e50a62\",\n    \"0x93252254d12511955f1aa464883ad0da793f84d900fea83e1df8bca0f2f4cf5b5f9acbaec06a24160d33f908ab5fea38\",\n    \"0x997cb55c26996586ba436a95566bd535e9c22452ca5d2a0ded2bd175376557fa895f9f4def4519241ff386a063f2e526\",\n    \"0xa12c78ad451e0ac911260ade2927a768b50cb4125343025d43474e7f465cdc446e9f52a84609c5e7e87ae6c9b3f56cda\",\n    \"0xa789d4ca55cbba327086563831b34487d63d0980ba8cf55197c016702ed6da9b102b1f0709ce3da3c53ff925793a3d73\",\n    \"0xa5d76acbb76741ce85be0e655b99baa04f7f587347947c0a30d27f8a49ae78cce06e1cde770a8b618d3db402be1c0c4b\",\n    \"0x873c0366668c8faddb0eb7c86f485718d65f8c4734020f1a18efd5fa123d3ea8a990977fe13592cd01d17e60809cb5ff\",\n    \"0xb659b71fe70f37573ff7c5970cc095a1dc0da3973979778f80a71a347ef25ad5746b2b9608bad4ab9a4a53a4d7df42d7\",\n    \"0xa34cbe05888e5e5f024a2db14cb6dcdc401a9cbd13d73d3c37b348f68688f87c24ca790030b8f84fef9e74b4eab5e412\",\n    \"0x94ce8010f85875c045b0f014db93ef5ab9f1f6842e9a5743dce9e4cb872c94affd9e77c1f1d1ab8b8660b52345d9acb9\",\n    \"0xadefa9b27a62edc0c5b019ddd3ebf45e4de846165256cf6329331def2e088c5232456d3de470fdce3fa758bfdd387512\",\n    \"0xa6b83821ba7c1f83cc9e4529cf4903adb93b26108e3d1f20a753070db072ad5a3689643144bdd9c5ea06bb9a7a515cd0\",\n    \"0xa3a9ddedc2a1b183eb1d52de26718151744db6050f86f3580790c51d09226bf05f15111691926151ecdbef683baa992c\",\n    \"0xa64bac89e7686932cdc5670d07f0b50830e69bfb8c93791c87c7ffa4913f8da881a9d8a8ce8c1a9ce5b6079358c54136\",\n    \"0xa77b5a63452cb1320b61ab6c7c2ef9cfbcade5fd4727583751fb2bf3ea330b5ca67757ec1f517bf4d503ec924fe32fbd\",\n    \"0x8746fd8d8eb99639d8cd0ca34c0d9c3230ed5a312aab1d3d925953a17973ee5aeb66e68667e93caf9cb817c868ea8f3d\",\n    \"0x88a2462a26558fc1fbd6e31aa8abdc706190a17c27fdc4217ffd2297d1b1f3321016e5c4b2384c5454d5717dc732ed03\",\n    \"0xb78893a97e93d730c8201af2e0d3b31cb923d38dc594ffa98a714e627c473d42ea82e0c4d2eeb06862ee22a9b2c54588\",\n    \"0x920cc8b5f1297cf215a43f6fc843e379146b4229411c44c0231f6749793d40f07b9af7699fd5d21fd69400b97febe027\",\n    \"0xa0f0eafce1e098a6b58c7ad8945e297cd93aaf10bc55e32e2e32503f02e59fc1d5776936577d77c0b1162cb93b88518b\",\n    \"0x98480ba0064e97a2e7a6c4769b4d8c2a322cfc9a3b2ca2e67e9317e2ce04c6e1108169a20bd97692e1cb1f1423b14908\",\n    \"0x83dbbb2fda7e287288011764a00b8357753a6a44794cc8245a2275237f11affdc38977214e463ad67aec032f3dfa37e9\",\n    \"0x86442fff37598ce2b12015ff19b01bb8a780b40ad353d143a0f30a06f6d23afd5c2b0a1253716c855dbf445cc5dd6865\",\n    \"0xb8a4c60c5171189414887847b9ed9501bff4e4c107240f063e2d254820d2906b69ef70406c585918c4d24f1dd052142b\",\n    \"0x919f33a98e84015b2034b57b5ffe9340220926b2c6e45f86fd79ec879dbe06a148ae68b77b73bf7d01bd638a81165617\",\n    \"0x95c13e78d89474a47fbc0664f6f806744b75dede95a479bbf844db4a7f4c3ae410ec721cb6ffcd9fa9c323da5740d5ae\",\n    \"0xab7151acc41fffd8ec6e90387700bcd7e1cde291ea669567295bea1b9dd3f1df2e0f31f3588cd1a1c08af8120aca4921\",\n    \"0x80e74c5c47414bd6eeef24b6793fb1fa2d8fb397467045fcff887c52476741d5bc4ff8b6d3387cb53ad285485630537f\",\n    \"0xa296ad23995268276aa351a7764d36df3a5a3cffd7dbeddbcea6b1f77adc112629fdeffa0918b3242b3ccd5e7587e946\",\n    \"0x813d2506a28a2b01cb60f49d6bd5e63c9b056aa56946faf2f33bd4f28a8d947569cfead3ae53166fc65285740b210f86\",\n    \"0x924b265385e1646287d8c09f6c855b094daaee74b9e64a0dddcf9ad88c6979f8280ba30c8597b911ef58ddb6c67e9fe3\",\n    \"0x8d531513c70c2d3566039f7ca47cd2352fd2d55b25675a65250bdb8b06c3843db7b2d29c626eed6391c238fc651cf350\",\n    \"0x82b338181b62fdc81ceb558a6843df767b6a6e3ceedc5485664b4ea2f555904b1a45fbb35f6cf5d96f27da10df82a325\",\n    \"0x92e62faaedea83a37f314e1d3cb4faaa200178371d917938e59ac35090be1db4b4f4e0edb78b9c991de202efe4f313d8\",\n    \"0x99d645e1b642c2dc065bac9aaa0621bc648c9a8351efb6891559c3a41ba737bd155fb32d7731950514e3ecf4d75980e4\",\n    \"0xb34a13968b9e414172fb5d5ece9a39cf2eb656128c3f2f6cc7a9f0c69c6bae34f555ecc8f8837dc34b5e470e29055c78\",\n    \"0xa2a0bb7f3a0b23a2cbc6585d59f87cd7e56b2bbcb0ae48f828685edd9f7af0f5edb4c8e9718a0aaf6ef04553ba71f3b7\",\n    \"0x8e1a94bec053ed378e524b6685152d2b52d428266f2b6eadd4bcb7c4e162ed21ab3e1364879673442ee2162635b7a4d8\",\n    \"0x9944adaff14a85eab81c73f38f386701713b52513c4d4b838d58d4ffa1d17260a6d056b02334850ea9a31677c4b078bd\",\n    \"0xa450067c7eceb0854b3eca3db6cf38669d72cb7143c3a68787833cbca44f02c0be9bfbe082896f8a57debb13deb2afb1\",\n    \"0x8be4ad3ac9ef02f7df09254d569939757101ee2eda8586fefcd8c847adc1efe5bdcb963a0cafa17651befaafb376a531\",\n    \"0x90f6de91ea50255f148ac435e08cf2ac00c772a466e38155bd7e8acf9197af55662c7b5227f88589b71abe9dcf7ba343\",\n    \"0x86e5a24f0748b106dee2d4d54e14a3b0af45a96cbee69cac811a4196403ebbee17fd24946d7e7e1b962ac7f66dbaf610\",\n    \"0xafdd96fbcda7aa73bf9eeb2292e036c25753d249caee3b9c013009cc22e10d3ec29e2aa6ddbb21c4e949b0c0bccaa7f4\",\n    \"0xb5a4e7436d5473647c002120a2cb436b9b28e27ad4ebdd7c5f122b91597c507d256d0cbd889d65b3a908531936e53053\",\n    \"0xb632414c3da704d80ac2f3e5e0e9f18a3637cdc2ebeb613c29300745582427138819c4e7b0bec3099c1b8739dac1807b\",\n    \"0xa28df1464d3372ce9f37ef1db33cc010f752156afae6f76949d98cd799c0cf225c20228ae86a4da592d65f0cffe3951b\",\n    \"0x898b93d0a31f7d3f11f253cb7a102db54b669fd150da302d8354d8e02b1739a47cb9bd88015f3baf12b00b879442464e\",\n    \"0x96fb88d89a12049091070cb0048a381902965e67a8493e3991eaabe5d3b7ff7eecd5c94493a93b174df3d9b2c9511755\",\n    \"0xb899cb2176f59a5cfba3e3d346813da7a82b03417cad6342f19cc8f12f28985b03bf031e856a4743fd7ebe16324805b0\",\n    \"0xa60e2d31bc48e0c0579db15516718a03b73f5138f15037491f4dae336c904e312eda82d50862f4debd1622bb0e56d866\",\n    \"0x979fc8b987b5cef7d4f4b58b53a2c278bd25a5c0ea6f41c715142ea5ff224c707de38451b0ad3aa5e749aa219256650a\",\n    \"0xb2a75bff18e1a6b9cf2a4079572e41205741979f57e7631654a3c0fcec57c876c6df44733c9da3d863db8dff392b44a3\",\n    \"0xb7a0f0e811222c91e3df98ff7f286b750bc3b20d2083966d713a84a2281744199e664879401e77470d44e5a90f3e5181\",\n    \"0x82b74ba21c9d147fbc338730e8f1f8a6e7fc847c3110944eb17a48bea5e06eecded84595d485506d15a3e675fd0e5e62\",\n    \"0xa7f44eef817d5556f0d1abcf420301217d23c69dd2988f44d91ea1f1a16c322263cbacd0f190b9ba22b0f141b9267b4f\",\n    \"0xaadb68164ede84fc1cb3334b3194d84ba868d5a88e4c9a27519eef4923bc4abf81aab8114449496c073c2a6a0eb24114\",\n    \"0xb5378605fabe9a8c12a5dc55ef2b1de7f51aedb61960735c08767a565793cea1922a603a6983dc25f7cea738d0f7c40d\",\n    \"0xa97a4a5cd8d51302e5e670aee78fe6b5723f6cc892902bbb4f131e82ca1dfd5de820731e7e3367fb0c4c1922a02196e3\",\n    \"0x8bdfeb15c29244d4a28896f2b2cb211243cd6a1984a3f5e3b0ebe5341c419beeab3304b390a009ffb47588018034b0ea\",\n    \"0xa9af3022727f2aa2fca3b096968e97edad3f08edcbd0dbca107b892ae8f746a9c0485e0d6eb5f267999b23a845923ed0\",\n    \"0x8e7594034feef412f055590fbb15b6322dc4c6ab7a4baef4685bd13d71a83f7d682b5781bdfa0d1c659489ce9c2b8000\",\n    \"0x84977ca6c865ebee021c58106c1a4ad0c745949ecc5332948002fd09bd9b890524878d0c29da96fd11207621136421fe\",\n    \"0x8687551a79158e56b2375a271136756313122132a6670fa51f99a1b5c229ed8eea1655a734abae13228b3ebfd2a825dd\",\n    \"0xa0227d6708979d99edfc10f7d9d3719fd3fc68b0d815a7185b60307e4c9146ad2f9be2b8b4f242e320d4288ceeb9504c\",\n    \"0x89f75583a16735f9dd8b7782a130437805b34280ccea8dac6ecaee4b83fe96947e7b53598b06fecfffdf57ffc12cc445\",\n    \"0xa0056c3353227f6dd9cfc8e3399aa5a8f1d71edf25d3d64c982910f50786b1e395c508d3e3727ac360e3e040c64b5298\",\n    \"0xb070e61a6d813626144b312ded1788a6d0c7cec650a762b2f8df6e4743941dd82a2511cd956a3f141fc81e15f4e092da\",\n    \"0xb4e6db232e028a1f989bb5fc13416711f42d389f63564d60851f009dcffac01acfd54efa307aa6d4c0f932892d4e62b0\",\n    \"0x89b5991a67db90024ddd844e5e1a03ef9b943ad54194ae0a97df775dde1addf31561874f4e40fbc37a896630f3bbda58\",\n    \"0xad0e8442cb8c77d891df49cdb9efcf2b0d15ac93ec9be1ad5c3b3cca1f4647b675e79c075335c1f681d56f14dc250d76\",\n    \"0xb5d55a6ae65bb34dd8306806cb49b5ccb1c83a282ee47085cf26c4e648e19a52d9c422f65c1cd7e03ca63e926c5e92ea\",\n    \"0xb749501347e5ec07e13a79f0cb112f1b6534393458b3678a77f02ca89dca973fa7b30e55f0b25d8b92b97f6cb0120056\",\n    \"0x94144b4a3ffc5eec6ba35ce9c245c148b39372d19a928e236a60e27d7bc227d18a8cac9983851071935d8ffb64b3a34f\",\n    \"0x92bb4f9f85bc8c028a3391306603151c6896673135f8a7aefedd27acb322c04ef5dac982fc47b455d6740023e0dd3ea3\",\n    \"0xb9633a4a101461a782fc2aa092e9dbe4e2ad00987578f18cd7cf0021a909951d60fe79654eb7897806795f93c8ff4d1c\",\n    \"0x809f0196753024821b48a016eca5dbb449a7c55750f25981bb7a4b4c0e0846c09b8f6128137905055fc43a3f0deb4a74\",\n    \"0xa27dc9cdd1e78737a443570194a03d89285576d3d7f3a3cf15cc55b3013e42635d4723e2e8fe1d0b274428604b630db9\",\n    \"0x861f60f0462e04cd84924c36a28163def63e777318d00884ab8cb64c8df1df0bce5900342163edb60449296484a6c5bf\",\n    \"0xb7bc23fb4e14af4c4704a944253e760adefeca8caee0882b6bbd572c84434042236f39ae07a8f21a560f486b15d82819\",\n    \"0xb9a6eb492d6dd448654214bd01d6dc5ff12067a11537ab82023fc16167507ee25eed2c91693912f4155d1c07ed9650b3\",\n    \"0x97678af29c68f9a5e213bf0fb85c265303714482cfc4c2c00b4a1e8a76ed08834ee6af52357b143a1ca590fb0265ea5a\",\n    \"0x8a15b499e9eca5b6cac3070b5409e8296778222018ad8b53a5d1f6b70ad9bb10c68a015d105c941ed657bf3499299e33\",\n    \"0xb487fefede2e8091f2c7bfe85770db2edff1db83d4effe7f7d87bff5ab1ace35e9b823a71adfec6737fede8d67b3c467\",\n    \"0x8b51b916402aa2c437fce3bcad6dad3be8301a1a7eab9d163085b322ffb6c62abf28637636fe6114573950117fc92898\",\n    \"0xb06a2106d031a45a494adec0881cb2f82275dff9dcdd2bc16807e76f3bec28a6734edd3d54f0be8199799a78cd6228ad\",\n    \"0xaf0a185391bbe2315eb97feac98ad6dd2e5d931d012c621abd6e404a31cc188b286fef14871762190acf086482b2b5e2\",\n    \"0x8e78ee8206506dd06eb7729e32fceda3bebd8924a64e4d8621c72e36758fda3d0001af42443851d6c0aea58562870b43\",\n    \"0xa1ba52a569f0461aaf90b49b92be976c0e73ec4a2c884752ee52ffb62dd137770c985123d405dfb5de70692db454b54a\",\n    \"0x8d51b692fa1543c51f6b62b9acb8625ed94b746ef96c944ca02859a4133a5629da2e2ce84e111a7af8d9a5b836401c64\",\n    \"0xa7a20d45044cf6492e0531d0b8b26ffbae6232fa05a96ed7f06bdb64c2b0f5ca7ec59d5477038096a02579e633c7a3ff\",\n    \"0x84df867b98c53c1fcd4620fef133ee18849c78d3809d6aca0fb6f50ff993a053a455993f216c42ab6090fa5356b8d564\",\n    \"0xa7227c439f14c48e2577d5713c97a5205feb69acb0b449152842e278fa71e8046adfab468089c8b2288af1fc51fa945b\",\n    \"0x855189b3a105670779997690876dfaa512b4a25a24931a912c2f0f1936971d2882fb4d9f0b3d9daba77eaf660e9d05d5\",\n    \"0xb5696bd6706de51c502f40385f87f43040a5abf99df705d6aac74d88c913b8ecf7a99a63d7a37d9bdf3a941b9e432ff5\",\n    \"0xab997beb0d6df9c98d5b49864ef0b41a2a2f407e1687dfd6089959757ba30ed02228940b0e841afe6911990c74d536c4\",\n    \"0xb36b65f85546ebfdbe98823d5555144f96b4ab39279facd19c0de3b8919f105ba0315a0784dce4344b1bc62d8bb4a5a3\",\n    \"0xb8371f0e4450788720ac5e0f6cd3ecc5413d33895083b2c168d961ec2b5c3de411a4cc0712481cbe8df8c2fa1a7af006\",\n    \"0x98325d8026b810a8b7a114171ae59a57e8bbc9848e7c3df992efc523621729fd8c9f52114ce01d7730541a1ada6f1df1\",\n    \"0x8d0e76dbd37806259486cd9a31bc8b2306c2b95452dc395546a1042d1d17863ef7a74c636b782e214d3aa0e8d717f94a\",\n    \"0xa4e15ead76da0214d702c859fb4a8accdcdad75ed08b865842bd203391ec4cba2dcc916455e685f662923b96ee0c023f\",\n    \"0x8618190972086ebb0c4c1b4a6c94421a13f378bc961cc8267a301de7390c5e73c3333864b3b7696d81148f9d4843fd02\",\n    \"0x85369d6cc7342e1aa15b59141517d8db8baaaeb7ab9670f3ba3905353948d575923d283b7e5a05b13a30e7baf1208a86\",\n    \"0x87c51ef42233c24a6da901f28c9a075d9ba3c625687c387ad6757b72ca6b5a8885e6902a3082da7281611728b1e45f26\",\n    \"0xaa6348a4f71927a3106ad0ea8b02fc8d8c65531e4ab0bd0a17243e66f35afe252e40ab8eef9f13ae55a72566ffdaff5c\",\n    \"0x96a3bc976e9d03765cc3fee275fa05b4a84c94fed6b767e23ca689394501e96f56f7a97cffddc579a6abff632bf153be\",\n    \"0x97dbf96c6176379fdb2b888be4e757b2bca54e74124bd068d3fa1dbd82a011bbeb75079da38e0cd22a761fe208ecad9b\",\n    \"0xb70cf0a1d14089a4129ec4e295313863a59da8c7e26bf74cc0e704ed7f0ee4d7760090d0ddf7728180f1bf2c5ac64955\",\n    \"0x882d664714cc0ffe53cbc9bef21f23f3649824f423c4dbad1f893d22c4687ab29583688699efc4d5101aa08b0c3e267a\",\n    \"0x80ecb7cc963e677ccaddbe3320831dd6ee41209acf4ed41b16dc4817121a3d86a1aac9c4db3d8c08a55d28257088af32\",\n    \"0xa25ba667d832b145f9ce18c3f9b1bd00737aa36db020e1b99752c8ef7d27c6c448982bd8d352e1b6df266b8d8358a8d5\",\n    \"0x83734841c13dee12759d40bdd209b277e743b0d08cc0dd1e0b7afd2d65bfa640400eefcf6be4a52e463e5b3d885eeac6\",\n    \"0x848d16505b04804afc773aebabb51b36fd8aacfbb0e09b36c0d5d57df3c0a3b92f33e7d5ad0a7006ec46ebb91df42b8c\",\n    \"0x909a8d793f599e33bb9f1dc4792a507a97169c87cd5c087310bc05f30afcd247470b4b56dec59894c0fb1d48d39bb54e\",\n    \"0x8e558a8559df84a1ba8b244ece667f858095c50bb33a5381e60fcc6ba586b69693566d8819b4246a27287f16846c1dfa\",\n    \"0x84d6b69729f5aaa000cd710c2352087592cfbdf20d5e1166977e195818e593fa1a50d1e04566be23163a2523dc1612f1\",\n    \"0x9536d262b7a42125d89f4f32b407d737ba8d9242acfc99d965913ab3e043dcac9f7072a43708553562cac4cba841df30\",\n    \"0x9598548923ca119d6a15fd10861596601dd1dedbcccca97bb208cdc1153cf82991ea8cc17686fbaa867921065265970c\",\n    \"0xb87f2d4af6d026e4d2836bc3d390a4a18e98a6e386282ce96744603bab74974272e97ac2da281afa21885e2cbb3a8001\",\n    \"0x991ece62bf07d1a348dd22191868372904b9f8cf065ae7aa4e44fd24a53faf6d851842e35fb472895963aa1992894918\",\n    \"0xa8c53dea4c665b30e51d22ca6bc1bc78aaf172b0a48e64a1d4b93439b053877ec26cb5221c55efd64fa841bbf7d5aff4\",\n    \"0x93487ec939ed8e740f15335b58617c3f917f72d07b7a369befd479ae2554d04deb240d4a14394b26192efae4d2f4f35d\",\n    \"0xa44793ab4035443f8f2968a40e043b4555960193ffa3358d22112093aadfe2c136587e4139ffd46d91ed4107f61ea5e0\",\n    \"0xb13fe033da5f0d227c75927d3dacb06dbaf3e1322f9d5c7c009de75cdcba5e308232838785ab69a70f0bedea755e003f\",\n    \"0x970a29b075faccd0700fe60d1f726bdebf82d2cc8252f4a84543ebd3b16f91be42a75c9719a39c4096139f0f31393d58\",\n    \"0xa4c3eb1f7160f8216fc176fb244df53008ff32f2892363d85254002e66e2de21ccfe1f3b1047589abee50f29b9d507e3\",\n    \"0x8c552885eab04ba40922a8f0c3c38c96089c95ff1405258d3f1efe8d179e39e1295cbf67677894c607ae986e4e6b1fb0\",\n    \"0xb3671746fa7f848c4e2ae6946894defadd815230b906b419143523cc0597bc1d6c0a4c1e09d49b66b4a2c11cde3a4de3\",\n    \"0x937a249a95813a5e2ef428e355efd202e15a37d73e56cfb7e57ea9f943f2ce5ca8026f2f1fd25bf164ba89d07077d858\",\n    \"0x83646bdf6053a04aa9e2f112499769e5bd5d0d10f2e13db3ca89bd45c0b3b7a2d752b7d137fb3909f9c62b78166c9339\",\n    \"0xb4eac4b91e763666696811b7ed45e97fd78310377ebea1674b58a2250973f80492ac35110ed1240cd9bb2d17493d708c\",\n    \"0x82db43a99bc6573e9d92a3fd6635dbbb249ac66ba53099c3c0c8c8080b121dd8243cd5c6e36ba0a4d2525bae57f5c89c\",\n    \"0xa64d6a264a681b49d134c655d5fc7756127f1ee7c93d328820f32bca68869f53115c0d27fef35fe71f7bc4fdaed97348\",\n    \"0x8739b7a9e2b4bc1831e7f04517771bc7cde683a5e74e052542517f8375a2f64e53e0d5ac925ef722327e7bb195b4d1d9\",\n    \"0x8f337cdd29918a2493515ebb5cf702bbe8ecb23b53c6d18920cc22f519e276ca9b991d3313e2d38ae17ae8bdfa4f8b7e\",\n    \"0xb0edeab9850e193a61f138ef2739fc42ceec98f25e7e8403bfd5fa34a7bc956b9d0898250d18a69fa4625a9b3d6129da\",\n    \"0xa9920f26fe0a6d51044e623665d998745c9eca5bce12051198b88a77d728c8238f97d4196f26e43b24f8841500b998d0\",\n    \"0x86e655d61502b979eeeeb6f9a7e1d0074f936451d0a1b0d2fa4fb3225b439a3770767b649256fe481361f481a8dbc276\",\n    \"0x84d3b32fa62096831cc3bf013488a9f3f481dfe293ae209ed19585a03f7db8d961a7a9dd0db82bd7f62d612707575d9c\",\n    \"0x81c827826ec9346995ffccf62a241e3b2d32f7357acd1b1f8f7a7dbc97022d3eb51b8a1230e23ce0b401d2e535e8cd78\",\n    \"0x94a1e40c151191c5b055b21e86f32e69cbc751dcbdf759a48580951834b96a1eed75914c0d19a38aefd21fb6c8d43d0c\",\n    \"0xab890222b44bc21b71f7c75e15b6c6e16bb03371acce4f8d4353ff3b8fcd42a14026589c5ed19555a3e15e4d18bfc3a3\",\n    \"0xaccb0be851e93c6c8cc64724cdb86887eea284194b10e7a43c90528ed97e9ec71ca69c6fac13899530593756dd49eab2\",\n    \"0xb630220aa9e1829c233331413ee28c5efe94ea8ea08d0c6bfd781955078b43a4f92915257187d8526873e6c919c6a1de\",\n    \"0xadd389a4d358c585f1274b73f6c3c45b58ef8df11f9d11221f620e241bf3579fba07427b288c0c682885a700cc1fa28d\",\n    \"0xa9fe6ca8bf2961a3386e8b8dcecc29c0567b5c0b3bcf3b0f9169f88e372b80151af883871fc5229815f94f43a6f5b2b0\",\n    \"0xad839ae003b92b37ea431fa35998b46a0afc3f9c0dd54c3b3bf7a262467b13ff3c323ada1c1ae02ac7716528bdf39e3e\",\n    \"0x9356d3fd0edcbbb65713c0f2a214394f831b26f792124b08c5f26e7f734b8711a87b7c4623408da6a091c9aef1f6af3c\",\n    \"0x896b25b083c35ac67f0af3784a6a82435b0e27433d4d74cd6d1eafe11e6827827799490fb1c77c11de25f0d75f14e047\",\n    \"0x8bfa019391c9627e8e5f05c213db625f0f1e51ec68816455f876c7e55b8f17a4f13e5aae9e3fb9e1cf920b1402ee2b40\",\n    \"0x8ba3a6faa6a860a8f3ce1e884aa8769ceded86380a86520ab177ab83043d380a4f535fe13884346c5e51bee68da6ab41\",\n    \"0xa8292d0844084e4e3bb7af92b1989f841a46640288c5b220fecfad063ee94e86e13d3d08038ec2ac82f41c96a3bfe14d\",\n    \"0x8229bb030b2fc566e11fd33c7eab7a1bb7b49fed872ea1f815004f7398cb03b85ea14e310ec19e1f23e0bdaf60f8f76c\",\n    \"0x8cfbf869ade3ec551562ff7f63c2745cc3a1f4d4dc853a0cd42dd5f6fe54228f86195ea8fe217643b32e9f513f34a545\",\n    \"0xac52a3c8d3270ddfe1b5630159da9290a5ccf9ccbdef43b58fc0a191a6c03b8a5974cf6e2bbc7bd98d4a40a3581482d7\",\n    \"0xab13decb9e2669e33a7049b8eca3ca327c40dea15ad6e0e7fa63ed506db1d258bc36ac88b35f65cae0984e937eb6575d\",\n    \"0xb5e748eb1a7a1e274ff0cc56311c198f2c076fe4b7e73e5f80396fe85358549df906584e6bb2c8195b3e2be7736850a5\",\n    \"0xb5cb911325d8f963c41f691a60c37831c7d3bbd92736efa33d1f77a22b3fde7f283127256c2f47e197571e6fe0b46149\",\n    \"0x8a01dc6ed1b55f26427a014faa347130738b191a06b800e32042a46c13f60b49534520214359d68eb2e170c31e2b8672\",\n    \"0xa72fa874866e19b2efb8e069328362bf7921ec375e3bcd6b1619384c3f7ee980f6cf686f3544e9374ff54b4d17a1629c\",\n    \"0x8db21092f7c5f110fba63650b119e82f4b42a997095d65f08f8237b02dd66fdf959f788df2c35124db1dbd330a235671\",\n    \"0x8c65d50433d9954fe28a09fa7ba91a70a590fe7ba6b3060f5e4be0f6cef860b9897fa935fb4ebc42133524eb071dd169\",\n    \"0xb4614058e8fa21138fc5e4592623e78b8982ed72aa35ee4391b164f00c68d277fa9f9eba2eeefc890b4e86eba5124591\",\n    \"0xab2ad3a1bce2fbd55ca6b7c23786171fe1440a97d99d6df4d80d07dd56ac2d7203c294b32fc9e10a6c259381a73f24a1\",\n    \"0x812ae3315fdc18774a8da3713a4679e8ed10b9405edc548c00cacbe25a587d32040566676f135e4723c5dc25df5a22e9\",\n    \"0xa464b75f95d01e5655b54730334f443c8ff27c3cb79ec7af4b2f9da3c2039c609908cd128572e1fd0552eb597e8cef8d\",\n    \"0xa0db3172e93ca5138fe419e1c49a1925140999f6eff7c593e5681951ee0ec1c7e454c851782cbd2b8c9bc90d466e90e0\",\n    \"0x806db23ba7d00b87d544eed926b3443f5f9c60da6b41b1c489fba8f73593b6e3b46ebfcab671ee009396cd77d5e68aa1\",\n    \"0x8bfdf2c0044cc80260994e1c0374588b6653947b178e8b312be5c2a05e05767e98ea15077278506aee7df4fee1aaf89e\",\n    \"0x827f6558c16841b5592ff089c9c31e31eb03097623524394813a2e4093ad2d3f8f845504e2af92195aaa8a1679d8d692\",\n    \"0x925c4f8eab2531135cd71a4ec88e7035b5eea34ba9d799c5898856080256b4a15ed1a746e002552e2a86c9c157e22e83\",\n    \"0xa9f9a368f0e0b24d00a35b325964c85b69533013f9c2cfad9708be5fb87ff455210f8cb8d2ce3ba58ca3f27495552899\",\n    \"0x8ac0d3bebc1cae534024187e7c71f8927ba8fcc6a1926cb61c2b6c8f26bb7831019e635a376146c29872a506784a4aaa\",\n    \"0x97c577be2cbbfdb37ad754fae9df2ada5fc5889869efc7e18a13f8e502fbf3f4067a509efbd46fd990ab47ce9a70f5a8\",\n    \"0x935e7d82bca19f16614aa43b4a3474e4d20d064e4bfdf1cea2909e5c9ab72cfe3e54dc50030e41ee84f3588cebc524e9\",\n    \"0x941aafc08f7c0d94cebfbb1f0aad5202c02e6e37f2c12614f57e727efa275f3926348f567107ee6d8914dd71e6060271\",\n    \"0xaf0fbc1ba05b4b5b63399686df3619968be5d40073de0313cbf5f913d3d4b518d4c249cdd2176468ccaa36040a484f58\",\n    \"0xa0c414f23f46ca6d69ce74c6f8a00c036cb0edd098af0c1a7d39c802b52cfb2d5dbdf93fb0295453d4646e2af7954d45\",\n    \"0x909cf39e11b3875bb63b39687ae1b5d1f5a15445e39bf164a0b14691b4ddb39a8e4363f584ef42213616abc4785b5d66\",\n    \"0xa92bac085d1194fbd1c88299f07a061d0bdd3f980b663e81e6254dbb288bf11478c0ee880e28e01560f12c5ccb3c0103\",\n    \"0x841705cd5cd76b943e2b7c5e845b9dd3c8defe8ef67e93078d6d5e67ade33ad4b0fd413bc196f93b0a4073c855cd97d4\",\n    \"0x8e7eb8364f384a9161e81d3f1d52ceca9b65536ae49cc35b48c3e2236322ba4ae9973e0840802d9fa4f4d82ea833544f\",\n    \"0xaed3ab927548bc8bec31467ba80689c71a168e34f50dcb6892f19a33a099f5aa6b3f9cb79f5c0699e837b9a8c7f27efe\",\n    \"0xb8fbf7696210a36e20edabd77839f4dfdf50d6d015cdf81d587f90284a9bcef7d2a1ff520728d7cc69a4843d6c20dedd\",\n    \"0xa9d533769ce6830211c884ae50a82a7bf259b44ac71f9fb11f0296fdb3981e6b4c1753fe744647b247ebc433a5a61436\",\n    \"0x8b4bdf90d33360b7f428c71cde0a49fb733badba8c726876945f58c620ce7768ae0e98fc8c31fa59d8955a4823336bb1\",\n    \"0x808d42238e440e6571c59e52a35ae32547d502dc24fd1759d8ea70a7231a95859baf30b490a4ba55fa2f3aaa11204597\",\n    \"0x85594701f1d2fee6dc1956bc44c7b31db93bdeec2f3a7d622c1a08b26994760773e3d57521a44cfd7e407ac3fd430429\",\n    \"0xa66de045ce7173043a6825e9dc440ac957e2efb6df0a337f4f8003eb0c719d873a52e6eba3cb0d69d977ca37d9187674\",\n    \"0x87a1c6a1fdff993fa51efa5c3ba034c079c0928a7d599b906336af7c2dcab9721ceaf3108c646490af9dff9a754f54b3\",\n    \"0x926424223e462ceb75aed7c22ade8a7911a903b7e5dd4bc49746ddce8657f4616325cd12667d4393ac52cdd866396d0e\",\n    \"0xb5dc96106593b42b30f06f0b0a1e0c1aafc70432e31807252d3674f0b1ea5e58eac8424879d655c9488d85a879a3e572\",\n    \"0x997ca0987735cc716507cb0124b1d266d218b40c9d8e0ecbf26a1d65719c82a637ce7e8be4b4815d307df717bde7c72a\",\n    \"0x92994d3f57a569b7760324bb5ae4e8e14e1633d175dab06aa57b8e391540e05f662fdc08b8830f489a063f59b689a688\",\n    \"0xa8087fcc6aa4642cb998bea11facfe87eb33b90a9aa428ab86a4124ad032fc7d2e57795311a54ec9f55cc120ebe42df1\",\n    \"0xa9bd7d1de6c0706052ca0b362e2e70e8c8f70f1f026ea189b4f87a08ce810297ebfe781cc8004430776c54c1a05ae90c\",\n    \"0x856d33282e8a8e33a3d237fb0a0cbabaf77ba9edf2fa35a831fdafcadf620561846aa6cbb6bdc5e681118e1245834165\",\n    \"0x9524a7aa8e97a31a6958439c5f3339b19370f03e86b89b1d02d87e4887309dbbe9a3a8d2befd3b7ed5143c8da7e0a8ad\",\n    \"0x824fdf433e090f8acbd258ac7429b21f36f9f3b337c6d0b71d1416a5c88a767883e255b2888b7c906dd2e9560c4af24c\",\n    \"0x88c7fee662ca7844f42ed5527996b35723abffd0d22d4ca203b9452c639a5066031207a5ae763dbc0865b3299d19b1ec\",\n    \"0x919dca5c5595082c221d5ab3a5bc230f45da7f6dec4eb389371e142c1b9c6a2c919074842479c2844b72c0d806170c0c\",\n    \"0xb939be8175715e55a684578d8be3ceff3087f60fa875fff48e52a6e6e9979c955efef8ff67cfa2b79499ea23778e33b0\",\n    \"0x873b6db725e7397d11bc9bed9ac4468e36619135be686790a79bc6ed4249058f1387c9a802ea86499f692cf635851066\",\n    \"0xaeae06db3ec47e9e5647323fa02fac44e06e59b885ad8506bf71b184ab3895510c82f78b6b22a5d978e8218e7f761e9f\",\n    \"0xb99c0a8359c72ab88448bae45d4bf98797a26bca48b0d4460cd6cf65a4e8c3dd823970ac3eb774ae5d0cea4e7fadf33e\",\n    \"0x8f10c8ec41cdfb986a1647463076a533e6b0eec08520c1562401b36bb063ac972aa6b28a0b6ce717254e35940b900e3c\",\n    \"0xa106d9be199636d7add43b942290269351578500d8245d4aae4c083954e4f27f64740a3138a66230391f2d0e6043a8de\",\n    \"0xa469997908244578e8909ff57cffc070f1dbd86f0098df3cfeb46b7a085cfecc93dc69ee7cad90ff1dc5a34d50fe580c\",\n    \"0xa4ef087bea9c20eb0afc0ee4caba7a9d29dfa872137828c721391273e402fb6714afc80c40e98bbd8276d3836bffa080\",\n    \"0xb07a013f73cd5b98dae0d0f9c1c0f35bff8a9f019975c4e1499e9bee736ca6fcd504f9bc32df1655ff333062382cff04\",\n    \"0xb0a77188673e87cc83348c4cc5db1eecf6b5184e236220c8eeed7585e4b928db849944a76ec60ef7708ef6dac02d5592\",\n    \"0xb1284b37e59b529f0084c0dacf0af6c0b91fc0f387bf649a8c74819debf606f7b07fc3e572500016fb145ec2b24e9f17\",\n    \"0x97b20b5b4d6b9129da185adfbf0d3d0b0faeba5b9715f10299e48ea0521709a8296a9264ce77c275a59c012b50b6519a\",\n    \"0xb9d37e946fae5e4d65c1fbfacc8a62e445a1c9d0f882e60cca649125af303b3b23af53c81d7bac544fb7fcfc7a314665\",\n    \"0x8e5acaac379f4bb0127efbef26180f91ff60e4c525bc9b798fc50dfaf4fe8a5aa84f18f3d3cfb8baead7d1e0499af753\",\n    \"0xb0c0b8ab1235bf1cda43d4152e71efc1a06c548edb964eb4afceb201c8af24240bf8ab5cae30a08604e77432b0a5faf0\",\n    \"0x8cc28d75d5c8d062d649cbc218e31c4d327e067e6dbd737ec0a35c91db44fbbd0d40ec424f5ed79814add16947417572\",\n    \"0x95ae6219e9fd47efaa9cb088753df06bc101405ba50a179d7c9f7c85679e182d3033f35b00dbba71fdcd186cd775c52e\",\n    \"0xb5d28fa09f186ebc5aa37453c9b4d9474a7997b8ae92748ecb940c14868792292ac7d10ade01e2f8069242b308cf97e5\",\n    \"0x8c922a0faa14cc6b7221f302df3342f38fc8521ec6c653f2587890192732c6da289777a6cd310747ea7b7d104af95995\",\n    \"0xb9ad5f660b65230de54de535d4c0fcae5bc6b59db21dea5500fdc12eea4470fb8ea003690fdd16d052523418d5e01e8c\",\n    \"0xa39a9dd41a0ff78c82979483731f1cd68d3921c3e9965869662c22e02dde3877802e180ba93f06e7346f96d9fa9261d2\",\n    \"0x8b32875977ec372c583b24234c27ed73aef00cdff61eb3c3776e073afbdeade548de9497c32ec6d703ff8ad0a5cb7fe4\",\n    \"0x9644cbe755a5642fe9d26cfecf170d3164f1848c2c2e271d5b6574a01755f3980b3fc870b98cf8528fef6ecef4210c16\",\n    \"0x81ea9d1fdd9dd66d60f40ce0712764b99da9448ae0b300f8324e1c52f154e472a086dda840cb2e0b9813dc8ce8afd4b5\",\n    \"0x906aaa4a7a7cdf01909c5cfbc7ded2abc4b869213cbf7c922d4171a4f2e637e56f17020b852ad339d83b8ac92f111666\",\n    \"0x939b5f11acbdeff998f2a080393033c9b9d8d5c70912ea651c53815c572d36ee822a98d6dfffb2e339f29201264f2cf4\",\n    \"0xaba4898bf1ccea9b9e2df1ff19001e05891581659c1cbbde7ee76c349c7fc7857261d9785823c9463a8aea3f40e86b38\",\n    \"0x83ca1a56b8a0be4820bdb5a9346357c68f9772e43f0b887729a50d2eb2a326bbcede676c8bf2e51d7c89bbd8fdb778a6\",\n    \"0x94e86e9fe6addfe2c3ee3a547267ed921f4230d877a85bb4442c2d9350c2fa9a9c54e6fe662de82d1a2407e4ab1691c2\",\n    \"0xa0cc3bdef671a59d77c6984338b023fa2b431b32e9ed2abe80484d73edc6540979d6f10812ecc06d4d0c5d4eaca7183c\",\n    \"0xb5343413c1b5776b55ea3c7cdd1f3af1f6bd802ea95effe3f2b91a523817719d2ecc3f8d5f3cc2623ace7e35f99ca967\",\n    \"0x92085d1ed0ed28d8cabe3e7ff1905ed52c7ceb1eac5503760c52fb5ee3a726aba7c90b483c032acc3f166b083d7ec370\",\n    \"0x8ec679520455275cd957fca8122724d287db5df7d29f1702a322879b127bff215e5b71d9c191901465d19c86c8d8d404\",\n    \"0xb65eb2c63d8a30332eb24ee8a0c70156fc89325ebbb38bacac7cf3f8636ad8a472d81ccca80423772abc00192d886d8a\",\n    \"0xa9fe1c060b974bee4d590f2873b28635b61bfcf614e61ff88b1be3eee4320f4874e21e8d666d8ac8c9aba672efc6ecae\",\n    \"0xb3fe2a9a389c006a831dea7e777062df84b5c2803f9574d7fbe10b7e1c125817986af8b6454d6be9d931a5ac94cfe963\",\n    \"0x95418ad13b734b6f0d33822d9912c4c49b558f68d08c1b34a0127fcfa666bcae8e6fda8832d2c75bb9170794a20e4d7c\",\n    \"0xa9a7df761e7f18b79494bf429572140c8c6e9d456c4d4e336184f3f51525a65eb9582bea1e601bdb6ef8150b7ca736a5\",\n    \"0xa0de03b1e75edf7998c8c1ac69b4a1544a6fa675a1941950297917366682e5644a4bda9cdeedfaf9473d7fccd9080b0c\",\n    \"0xa61838af8d95c95edf32663a68f007d95167bf6e41b0c784a30b22d8300cfdd5703bd6d16e86396638f6db6ae7e42a85\",\n    \"0x8866d62084d905c145ff2d41025299d8b702ac1814a7dec4e277412c161bc9a62fed735536789cb43c88693c6b423882\",\n    \"0x91da22c378c81497fe363e7f695c0268443abee50f8a6625b8a41e865638a643f07b157ee566de09ba09846934b4e2d7\",\n    \"0x941d21dd57c9496aa68f0c0c05507405fdd413acb59bc668ce7e92e1936c68ec4b065c3c30123319884149e88228f0b2\",\n    \"0xa77af9b094bc26966ddf2bf9e1520c898194a5ccb694915950dadc204facbe3066d3d89f50972642d76b14884cfbaa21\",\n    \"0x8e76162932346869f4618bde744647f7ab52ab498ad654bdf2a4feeb986ac6e51370841e5acbb589e38b6e7142bb3049\",\n    \"0xb60979ace17d6937ece72e4f015da4657a443dd01cebc7143ef11c09e42d4aa8855999a65a79e2ea0067f31c9fc2ab0f\",\n    \"0xb3e2ffdd5ee6fd110b982fd4fad4b93d0fca65478f986d086eeccb0804960bfaa1919afa743c2239973ea65091fe57d2\",\n    \"0x8ce0ce05e7d7160d44574011da687454dbd3c8b8290aa671731b066e2c82f8cf2d63cb8e932d78c6122ec610e44660e6\",\n    \"0xab005dd8d297045c39e2f72fb1c48edb501ccf3575d3d04b9817b3afee3f0bb0f3f53f64bda37d1d9cde545aae999bae\",\n    \"0x95bd7edb4c4cd60e3cb8a72558845a3cce6bb7032ccdf33d5a49ebb6ddf203bc3c79e7b7e550735d2d75b04c8b2441e8\",\n    \"0x889953ee256206284094e4735dbbb17975bafc7c3cb94c9fbfee4c3e653857bfd49e818f64a47567f721b98411a3b454\",\n    \"0xb188423e707640ab0e75a061e0b62830cde8afab8e1ad3dae30db69ffae4e2fc005bababbdcbd7213b918ed4f70e0c14\",\n    \"0xa97e0fafe011abd70d4f99a0b36638b3d6e7354284588f17a88970ed48f348f88392779e9a038c6cbc9208d998485072\",\n    \"0x87db11014a91cb9b63e8dfaa82cdebca98272d89eb445ee1e3ff9dbaf2b3fad1a03b888cffc128e4fe208ed0dddece0f\",\n    \"0xaad2e40364edd905d66ea4ac9d51f9640d6fda9a54957d26ba233809851529b32c85660fa401dbee3679ec54fa6dd966\",\n    \"0x863e99336ca6edf03a5a259e59a2d0f308206e8a2fb320cfc0be06057366df8e0f94b33a28f574092736b3c5ada84270\",\n    \"0xb34bcc56a057589f34939a1adc51de4ff6a9f4fee9c7fa9aa131e28d0cf0759a0c871b640162acdfbf91f3f1b59a3703\",\n    \"0x935dd28f2896092995c5eff1618e5b6efe7a40178888d7826da9b0503c2d6e68a28e7fac1a334e166d0205f0695ef614\",\n    \"0xb842cd5f8f5de5ca6c68cb4a5c1d7b451984930eb4cc18fd0934d52fdc9c3d2d451b1c395594d73bc3451432bfba653f\",\n    \"0x9014537885ce2debad736bc1926b25fdab9f69b216bf024f589c49dc7e6478c71d595c3647c9f65ff980b14f4bb2283b\",\n    \"0x8e827ccca1dd4cd21707140d10703177d722be0bbe5cac578db26f1ef8ad2909103af3c601a53795435b27bf95d0c9ed\",\n    \"0x8a0b8ad4d466c09d4f1e9167410dbe2edc6e0e6229d4b3036d30f85eb6a333a18b1c968f6ca6d6889bb08fecde017ef4\",\n    \"0x9241ee66c0191b06266332dc9161dede384c4bb4e116dbd0890f3c3790ec5566da4568243665c4725b718ac0f6b5c179\",\n    \"0xaeb4d5fad81d2b505d47958a08262b6f1b1de9373c2c9ba6362594194dea3e002ab03b8cbb43f867be83065d3d370f19\",\n    \"0x8781bc83bb73f7760628629fe19e4714b494dbed444c4e4e4729b7f6a8d12ee347841a199888794c2234f51fa26fc2b9\",\n    \"0xb58864f0acd1c2afa29367e637cbde1968d18589245d9936c9a489c6c495f54f0113ecdcbe4680ac085dd3c397c4d0c3\",\n    \"0x94a24284afaeead61e70f3e30f87248d76e9726759445ca18cdb9360586c60cc9f0ec1c397f9675083e0b56459784e2e\",\n    \"0xaed358853f2b54dcbddf865e1816c2e89be12e940e1abfa661e2ee63ffc24a8c8096be2072fa83556482c0d89e975124\",\n    \"0xb95374e6b4fc0765708e370bc881e271abf2e35c08b056a03b847e089831ef4fe3124b9c5849d9c276eb2e35b3daf264\",\n    \"0xb834cdbcfb24c8f84bfa4c552e7fadc0028a140952fd69ed13a516e1314a4cd35d4b954a77d51a1b93e1f5d657d0315d\",\n    \"0x8fb6d09d23bfa90e7443753d45a918d91d75d8e12ec7d016c0dfe94e5c592ba6aaf483d2f16108d190822d955ad9cdc3\",\n    \"0xaa315cd3c60247a6ad4b04f26c5404c2713b95972843e4b87b5a36a89f201667d70f0adf20757ebe1de1b29ae27dda50\",\n    \"0xa116862dca409db8beff5b1ccd6301cdd0c92ca29a3d6d20eb8b87f25965f42699ca66974dd1a355200157476b998f3b\",\n    \"0xb4c2f5fe173c4dc8311b60d04a65ce1be87f070ac42e13cd19c6559a2931c6ee104859cc2520edebbc66a13dc7d30693\",\n    \"0x8d4a02bf99b2260c334e7d81775c5cf582b00b0c982ce7745e5a90624919028278f5e9b098573bad5515ce7fa92a80c8\",\n    \"0x8543493bf564ce6d97bd23be9bff1aba08bd5821ca834f311a26c9139c92a48f0c2d9dfe645afa95fec07d675d1fd53b\",\n    \"0x9344239d13fde08f98cb48f1f87d34cf6abe8faecd0b682955382a975e6eed64e863fa19043290c0736261622e00045c\",\n    \"0xaa49d0518f343005ca72b9e6c7dcaa97225ce6bb8b908ebbe7b1a22884ff8bfb090890364e325a0d414ad180b8f161d1\",\n    \"0x907d7fd3e009355ab326847c4a2431f688627faa698c13c03ffdd476ecf988678407f029b8543a475dcb3dafdf2e7a9c\",\n    \"0x845f1f10c6c5dad2adc7935f5cd2e2b32f169a99091d4f1b05babe7317b9b1cdce29b5e62f947dc621b9acbfe517a258\",\n    \"0x8f3be8e3b380ea6cdf9e9c237f5e88fd5a357e5ded80ea1fc2019810814de82501273b4da38916881125b6fa0cfd4459\",\n    \"0xb9c7f487c089bf1d20c822e579628db91ed9c82d6ca652983aa16d98b4270c4da19757f216a71b9c13ddee3e6e43705f\",\n    \"0x8ba2d8c88ad2b872db104ea8ddbb006ec2f3749fd0e19298a804bb3a5d94de19285cc7fb19fee58a66f7851d1a66c39f\",\n    \"0x9375ecd3ed16786fe161af5d5c908f56eeb467a144d3bbddfc767e90065b7c94fc53431adebecba2b6c9b5821184d36e\",\n    \"0xa49e069bfadb1e2e8bff6a4286872e2a9765d62f0eaa4fcb0e5af4bbbed8be3510fb19849125a40a8a81d1e33e81c3eb\",\n    \"0x9522cc66757b386aa6b88619525c8ce47a5c346d590bb3647d12f991e6c65c3ab3c0cfc28f0726b6756c892eae1672be\",\n    \"0xa9a0f1f51ff877406fa83a807aeb17b92a283879f447b8a2159653db577848cc451cbadd01f70441e351e9ed433c18bc\",\n    \"0x8ff7533dcff6be8714df573e33f82cf8e9f2bcaaa43e939c4759d52b754e502717950de4b4252fb904560fc31dce94a4\",\n    \"0x959724671e265a28d67c29d95210e97b894b360da55e4cf16e6682e7912491ed8ca14bfaa4dce9c25a25b16af580494f\",\n    \"0x92566730c3002f4046c737032487d0833c971e775de59fe02d9835c9858e2e3bc37f157424a69764596c625c482a2219\",\n    \"0xa84b47ceff13ed9c3e5e9cdf6739a66d3e7c2bd8a6ba318fefb1a9aecf653bb2981da6733ddb33c4b0a4523acc429d23\",\n    \"0xb4ddf571317e44f859386d6140828a42cf94994e2f1dcbcc9777f4eebbfc64fc1e160b49379acc27c4672b8e41835c5d\",\n    \"0x8ab95c94072b853d1603fdd0a43b30db617d13c1d1255b99075198e1947bfa5f59aed2b1147548a1b5e986cd9173d15c\",\n    \"0x89511f2eab33894fd4b3753d24249f410ff7263052c1fef6166fc63a79816656b0d24c529e45ccce6be28de6e375d916\",\n    \"0xa0866160ca63d4f2be1b4ea050dac6b59db554e2ebb4e5b592859d8df339b46fd7cb89aaed0951c3ee540aee982c238a\",\n    \"0x8fcc5cbba1b94970f5ff2eb1922322f5b0aa7d918d4b380c9e7abfd57afd8b247c346bff7b87af82efbce3052511cd1b\",\n    \"0x99aeb2a5e846b0a2874cca02c66ed40d5569eb65ab2495bc3f964a092e91e1517941f2688e79f8cca49cd3674c4e06dc\",\n    \"0xb7a096dc3bad5ca49bee94efd884aa3ff5615cf3825cf95fbe0ce132e35f46581d6482fa82666c7ef5f1643eaee8f1ca\",\n    \"0x94393b1da6eaac2ffd186b7725eca582f1ddc8cdd916004657f8a564a7c588175cb443fc6943b39029f5bbe0add3fad8\",\n    \"0x884b85fe012ccbcd849cb68c3ad832d83b3ef1c40c3954ffdc97f103b1ed582c801e1a41d9950f6bddc1d11f19d5ec76\",\n    \"0xb00061c00131eded8305a7ce76362163deb33596569afb46fe499a7c9d7a0734c084d336b38d168024c2bb42b58e7660\",\n    \"0xa439153ac8e6ca037381e3240e7ba08d056c83d7090f16ed538df25901835e09e27de2073646e7d7f3c65056af6e4ce7\",\n    \"0x830fc9ca099097d1f38b90e6843dc86f702be9d20bdacc3e52cae659dc41df5b8d2c970effa6f83a5229b0244a86fe22\",\n    \"0xb81ea2ffaaff2bb00dd59a9ab825ba5eed4db0d8ac9c8ed1a632ce8f086328a1cddd045fbe1ace289083c1325881b7e7\",\n    \"0xb51ea03c58daf2db32c99b9c4789b183365168cb5019c72c4cc91ac30b5fb7311d3db76e6fa41b7cd4a8c81e2f6cdc94\",\n    \"0xa4170b2c6d09ca5beb08318730419b6f19215ce6c631c854116f904be3bc30dd85a80c946a8ab054d3e307afaa3f8fbc\",\n    \"0x897cc42ff28971ff54d2a55dd6b35cfb8610ac902f3c06e3a5cea0e0a257e870c471236a8e84709211c742a09c5601a6\",\n    \"0xa18f2e98d389dace36641621488664ecbb422088ab03b74e67009b8b8acacaaa24fdcf42093935f355207d934adc52a8\",\n    \"0x92adcfb678cc2ba19c866f3f2b988fdcb4610567f3ab436cc0cb9acaf5a88414848d71133ebdbec1983e38e6190f1b5f\",\n    \"0xa86d43c2ce01b366330d3b36b3ca85f000c3548b8297e48478da1ee7d70d8576d4650cba7852ed125c0d7cb6109aa7f3\",\n    \"0x8ed31ceed9445437d7732dce78a762d72ff32a7636bfb3fd7974b7ae15db414d8184a1766915244355deb354fbc5803b\",\n    \"0x9268f70032584f416e92225d65af9ea18c466ebc7ae30952d56a4e36fd9ea811dde0a126da9220ba3c596ec54d8a335e\",\n    \"0x9433b99ee94f2d3fbdd63b163a2bdf440379334c52308bd24537f7defd807145a062ff255a50d119a7f29f4b85d250e3\",\n    \"0x90ce664f5e4628a02278f5cf5060d1a34f123854634b1870906e5723ac9afd044d48289be283b267d45fcbf3f4656aaf\",\n    \"0xaaf21c4d59378bb835d42ae5c5e5ab7a3c8c36a59e75997989313197752b79a472d866a23683b329ea69b048b87fa13e\",\n    \"0xb83c0589b304cec9ede549fde54f8a7c2a468c6657da8c02169a6351605261202610b2055c639b9ed2d5b8c401fb8f56\",\n    \"0x9370f326ea0f170c2c05fe2c5a49189f20aec93b6b18a5572a818cd4c2a6adb359e68975557b349fb54f065d572f4c92\",\n    \"0xac3232fa5ce6f03fca238bef1ce902432a90b8afce1c85457a6bee5571c033d4bceefafc863af04d4e85ac72a4d94d51\",\n    \"0x80d9ea168ff821b22c30e93e4c7960ce3ad3c1e6deeebedd342a36d01bd942419b187e2f382dbfd8caa34cca08d06a48\",\n    \"0xa387a3c61676fb3381eefa2a45d82625635a666e999aba30e3b037ec9e040f414f9e1ad9652abd3bcad63f95d85038db\",\n    \"0xa1b229fe32121e0b391b0f6e0180670b9dc89d79f7337de4c77ea7ad0073e9593846f06797c20e923092a08263204416\",\n    \"0x92164a9d841a2b828cedf2511213268b698520f8d1285852186644e9a0c97512cafa4bfbe29af892c929ebccd102e998\",\n    \"0x82ee2fa56308a67c7db4fd7ef539b5a9f26a1c2cc36da8c3206ba4b08258fbb3cec6fe5cdbd111433fb1ba2a1e275927\",\n    \"0x8c77bfe9e191f190a49d46f05600603fa42345592539b82923388d72392404e0b29a493a15e75e8b068dddcd444c2928\",\n    \"0x80b927f93ccf79dcf5c5b20bcf5a7d91d7a17bc0401bb7cc9b53a6797feac31026eb114257621f5a64a52876e4474cc1\",\n    \"0xb6b68b6501c37804d4833d5a063dd108a46310b1400549074e3cac84acc6d88f73948b7ad48d686de89c1ec043ae8c1a\",\n    \"0xab3da00f9bdc13e3f77624f58a3a18fc3728956f84b5b549d62f1033ae4b300538e53896e2d943f160618e05af265117\",\n    \"0xb6830e87233b8eace65327fdc764159645b75d2fd4024bf8f313b2dd5f45617d7ecfb4a0b53ccafb5429815a9a1adde6\",\n    \"0xb9251cfe32a6dc0440615aadcd98b6b1b46e3f4e44324e8f5142912b597ee3526bea2431e2b0282bb58f71be5b63f65e\",\n    \"0xaf8d70711e81cdddfb39e67a1b76643292652584c1ce7ce4feb1641431ad596e75c9120e85f1a341e7a4da920a9cdd94\",\n    \"0x98cd4e996594e89495c078bfd52a4586b932c50a449a7c8dfdd16043ca4cda94dafbaa8ad1b44249c99bbcc52152506e\",\n    \"0xb9fc6d1c24f48404a4a64fbe3e43342738797905db46e4132aee5f086aaa4c704918ad508aaefa455cfe1b36572e6242\",\n    \"0xa365e871d30ba9291cedaba1be7b04e968905d003e9e1af7e3b55c5eb048818ae5b913514fb08b24fb4fbdccbb35d0b8\",\n    \"0x93bf99510971ea9af9f1e364f1234c898380677c8e8de9b0dd24432760164e46c787bc9ec42a7ad450500706cf247b2d\",\n    \"0xb872f825a5b6e7b9c7a9ddfeded3516f0b1449acc9b4fd29fc6eba162051c17416a31e5be6d3563f424d28e65bab8b8f\",\n    \"0xb06b780e5a5e8eb4f4c9dc040f749cf9709c8a4c9ef15e925f442b696e41e5095db0778a6c73bcd329b265f2c6955c8b\",\n    \"0x848f1a981f5fc6cd9180cdddb8d032ad32cdfa614fc750d690dbae36cc0cd355cbf1574af9b3ffc8b878f1b2fafb9544\",\n    \"0xa03f48cbff3e9e8a3a655578051a5ae37567433093ac500ed0021c6250a51b767afac9bdb194ee1e3eac38a08c0eaf45\",\n    \"0xb5be78ce638ff8c4aa84352b536628231d3f7558c5be3bf010b28feac3022e64691fa672f358c8b663904aebe24a54ed\",\n    \"0xa9d4da70ff676fa55d1728ba6ab03b471fa38b08854d99e985d88c2d050102d8ccffbe1c90249a5607fa7520b15fe791\",\n    \"0x8fe9f7092ffb0b69862c8e972fb1ecf54308c96d41354ed0569638bb0364f1749838d6d32051fff1599112978c6e229c\",\n    \"0xae6083e95f37770ecae0df1e010456f165d96cfe9a7278c85c15cffd61034081ce5723e25e2bede719dc9341ec8ed481\",\n    \"0xa260891891103089a7afbd9081ea116cfd596fd1015f5b65e10b0961eb37fab7d09c69b7ce4be8bf35e4131848fb3fe4\",\n    \"0x8d729fa32f6eb9fd2f6a140bef34e8299a2f3111bffd0fe463aa8622c9d98bfd31a1df3f3e87cd5abc52a595f96b970e\",\n    \"0xa30ec6047ae4bc7da4daa7f4c28c93aedb1112cfe240e681d07e1a183782c9ff6783ac077c155af23c69643b712a533f\",\n    \"0xac830726544bfe7b5467339e5114c1a75f2a2a8d89453ce86115e6a789387e23551cd64620ead6283dfa4538eb313d86\",\n    \"0x8445c135b7a48068d8ed3e011c6d818cfe462b445095e2fbf940301e50ded23f272d799eea47683fc027430ce14613ef\",\n    \"0x95785411715c9ae9d8293ce16a693a2aa83e3cb1b4aa9f76333d0da2bf00c55f65e21e42e50e6c5772ce213dd7b4f7a0\",\n    \"0xb273b024fa18b7568c0d1c4d2f0c4e79ec509dafac8c5951f14192d63ddbcf2d8a7512c1c1b615cc38fa3e336618e0c5\",\n    \"0xa78b9d3ea4b6a90572eb27956f411f1d105fdb577ee2ffeec9f221da9b45db84bfe866af1f29597220c75e0c37a628d8\",\n    \"0xa4be2bf058c36699c41513c4d667681ce161a437c09d81383244fc55e1c44e8b1363439d0cce90a3e44581fb31d49493\",\n    \"0xb6eef13040f17dd4eba22aaf284d2f988a4a0c4605db44b8d2f4bf9567ac794550b543cc513c5f3e2820242dd704152e\",\n    \"0x87eb00489071fa95d008c5244b88e317a3454652dcb1c441213aa16b28cd3ecaa9b22fec0bdd483c1df71c37119100b1\",\n    \"0x92d388acdcb49793afca329cd06e645544d2269234e8b0b27d2818c809c21726bc9cf725651b951e358a63c83dedee24\",\n    \"0xae27e219277a73030da27ab5603c72c8bd81b6224b7e488d7193806a41343dff2456132274991a4722fdb0ef265d04cd\",\n    \"0x97583e08ecb82bbc27c0c8476d710389fa9ffbead5c43001bd36c1b018f29faa98de778644883e51870b69c5ffb558b5\",\n    \"0x90a799a8ce73387599babf6b7da12767c0591cadd36c20a7990e7c05ea1aa2b9645654ec65308ee008816623a2757a6a\",\n    \"0xa1b47841a0a2b06efd9ab8c111309cc5fc9e1d5896b3e42ed531f6057e5ade8977c29831ce08dbda40348386b1dcc06d\",\n    \"0xb92b8ef59bbddb50c9457691bc023d63dfcc54e0fd88bd5d27a09e0d98ac290fc90e6a8f6b88492043bf7c87fac8f3e4\",\n    \"0xa9d6240b07d62e22ec8ab9b1f6007c975a77b7320f02504fc7c468b4ee9cfcfd945456ff0128bc0ef2174d9e09333f8d\",\n    \"0x8e96534c94693226dc32bca79a595ca6de503af635f802e86442c67e77564829756961d9b701187fe91318da515bf0e6\",\n    \"0xb6ba290623cd8dd5c2f50931c0045d1cfb0c30877bc8fe58cbc3ff61ee8da100045a39153916efa1936f4aee0892b473\",\n    \"0xb43baa7717fac02d4294f5b3bb5e58a65b3557747e3188b482410388daac7a9c177f762d943fd5dcf871273921213da8\",\n    \"0xb9cf00f8fb5e2ef2b836659fece15e735060b2ea39b8e901d3dcbdcf612be8bf82d013833718c04cd46ffaa70b85f42e\",\n    \"0x8017d0c57419e414cbba504368723e751ef990cc6f05dad7b3c2de6360adc774ad95512875ab8337d110bf39a42026fa\",\n    \"0xae7401048b838c0dcd4b26bb6c56d79d51964a0daba780970b6c97daee4ea45854ea0ac0e4139b3fe60dac189f84df65\",\n    \"0x887b237b0cd0f816b749b21db0b40072f9145f7896c36916296973f9e6990ede110f14e5976c906d08987c9836cca57f\",\n    \"0xa88c3d5770148aee59930561ca1223aceb2c832fb5417e188dca935905301fc4c6c2c9270bc1dff7add490a125eb81c6\",\n    \"0xb6cf9b02c0cd91895ad209e38c54039523f137b5848b9d3ad33ae43af6c20c98434952db375fe378de7866f2d0e8b18a\",\n    \"0x84ef3d322ff580c8ad584b1fe4fe346c60866eb6a56e982ba2cf3b021ecb1fdb75ecc6c29747adda86d9264430b3f816\",\n    \"0xa0561c27224baf0927ad144cb71e31e54a064c598373fcf0d66aebf98ab7af1d8e2f343f77baefff69a6da750a219e11\",\n    \"0xaa5cc43f5b8162b016f5e1b61214c0c9d15b1078911c650b75e6cdfb49b85ee04c6739f5b1687d15908444f691f732de\",\n    \"0xad4ac099b935589c7b8fdfdf3db332b7b82bb948e13a5beb121ebd7db81a87d278024a1434bcf0115c54ca5109585c3d\",\n    \"0x8a00466abf3f109a1dcd19e643b603d3af23d42794ef8ca2514dd507ecea44a031ac6dbc18bd02f99701168b25c1791e\",\n    \"0xb00b5900dfad79645f8bee4e5adc7b84eb22e5b1e67df77ccb505b7fc044a6c08a8ea5faca662414eb945f874f884cea\",\n    \"0x950e204e5f17112250b22ea6bb8423baf522fc0af494366f18fe0f949f51d6e6812074a80875cf1ed9c8e7420058d541\",\n    \"0x91e5cbf8bb1a1d50c81608c9727b414d0dd2fb467ebc92f100882a3772e54f94979cfdf8e373fdef7c7fcdd60fec9e00\",\n    \"0xa093f6a857b8caaff80599c2e89c962b415ecbaa70d8fd973155fa976a284c6b29a855f5f7a3521134d00d2972755188\",\n    \"0xb4d55a3551b00da54cc010f80d99ddd2544bde9219a3173dfaadf3848edc7e4056ab532fb75ac26f5f7141e724267663\",\n    \"0xa03ea050fc9b011d1b04041b5765d6f6453a93a1819cd9bd6328637d0b428f08526466912895dcc2e3008ee58822e9a7\",\n    \"0x99b12b3665e473d01bc6985844f8994fb65cb15745024fb7af518398c4a37ff215da8f054e8fdf3286984ae36a73ca5e\",\n    \"0x9972c7e7a7fb12e15f78d55abcaf322c11249cd44a08f62c95288f34f66b51f146302bce750ff4d591707075d9123bd2\",\n    \"0xa64b4a6d72354e596d87cda213c4fc2814009461570ccb27d455bbe131f8d948421a71925425b546d8cf63d5458cd64b\",\n    \"0x91c215c73b195795ede2228b7ed1f6e37892e0c6b0f4a0b5a16c57aa1100c84df9239054a173b6110d6c2b7f4bf1ce52\",\n    \"0x88807198910ec1303480f76a3683870246a995e36adaeadc29c22f0bdba8152fe705bd070b75de657b04934f7d0ccf80\",\n    \"0xb37c0026c7b32eb02cacac5b55cb5fe784b8e48b2945c64d3037af83ece556a117f0ff053a5968c2f5fa230e291c1238\",\n    \"0x94c768384ce212bc2387e91ce8b45e4ff120987e42472888a317abc9dcdf3563b62e7a61c8e98d7cdcbe272167d91fc6\",\n    \"0xa10c2564936e967a390cb14ef6e8f8b04ea9ece5214a38837eda09e79e0c7970b1f83adf017c10efd6faa8b7ffa2c567\",\n    \"0xa5085eed3a95f9d4b1269182ea1e0d719b7809bf5009096557a0674bde4201b0ddc1f0f16a908fc468846b3721748ce3\",\n    \"0x87468eb620b79a0a455a259a6b4dfbc297d0d53336537b771254dd956b145dc816b195b7002647ea218552e345818a3f\",\n    \"0xace2b77ffb87366af0a9cb5d27d6fc4a14323dbbf1643f5f3c4559306330d86461bb008894054394cbfaefeaa0bc2745\",\n    \"0xb27f56e840a54fbd793f0b7a7631aa4cee64b5947e4382b2dfb5eb1790270288884c2a19afebe5dc0c6ef335d4531c1c\",\n    \"0x876e438633931f7f895062ee16c4b9d10428875f7bc79a8e156a64d379a77a2c45bf5430c5ab94330f03da352f1e9006\",\n    \"0xa2512a252587d200d2092b44c914df54e04ff8bcef36bf631f84bde0cf5a732e3dc7f00f662842cfd74b0b0f7f24180e\",\n    \"0x827f1bc8f54a35b7a4bd8154f79bcc055e45faed2e74adf7cf21cca95df44d96899e847bd70ead6bb27b9c0ed97bbd8b\",\n    \"0xa0c92cf5a9ed843714f3aea9fe7b880f622d0b4a3bf66de291d1b745279accf6ba35097849691370f41732ba64b5966b\",\n    \"0xa63f5c1e222775658421c487b1256b52626c6f79cb55a9b7deb2352622cedffb08502042d622eb3b02c97f9c09f9c957\",\n    \"0x8cc093d52651e65fb390e186db6cc4de559176af4624d1c44cb9b0e836832419dacac7b8db0627b96288977b738d785d\",\n    \"0xaa7b6a17dfcec146134562d32a12f7bd7fe9522e300859202a02939e69dbd345ed7ff164a184296268f9984f9312e8fc\",\n    \"0x8ac76721f0d2b679f023d06cbd28c85ae5f4b43c614867ccee88651d4101d4fd352dbdb65bf36bfc3ebc0109e4b0c6f9\",\n    \"0x8d350f7c05fc0dcd9a1170748846fb1f5d39453e4cb31e6d1457bed287d96fc393b2ecc53793ca729906a33e59c6834a\",\n    \"0xb9913510dfc5056d7ec5309f0b631d1ec53e3a776412ada9aefdaf033c90da9a49fdde6719e7c76340e86599b1f0eec2\",\n    \"0x94955626bf4ce87612c5cfffcf73bf1c46a4c11a736602b9ba066328dc52ad6d51e6d4f53453d4ed55a51e0aad810271\",\n    \"0xb0fcab384fd4016b2f1e53f1aafd160ae3b1a8865cd6c155d7073ecc1664e05b1d8bca1def39c158c7086c4e1103345e\",\n    \"0x827de3f03edfbde08570b72de6662c8bfa499b066a0a27ebad9b481c273097d17a5a0a67f01553da5392ec3f149b2a78\",\n    \"0xab7940384c25e9027c55c40df20bd2a0d479a165ced9b1046958353cd69015eeb1e44ed2fd64e407805ba42df10fc7bf\",\n    \"0x8ad456f6ff8cd58bd57567d931f923d0c99141978511b17e03cab7390a72b9f62498b2893e1b05c7c22dd274e9a31919\",\n    \"0xac75399e999effe564672db426faa17a839e57c5ef735985c70cd559a377adec23928382767b55ed5a52f7b11b54b756\",\n    \"0xb17f975a00b817299ac7af5f2024ea820351805df58b43724393bfb3920a8cd747a3bbd4b8286e795521489db3657168\",\n    \"0xa2bed800a6d95501674d9ee866e7314063407231491d794f8cf57d5be020452729c1c7cefd8c50dc1540181f5caab248\",\n    \"0x9743f5473171271ffdd3cc59a3ae50545901a7b45cd4bc3570db487865f3b73c0595bebabbfe79268809ee1862e86e4a\",\n    \"0xb7eab77c2d4687b60d9d7b04e842b3880c7940140012583898d39fcc22d9b9b0a9be2c2e3788b3e6f30319b39c338f09\",\n    \"0x8e2b8f797a436a1b661140e9569dcf3e1eea0a77c7ff2bc4ff0f3e49af04ed2de95e255df8765f1d0927fb456a9926b1\",\n    \"0x8aefea201d4a1f4ff98ffce94e540bb313f2d4dfe7e9db484a41f13fc316ed02b282e1acc9bc6f56cad2dc2e393a44c9\",\n    \"0xb950c17c0e5ca6607d182144aa7556bb0efe24c68f06d79d6413a973b493bfdf04fd147a4f1ab03033a32004cc3ea66f\",\n    \"0xb7b8dcbb179a07165f2dc6aa829fad09f582a71b05c3e3ea0396bf9e6fe73076f47035c031c2101e8e38e0d597eadd30\",\n    \"0xa9d77ed89c77ec1bf8335d08d41c3c94dcca9fd1c54f22837b4e54506b212aa38d7440126c80648ab7723ff18e65ed72\",\n    \"0xa819d6dfd4aef70e52b8402fe5d135f8082d40eb7d3bb5c4d7997395b621e2bb10682a1bad2c9caa33dd818550fc3ec6\",\n    \"0x8f6ee34128fac8bbf13ce2d68b2bb363eb4fd65b297075f88e1446ddeac242500eeb4ef0735e105882ff5ba8c44c139b\",\n    \"0xb4440e48255c1644bcecf3a1e9958f1ec4901cb5b1122ee5b56ffd02cad1c29c4266999dbb85aa2605c1b125490074d4\",\n    \"0xa43304a067bede5f347775d5811cf65a6380a8d552a652a0063580b5c5ef12a0867a39c7912fa219e184f4538eba1251\",\n    \"0xa891ad67a790089ffc9f6d53e6a3d63d3556f5f693e0cd8a7d0131db06fd4520e719cfcc3934f0a8f62a95f90840f1d4\",\n    \"0xaea6df8e9bb871081aa0fc5a9bafb00be7d54012c5baf653791907d5042a326aeee966fd9012a582cc16695f5baf7042\",\n    \"0x8ffa2660dc52ed1cd4eff67d6a84a8404f358a5f713d04328922269bee1e75e9d49afeec0c8ad751620f22352a438e25\",\n    \"0x87ec6108e2d63b06abed350f8b363b7489d642486f879a6c3aa90e5b0f335efc2ff2834eef9353951a42136f8e6a1b32\",\n    \"0x865619436076c2760d9e87ddc905023c6de0a8d56eef12c98a98c87837f2ca3f27fd26a2ad752252dbcbe2b9f1d5a032\",\n    \"0x980437dce55964293cb315c650c5586ffd97e7a944a83f6618af31c9d92c37b53ca7a21bb5bc557c151b9a9e217e7098\",\n    \"0x95d128fc369df4ad8316b72aea0ca363cbc7b0620d6d7bb18f7076a8717a6a46956ff140948b0cc4f6d2ce33b5c10054\",\n    \"0x8c7212d4a67b9ec70ebbca04358ad2d36494618d2859609163526d7b3acc2fc935ca98519380f55e6550f70a9bc76862\",\n    \"0x893a2968819401bf355e85eee0f0ed0406a6d4a7d7f172d0017420f71e00bb0ba984f6020999a3cdf874d3cd8ebcd371\",\n    \"0x9103c1af82dece25d87274e89ea0acd7e68c2921c4af3d8d7c82ab0ed9990a5811231b5b06113e7fa43a6bd492b4564f\",\n    \"0x99cfd87a94eab7d35466caa4ed7d7bb45e5c932b2ec094258fb14bf205659f83c209b83b2f2c9ccb175974b2a33e7746\",\n    \"0x874b6b93e4ee61be3f00c32dd84c897ccd6855c4b6251eb0953b4023634490ed17753cd3223472873cbc6095b2945075\",\n    \"0x84a32c0dc4ea60d33aac3e03e70d6d639cc9c4cc435c539eff915017be3b7bdaba33349562a87746291ebe9bc5671f24\",\n    \"0xa7057b24208928ad67914e653f5ac1792c417f413d9176ba635502c3f9c688f7e2ee81800d7e3dc0a340c464da2fd9c5\",\n    \"0xa03fb9ed8286aacfa69fbd5d953bec591c2ae4153400983d5dbb6cd9ea37fff46ca9e5cceb9d117f73e9992a6c055ad2\",\n    \"0x863b2de04e89936c9a4a2b40380f42f20aefbae18d03750fd816c658aee9c4a03df7b12121f795c85d01f415baaeaa59\",\n    \"0x8526eb9bd31790fe8292360d7a4c3eed23be23dd6b8b8f01d2309dbfdc0cfd33ad1568ddd7f8a610f3f85a9dfafc6a92\",\n    \"0xb46ab8c5091a493d6d4d60490c40aa27950574a338ea5bbc045be3a114af87bdcb160a8c80435a9b7ad815f3cb56a3f3\",\n    \"0xaeadc47b41a8d8b4176629557646202f868b1d728b2dda58a347d937e7ffc8303f20d26d6c00b34c851b8aeec547885d\",\n    \"0xaebb19fc424d72c1f1822aa7adc744cd0ef7e55727186f8df8771c784925058c248406ebeeaf3c1a9ee005a26e9a10c6\",\n    \"0x8ff96e81c1a4a2ab1b4476c21018fae0a67e92129ee36120cae8699f2d7e57e891f5c624902cb1b845b944926a605cc3\",\n    \"0x8251b8d2c43fadcaa049a9e7aff838dae4fb32884018d58d46403ac5f3beb5c518bfd45f03b8abb710369186075eb71c\",\n    \"0xa8b2a64f865f51a5e5e86a66455c093407933d9d255d6b61e1fd81ffafc9538d73caaf342338a66ba8ee166372a3d105\",\n    \"0xaad915f31c6ba7fdc04e2aaac62e84ef434b7ee76a325f07dc430d12c84081999720181067b87d792efd0117d7ee1eab\",\n    \"0xa13db3bb60389883fd41d565c54fb5180d9c47ce2fe7a169ae96e01d17495f7f4fa928d7e556e7c74319c4c25d653eb2\",\n    \"0xa4491b0198459b3f552855d680a59214eb74e6a4d6c5fa3b309887dc50ebea2ecf6d26c040550f7dc478b452481466fb\",\n    \"0x8f017f13d4b1e3f0c087843582b52d5f8d13240912254d826dd11f8703a99a2f3166dfbdfdffd9a3492979d77524276b\",\n    \"0x96c3d5dcd032660d50d7cd9db2914f117240a63439966162b10c8f1f3cf74bc83b0f15451a43b31dbd85e4a7ce0e4bb1\",\n    \"0xb479ec4bb79573d32e0ec93b92bdd7ec8c26ddb5a2d3865e7d4209d119fd3499eaac527615ffac78c440e60ef3867ae0\",\n    \"0xb2c49c4a33aa94b52b6410b599e81ff15490aafa7e43c8031c865a84e4676354a9c81eb4e7b8be6825fdcefd1e317d44\",\n    \"0x906dc51d6a90c089b6704b47592805578a6eed106608eeb276832f127e1b8e858b72e448edcbefb497d152447e0e68ff\",\n    \"0xb0e81c63b764d7dfbe3f3fddc9905aef50f3633e5d6a4af6b340495124abedcff5700dfd1577bbbed7b6bf97d02719cb\",\n    \"0x9304c64701e3b4ed6d146e48a881f7d83a17f58357cca0c073b2bb593afd2d94f6e2a7a1ec511d0a67ad6ff4c3be5937\",\n    \"0xb6fdbd12ba05aa598d80b83f70a15ef90e5cba7e6e75fa038540ee741b644cd1f408a6cecfd2a891ef8d902de586c6b5\",\n    \"0xb80557871a6521b1b3c74a1ba083ae055b575df607f1f7b04c867ba8c8c181ea68f8d90be6031f4d25002cca27c44da2\",\n    \"0xaa7285b8e9712e06b091f64163f1266926a36607f9d624af9996856ed2aaf03a580cb22ce407d1ade436c28b44ca173f\",\n    \"0x8148d72b975238b51e6ea389e5486940d22641b48637d7dfadfa603a605bfc6d74a016480023945d0b85935e396aea5d\",\n    \"0x8a014933a6aea2684b5762af43dcf4bdbb633cd0428d42d71167a2b6fc563ece5e618bff22f1db2ddb69b845b9a2db19\",\n    \"0x990d91740041db770d0e0eb9d9d97d826f09fd354b91c41e0716c29f8420e0e8aac0d575231efba12fe831091ec38d5a\",\n    \"0x9454d0d32e7e308ddec57cf2522fb1b67a2706e33fb3895e9e1f18284129ab4f4c0b7e51af25681d248d7832c05eb698\",\n    \"0xa5bd434e75bac105cb3e329665a35bce6a12f71dd90c15165777d64d4c13a82bceedb9b48e762bd24034e0fc9fbe45f4\",\n    \"0xb09e3b95e41800d4dc29c6ffdaab2cd611a0050347f6414f154a47ee20ee59bf8cf7181454169d479ebce1eb5c777c46\",\n    \"0xb193e341d6a047d15eea33766d656d807b89393665a783a316e9ba10518e5515c8e0ade3d6e15641d917a8a172a5a635\",\n    \"0xade435ec0671b3621dde69e07ead596014f6e1daa1152707a8c18877a8b067bde2895dd47444ffa69db2bbef1f1d8816\",\n    \"0xa7fd3d6d87522dfc56fb47aef9ce781a1597c56a8bbfd796baba907afdc872f753d732bfda1d3402aee6c4e0c189f52d\",\n    \"0xa298cb4f4218d0464b2fab393e512bbc477c3225aa449743299b2c3572f065bc3a42d07e29546167ed9e1b6b3b3a3af3\",\n    \"0xa9ee57540e1fd9c27f4f0430d194b91401d0c642456c18527127d1f95e2dba41c2c86d1990432eb38a692fda058fafde\",\n    \"0x81d6c1a5f93c04e6d8e5a7e0678c1fc89a1c47a5c920bcd36180125c49fcf7c114866b90e90a165823560b19898a7c16\",\n    \"0xa4b7a1ec9e93c899b9fd9aaf264c50e42c36c0788d68296a471f7a3447af4dbc81e4fa96070139941564083ec5b5b5a1\",\n    \"0xb3364e327d381f46940c0e11e29f9d994efc6978bf37a32586636c0070b03e4e23d00650c1440f448809e1018ef9f6d8\",\n    \"0x8056e0913a60155348300e3a62e28b5e30629a90f7dd4fe11289097076708110a1d70f7855601782a3cdc5bdb1ca9626\",\n    \"0xb4980fd3ea17bac0ba9ee1c470b17e575bb52e83ebdd7d40c93f4f87bebeaff1c8a679f9d3d09d635f068d37d5bd28bd\",\n    \"0x905a9299e7e1853648e398901dfcd437aa575c826551f83520df62984f5679cb5f0ea86aa45ed3e18b67ddc0dfafe809\",\n    \"0xab99553bf31a84f2e0264eb34a08e13d8d15e2484aa9352354becf9a15999c76cc568d68274b70a65e49703fc23540d0\",\n    \"0xa43681597bc574d2dae8964c9a8dc1a07613d7a1272bdcb818d98c85d44e16d744250c33f3b5e4d552d97396b55e601f\",\n    \"0xa54e5a31716fccb50245898c99865644405b8dc920ded7a11f3d19bdc255996054b268e16f2e40273f11480e7145f41e\",\n    \"0x8134f3ad5ef2ad4ba12a8a4e4d8508d91394d2bcdc38b7c8c8c0b0a820357ac9f79d286c65220f471eb1adca1d98fc68\",\n    \"0x94e2f755e60471578ab2c1adb9e9cea28d4eec9b0e92e0140770bca7002c365fcabfe1e5fb4fe6cfe79a0413712aa3ef\",\n    \"0xad48f8d0ce7eb3cc6e2a3086ad96f562e5bed98a360721492ae2e74dc158586e77ec8c35d5fd5927376301b7741bad2b\",\n    \"0x8614f0630bdd7fbad3a31f55afd9789f1c605dc85e7dc67e2edfd77f5105f878bb79beded6e9f0b109e38ea7da67e8d5\",\n    \"0x9804c284c4c5e77dabb73f655b12181534ca877c3e1e134aa3f47c23b7ec92277db34d2b0a5d38d2b69e5d1c3008a3e3\",\n    \"0xa51b99c3088e473afdaa9e0a9f7e75a373530d3b04e44e1148da0726b95e9f5f0c7e571b2da000310817c36f84b19f7f\",\n    \"0xac4ff909933b3b76c726b0a382157cdc74ab851a1ac6cef76953c6444441804cc43abb883363f416592e8f6cfbc4550b\",\n    \"0xae7d915eb9fc928b65a29d6edbc75682d08584d0014f7bcf17d59118421ae07d26a02137d1e4de6938bcd1ab8ef48fad\",\n    \"0x852f7e453b1af89b754df6d11a40d5d41ea057376e8ecacd705aacd2f917457f4a093d6b9a8801837fa0f62986ad7149\",\n    \"0x92c6bf5ada5d0c3d4dd8058483de36c215fa98edab9d75242f3eff9db07c734ad67337da6f0eefe23a487bf75a600dee\",\n    \"0xa2b42c09d0db615853763552a48d2e704542bbd786aae016eb58acbf6c0226c844f5fb31e428cb6450b9db855f8f2a6f\",\n    \"0x880cc07968266dbfdcfbc21815cd69e0eddfee239167ac693fb0413912d816f2578a74f7716eecd6deefa68c6eccd394\",\n    \"0xb885b3ace736cd373e8098bf75ba66fa1c6943ca1bc4408cd98ac7074775c4478594f91154b8a743d9c697e1b29f5840\",\n    \"0xa51ce78de512bd87bfa0835de819941dffbf18bec23221b61d8096fc9436af64e0693c335b54e7bfc763f287bdca2db6\",\n    \"0xa3c76166a3bdb9b06ef696e57603b58871bc72883ee9d45171a30fe6e1d50e30bc9c51b4a0f5a7270e19a77b89733850\",\n    \"0xacefc5c6f8a1e7c24d7b41e0fc7f6f3dc0ede6cf3115ffb9a6e54b1d954cbca9bda8ad7a084be9be245a1b8e9770d141\",\n    \"0xb420ed079941842510e31cfad117fa11fb6b4f97dfbc6298cb840f27ebaceba23eeaf3f513bcffbf5e4aae946310182d\",\n    \"0x95c3bb5ef26c5ed2f035aa5d389c6b3c15a6705b9818a3fefaed28922158b35642b2e8e5a1a620fdad07e75ad4b43af4\",\n    \"0x825149f9081ecf07a2a4e3e8b5d21bade86c1a882475d51c55ee909330b70c5a2ac63771c8600c6f38df716af61a3ea1\",\n    \"0x873b935aae16d9f08adbc25353cee18af2f1b8d5f26dec6538d6bbddc515f2217ed7d235dcfea59ae61b428798b28637\",\n    \"0x9294150843a2bedcedb3bb74c43eb28e759cf9499582c5430bccefb574a8ddd4f11f9929257ff4c153990f9970a2558f\",\n    \"0xb619563a811cc531da07f4f04e5c4c6423010ff9f8ed7e6ec9449162e3d501b269fb1c564c09c0429431879b0f45df02\",\n    \"0x91b509b87eb09f007d839627514658c7341bc76d468920fe8a740a8cb96a7e7e631e0ea584a7e3dc1172266f641d0f5c\",\n    \"0x8b8aceace9a7b9b4317f1f01308c3904d7663856946afbcea141a1c615e21ccad06b71217413e832166e9dd915fbe098\",\n    \"0x87b3b36e725833ea0b0f54753c3728c0dbc87c52d44d705ffc709f2d2394414c652d3283bab28dcce09799504996cee0\",\n    \"0xb2670aad5691cbf308e4a6a77a075c4422e6cbe86fdba24e9f84a313e90b0696afb6a067eebb42ba2d10340d6a2f6e51\",\n    \"0x876784a9aff3d54faa89b2bacd3ff5862f70195d0b2edc58e8d1068b3c9074c0da1cfa23671fe12f35e33b8a329c0ccd\",\n    \"0x8b48b9e758e8a8eae182f5cbec96f67d20cca6d3eee80a2d09208eb1d5d872e09ef23d0df8ebbb9b01c7449d0e3e3650\",\n    \"0xb79303453100654c04a487bdcadc9e3578bc80930c489a7069a52e8ca1dba36c492c8c899ce025f8364599899baa287d\",\n    \"0x961b35a6111da54ece6494f24dacd5ea46181f55775b5f03df0e370c34a5046ac2b4082925855325bb42bc2a2c98381d\",\n    \"0xa31feb1be3f5a0247a1f7d487987eb622e34fca817832904c6ee3ee60277e5847945a6f6ea1ac24542c72e47bdf647df\",\n    \"0xa12a2aa3e7327e457e1aae30e9612715dd2cfed32892c1cd6dcda4e9a18203af8a44afb46d03b2eed89f6b9c5a2c0c23\",\n    \"0xa08265a838e69a2ca2f80fead6ccf16f6366415b920c0b22ee359bcd8d4464ecf156f400a16a7918d52e6d733dd64211\",\n    \"0xb723d6344e938d801cca1a00032af200e541d4471fd6cbd38fb9130daa83f6a1dffbbe7e67fc20f9577f884acd7594b2\",\n    \"0xa6733d83ec78ba98e72ddd1e7ff79b7adb0e559e256760d0c590a986e742445e8cdf560d44b29439c26d87edd0b07c8c\",\n    \"0xa61c2c27d3f7b9ff4695a17afedf63818d4bfba390507e1f4d0d806ce8778d9418784430ce3d4199fd3bdbc2504d2af3\",\n    \"0x8332f3b63a6dc985376e8b1b25eeae68be6160fbe40053ba7bcf6f073204f682da72321786e422d3482fd60c9e5aa034\",\n    \"0xa280f44877583fbb6b860d500b1a3f572e3ee833ec8f06476b3d8002058e25964062feaa1e5bec1536d734a5cfa09145\",\n    \"0xa4026a52d277fcea512440d2204f53047718ebfcae7b48ac57ea7f6bfbc5de9d7304db9a9a6cbb273612281049ddaec5\",\n    \"0x95cdf69c831ab2fad6c2535ede9c07e663d2ddccc936b64e0843d2df2a7b1c31f1759c3c20f1e7a57b1c8f0dbb21b540\",\n    \"0x95c96cec88806469c277ab567863c5209027cecc06c7012358e5f555689c0d9a5ffb219a464f086b45817e8536b86d2f\",\n    \"0xafe38d4684132a0f03d806a4c8df556bf589b25271fbc6fe2e1ed16de7962b341c5003755da758d0959d2e6499b06c68\",\n    \"0xa9b77784fda64987f97c3a23c5e8f61b918be0f7c59ba285084116d60465c4a2aaafc8857eb16823282cc83143eb9126\",\n    \"0xa830f05881ad3ce532a55685877f529d32a5dbe56cea57ffad52c4128ee0fad0eeaf0da4362b55075e77eda7babe70e5\",\n    \"0x992b3ad190d6578033c13ed5abfee4ef49cbc492babb90061e3c51ee4b5790cdd4c8fc1abff1fa2c00183b6b64f0bbbe\",\n    \"0xb1015424d9364aeff75de191652dc66484fdbec3e98199a9eb9671ec57bec6a13ff4b38446e28e4d8aedb58dd619cd90\",\n    \"0xa745304604075d60c9db36cada4063ac7558e7ec2835d7da8485e58d8422e817457b8da069f56511b02601289fbb8981\",\n    \"0xa5ba4330bc5cb3dbe0486ddf995632a7260a46180a08f42ae51a2e47778142132463cc9f10021a9ad36986108fefa1a9\",\n    \"0xb419e9fd4babcaf8180d5479db188bb3da232ae77a1c4ed65687c306e6262f8083070a9ac32220cddb3af2ec73114092\",\n    \"0xa49e23dc5f3468f3bf3a0bb7e4a114a788b951ff6f23a3396ae9e12cbff0abd1240878a3d1892105413dbc38818e807c\",\n    \"0xb7ecc7b4831f650202987e85b86bc0053f40d983f252e9832ef503aea81c51221ce93279da4aa7466c026b2d2070e55d\",\n    \"0x96a8c35cb87f84fa84dcd6399cc2a0fd79cc9158ef4bdde4bae31a129616c8a9f2576cd19baa3f497ca34060979aed7d\",\n    \"0x8681b2c00aa62c2b519f664a95dcb8faef601a3b961bb4ce5d85a75030f40965e2983871d41ea394aee934e859581548\",\n    \"0x85c229a07efa54a713d0790963a392400f55fbb1a43995a535dc6c929f20d6a65cf4efb434e0ad1cb61f689b8011a3bc\",\n    \"0x90856f7f3444e5ad44651c28e24cc085a5db4d2ffe79aa53228c26718cf53a6e44615f3c5cda5aa752d5f762c4623c66\",\n    \"0x978999b7d8aa3f28a04076f74d11c41ef9c89fdfe514936c4238e0f13c38ec97e51a5c078ebc6409e517bfe7ccb42630\",\n    \"0xa099914dd7ed934d8e0d363a648e9038eb7c1ec03fa04dbcaa40f7721c618c3ef947afef7a16b4d7ac8c12aa46637f03\",\n    \"0xab2a104fed3c83d16f2cda06878fa5f30c8c9411de71bfb67fd2fc9aa454dcbcf3d299d72f8cc12e919466a50fcf7426\",\n    \"0xa4471d111db4418f56915689482f6144efc4664cfb0311727f36c864648d35734351becc48875df96f4abd3cfcf820f9\",\n    \"0x83be11727cd30ea94ccc8fa31b09b81c9d6a9a5d3a4686af9da99587332fe78c1f94282f9755854bafd6033549afec91\",\n    \"0x88020ff971dc1a01a9e993cd50a5d2131ffdcbb990c1a6aaa54b20d8f23f9546a70918ea57a21530dcc440c1509c24ad\",\n    \"0xae24547623465e87905eaffa1fa5d52bb7c453a8dbd89614fa8819a2abcedaf455c2345099b7324ae36eb0ad7c8ef977\",\n    \"0xb59b0c60997de1ee00b7c388bc7101d136c9803bf5437b1d589ba57c213f4f835a3e4125b54738e78abbc21b000f2016\",\n    \"0xa584c434dfe194546526691b68fa968c831c31da42303a1d735d960901c74011d522246f37f299555416b8cf25c5a548\",\n    \"0x80408ce3724f4837d4d52376d255e10f69eb8558399ae5ca6c11b78b98fe67d4b93157d2b9b639f1b5b64198bfe87713\",\n    \"0xabb941e8d406c2606e0ddc35c113604fdd9d249eacc51cb64e2991e551b8639ce44d288cc92afa7a1e7fc599cfc84b22\",\n    \"0xb223173f560cacb1c21dba0f1713839e348ad02cbfdef0626748604c86f89e0f4c919ed40b583343795bdd519ba952c8\",\n    \"0xaf1c70512ec3a19d98b8a1fc3ff7f7f5048a27d17d438d43f561974bbdd116fcd5d5c21040f3447af3f0266848d47a15\",\n    \"0x8a44809568ebe50405bede19b4d2607199159b26a1b33e03d180e6840c5cf59d991a4fb150d111443235d75ecad085b7\",\n    \"0xb06207cdca46b125a27b3221b5b50cf27af4c527dd7c80e2dbcebbb09778a96df3af67e50f07725239ce3583dad60660\",\n    \"0x993352d9278814ec89b26a11c4a7c4941bf8f0e6781ae79559d14749ee5def672259792db4587f85f0100c7bb812f933\",\n    \"0x9180b8a718b971fd27bc82c8582d19c4b4f012453e8c0ffeeeffe745581fc6c07875ab28be3af3fa3896d19f0c89ac5b\",\n    \"0x8b8e1263eb48d0fe304032dd5ea1f30e73f0121265f7458ba9054d3626894e8a5fef665340abd2ede9653045c2665938\",\n    \"0x99a2beee4a10b7941c24b2092192faf52b819afd033e4a2de050fd6c7f56d364d0cf5f99764c3357cf32399e60fc5d74\",\n    \"0x946a4aad7f8647ea60bee2c5fcdeb6f9a58fb2cfca70c4d10e458027a04846e13798c66506151be3df9454b1e417893f\",\n    \"0xa672a88847652d260b5472d6908d1d57e200f1e492d30dd1cecc441cdfc9b76e016d9bab560efd4d7f3c30801de884a9\",\n    \"0x9414e1959c156cde1eb24e628395744db75fc24b9df4595350aaad0bc38e0246c9b4148f6443ef68b8e253a4a6bcf11c\",\n    \"0x9316e9e4ec5fab4f80d6540df0e3a4774db52f1d759d2e5b5bcd3d7b53597bb007eb1887cb7dc61f62497d51ffc8d996\",\n    \"0x902d6d77bb49492c7a00bc4b70277bc28c8bf9888f4307bb017ac75a962decdedf3a4e2cf6c1ea9f9ba551f4610cbbd7\",\n    \"0xb07025a18b0e32dd5e12ec6a85781aa3554329ea12c4cd0d3b2c22e43d777ef6f89876dd90a9c8fb097ddf61cf18adc5\",\n    \"0xb355a849ad3227caa4476759137e813505ec523cbc2d4105bc7148a4630f9e81918d110479a2d5f5e4cd9ccec9d9d3e3\",\n    \"0xb49532cfdf02ee760109881ad030b89c48ee3bb7f219ccafc13c93aead754d29bdafe345be54c482e9d5672bd4505080\",\n    \"0x9477802410e263e4f938d57fa8f2a6cac7754c5d38505b73ee35ea3f057aad958cb9722ba6b7b3cfc4524e9ca93f9cdc\",\n    \"0x9148ea83b4436339580f3dbc9ba51509e9ab13c03063587a57e125432dd0915f5d2a8f456a68f8fff57d5f08c8f34d6e\",\n    \"0xb00b6b5392b1930b54352c02b1b3b4f6186d20bf21698689bbfc7d13e86538a4397b90e9d5c93fd2054640c4dbe52a4f\",\n    \"0x926a9702500441243cd446e7cbf15dde16400259726794694b1d9a40263a9fc9e12f7bcbf12a27cb9aaba9e2d5848ddc\",\n    \"0xa0c6155f42686cbe7684a1dc327100962e13bafcf3db97971fc116d9f5c0c8355377e3d70979cdbd58fd3ea52440901c\",\n    \"0xa277f899f99edb8791889d0817ea6a96c24a61acfda3ad8c3379e7c62b9d4facc4b965020b588651672fd261a77f1bfc\",\n    \"0x8f528cebb866b501f91afa50e995234bef5bf20bff13005de99cb51eaac7b4f0bf38580cfd0470de40f577ead5d9ba0f\",\n    \"0x963fc03a44e9d502cc1d23250efef44d299befd03b898d07ce63ca607bb474b5cf7c965a7b9b0f32198b04a8393821f7\",\n    \"0xab087438d0a51078c378bf4a93bd48ef933ff0f1fa68d02d4460820df564e6642a663b5e50a5fe509527d55cb510ae04\",\n    \"0xb0592e1f2c54746bb076be0fa480e1c4bebc4225e1236bcda3b299aa3853e3afb401233bdbcfc4a007b0523a720fbf62\",\n    \"0x851613517966de76c1c55a94dc4595f299398a9808f2d2f0a84330ba657ab1f357701d0895f658c18a44cb00547f6f57\",\n    \"0xa2fe9a1dd251e72b0fe4db27be508bb55208f8f1616b13d8be288363ec722826b1a1fd729fc561c3369bf13950bf1fd6\",\n    \"0xb896cb2bc2d0c77739853bc59b0f89b2e008ba1f701c9cbe3bef035f499e1baee8f0ff1e794854a48c320586a2dfc81a\",\n    \"0xa1b60f98e5e5106785a9b81a85423452ee9ef980fa7fa8464f4366e73f89c50435a0c37b2906052b8e58e212ebd366cf\",\n    \"0xa853b0ebd9609656636df2e6acd5d8839c0fda56f7bf9288a943b06f0b67901a32b95e016ca8bc99bd7b5eab31347e72\",\n    \"0xb290fa4c1346963bd5225235e6bdf7c542174dab4c908ab483d1745b9b3a6015525e398e1761c90e4b49968d05e30eea\",\n    \"0xb0f65a33ad18f154f1351f07879a183ad62e5144ad9f3241c2d06533dad09cbb2253949daff1bb02d24d16a3569f7ef0\",\n    \"0xa00db59b8d4218faf5aeafcd39231027324408f208ec1f54d55a1c41228b463b88304d909d16b718cfc784213917b71e\",\n    \"0xb8d695dd33dc2c3bc73d98248c535b2770ad7fa31aa726f0aa4b3299efb0295ba9b4a51c71d314a4a1bd5872307534d1\",\n    \"0xb848057cca2ca837ee49c42b88422303e58ea7d2fc76535260eb5bd609255e430514e927cc188324faa8e657396d63ec\",\n    \"0x92677836061364685c2aaf0313fa32322746074ed5666fd5f142a7e8f87135f45cd10e78a17557a4067a51dfde890371\",\n    \"0xa854b22c9056a3a24ab164a53e5c5cf388616c33e67d8ebb4590cb16b2e7d88b54b1393c93760d154208b5ca822dc68f\",\n    \"0x86fff174920388bfab841118fb076b2b0cdec3fdb6c3d9a476262f82689fb0ed3f1897f7be9dbf0932bb14d346815c63\",\n    \"0x99661cf4c94a74e182752bcc4b98a8c2218a8f2765642025048e12e88ba776f14f7be73a2d79bd21a61def757f47f904\",\n    \"0x8a8893144d771dca28760cba0f950a5d634195fd401ec8cf1145146286caffb0b1a6ba0c4c1828d0a5480ce49073c64c\",\n    \"0x938a59ae761359ee2688571e7b7d54692848eb5dde57ffc572b473001ea199786886f8c6346a226209484afb61d2e526\",\n    \"0x923f68a6aa6616714cf077cf548aeb845bfdd78f2f6851d8148cba9e33a374017f2f3da186c39b82d14785a093313222\",\n    \"0xac923a93d7da7013e73ce8b4a2b14b8fd0cc93dc29d5de941a70285bdd19be4740fedfe0c56b046689252a3696e9c5bc\",\n    \"0xb49b32c76d4ec1a2c68d4989285a920a805993bc6fcce6dacd3d2ddae73373050a5c44ba8422a3781050682fa0ef6ba2\",\n    \"0x8a367941c07c3bdca5712524a1411bad7945c7c48ffc7103b1d4dff2c25751b0624219d1ccde8c3f70c465f954be5445\",\n    \"0xb838f029df455efb6c530d0e370bbbf7d87d61a9aea3d2fe5474c5fe0a39cf235ceecf9693c5c6c5820b1ba8f820bd31\",\n    \"0xa8983b7c715eaac7f13a001d2abc462dfc1559dab4a6b554119c271aa8fe00ffcf6b6949a1121f324d6d26cb877bcbae\",\n    \"0xa2afb24ad95a6f14a6796315fbe0d8d7700d08f0cfaf7a2abe841f5f18d4fecf094406cbd54da7232a159f9c5b6e805e\",\n    \"0x87e8e95ad2d62f947b2766ff405a23f7a8afba14e7f718a691d95369c79955cdebe24c54662553c60a3f55e6322c0f6f\",\n    \"0x87c2cbcecb754e0cc96128e707e5c5005c9de07ffd899efa3437cadc23362f5a1d3fcdd30a1f5bdc72af3fb594398c2a\",\n    \"0x91afd6ee04f0496dc633db88b9370d41c428b04fd991002502da2e9a0ef051bcd7b760e860829a44fbe5539fa65f8525\",\n    \"0x8c50e5d1a24515a9dd624fe08b12223a75ca55196f769f24748686315329b337efadca1c63f88bee0ac292dd0a587440\",\n    \"0x8a07e8f912a38d94309f317c32068e87f68f51bdfa082d96026f5f5f8a2211621f8a3856dda8069386bf15fb2d28c18f\",\n    \"0x94ad1dbe341c44eeaf4dc133eed47d8dbfe752575e836c075745770a6679ff1f0e7883b6aa917462993a7f469d74cab5\",\n    \"0x8745f8bd86c2bb30efa7efb7725489f2654f3e1ac4ea95bd7ad0f3cfa223055d06c187a16192d9d7bdaea7b050c6a324\",\n    \"0x900d149c8d79418cda5955974c450a70845e02e5a4ecbcc584a3ca64d237df73987c303e3eeb79da1af83bf62d9e579f\",\n    \"0x8f652ab565f677fb1a7ba03b08004e3cda06b86c6f1b0b9ab932e0834acf1370abb2914c15b0d08327b5504e5990681c\",\n    \"0x9103097d088be1f75ab9d3da879106c2f597e2cc91ec31e73430647bdd5c33bcfd771530d5521e7e14df6acda44f38a6\",\n    \"0xb0fec7791cfb0f96e60601e1aeced9a92446b61fedab832539d1d1037558612d78419efa87ff5f6b7aab8fd697d4d9de\",\n    \"0xb9d2945bdb188b98958854ba287eb0480ef614199c4235ce5f15fc670b8c5ffe8eeb120c09c53ea8a543a022e6a321ac\",\n    \"0xa9461bb7d5490973ebaa51afc0bb4a5e42acdccb80e2f939e88b77ac28a98870e103e1042899750f8667a8cc9123bae9\",\n    \"0xa37fdf11d4bcb2aed74b9f460a30aa34afea93386fa4cdb690f0a71bc58f0b8df60bec56e7a24f225978b862626fa00e\",\n    \"0xa214420e183e03d531cf91661466ea2187d84b6e814b8b20b3730a9400a7d25cf23181bb85589ebc982cec414f5c2923\",\n    \"0xad09a45a698a6beb3e0915f540ef16e9af7087f53328972532d6b5dfe98ce4020555ece65c6cbad8bd6be8a4dfefe6fd\",\n    \"0xab6742800b02728c92d806976764cb027413d6f86edd08ad8bb5922a2969ee9836878cd39db70db0bd9a2646862acc4f\",\n    \"0x974ca9305bd5ea1dc1755dff3b63e8bfe9f744321046c1395659bcea2a987b528e64d5aa96ac7b015650b2253b37888d\",\n    \"0x84eee9d6bce039c52c2ebc4fccc0ad70e20c82f47c558098da4be2f386a493cbc76adc795b5488c8d11b6518c2c4fab8\",\n    \"0x875d7bda46efcb63944e1ccf760a20144df3b00d53282b781e95f12bfc8f8316dfe6492c2efbf796f1150e36e436e9df\",\n    \"0xb68a2208e0c587b5c31b5f6cb32d3e6058a9642e2d9855da4f85566e1412db528475892060bb932c55b3a80877ad7b4a\",\n    \"0xba006368ecab5febb6ab348644d9b63de202293085ed468df8bc24d992ae8ce468470aa37f36a73630c789fb9c819b30\",\n    \"0x90a196035150846cd2b482c7b17027471372a8ce7d914c4d82b6ea7fa705d8ed5817bd42d63886242585baf7d1397a1c\",\n    \"0xa223b4c85e0daa8434b015fd9170b5561fe676664b67064974a1e9325066ecf88fc81f97ab5011c59fad28cedd04b240\",\n    \"0x82e8ec43139cf15c6bbeed484b62e06cded8a39b5ce0389e4cbe9c9e9c02f2f0275d8d8d4e8dfec8f69a191bef220408\",\n    \"0x81a3fc07a7b68d92c6ee4b6d28f5653ee9ec85f7e2ee1c51c075c1b130a8c5097dc661cf10c5aff1c7114b1a6a19f11a\",\n    \"0x8ed2ef8331546d98819a5dd0e6c9f8cb2630d0847671314a28f277faf68da080b53891dd75c82cbcf7788b255490785d\",\n    \"0xacecabf84a6f9bbed6b2fc2e7e4b48f02ef2f15e597538a73aea8f98addc6badda15e4695a67ecdb505c1554e8f345ec\",\n    \"0xb8f51019b2aa575f8476e03dcadf86cc8391f007e5f922c2a36b2daa63f5a503646a468990cd5c65148d323942193051\",\n    \"0xaaa595a84b403ec65729bc1c8055a94f874bf9adddc6c507b3e1f24f79d3ad359595a672b93aab3394db4e2d4a7d8970\",\n    \"0x895144c55fcbd0f64d7dd69e6855cfb956e02b5658eadf0f026a70703f3643037268fdd673b0d21b288578a83c6338dd\",\n    \"0xa2e92ae6d0d237d1274259a8f99d4ea4912a299816350b876fba5ebc60b714490e198a916e1c38c6e020a792496fa23c\",\n    \"0xa45795fda3b5bb0ad1d3c628f6add5b2a4473a1414c1a232e80e70d1cfffd7f8a8d9861f8df2946999d7dbb56bf60113\",\n    \"0xb6659bf7f6f2fef61c39923e8c23b8c70e9c903028d8f62516d16755cd3fba2fe41c285aa9432dc75ab08f8a1d8a81fc\",\n    \"0xa735609a6bc5bfd85e58234fc439ff1f58f1ff1dd966c5921d8b649e21f006bf2b8642ad8a75063c159aaf6935789293\",\n    \"0xa3c622eb387c9d15e7bda2e3e84d007cb13a6d50d655c3f2f289758e49d3b37b9a35e4535d3cc53d8efd51f407281f19\",\n    \"0x8afe147b53ad99220f5ef9d763bfc91f9c20caecbcf823564236fb0e6ede49414c57d71eec4772c8715cc65a81af0047\",\n    \"0xb5f0203233cf71913951e9c9c4e10d9243e3e4a1f2cb235bf3f42009120ba96e04aa414c9938ea8873b63148478927e8\",\n    \"0x93c52493361b458d196172d7ba982a90a4f79f03aa8008edc322950de3ce6acf4c3977807a2ffa9e924047e02072b229\",\n    \"0xb9e72b805c8ac56503f4a86c82720afbd5c73654408a22a2ac0b2e5caccdfb0e20b59807433a6233bc97ae58cf14c70a\",\n    \"0xaf0475779b5cee278cca14c82da2a9f9c8ef222eb885e8c50cca2315fea420de6e04146590ed0dd5a29c0e0812964df5\",\n    \"0xb430ccab85690db02c2d0eb610f3197884ca12bc5f23c51e282bf3a6aa7e4a79222c3d8761454caf55d6c01a327595f9\",\n    \"0x830032937418b26ee6da9b5206f3e24dc76acd98589e37937e963a8333e5430abd6ce3dd93ef4b8997bd41440eed75d6\",\n    \"0x8820a6d73180f3fe255199f3f175c5eb770461ad5cfdde2fb11508041ed19b8c4ce66ad6ecebf7d7e836cc2318df47ca\",\n    \"0xaef1393e7d97278e77bbf52ef6e1c1d5db721ccf75fe753cf47a881fa034ca61eaa5098ee5a344c156d2b14ff9e284ad\",\n    \"0x8a4a26c07218948c1196c45d927ef4d2c42ade5e29fe7a91eaebe34a29900072ce5194cf28d51f746f4c4c649daf4396\",\n    \"0x84011dc150b7177abdcb715efbd8c201f9cb39c36e6069af5c50a096021768ba40cef45b659c70915af209f904ede3b6\",\n    \"0xb1bd90675411389bb66910b21a4bbb50edce5330850c5ab0b682393950124252766fc81f5ecfc72fb7184387238c402e\",\n    \"0x8dfdcd30583b696d2c7744655f79809f451a60c9ad5bf1226dc078b19f4585d7b3ef7fa9d54e1ac09520d95cbfd20928\",\n    \"0xb351b4dc6d98f75b8e5a48eb7c6f6e4b78451991c9ba630e5a1b9874c15ac450cd409c1a024713bf2cf82dc400e025ef\",\n    \"0xa462b8bc97ac668b97b28b3ae24b9f5de60e098d7b23ecb600d2194cd35827fb79f77c3e50d358f5bd72ee83fef18fa0\",\n    \"0xa183753265c5f7890270821880cce5f9b2965b115ba783c6dba9769536f57a04465d7da5049c7cf8b3fcf48146173c18\",\n    \"0xa8a771b81ed0d09e0da4d79f990e58eabcd2be3a2680419502dd592783fe52f657fe55125b385c41d0ba3b9b9cf54a83\",\n    \"0xa71ec577db46011689d073245e3b1c3222a9b1fe6aa5b83629adec5733dd48617ebea91346f0dd0e6cdaa86e4931b168\",\n    \"0xa334b8b244f0d598a02da6ae0f918a7857a54dce928376c4c85df15f3b0f2ba3ac321296b8b7c9dd47d770daf16c8f8c\",\n    \"0xa29037f8ef925c417c90c4df4f9fb27fb977d04e2b3dd5e8547d33e92ab72e7a00f5461de21e28835319eae5db145eb7\",\n    \"0xb91054108ae78b00e3298d667b913ebc44d8f26e531eae78a8fe26fdfb60271c97efb2dee5f47ef5a3c15c8228138927\",\n    \"0x926c13efbe90604f6244be9315a34f72a1f8d1aab7572df431998949c378cddbf2fe393502c930fff614ff06ae98a0ce\",\n    \"0x995c758fd5600e6537089b1baa4fbe0376ab274ff3e82a17768b40df6f91c2e443411de9cafa1e65ea88fb8b87d504f4\",\n    \"0x9245ba307a7a90847da75fca8d77ec03fdfc812c871e7a2529c56a0a79a6de16084258e7a9ac4ae8a3756f394336e21c\",\n    \"0x99e0cfa2bb57a7e624231317044c15e52196ecce020db567c8e8cb960354a0be9862ee0c128c60b44777e65ac315e59f\",\n    \"0xad4f6b3d27bbbb744126601053c3dc98c07ff0eb0b38a898bd80dce778372846d67e5ab8fb34fb3ad0ef3f235d77ba7f\",\n    \"0xa0f12cae3722bbbca2e539eb9cc7614632a2aefe51410430070a12b5bc5314ecec5857b7ff8f41e9980cac23064f7c56\",\n    \"0xb487f1bc59485848c98222fd3bc36c8c9bb3d2912e2911f4ceca32c840a7921477f9b1fe00877e05c96c75d3eecae061\",\n    \"0xa6033db53925654e18ecb3ce715715c36165d7035db9397087ac3a0585e587998a53973d011ac6d48af439493029cee6\",\n    \"0xa6b4d09cd01c70a3311fd131d3710ccf97bde3e7b80efd5a8c0eaeffeb48cca0f951ced905290267b115b06d46f2693b\",\n    \"0xa9dff1df0a8f4f218a98b6f818a693fb0d611fed0fc3143537cbd6578d479af13a653a8155e535548a2a0628ae24fa58\",\n    \"0xa58e469f65d366b519f9a394cacb7edaddac214463b7b6d62c2dbc1316e11c6c5184ce45c16de2d77f990dcdd8b55430\",\n    \"0x989e71734f8119103586dc9a3c5f5033ddc815a21018b34c1f876cdfc112efa868d5751bf6419323e4e59fa6a03ece1c\",\n    \"0xa2da00e05036c884369e04cf55f3de7d659cd5fa3f849092b2519dd263694efe0f051953d9d94b7e121f0aee8b6174d7\",\n    \"0x968f3c029f57ee31c4e1adea89a7f92e28483af9a74f30fbdb995dc2d40e8e657dff8f8d340d4a92bf65f54440f2859f\",\n    \"0x932778df6f60ac1639c1453ef0cbd2bf67592759dcccb3e96dcc743ff01679e4c7dd0ef2b0833dda548d32cb4eba49e2\",\n    \"0xa805a31139f8e0d6dae1ac87d454b23a3dc9fc653d4ca18d4f8ebab30fc189c16e73981c2cb7dd6f8c30454a5208109d\",\n    \"0xa9ba0991296caa2aaa4a1ceacfb205544c2a2ec97088eace1d84ee5e2767656a172f75d2f0c4e16a3640a0e0dec316e0\",\n    \"0xb1e49055c968dced47ec95ae934cf45023836d180702e20e2df57e0f62fb85d7ac60d657ba3ae13b8560b67210449459\",\n    \"0xa94e1da570a38809c71e37571066acabff7bf5632737c9ab6e4a32856924bf6211139ab3cedbf083850ff2d0e0c0fcfc\",\n    \"0x88ef1bb322000c5a5515b310c838c9af4c1cdbb32eab1c83ac3b2283191cd40e9573747d663763a28dad0d64adc13840\",\n    \"0xa987ce205f923100df0fbd5a85f22c9b99b9b9cbe6ddfa8dfda1b8fe95b4f71ff01d6c5b64ca02eb24edb2b255a14ef0\",\n    \"0x84fe8221a9e95d9178359918a108de4763ebfa7a6487facb9c963406882a08a9a93f492f8e77cf9e7ea41ae079c45993\",\n    \"0xaa1cf3dc7c5dcfa15bbbc811a4bb6dbac4fba4f97fb1ed344ab60264d7051f6eef19ea9773441d89929ee942ed089319\",\n    \"0x8f6a7d610d59d9f54689bbe6a41f92d9f6096cde919c1ab94c3c7fcecf0851423bc191e5612349e10f855121c0570f56\",\n    \"0xb5af1fa7894428a53ea520f260f3dc3726da245026b6d5d240625380bfb9c7c186df0204bb604efac5e613a70af5106e\",\n    \"0xa5bce6055ff812e72ce105f147147c7d48d7a2313884dd1f488b1240ee320f13e8a33f5441953a8e7a3209f65b673ce1\",\n    \"0xb9b55b4a1422677d95821e1d042ab81bbf0bf087496504021ec2e17e238c2ca6b44fb3b635a5c9eac0871a724b8d47c3\",\n    \"0x941c38e533ce4a673a3830845b56786585e5fe49c427f2e5c279fc6db08530c8f91db3e6c7822ec6bb4f956940052d18\",\n    \"0xa38e191d66c625f975313c7007bbe7431b5a06ed2da1290a7d5d0f2ec73770d476efd07b8e632de64597d47df175cbb0\",\n    \"0x94ba76b667abf055621db4c4145d18743a368d951565632ed4e743dd50dd3333507c0c34f286a5c5fdbf38191a2255cd\",\n    \"0xa5ca38c60be5602f2bfa6e00c687ac96ac36d517145018ddbee6f12eb0faa63dd57909b9eeed26085fe5ac44e55d10ab\",\n    \"0xb00fea3b825e60c1ed1c5deb4b551aa65a340e5af36b17d5262c9cd2c508711e4dc50dc2521a2c16c7c901902266e64a\",\n    \"0x971b86fc4033485e235ccb0997a236206ba25c6859075edbcdf3c943116a5030b7f75ebca9753d863a522ba21a215a90\",\n    \"0xb3b31f52370de246ee215400975b674f6da39b2f32514fe6bd54e747752eedca22bb840493b44a67df42a3639c5f901f\",\n    \"0xaffbbfac9c1ba7cbfa1839d2ae271dd6149869b75790bf103230637da41857fc326ef3552ff31c15bda0694080198143\",\n    \"0xa95d42aa7ef1962520845aa3688f2752d291926f7b0d73ea2ee24f0612c03b43f2b0fe3c9a9a99620ffc8d487b981bc2\",\n    \"0x914a266065caf64985e8c5b1cb2e3f4e3fe94d7d085a1881b1fefa435afef4e1b39a98551d096a62e4f5cc1a7f0fdc2e\",\n    \"0x81a0b4a96e2b75bc1bf2dbd165d58d55cfd259000a35504d1ffb18bc346a3e6f07602c683723864ffb980f840836fd8d\",\n    \"0x91c1556631cddd4c00b65b67962b39e4a33429029d311c8acf73a18600e362304fb68bccb56fde40f49e95b7829e0b87\",\n    \"0x8befbacc19e57f7c885d1b7a6028359eb3d80792fe13b92a8400df21ce48deb0bb60f2ddb50e3d74f39f85d7eab23adc\",\n    \"0x92f9458d674df6e990789690ec9ca73dacb67fc9255b58c417c555a8cc1208ace56e8e538f86ba0f3615573a0fbac00d\",\n    \"0xb4b1b3062512d6ae7417850c08c13f707d5838e43d48eb98dd4621baf62eee9e82348f80fe9b888a12874bfa538771f8\",\n    \"0xa13c4a3ac642ede37d9c883f5319e748d2b938f708c9d779714108a449b343f7b71a6e3ef4080fee125b416762920273\",\n    \"0xaf44983d5fc8cceee0551ef934e6e653f2d3efa385e5c8a27a272463a6f333e290378cc307c2b664eb923c78994e706e\",\n    \"0xa389fd6c59fe2b4031cc244e22d3991e541bd203dd5b5e73a6159e72df1ab41d49994961500dcde7989e945213184778\",\n    \"0x8d2141e4a17836c548de9598d7b298b03f0e6c73b7364979a411c464e0628e21cff6ac3d6decdba5d1c4909eff479761\",\n    \"0x980b22ef53b7bdf188a3f14bc51b0dbfdf9c758826daa3cbc1e3986022406a8aa9a6a79e400567120b88c67faa35ce5f\",\n    \"0xa28882f0a055f96df3711de5d0aa69473e71245f4f3e9aa944e9d1fb166e02caa50832e46da6d3a03b4801735fd01b29\",\n    \"0x8db106a37d7b88f5d995c126abb563934dd8de516af48e85695d02b1aea07f79217e3cdd03c6f5ca57421830186c772b\",\n    \"0xb5a7e50da0559a675c472f7dfaee456caab6695ab7870541b2be8c2b118c63752427184aad81f0e1afc61aef1f28c46f\",\n    \"0x9962118780e20fe291d10b64f28d09442a8e1b5cffd0f3dd68d980d0614050a626c616b44e9807fbee7accecae00686a\",\n    \"0xb38ddf33745e8d2ad6a991aefaf656a33c5f8cbe5d5b6b6fd03bd962153d8fd0e01b5f8f96d80ae53ab28d593ab1d4e7\",\n    \"0x857dc12c0544ff2c0c703761d901aba636415dee45618aba2e3454ff9cbc634a85c8b05565e88520ff9be2d097c8b2b1\",\n    \"0xa80d465c3f8cc63af6d74a6a5086b626c1cb4a8c0fee425964c3bd203d9d7094e299f81ce96d58afc20c8c9a029d9dae\",\n    \"0x89e1c8fbde8563763be483123a3ed702efac189c6d8ab4d16c85e74bbaf856048cc42d5d6e138633a38572ba5ec3f594\",\n    \"0x893a594cf495535f6d216508f8d03c317dcf03446668cba688da90f52d0111ac83d76ad09bf5ea47056846585ee5c791\",\n    \"0xaadbd8be0ae452f7f9450c7d2957598a20cbf10139a4023a78b4438172d62b18b0de39754dd2f8862dbd50a3a0815e53\",\n    \"0xae7d39670ecca3eb6db2095da2517a581b0e8853bdfef619b1fad9aacd443e7e6a40f18209fadd44038a55085c5fe8b2\",\n    \"0x866ef241520eacb6331593cfcb206f7409d2f33d04542e6e52cba5447934e02d44c471f6c9a45963f9307e9809ab91d9\",\n    \"0xb1a09911ad3864678f7be79a9c3c3eb5c84a0a45f8dcb52c67148f43439aeaaa9fd3ed3471276b7e588b49d6ebe3033a\",\n    \"0xadd07b7f0dbb34049cd8feeb3c18da5944bf706871cfd9f14ff72f6c59ad217ebb1f0258b13b167851929387e4e34cfe\",\n    \"0xae048892d5c328eefbdd4fba67d95901e3c14d974bfc0a1fc68155ca9f0d59e61d7ba17c6c9948b120cf35fd26e6fee9\",\n    \"0x9185b4f3b7da0ddb4e0d0f09b8a9e0d6943a4611e43f13c3e2a767ed8592d31e0ba3ebe1914026a3627680274291f6e5\",\n    \"0xa9c022d4e37b0802284ce3b7ee9258628ab4044f0db4de53d1c3efba9de19d15d65cc5e608dbe149c21c2af47d0b07b5\",\n    \"0xb24dbd5852f8f24921a4e27013b6c3fa8885b973266cb839b9c388efad95821d5d746348179dcc07542bd0d0aefad1ce\",\n    \"0xb5fb4f279300876a539a27a441348764908bc0051ebd66dc51739807305e73db3d2f6f0f294ffb91b508ab150eaf8527\",\n    \"0xace50841e718265b290c3483ed4b0fdd1175338c5f1f7530ae9a0e75d5f80216f4de37536adcbc8d8c95982e88808cd0\",\n    \"0xb19cadcde0f63bd1a9c24bd9c2806f53c14c0b9735bf351601498408ba503ddbd2037c891041cbba47f58b8c483f3b21\",\n    \"0xb6061e63558d312eb891b97b39aa552fa218568d79ee26fe6dd5b864aea9e3216d8f2e2f3b093503be274766dac41426\",\n    \"0x89730fdb2876ab6f0fe780d695f6e12090259027e789b819956d786e977518057e5d1d7f5ab24a3ae3d5d4c97773bd2b\",\n    \"0xb6fa841e81f9f2cad0163a02a63ae96dc341f7ae803b616efc6e1da2fbea551c1b96b11ad02c4afbdf6d0cc9f23da172\",\n    \"0x8fb66187182629c861ddb6896d7ed3caf2ad050c3dba8ab8eb0d7a2c924c3d44c48d1a148f9e33fb1f061b86972f8d21\",\n    \"0x86022ac339c1f84a7fa9e05358c1a5b316b4fc0b83dbe9c8c7225dc514f709d66490b539359b084ce776e301024345fa\",\n    \"0xb50b9c321468da950f01480bb62b6edafd42f83c0001d6e97f2bd523a1c49a0e8574fb66380ea28d23a7c4d54784f9f0\",\n    \"0xa31c05f7032f30d1dac06678be64d0250a071fd655e557400e4a7f4c152be4d5c7aa32529baf3e5be7c4bd49820054f6\",\n    \"0xb95ac0848cd322684772119f5b682d90a66bbf9dac411d9d86d2c34844bbd944dbaf8e47aa41380455abd51687931a78\",\n    \"0xae4a6a5ce9553b65a05f7935e61e496a4a0f6fd8203367a2c627394c9ce1e280750297b74cdc48fd1d9a31e93f97bef4\",\n    \"0xa22daf35f6e9b05e52e0b07f7bd1dbbebd2c263033fb0e1b2c804e2d964e2f11bc0ece6aca6af079dd3a9939c9c80674\",\n    \"0x902150e0cb1f16b9b59690db35281e28998ce275acb313900da8b2d8dfd29fa1795f8ca3ff820c31d0697de29df347c1\",\n    \"0xb17b5104a5dc665cdd7d47e476153d715eb78c6e5199303e4b5445c21a7fa7cf85fe7cfd08d7570f4e84e579b005428c\",\n    \"0xa03f49b81c15433f121680aa02d734bb9e363af2156654a62bcb5b2ba2218398ccb0ff61104ea5d7df5b16ea18623b1e\",\n    \"0x802101abd5d3c88876e75a27ffc2f9ddcce75e6b24f23dba03e5201281a7bd5cc7530b6a003be92d225093ca17d3c3bb\",\n    \"0xa4d183f63c1b4521a6b52226fc19106158fc8ea402461a5cccdaa35fee93669df6a8661f45c1750cd01308149b7bf08e\",\n    \"0x8d17c22e0c8403b69736364d460b3014775c591032604413d20a5096a94d4030d7c50b9fe3240e31d0311efcf9816a47\",\n    \"0x947225acfcce5992eab96276f668c3cbe5f298b90a59f2bb213be9997d8850919e8f496f182689b5cbd54084a7332482\",\n    \"0x8df6f4ed216fc8d1905e06163ba1c90d336ab991a18564b0169623eb39b84e627fa267397da15d3ed754d1f3423bff07\",\n    \"0x83480007a88f1a36dea464c32b849a3a999316044f12281e2e1c25f07d495f9b1710b4ba0d88e9560e72433addd50bc2\",\n    \"0xb3019d6e591cf5b33eb972e49e06c6d0a82a73a75d78d383dd6f6a4269838289e6e07c245f54fed67f5c9bb0fd5e1c5f\",\n    \"0x92e8ce05e94927a9fb02debadb99cf30a26172b2705003a2c0c47b3d8002bf1060edb0f6a5750aad827c98a656b19199\",\n    \"0xac2aff801448dbbfc13cca7d603fd9c69e82100d997faf11f465323b97255504f10c0c77401e4d1890339d8b224f5803\",\n    \"0xb0453d9903d08f508ee27e577445dc098baed6cde0ac984b42e0f0efed62760bd58d5816cf1e109d204607b7b175e30c\",\n    \"0xae68dc4ba5067e825d46d2c7c67f1009ceb49d68e8d3e4c57f4bcd299eb2de3575d42ea45e8722f8f28497a6e14a1cfe\",\n    \"0xb22486c2f5b51d72335ce819bbafb7fa25eb1c28a378a658f13f9fc79cd20083a7e573248d911231b45a5cf23b561ca7\",\n    \"0x89d1201d1dbd6921867341471488b4d2fd0fc773ae1d4d074c78ae2eb779a59b64c00452c2a0255826fca6b3d03be2b1\",\n    \"0xa2998977c91c7a53dc6104f5bc0a5b675e5350f835e2f0af69825db8af4aeb68435bdbcc795f3dd1f55e1dd50bc0507f\",\n    \"0xb0be4937a925b3c05056ed621910d535ccabf5ab99fd3b9335080b0e51d9607d0fd36cb5781ff340018f6acfca4a9736\",\n    \"0xaea145a0f6e0ba9df8e52e84bb9c9de2c2dc822f70d2724029b153eb68ee9c17de7d35063dcd6a39c37c59fdd12138f7\",\n    \"0x91cb4545d7165ee8ffbc74c874baceca11fdebbc7387908d1a25877ca3c57f2c5def424dab24148826832f1e880bede0\",\n    \"0xb3b579cb77573f19c571ad5eeeb21f65548d7dff9d298b8d7418c11f3e8cd3727c5b467f013cb87d6861cfaceee0d2e3\",\n    \"0xb98a1eeec2b19fecc8378c876d73645aa52fb99e4819903735b2c7a885b242787a30d1269a04bfb8573d72d9bbc5f0f0\",\n    \"0x940c1f01ed362bd588b950c27f8cc1d52276c71bb153d47f07ec85b038c11d9a8424b7904f424423e714454d5e80d1cd\",\n    \"0xaa343a8ecf09ce11599b8cf22f7279cf80f06dbf9f6d62cb05308dbbb39c46fd0a4a1240b032665fbb488a767379b91b\",\n    \"0x87c3ac72084aca5974599d3232e11d416348719e08443acaba2b328923af945031f86432e170dcdd103774ec92e988c9\",\n    \"0x91d6486eb5e61d2b9a9e742c20ec974a47627c6096b3da56209c2b4e4757f007e793ebb63b2b246857c9839b64dc0233\",\n    \"0xaebcd3257d295747dd6fc4ff910d839dd80c51c173ae59b8b2ec937747c2072fa85e3017f9060aa509af88dfc7529481\",\n    \"0xb3075ba6668ca04eff19efbfa3356b92f0ab12632dcda99cf8c655f35b7928c304218e0f9799d68ef9f809a1492ff7db\",\n    \"0x93ba7468bb325639ec2abd4d55179c69fd04eaaf39fc5340709227bbaa4ad0a54ea8b480a1a3c8d44684e3be0f8d1980\",\n    \"0xa6aef86c8c0d92839f38544d91b767c582568b391071228ff5a5a6b859c87bf4f81a7d926094a4ada1993ddbd677a920\",\n    \"0x91dcd6d14207aa569194aa224d1e5037b999b69ade52843315ca61ba26abe9a76412c9e88259bc5cf5d7b95b97d9c3bc\",\n    \"0xb3b483d31c88f78d49bd065893bc1e3d2aa637e27dedb46d9a7d60be7660ce7a10aaaa7deead362284a52e6d14021178\",\n    \"0x8e5730070acf8371461ef301cc4523e8e672aa0e3d945d438a0e0aa6bdf8cb9c685dcf38df429037b0c8aff3955c6f5b\",\n    \"0xb8c6d769890a8ee18dc4f9e917993315877c97549549b34785a92543cbeec96a08ae3a28d6e809c4aacd69de356c0012\",\n    \"0x95ca86cd384eaceaa7c077c5615736ca31f36824bd6451a16142a1edc129fa42b50724aeed7c738f08d7b157f78b569e\",\n    \"0x94df609c6d71e8eee7ab74226e371ccc77e01738fe0ef1a6424435b4570fe1e5d15797b66ed0f64eb88d4a3a37631f0e\",\n    \"0x89057b9783212add6a0690d6bb99097b182738deff2bd9e147d7fd7d6c8eacb4c219923633e6309ad993c24572289901\",\n    \"0x83a0f9f5f265c5a0e54defa87128240235e24498f20965009fef664f505a360b6fb4020f2742565dfc7746eb185bcec0\",\n    \"0x91170da5306128931349bc3ed50d7df0e48a68b8cc8420975170723ac79d8773e4fa13c5f14dc6e3fafcad78379050b1\",\n    \"0xb7178484d1b55f7e56a4cc250b6b2ec6040437d96bdfddfa7b35ed27435860f3855c2eb86c636f2911b012eb83b00db8\",\n    \"0xac0b00c4322d1e4208e09cd977b4e54d221133ff09551f75b32b0b55d0e2be80941dda26257b0e288c162e63c7e9cf68\",\n    \"0x9690ed9e7e53ed37ff362930e4096b878b12234c332fd19d5d064824084245952eda9f979e0098110d6963e468cf513e\",\n    \"0xb6fa547bb0bb83e5c5be0ed462a8783fba119041c136a250045c09d0d2af330c604331e7de960df976ff76d67f8000cd\",\n    \"0x814603907c21463bcf4e59cfb43066dfe1a50344ae04ef03c87c0f61b30836c3f4dea0851d6fa358c620045b7f9214c8\",\n    \"0x9495639e3939fad2a3df00a88603a5a180f3c3a0fe4d424c35060e2043e0921788003689887b1ed5be424d9a89bb18bb\",\n    \"0xaba4c02d8d57f2c92d5bc765885849e9ff8393d6554f5e5f3e907e5bfac041193a0d8716d7861104a4295d5a03c36b03\",\n    \"0x8ead0b56c1ca49723f94a998ba113b9058059321da72d9e395a667e6a63d5a9dac0f5717cec343f021695e8ced1f72af\",\n    \"0xb43037f7e3852c34ed918c5854cd74e9d5799eeddfe457d4f93bb494801a064735e326a76e1f5e50a339844a2f4a8ec9\",\n    \"0x99db8422bb7302199eb0ff3c3d08821f8c32f53a600c5b6fb43e41205d96adae72be5b460773d1280ad1acb806af9be8\",\n    \"0x8a9be08eae0086c0f020838925984df345c5512ff32e37120b644512b1d9d4fecf0fd30639ca90fc6cf334a86770d536\",\n    \"0x81b43614f1c28aa3713a309a88a782fb2bdfc4261dd52ddc204687791a40cf5fd6a263a8179388596582cccf0162efc2\",\n    \"0xa9f3a8b76912deb61d966c75daf5ddb868702ebec91bd4033471c8e533183df548742a81a2671de5be63a502d827437d\",\n    \"0x902e2415077f063e638207dc7e14109652e42ab47caccd6204e2870115791c9defac5425fd360b37ac0f7bd8fe7011f8\",\n    \"0xaa18e4fdc1381b59c18503ae6f6f2d6943445bd00dd7d4a2ad7e5adad7027f2263832690be30d456e6d772ad76f22350\",\n    \"0xa348b40ba3ba7d81c5d4631f038186ebd5e5f314f1ea737259151b07c3cc8cf0c6ed4201e71bcc1c22fefda81a20cde6\",\n    \"0xaa1306f7ac1acbfc47dc6f7a0cb6d03786cec8c8dc8060388ccda777bca24bdc634d03e53512c23dba79709ff64f8620\",\n    \"0x818ccfe46e700567b7f3eb400e5a35f6a5e39b3db3aa8bc07f58ace35d9ae5a242faf8dbccd08d9a9175bbce15612155\",\n    \"0xb7e3da2282b65dc8333592bb345a473f03bd6df69170055fec60222de9897184536bf22b9388b08160321144d0940279\",\n    \"0xa4d976be0f0568f4e57de1460a1729129252b44c552a69fceec44e5b97c96c711763360d11f9e5bf6d86b4976bf40d69\",\n    \"0x85d185f0397c24c2b875b09b6328a23b87982b84ee880f2677a22ff4c9a1ba9f0fea000bb3f7f66375a00d98ebafce17\",\n    \"0xb4ccbb8c3a2606bd9b87ce022704663af71d418351575f3b350d294f4efc68c26f9a2ce49ff81e6ff29c3b63d746294e\",\n    \"0x93ffd3265fddb63724dfde261d1f9e22f15ecf39df28e4d89e9fea03221e8e88b5dd9b77628bacaa783c6f91802d47cc\",\n    \"0xb1fd0f8d7a01378e693da98d03a2d2fda6b099d03454b6f2b1fa6472ff6bb092751ce6290059826b74ac0361eab00e1e\",\n    \"0xa89f440c71c561641589796994dd2769616b9088766e983c873fae0716b95c386c8483ab8a4f367b6a68b72b7456dd32\",\n    \"0xaf4fe92b01d42d03dd5d1e7fa55e96d4bbcb7bf7d4c8c197acd16b3e0f3455807199f683dcd263d74547ef9c244b35cc\",\n    \"0xa8227f6e0a344dfe76bfbe7a1861be32c4f4bed587ccce09f9ce2cf481b2dda8ae4f566154bc663d15f962f2d41761bd\",\n    \"0xa7b361663f7495939ed7f518ba45ea9ff576c4e628995b7aea026480c17a71d63fc2c922319f0502eb7ef8f14a406882\",\n    \"0x8ddcf382a9f39f75777160967c07012cfa89e67b19714a7191f0c68eaf263935e5504e1104aaabd0899348c972a8d3c6\",\n    \"0x98c95b9f6f5c91f805fb185eedd06c6fc4457d37dd248d0be45a6a168a70031715165ea20606245cbdf8815dc0ac697f\",\n    \"0x805b44f96e001e5909834f70c09be3efcd3b43632bcac5b6b66b6d227a03a758e4b1768ce2a723045681a1d34562aaeb\",\n    \"0xb0e81b07cdc45b3dca60882676d9badb99f25c461b7efe56e3043b80100bb62d29e1873ae25eb83087273160ece72a55\",\n    \"0xb0c53f0abe78ee86c7b78c82ae1f7c070bb0b9c45c563a8b3baa2c515d482d7507bb80771e60b38ac13f78b8af92b4a9\",\n    \"0xa7838ef6696a9e4d2e5dfd581f6c8d6a700467e8fd4e85adabb5f7a56f514785dd4ab64f6f1b48366f7d94728359441b\",\n    \"0x88c76f7700a1d23c30366a1d8612a796da57b2500f97f88fdf2d76b045a9d24e7426a8ffa2f4e86d3046937a841dad58\",\n    \"0xad8964baf98c1f02e088d1d9fcb3af6b1dfa44cdfe0ed2eae684e7187c33d3a3c28c38e8f4e015f9c04d451ed6f85ff6\",\n    \"0x90e9d00a098317ececaa9574da91fc149eda5b772dedb3e5a39636da6603aa007804fa86358550cfeff9be5a2cb7845e\",\n    \"0xa56ff4ddd73d9a6f5ab23bb77efa25977917df63571b269f6a999e1ad6681a88387fcc4ca3b26d57badf91b236503a29\",\n    \"0x97ad839a6302c410a47e245df84c01fb9c4dfef86751af3f9340e86ff8fc3cd52fa5ff0b9a0bd1d9f453e02ca80658a6\",\n    \"0xa4c8c44cbffa804129e123474854645107d1f0f463c45c30fd168848ebea94880f7c0c5a45183e9eb837f346270bdb35\",\n    \"0xa72e53d0a1586d736e86427a93569f52edd2f42b01e78aee7e1961c2b63522423877ae3ac1227a2cf1e69f8e1ff15bc3\",\n    \"0x8559f88a7ef13b4f09ac82ae458bbae6ab25671cfbf52dae7eac7280d6565dd3f0c3286aec1a56a8a16dc3b61d78ce47\",\n    \"0x8221503f4cdbed550876c5dc118a3f2f17800c04e8be000266633c83777b039a432d576f3a36c8a01e8fd18289ebc10b\",\n    \"0x99bfbe5f3e46d4d898a578ba86ed26de7ed23914bd3bcdf3c791c0bcd49398a52419077354a5ab75cea63b6c871c6e96\",\n    \"0xaa134416d8ff46f2acd866c1074af67566cfcf4e8be8d97329dfa0f603e1ff208488831ce5948ac8d75bfcba058ddcaa\",\n    \"0xb02609d65ebfe1fe8e52f21224a022ea4b5ea8c1bd6e7b9792eed8975fc387cdf9e3b419b8dd5bcce80703ab3a12a45f\",\n    \"0xa4f14798508698fa3852e5cac42a9db9797ecee7672a54988aa74037d334819aa7b2ac7b14efea6b81c509134a6b7ad2\",\n    \"0x884f01afecbcb987cb3e7c489c43155c416ed41340f61ecb651d8cba884fb9274f6d9e7e4a46dd220253ae561614e44c\",\n    \"0xa05523c9e71dce1fe5307cc71bd721feb3e1a0f57a7d17c7d1c9fb080d44527b7dbaa1f817b1af1c0b4322e37bc4bb1e\",\n    \"0x8560aec176a4242b39f39433dd5a02d554248c9e49d3179530815f5031fee78ba9c71a35ceeb2b9d1f04c3617c13d8f0\",\n    \"0x996aefd402748d8472477cae76d5a2b92e3f092fc834d5222ae50194dd884c9fb8b6ed8e5ccf8f6ed483ddbb4e80c747\",\n    \"0x8fd09900320000cbabc40e16893e2fcf08815d288ec19345ad7b6bb22f7d78a52b6575a3ca1ca2f8bc252d2eafc928ec\",\n    \"0x939e51f73022bc5dc6862a0adf8fb8a3246b7bfb9943cbb4b27c73743926cc20f615a036c7e5b90c80840e7f1bfee0e7\",\n    \"0xa0a6258700cadbb9e241f50766573bf9bdb7ad380b1079dc3afb4054363d838e177b869cad000314186936e40359b1f2\",\n    \"0x972699a4131c8ed27a2d0e2104d54a65a7ff1c450ad9da3a325c662ab26869c21b0a84d0700b98c8b5f6ce3b746873d7\",\n    \"0xa454c7fe870cb8aa6491eafbfb5f7872d6e696033f92e4991d057b59d70671f2acdabef533e229878b60c7fff8f748b1\",\n    \"0xa167969477214201f09c79027b10221e4707662e0c0fde81a0f628249f2f8a859ce3d30a7dcc03b8ecca8f7828ad85c7\",\n    \"0x8ff6b7265175beb8a63e1dbf18c9153fb2578c207c781282374f51b40d57a84fd2ef2ea2b9c6df4a54646788a62fd17f\",\n    \"0xa3d7ebeccde69d73d8b3e76af0da1a30884bb59729503ff0fb0c3bccf9221651b974a6e72ea33b7956fc3ae758226495\",\n    \"0xb71ef144c9a98ce5935620cb86c1590bd4f48e5a2815d25c0cdb008fde628cf628c31450d3d4f67abbfeb16178a74cfd\",\n    \"0xb5e0a16d115134f4e2503990e3f2035ed66b9ccf767063fe6747870d97d73b10bc76ed668550cb82eedc9a2ca6f75524\",\n    \"0xb30ffaaf94ee8cbc42aa2c413175b68afdb207dbf351fb20be3852cb7961b635c22838da97eaf43b103aff37e9e725cc\",\n    \"0x98aa7d52284f6c1f22e272fbddd8c8698cf8f5fbb702d5de96452141fafb559622815981e50b87a72c2b1190f59a7deb\",\n    \"0x81fbacda3905cfaf7780bb4850730c44166ed26a7c8d07197a5d4dcd969c09e94a0461638431476c16397dd7bdc449f9\",\n    \"0x95e47021c1726eac2e5853f570d6225332c6e48e04c9738690d53e07c6b979283ebae31e2af1fc9c9b3e59f87e5195b1\",\n    \"0xac024a661ba568426bb8fce21780406537f518075c066276197300841e811860696f7588188bc01d90bace7bc73d56e3\",\n    \"0xa4ebcaf668a888dd404988ab978594dee193dad2d0aec5cdc0ccaf4ec9a7a8228aa663db1da8ddc52ec8472178e40c32\",\n    \"0xa20421b8eaf2199d93b083f2aff37fb662670bd18689d046ae976d1db1fedd2c2ff897985ecc6277b396db7da68bcb27\",\n    \"0x8bc33d4b40197fd4d49d1de47489d10b90d9b346828f53a82256f3e9212b0cbc6930b895e879da9cec9fedf026aadb3e\",\n    \"0xaaafdd1bec8b757f55a0433eddc0a39f818591954fd4e982003437fcceb317423ad7ee74dbf17a2960380e7067a6b4e2\",\n    \"0xaad34277ebaed81a6ec154d16736866f95832803af28aa5625bf0461a71d02b1faba02d9d9e002be51c8356425a56867\",\n    \"0x976e9c8b150d08706079945bd0e84ab09a648ecc6f64ded9eb5329e57213149ae409ae93e8fbd8eda5b5c69f5212b883\",\n    \"0x8097fae1653247d2aed4111533bc378171d6b2c6d09cbc7baa9b52f188d150d645941f46d19f7f5e27b7f073c1ebd079\",\n    \"0x83905f93b250d3184eaba8ea7d727c4464b6bdb027e5cbe4f597d8b9dc741dcbea709630bd4fd59ce24023bec32fc0f3\",\n    \"0x8095030b7045cff28f34271386e4752f9a9a0312f8df75de4f424366d78534be2b8e1720a19cb1f9a2d21105d790a225\",\n    \"0xa7b7b73a6ae2ed1009c49960374b0790f93c74ee03b917642f33420498c188a169724945a975e5adec0a1e83e07fb1b2\",\n    \"0x856a41c54df393b6660b7f6354572a4e71c8bfca9cabaffb3d4ef2632c015e7ee2bc10056f3eccb3dbed1ad17d939178\",\n    \"0xa8f7a55cf04b38cd4e330394ee6589da3a07dc9673f74804fdf67b364e0b233f14aec42e783200a2e4666f7c5ff62490\",\n    \"0x82c529f4e543c6bca60016dc93232c115b359eaee2798a9cf669a654b800aafe6ab4ba58ea8b9cdda2b371c8d62fa845\",\n    \"0x8caab020c1baddce77a6794113ef1dfeafc5f5000f48e97f4351b588bf02f1f208101745463c480d37f588d5887e6d8c\",\n    \"0x8fa91b3cc400f48b77b6fd77f3b3fbfb3f10cdff408e1fd22d38f77e087b7683adad258804409ba099f1235b4b4d6fea\",\n    \"0x8aa02787663d6be9a35677d9d8188b725d5fcd770e61b11b64e3def8808ea5c71c0a9afd7f6630c48634546088fcd8e2\",\n    \"0xb5635b7b972e195cab878b97dea62237c7f77eb57298538582a330b1082f6207a359f2923864630136d8b1f27c41b9aa\",\n    \"0x8257bb14583551a65975946980c714ecd6e5b629672bb950b9caacd886fbd22704bc9e3ba7d30778adab65dc74f0203a\",\n    \"0xab5fe1cd12634bfa4e5c60d946e2005cbd38f1063ec9a5668994a2463c02449a0a185ef331bd86b68b6e23a8780cb3ba\",\n    \"0xa7d3487da56cda93570cc70215d438204f6a2709bfb5fda6c5df1e77e2efc80f4235c787e57fbf2c74aaff8cbb510a14\",\n    \"0xb61cff7b4c49d010e133319fb828eb900f8a7e55114fc86b39c261a339c74f630e1a7d7e1350244ada566a0ff3d46c4b\",\n    \"0x8d4d1d55d321d278db7a85522ccceca09510374ca81d4d73e3bb5249ace7674b73900c35a531ec4fa6448fabf7ad00dc\",\n    \"0x966492248aee24f0f56c8cfca3c8ec6ba3b19abb69ae642041d4c3be8523d22c65c4dafcab4c58989ccc4e0bd2f77919\",\n    \"0xb20c320a90cb220b86e1af651cdc1e21315cd215da69f6787e28157172f93fc8285dcd59b039c626ed8ca4633cba1a47\",\n    \"0xaae9e6b22f018ceb5c0950210bb8182cb8cb61014b7e14581a09d36ebd1bbfebdb2b82afb7fdb0cf75e58a293d9c456d\",\n    \"0x875547fb67951ad37b02466b79f0c9b985ccbc500cfb431b17823457dc79fb9597ec42cd9f198e15523fcd88652e63a4\",\n    \"0x92afce49773cb2e20fb21e4f86f18e0959ebb9c33361547ddb30454ee8e36b1e234019cbdca0e964cb292f7f77df6b90\",\n    \"0x8af85343dfe1821464c76ba11c216cbef697b5afc69c4d821342e55afdac047081ec2e3f7b09fc14b518d9a23b78c003\",\n    \"0xb7de4a1648fd63f3a918096ea669502af5357438e69dac77cb8102b6e6c15c76e033cfaa80dafc806e535ede5c1a20aa\",\n    \"0xac80e9b545e8bd762951d96c9ce87f629d01ffcde07efc2ef7879ca011f1d0d8a745abf26c9d452541008871304fac00\",\n    \"0xa4cf0f7ed724e481368016c38ea5816698a5f68eb21af4d3c422d2ba55f96a33e427c2aa40de1b56a7cfac7f7cf43ab0\",\n    \"0x899b0a678bb2db2cae1b44e75a661284844ebcdd87abf308fedeb2e4dbe5c5920c07db4db7284a7af806a2382e8b111a\",\n    \"0xaf0588a2a4afce2b1b13c1230816f59e8264177e774e4a341b289a101dcf6af813638fed14fb4d09cb45f35d5d032609\",\n    \"0xa4b8df79e2be76e9f5fc5845f06fe745a724cf37c82fcdb72719b77bdebea3c0e763f37909373e3a94480cc5e875cba0\",\n    \"0x83e42c46d88930c8f386b19fd999288f142d325e2ebc86a74907d6d77112cb0d449bc511c95422cc810574031a8cbba9\",\n    \"0xb5e39534070de1e5f6e27efbdd3dc917d966c2a9b8cf2d893f964256e95e954330f2442027dc148c776d63a95bcde955\",\n    \"0x958607569dc28c075e658cd4ae3927055c6bc456eef6212a6fea8205e48ed8777a8064f584cda38fe5639c371e2e7fba\",\n    \"0x812adf409fa63575113662966f5078a903212ffb65c9b0bbe62da0f13a133443a7062cb8fd70f5e5dd5559a32c26d2c8\",\n    \"0xa679f673e5ce6a3cce7fa31f22ee3785e96bcb55e5a776e2dd3467bef7440e3555d1a9b87cb215e86ee9ed13a090344b\",\n    \"0xafedbb34508b159eb25eb2248d7fe328f86ef8c7d84c62d5b5607d74aae27cc2cc45ee148eb22153b09898a835c58df4\",\n    \"0xb75505d4f6b67d31e665cfaf5e4acdb5838ae069166b7fbcd48937c0608a59e40a25302fcc1873d2e81c1782808c70f0\",\n    \"0xb62515d539ec21a155d94fc00ea3c6b7e5f6636937bce18ed5b618c12257fb82571886287fd5d1da495296c663ebc512\",\n    \"0xab8e1a9446bbdd588d1690243b1549d230e6149c28f59662b66a8391a138d37ab594df38e7720fae53217e5c3573b5be\",\n    \"0xb31e8abf4212e03c3287bb2c0a153065a7290a16764a0bac8f112a72e632185a654bb4e88fdd6053e6c7515d9719fadb\",\n    \"0xb55165477fe15b6abd2d0f4fddaa9c411710dcc4dd712daba3d30e303c9a3ee5415c256f9dc917ecf18c725b4dbab059\",\n    \"0xa0939d4f57cacaae549b78e87cc234de4ff6a35dc0d9cd5d7410abc30ebcd34c135e008651c756e5a9d2ca79c40ef42b\",\n    \"0x8cf10e50769f3443340844aad4d56ec790850fed5a41fcbd739abac4c3015f0a085a038fbe7fae9f5ad899cce5069f6b\",\n    \"0x924055e804d82a99ea4bb160041ea4dc14b568abf379010bc1922fde5d664718c31d103b8b807e3a1ae809390e708c73\",\n    \"0x8ec0f9d26f71b0f2e60a179e4fd1778452e2ffb129d50815e5d7c7cb9415fa69ae5890578086e8ef6bfde35ad2a74661\",\n    \"0x98c7f12b15ec4426b59f737f73bf5faea4572340f4550b7590dfb7f7ffedb2372e3e555977c63946d579544c53210ad0\",\n    \"0x8a935f7a955c78f69d66f18eee0092e5e833fa621781c9581058e219af4d7ceee48b84e472e159dda6199715fb2f9acf\",\n    \"0xb78d4219f95a2dbfaa7d0c8a610c57c358754f4f43c2af312ab0fe8f10a5f0177e475332fb8fd23604e474fc2abeb051\",\n    \"0x8d086a14803392b7318c28f1039a17e3cfdcece8abcaca3657ec3d0ac330842098a85c0212f889fabb296dfb133ce9aa\",\n    \"0xa53249f417aac82f2c2a50c244ce21d3e08a5e5a8bd33bec2a5ab0d6cd17793e34a17edfa3690899244ce201e2fb9986\",\n    \"0x8619b0264f9182867a1425be514dc4f1ababc1093138a728a28bd7e4ecc99b9faaff68c23792264bc6e4dce5f52a5c52\",\n    \"0x8c171edbbbde551ec19e31b2091eb6956107dd9b1f853e1df23bff3c10a3469ac77a58335eee2b79112502e8e163f3de\",\n    \"0xa9d19ec40f0ca07c238e9337c6d6a319190bdba2db76fb63902f3fb459aeeb50a1ac30db5b25ee1b4201f3ca7164a7f4\",\n    \"0xb9c6ec14b1581a03520b8d2c1fbbc31fb8ceaef2c0f1a0d0080b6b96e18442f1734bea7ef7b635d787c691de4765d469\",\n    \"0x8cb437beb4cfa013096f40ccc169a713dc17afee6daa229a398e45fd5c0645a9ad2795c3f0cd439531a7151945d7064d\",\n    \"0xa6e8740cc509126e146775157c2eb278003e5bb6c48465c160ed27888ca803fa12eee1f6a8dd7f444f571664ed87fdc1\",\n    \"0xb75c1fecc85b2732e96b3f23aefb491dbd0206a21d682aee0225838dc057d7ed3b576176353e8e90ae55663f79e986e4\",\n    \"0xad8d249b0aea9597b08358bce6c77c1fd552ef3fbc197d6a1cfe44e5e6f89b628b12a6fb04d5dcfcbacc51f46e4ae7bb\",\n    \"0xb998b2269932cbd58d04b8e898d373ac4bb1a62e8567484f4f83e224061bc0f212459f1daae95abdbc63816ae6486a55\",\n    \"0x827988ef6c1101cddc96b98f4a30365ff08eea2471dd949d2c0a9b35c3bbfa8c07054ad1f4c88c8fbf829b20bb5a9a4f\",\n    \"0x8692e638dd60babf7d9f2f2d2ce58e0ac689e1326d88311416357298c6a2bffbfebf55d5253563e7b3fbbf5072264146\",\n    \"0xa685d75b91aea04dbc14ab3c1b1588e6de96dae414c8e37b8388766029631b28dd860688079b12d09cd27f2c5af11adf\",\n    \"0xb57eced93eec3371c56679c259b34ac0992286be4f4ff9489d81cf9712403509932e47404ddd86f89d7c1c3b6391b28c\",\n    \"0xa1c8b4e42ebcbd8927669a97f1b72e236fb19249325659e72be7ddaaa1d9e81ca2abb643295d41a8c04a2c01f9c0efd7\",\n    \"0x877c33de20d4ed31674a671ba3e8f01a316581e32503136a70c9c15bf0b7cb7b1cba6cd4eb641fad165fb3c3c6c235fd\",\n    \"0xa2a469d84ec478da40838f775d11ad38f6596eb41caa139cc190d6a10b5108c09febae34ffdafac92271d2e73c143693\",\n    \"0x972f817caedb254055d52e963ed28c206848b6c4cfdb69dbc961c891f8458eaf582a6d4403ce1177d87bc2ea410ef60a\",\n    \"0xaccbd739e138007422f28536381decc54bb6bd71d93edf3890e54f9ef339f83d2821697d1a4ac1f5a98175f9a9ecb9b5\",\n    \"0x8940f8772e05389f823b62b3adc3ed541f91647f0318d7a0d3f293aeeb421013de0d0a3664ea53dd24e5fbe02d7efef6\",\n    \"0x8ecce20f3ef6212edef07ec4d6183fda8e0e8cad2c6ccd0b325e75c425ee1faba00b5c26b4d95204238931598d78f49d\",\n    \"0x97cc72c36335bd008afbed34a3b0c7225933faba87f7916d0a6d2161e6f82e0cdcda7959573a366f638ca75d30e9dab1\",\n    \"0x9105f5de8699b5bdb6bd3bb6cc1992d1eac23929c29837985f83b22efdda92af64d9c574aa9640475087201bbbe5fd73\",\n    \"0x8ffb33c4f6d05c413b9647eb6933526a350ed2e4278ca2ecc06b0e8026d8dbe829c476a40e45a6df63a633090a3f82ef\",\n    \"0x8bfc6421fdc9c2d2aaa68d2a69b1a2728c25b84944cc3e6a57ff0c94bfd210d1cbf4ff3f06702d2a8257024d8be7de63\",\n    \"0xa80e1dc1dddfb41a70220939b96dc6935e00b32fb8be5dff4eed1f1c650002ff95e4af481c43292e3827363b7ec4768a\",\n    \"0x96f714ebd54617198bd636ba7f7a7f8995a61db20962f2165078d9ed8ee764d5946ef3cbdc7ebf8435bb8d5dd4c1deac\",\n    \"0x8cdb0890e33144d66391d2ae73f5c71f5a861f72bc93bff6cc399fc25dd1f9e17d8772592b44593429718784802ac377\",\n    \"0x8ccf9a7f80800ee770b92add734ed45a73ecc31e2af0e04364eefc6056a8223834c7c0dc9dfc52495bdec6e74ce69994\",\n    \"0xaa0875f423bd68b5f10ba978ddb79d3b96ec093bfbac9ff366323193e339ed7c4578760fb60f60e93598bdf1e5cc4995\",\n    \"0xa9214f523957b59c7a4cb61a40251ad72aba0b57573163b0dc0f33e41d2df483fb9a1b85a5e7c080e9376c866790f8cb\",\n    \"0xb6224b605028c6673a536cc8ff9aeb94e7a22e686fda82cf16068d326469172f511219b68b2b3affb7933af0c1f80d07\",\n    \"0xb6d58968d8a017c6a34e24c2c09852f736515a2c50f37232ac6b43a38f8faa7572cc31dade543b594b61b5761c4781d0\",\n    \"0x8a97cefe5120020c38deeb861d394404e6c993c6cbd5989b6c9ebffe24f46ad11b4ba6348e2991cbf3949c28cfc3c99d\",\n    \"0x95bf046f8c3a9c0ce2634be4de3713024daec3fc4083e808903b25ce3ac971145af90686b451efcc72f6b22df0216667\",\n    \"0xa6a4e2f71b8fa28801f553231eff2794c0f10d12e7e414276995e21195abc9c2983a8997e41af41e78d19ff6fbb2680b\",\n    \"0x8e5e62a7ca9c2f58ebaab63db2ff1fb1ff0877ae94b7f5e2897f273f684ae639dff44cc65718f78a9c894787602ab26a\",\n    \"0x8542784383eec4f565fcb8b9fc2ad8d7a644267d8d7612a0f476fc8df3aff458897a38003d506d24142ad18f93554f2b\",\n    \"0xb7db68ba4616ea072b37925ec4fb39096358c2832cc6d35169e032326b2d6614479f765ae98913c267105b84afcb9bf2\",\n    \"0x8b31dbb9457d23d416c47542c786e07a489af35c4a87dadb8ee91bea5ac4a5315e65625d78dad2cf8f9561af31b45390\",\n    \"0xa8545a1d91ac17257732033d89e6b7111db8242e9c6ebb0213a88906d5ef407a2c6fdb444e29504b06368b6efb4f4839\",\n    \"0xb1bd85d29ebb28ccfb05779aad8674906b267c2bf8cdb1f9a0591dd621b53a4ee9f2942687ee3476740c0b4a7621a3ae\",\n    \"0xa2b54534e152e46c50d91fff03ae9cd019ff7cd9f4168b2fe7ac08ef8c3bbc134cadd3f9d6bd33d20ae476c2a8596c8a\",\n    \"0xb19b571ff4ae3e9f5d95acda133c455e72c9ea9973cae360732859836c0341c4c29ab039224dc5bc3deb824e031675d8\",\n    \"0x940b5f80478648bac025a30f3efeb47023ce20ee98be833948a248bca6979f206bb28fc0f17b90acf3bb4abd3d14d731\",\n    \"0x8f106b40588586ac11629b96d57808ad2808915d89539409c97414aded90b4ff23286a692608230a52bff696055ba5d6\",\n    \"0xae6bda03aa10da3d2abbc66d764ca6c8d0993e7304a1bdd413eb9622f3ca1913baa6da1e9f4f9e6cf847f14f44d6924d\",\n    \"0xa18e7796054a340ef826c4d6b5a117b80927afaf2ebd547794c400204ae2caf277692e2eabb55bc2f620763c9e9da66d\",\n    \"0x8d2d25180dc2c65a4844d3e66819ccfcf48858f0cc89e1c77553b463ec0f7feb9a4002ce26bc618d1142549b9850f232\",\n    \"0x863f413a394de42cc8166c1c75d513b91d545fff1de6b359037a742c70b008d34bf8e587afa2d62c844d0c6f0ea753e7\",\n    \"0x83cd0cf62d63475e7fcad18a2e74108499cdbf28af2113cfe005e3b5887794422da450b1944d0a986eb7e1f4c3b18f25\",\n    \"0xb4f8b350a6d88fea5ab2e44715a292efb12eb52df738c9b2393da3f1ddee68d0a75b476733ccf93642154bceb208f2b8\",\n    \"0xb3f52aaa4cd4221cb9fc45936cc67fd3864bf6d26bf3dd86aa85aa55ecfc05f5e392ecce5e7cf9406b4b1c4fce0398c8\",\n    \"0xb33137084422fb643123f40a6df2b498065e65230fc65dc31791c330e898c51c3a65ff738930f32c63d78f3c9315f85b\",\n    \"0x91452bfa75019363976bb7337fe3a73f1c10f01637428c135536b0cdc7da5ce558dae3dfc792aa55022292600814a8ef\",\n    \"0xad6ba94c787cd4361ca642c20793ea44f1f127d4de0bb4a77c7fbfebae0fcadbf28e2cb6f0c12c12a07324ec8c19761d\",\n    \"0x890aa6248b17f1501b0f869c556be7bf2b1d31a176f9978bb97ab7a6bd4138eed32467951c5ef1871944b7f620542f43\",\n    \"0x82111db2052194ee7dd22ff1eafffac0443cf969d3762cceae046c9a11561c0fdce9c0711f88ac01d1bed165f8a7cee3\",\n    \"0xb1527b71df2b42b55832f72e772a466e0fa05743aacc7814f4414e4bcc8d42a4010c9e0fd940e6f254cafedff3cd6543\",\n    \"0x922370fa49903679fc565f09c16a5917f8125e72acfeb060fcdbadbd1644eb9f4016229756019c93c6d609cda5d5d174\",\n    \"0xaa4c7d98a96cab138d2a53d4aee8ebff6ef903e3b629a92519608d88b3bbd94de5522291a1097e6acf830270e64c8ee1\",\n    \"0xb3dc21608a389a72d3a752883a382baaafc61ecc44083b832610a237f6a2363f24195acce529eb4aed4ef0e27a12b66e\",\n    \"0x94619f5de05e07b32291e1d7ab1d8b7337a2235e49d4fb5f3055f090a65e932e829efa95db886b32b153bdd05a53ec8c\",\n    \"0xade1e92722c2ffa85865d2426fb3d1654a16477d3abf580cfc45ea4b92d5668afc9d09275d3b79283e13e6b39e47424d\",\n    \"0xb7201589de7bed094911dd62fcd25c459a8e327ac447b69f541cdba30233063e5ddffad0b67e9c3e34adcffedfd0e13d\",\n    \"0x809d325310f862d6549e7cb40f7e5fc9b7544bd751dd28c4f363c724a0378c0e2adcb5e42ec8f912f5f49f18f3365c07\",\n    \"0xa79c20aa533de7a5d671c99eb9eb454803ba54dd4f2efa3c8fec1a38f8308e9905c71e9282955225f686146388506ff6\",\n    \"0xa85eeacb5e8fc9f3ed06a3fe2dc3108ab9f8c5877b148c73cf26e4e979bf5795edbe2e63a8d452565fd1176ed40402b2\",\n    \"0x97ef55662f8a1ec0842b22ee21391227540adf7708f491436044f3a2eb18c471525e78e1e14fa292507c99d74d7437c6\",\n    \"0x93110d64ed5886f3d16ce83b11425576a3a7a9bb831cd0de3f9a0b0f2270a730d68136b4ef7ff035ede004358f419b5c\",\n    \"0xac9ed0a071517f0ae4f61ce95916a90ba9a77a3f84b0ec50ef7298acdcd44d1b94525d191c39d6bd1bb68f4471428760\",\n    \"0x98abd6a02c7690f5a339adf292b8c9368dfc12e0f8069cf26a5e0ce54b4441638f5c66ea735142f3c28e00a0024267e6\",\n    \"0xb51efb73ba6d44146f047d69b19c0722227a7748b0e8f644d0fc9551324cf034c041a2378c56ce8b58d06038fb8a78de\",\n    \"0x8f115af274ef75c1662b588b0896b97d71f8d67986ae846792702c4742ab855952865ce236b27e2321967ce36ff93357\",\n    \"0xb3c4548f14d58b3ab03c222da09e4381a0afe47a72d18d50a94e0008797f78e39e99990e5b4757be62310d400746e35a\",\n    \"0xa9b1883bd5f31f909b8b1b6dcb48c1c60ed20aa7374b3ffa7f5b2ed036599b5bef33289d23c80a5e6420d191723b92f7\",\n    \"0x85d38dffd99487ae5bb41ab4a44d80a46157bbbe8ef9497e68f061721f74e4da513ccc3422936b059575975f6787c936\",\n    \"0xadf870fcb96e972c033ab7a35d28ae79ee795f82bc49c3bd69138f0e338103118d5529c53f2d72a9c0d947bf7d312af2\",\n    \"0xab4c7a44e2d9446c6ff303eb49aef0e367a58b22cc3bb27b4e69b55d1d9ee639c9234148d2ee95f9ca8079b1457d5a75\",\n    \"0xa386420b738aba2d7145eb4cba6d643d96bda3f2ca55bb11980b318d43b289d55a108f4bc23a9606fb0bccdeb3b3bb30\",\n    \"0x847020e0a440d9c4109773ecca5d8268b44d523389993b1f5e60e541187f7c597d79ebd6e318871815e26c96b4a4dbb1\",\n    \"0xa530aa7e5ca86fcd1bec4b072b55cc793781f38a666c2033b510a69e110eeabb54c7d8cbcb9c61fee531a6f635ffa972\",\n    \"0x87364a5ea1d270632a44269d686b2402da737948dac27f51b7a97af80b66728b0256547a5103d2227005541ca4b7ed04\",\n    \"0x8816fc6e16ea277de93a6d793d0eb5c15e9e93eb958c5ef30adaf8241805adeb4da8ce19c3c2167f971f61e0b361077d\",\n    \"0x8836a72d301c42510367181bb091e4be377777aed57b73c29ef2ce1d475feedd7e0f31676284d9a94f6db01cc4de81a2\",\n    \"0xb0d9d8b7116156d9dde138d28aa05a33e61f8a85839c1e9071ccd517b46a5b4b53acb32c2edd7150c15bc1b4bd8db9e3\",\n    \"0xae931b6eaeda790ba7f1cd674e53dc87f6306ff44951fa0df88d506316a5da240df9794ccbd7215a6470e6b31c5ea193\",\n    \"0x8c6d5bdf87bd7f645419d7c6444e244fe054d437ed1ba0c122fde7800603a5fadc061e5b836cb22a6cfb2b466f20f013\",\n    \"0x90d530c6d0cb654999fa771b8d11d723f54b8a8233d1052dc1e839ea6e314fbed3697084601f3e9bbb71d2b4eaa596df\",\n    \"0xb0d341a1422588c983f767b1ed36c18b141774f67ef6a43cff8e18b73a009da10fc12120938b8bba27f225bdfd3138f9\",\n    \"0xa131b56f9537f460d304e9a1dd75702ace8abd68cb45419695cb8dee76998139058336c87b7afd6239dc20d7f8f940cc\",\n    \"0xaa6c51fa28975f709329adee1bbd35d49c6b878041841a94465e8218338e4371f5cb6c17f44a63ac93644bf28f15d20f\",\n    \"0x88440fb584a99ebd7f9ea04aaf622f6e44e2b43bbb49fb5de548d24a238dc8f26c8da2ccf03dd43102bda9f16623f609\",\n    \"0x9777b8695b790e702159a4a750d5e7ff865425b95fa0a3c15495af385b91c90c00a6bd01d1b77bffe8c47d01baae846f\",\n    \"0x8b9d764ece7799079e63c7f01690c8eff00896a26a0d095773dea7a35967a8c40db7a6a74692f0118bf0460c26739af4\",\n    \"0x85808c65c485520609c9e61fa1bb67b28f4611d3608a9f7a5030ee61c3aa3c7e7dc17fff48af76b4aecee2cb0dbd22ac\",\n    \"0xad2783a76f5b3db008ef5f7e67391fda4e7e36abde6b3b089fc4835b5c339370287935af6bd53998bed4e399eda1136d\",\n    \"0x96f18ec03ae47c205cc4242ca58e2eff185c9dca86d5158817e2e5dc2207ab84aadda78725f8dc080a231efdc093b940\",\n    \"0x97de1ab6c6cc646ae60cf7b86df73b9cf56cc0cd1f31b966951ebf79fc153531af55ca643b20b773daa7cab784b832f7\",\n    \"0x870ba266a9bfa86ef644b1ef025a0f1b7609a60de170fe9508de8fd53170c0b48adb37f19397ee8019b041ce29a16576\",\n    \"0xad990e888d279ac4e8db90619d663d5ae027f994a3992c2fbc7d262b5990ae8a243e19157f3565671d1cb0de17fe6e55\",\n    \"0x8d9d5adcdd94c5ba3be4d9a7428133b42e485f040a28d16ee2384758e87d35528f7f9868de9bd23d1a42a594ce50a567\",\n    \"0x85a33ed75d514ece6ad78440e42f7fcdb59b6f4cff821188236d20edae9050b3a042ce9bc7d2054296e133d033e45022\",\n    \"0x92afd2f49a124aaba90de59be85ff269457f982b54c91b06650c1b8055f9b4b0640fd378df02a00e4fc91f7d226ab980\",\n    \"0x8c0ee09ec64bd831e544785e3d65418fe83ed9c920d9bb4d0bf6dd162c1264eb9d6652d2def0722e223915615931581c\",\n    \"0x8369bedfa17b24e9ad48ebd9c5afea4b66b3296d5770e09b00446c5b0a8a373d39d300780c01dcc1c6752792bccf5fd0\",\n    \"0x8b9e960782576a59b2eb2250d346030daa50bbbec114e95cdb9e4b1ba18c3d34525ae388f859708131984976ca439d94\",\n    \"0xb682bface862008fea2b5a07812ca6a28a58fd151a1d54c708fc2f8572916e0d678a9cb8dc1c10c0470025c8a605249e\",\n    \"0xa38d5e189bea540a824b36815fc41e3750760a52be0862c4cac68214febdc1a754fb194a7415a8fb7f96f6836196d82a\",\n    \"0xb9e7fbda650f18c7eb8b40e42cc42273a7298e65e8be524292369581861075c55299ce69309710e5b843cb884de171bd\",\n    \"0xb6657e5e31b3193874a1bace08f42faccbd3c502fb73ad87d15d18a1b6c2a146f1baa929e6f517db390a5a47b66c0acf\",\n    \"0xae15487312f84ed6265e4c28327d24a8a0f4d2d17d4a5b7c29b974139cf93223435aaebe3af918f5b4bb20911799715f\",\n    \"0x8bb4608beb06bc394e1a70739b872ce5a2a3ffc98c7547bf2698c893ca399d6c13686f6663f483894bccaabc3b9c56ad\",\n    \"0xb58ac36bc6847077584308d952c5f3663e3001af5ecf2e19cb162e1c58bd6c49510205d453cffc876ca1dc6b8e04a578\",\n    \"0x924f65ced61266a79a671ffb49b300f0ea44c50a0b4e3b02064faa99fcc3e4f6061ea8f38168ab118c5d47bd7804590e\",\n    \"0x8d67d43b8a06b0ff4fafd7f0483fa9ed1a9e3e658a03fb49d9d9b74e2e24858dc1bed065c12392037b467f255d4e5643\",\n    \"0xb4d4f87813125a6b355e4519a81657fa97c43a6115817b819a6caf4823f1d6a1169683fd68f8d025cdfa40ebf3069acb\",\n    \"0xa7fd4d2c8e7b59b8eed3d4332ae94b77a89a2616347402f880bc81bde072220131e6dbec8a605be3a1c760b775375879\",\n    \"0x8d4a7d8fa6f55a30df37bcf74952e2fa4fd6676a2e4606185cf154bdd84643fd01619f8fb8813a564f72e3f574f8ce30\",\n    \"0x8086fb88e6260e9a9c42e9560fde76315ff5e5680ec7140f2a18438f15bc2cc7d7d43bfb5880b180b738c20a834e6134\",\n    \"0x916c4c54721de03934fee6f43de50bb04c81f6f8dd4f6781e159e71c40c60408aa54251d457369d133d4ba3ed7c12cb4\",\n    \"0x902e5bf468f11ed9954e2a4a595c27e34abe512f1d6dc08bbca1c2441063f9af3dc5a8075ab910a10ff6c05c1c644a35\",\n    \"0xa1302953015e164bf4c15f7d4d35e3633425a78294406b861675667eec77765ff88472306531e5d3a4ec0a2ff0dd6a9e\",\n    \"0x87874461df3c9aa6c0fa91325576c0590f367075f2f0ecfeb34afe162c04c14f8ce9d608c37ac1adc8b9985bc036e366\",\n    \"0x84b50a8a61d3cc609bfb0417348133e698fe09a6d37357ce3358de189efcf35773d78c57635c2d26c3542b13cc371752\",\n    \"0xacaed2cff8633d12c1d12bb7270c54d65b0b0733ab084fd47f81d0a6e1e9b6f300e615e79538239e6160c566d8bb8d29\",\n    \"0x889e6a0e136372ca4bac90d1ab220d4e1cad425a710e8cdd48b400b73bb8137291ceb36a39440fa84305783b1d42c72f\",\n    \"0x90952e5becec45b2b73719c228429a2c364991cf1d5a9d6845ae5b38018c2626f4308daa322cab1c72e0f6c621bb2b35\",\n    \"0x8f5a97a801b6e9dcd66ccb80d337562c96f7914e7169e8ff0fda71534054c64bf2a9493bb830623d612cfe998789be65\",\n    \"0x84f3df8b9847dcf1d63ca470dc623154898f83c25a6983e9b78c6d2d90a97bf5e622445be835f32c1e55e6a0a562ea78\",\n    \"0x91d12095cd7a88e7f57f254f02fdb1a1ab18984871dead2f107404bcf8069fe68258c4e6f6ebd2477bddf738135400bb\",\n    \"0xb771a28bc04baef68604d4723791d3712f82b5e4fe316d7adc2fc01b935d8e644c06d59b83bcb542afc40ebafbee0683\",\n    \"0x872f6341476e387604a7e93ae6d6117e72d164e38ebc2b825bc6df4fcce815004d7516423c190c1575946b5de438c08d\",\n    \"0x90d6b4aa7d40a020cdcd04e8b016d041795961a8e532a0e1f4041252131089114a251791bf57794cadb7d636342f5d1c\",\n    \"0x899023ba6096a181448d927fed7a0fe858be4eac4082a42e30b3050ee065278d72fa9b9d5ce3bc1372d4cbd30a2f2976\",\n    \"0xa28f176571e1a9124f95973f414d5bdbf5794d41c3839d8b917100902ac4e2171eb940431236cec93928a60a77ede793\",\n    \"0x838dbe5bcd29c4e465d02350270fa0036cd46f8730b13d91e77afb7f5ed16525d0021d3b2ae173a76c378516a903e0cb\",\n    \"0x8e105d012dd3f5d20f0f1c4a7e7f09f0fdd74ce554c3032e48da8cce0a77260d7d47a454851387770f5c256fa29bcb88\",\n    \"0x8f4df0f9feeb7a487e1d138d13ea961459a6402fd8f8cabb226a92249a0d04ded5971f3242b9f90d08da5ff66da28af6\",\n    \"0xad1cfda4f2122a20935aa32fb17c536a3653a18617a65c6836700b5537122af5a8206befe9eaea781c1244c43778e7f1\",\n    \"0x832c6f01d6571964ea383292efc8c8fa11e61c0634a25fa180737cc7ab57bc77f25e614aac9a2a03d98f27b3c1c29de2\",\n    \"0x903f89cc13ec6685ac7728521898781fecb300e9094ef913d530bf875c18bcc3ceed7ed51e7b482d45619ab4b025c2e9\",\n    \"0xa03c474bb915aad94f171e8d96f46abb2a19c9470601f4c915512ec8b9e743c3938450a2a5b077b4618b9df8809e1dc1\",\n    \"0x83536c8456f306045a5f38ae4be2e350878fa7e164ea408d467f8c3bc4c2ee396bd5868008c089183868e4dfad7aa50b\",\n    \"0x88f26b4ea1b236cb326cd7ad7e2517ec8c4919598691474fe15d09cabcfc37a8d8b1b818f4d112432ee3a716b0f37871\",\n    \"0xa44324e3fe96e9c12b40ded4f0f3397c8c7ee8ff5e96441118d8a6bfad712d3ac990b2a6a23231a8f691491ac1fd480f\",\n    \"0xb0de4693b4b9f932191a21ee88629964878680152a82996c0019ffc39f8d9369bbe2fe5844b68d6d9589ace54af947e4\",\n    \"0x8e5d8ba948aea5fd26035351a960e87f0d23efddd8e13236cc8e4545a3dda2e9a85e6521efb8577e03772d3637d213d9\",\n    \"0x93efc82d2017e9c57834a1246463e64774e56183bb247c8fc9dd98c56817e878d97b05f5c8d900acf1fbbbca6f146556\",\n    \"0x8731176363ad7658a2862426ee47a5dce9434216cef60e6045fa57c40bb3ce1e78dac4510ae40f1f31db5967022ced32\",\n    \"0xb10c9a96745722c85bdb1a693100104d560433d45b9ac4add54c7646a7310d8e9b3ca9abd1039d473ae768a18e489845\",\n    \"0xa2ac374dfbb464bf850b4a2caf15b112634a6428e8395f9c9243baefd2452b4b4c61b0cb2836d8eae2d57d4900bf407e\",\n    \"0xb69fe3ded0c4f5d44a09a0e0f398221b6d1bf5dbb8bc4e338b93c64f1a3cac1e4b5f73c2b8117158030ec03787f4b452\",\n    \"0x8852cdbaf7d0447a8c6f211b4830711b3b5c105c0f316e3a6a18dcfbb9be08bd6f4e5c8ae0c3692da08a2dfa532f9d5c\",\n    \"0x93bbf6d7432a7d98ade3f94b57bf9f4da9bc221a180a370b113066dd42601bb9e09edd79e2e6e04e00423399339eebda\",\n    \"0xa80941c391f1eeafc1451c59e4775d6a383946ff22997aeaadf806542ba451d3b0f0c6864eeba954174a296efe2c1550\",\n    \"0xa045fe2bb011c2a2f71a0181a8f457a3078470fb74c628eab8b59aef69ffd0d649723bf74d6885af3f028bc5a104fb39\",\n    \"0xb9d8c35911009c4c8cad64692139bf3fc16b78f5a19980790cb6a7aea650a25df4231a4437ae0c351676a7e42c16134f\",\n    \"0x94c79501ded0cfcbab99e1841abe4a00a0252b3870e20774c3da16c982d74c501916ec28304e71194845be6e3113c7ab\",\n    \"0x900a66418b082a24c6348d8644ddb1817df5b25cb33044a519ef47cc8e1f7f1e38d2465b7b96d32ed472d2d17f8414c6\",\n    \"0xb26f45d393b8b2fcb29bdbb16323dc7f4b81c09618519ab3a39f8ee5bd148d0d9f3c0b5dfab55b5ce14a1cb9206d777b\",\n    \"0xaa1a87735fc493a80a96a9a57ca40a6d9c32702bfcaa9869ce1a116ae65d69cefe2f3e79a12454b4590353e96f8912b4\",\n    \"0xa922b188d3d0b69b4e4ea2a2aa076566962844637da12c0832105d7b31dea4a309eee15d12b7a336be3ea36fcbd3e3b7\",\n    \"0x8f3841fcf4105131d8c4d9885e6e11a46c448226401cf99356c291fadb864da9fa9d30f3a73c327f23f9fd99a11d633e\",\n    \"0x9791d1183fae270e226379af6c497e7da803ea854bb20afa74b253239b744c15f670ee808f708ede873e78d79a626c9a\",\n    \"0xa4cad52e3369491ada61bf28ada9e85de4516d21c882e5f1cd845bea9c06e0b2887b0c5527fcff6fc28acd3c04f0a796\",\n    \"0xb9ac86a900899603452bd11a7892a9bfed8054970bfcbeaa8c9d1930db891169e38d6977f5258c25734f96c8462eee3b\",\n    \"0xa3a154c28e5580656a859f4efc2f5ebfa7eaa84ca40e3f134fa7865e8581586db74992dbfa4036aa252fba103773ddde\",\n    \"0x95cc2a0c1885a029e094f5d737e3ecf4d26b99036453a8773c77e360101f9f98676ee246f6f732a377a996702d55691f\",\n    \"0x842651bbe99720438d8d4b0218feb60481280c05beb17750e9ca0d8c0599a60f873b7fbdcc7d8835ba9a6d57b16eec03\",\n    \"0x81ee54699da98f5620307893dcea8f64670609fa20e5622265d66283adeac122d458b3308c5898e6c57c298db2c8b24f\",\n    \"0xb97868b0b2bc98032d68352a535a1b341b9ff3c7af4e3a7f3ebc82d3419daa1b5859d6aedc39994939623c7cd878bd9b\",\n    \"0xb60325cd5d36461d07ef253d826f37f9ee6474a760f2fff80f9873d01fd2b57711543cdc8d7afa1c350aa753c2e33dea\",\n    \"0x8c205326c11d25a46717b780c639d89714c7736c974ae71287e3f4b02e6605ac2d9b4928967b1684f12be040b7bf2dd3\",\n    \"0x95a392d82db51e26ade6c2ccd3396d7e40aff68fa570b5951466580d6e56dda51775dce5cf3a74a7f28c3cb2eb551c4d\",\n    \"0x8f2cc8071eb56dffb70bda6dd433b556221dc8bba21c53353c865f00e7d4d86c9e39f119ea9a8a12ef583e9a55d9a6b6\",\n    \"0x9449a71af9672aaf8856896d7e3d788b22991a7103f75b08c0abbcc2bfe60fda4ed8ce502cea4511ff0ea52a93e81222\",\n    \"0x857090ab9fdb7d59632d068f3cc8cf27e61f0d8322d30e6b38e780a1f05227199b4cd746aac1311c36c659ef20931f28\",\n    \"0x98a891f4973e7d9aaf9ac70854608d4f7493dffc7e0987d7be9dd6029f6ea5636d24ef3a83205615ca1ff403750058e1\",\n    \"0xa486e1365bbc278dd66a2a25d258dc82f46b911103cb16aab3945b9c95ae87b386313a12b566df5b22322ede0afe25ad\",\n    \"0xa9a1eb399ed95d396dccd8d1ac718043446f8b979ec62bdce51c617c97a312f01376ab7fb87d27034e5f5570797b3c33\",\n    \"0xb7abc3858d7a74bb446218d2f5a037e0fae11871ed9caf44b29b69c500c1fa1dcfad64c9cdccc9d80d5e584f06213deb\",\n    \"0x8cfb09fe2e202faa4cebad932b1d35f5ca204e1c2a0c740a57812ac9a6792130d1312aabd9e9d4c58ca168bfebd4c177\",\n    \"0xa90a305c2cd0f184787c6be596fa67f436afd1f9b93f30e875f817ac2aae8bdd2e6e656f6be809467e6b3ad84adb86b1\",\n    \"0x80a9ef993c2b009ae172cc8f7ec036f5734cf4f4dfa06a7db4d54725e7fbfae5e3bc6f22687bdbb6961939d6f0c87537\",\n    \"0x848ade1901931e72b955d7db1893f07003e1708ff5d93174bac5930b9a732640f0578839203e9b77eb27965c700032d3\",\n    \"0x93fdf4697609c5ae9c33b9ca2f5f1af44abeb2b98dc4fdf732cf7388de086f410730dc384d9b7a7f447bb009653c8381\",\n    \"0x89ce3fb805aea618b5715c0d22a9f46da696b6fa86794f56fdf1d44155a33d42daf1920bcbe36cbacf3cf4c92df9cbc7\",\n    \"0x829ce2c342cf82aa469c65f724f308f7a750bd1494adc264609cd790c8718b8b25b5cab5858cf4ee2f8f651d569eea67\",\n    \"0xaf2f0cee7bf413204be8b9df59b9e4991bc9009e0d6dbe6815181df0ec2ca93ab8f4f3135b1c14d8f53d74bff0bd6f27\",\n    \"0xb87998cecf7b88cde93d1779f10a521edd5574a2fbd240102978639ec57433ba08cdb53849038a329cebbe74657268d2\",\n    \"0xa64542a1261a6ed3d720c2c3a802303aad8c4c110c95d0f12e05c1065e66f42da494792b6bfc5b9272363f3b1d457f58\",\n    \"0x86a6fd042e4f282fadf07a4bfee03fc96a3aea49f7a00f52bf249a20f1ec892326855410e61f37fbb27d9305eb2fc713\",\n    \"0x967ea5bc403b6db269682f7fd0df90659350d7e1aa66bc4fab4c9dfcd75ed0bba4b52f1cebc5f34dc8ba810793727629\",\n    \"0xa52990f9f3b8616ce3cdc2c74cd195029e6a969753dcf2d1630438700e7d6ebde36538532b3525ac516f5f2ce9dd27a3\",\n    \"0xa64f7ff870bab4a8bf0d4ef6f5c744e9bf1021ed08b4c80903c7ad318e80ba1817c3180cc45cb5a1cae1170f0241655f\",\n    \"0xb00f706fa4de1f663f021e8ad3d155e84ce6084a409374b6e6cd0f924a0a0b51bebaaaf1d228c77233a73b0a5a0df0e9\",\n    \"0x8b882cc3bff3e42babdb96df95fb780faded84887a0a9bab896bef371cdcf169d909f5658649e93006aa3c6e1146d62e\",\n    \"0x9332663ef1d1dcf805c3d0e4ce7a07d9863fb1731172e766b3cde030bf81682cc011e26b773fb9c68e0477b4ae2cfb79\",\n    \"0xa8aa8151348dbd4ef40aaeb699b71b4c4bfd3218560c120d85036d14f678f6736f0ec68e80ce1459d3d35feccc575164\",\n    \"0xa16cd8b729768f51881c213434aa28301fa78fcb554ddd5f9012ee1e4eae7b5cb3dd88d269d53146dea92d10790faf0b\",\n    \"0x86844f0ef9d37142faf3b1e196e44fbe280a3ba4189aa05c356778cb9e3b388a2bff95eed305ada8769935c9974e4c57\",\n    \"0xae2eec6b328fccf3b47bcdac32901ac2744a51beb410b04c81dea34dee4912b619466a4f5e2780d87ecefaebbe77b46d\",\n    \"0x915df4c38d301c8a4eb2dc5b1ba0ffaad67cbb177e0a80095614e9c711f4ef24a4cef133f9d982a63d2a943ba6c8669d\",\n    \"0xae6a2a4dedfc2d1811711a8946991fede972fdf2a389b282471280737536ffc0ac3a6d885b1f8bda0366eb0b229b9979\",\n    \"0xa9b628c63d08b8aba6b1317f6e91c34b2382a6c85376e8ef2410a463c6796740ae936fc4e9e0737cb9455d1daa287bd8\",\n    \"0x848e30bf7edf2546670b390d5cf9ab71f98fcb6add3c0b582cb34996c26a446dee5d1bde4fdcde4fc80c10936e117b29\",\n    \"0x907d6096c7c8c087d1808dd995d5d2b9169b3768c3f433475b50c2e2bd4b082f4d543afd8b0b0ddffa9c66222a72d51d\",\n    \"0xa59970a2493b07339124d763ac9d793c60a03354539ecbcf6035bc43d1ea6e35718202ae6d7060b7d388f483d971573c\",\n    \"0xb9cfef2af9681b2318f119d8611ff6d9485a68d8044581b1959ab1840cbca576dbb53eec17863d2149966e9feb21122f\",\n    \"0xad47271806161f61d3afa45cdfe2babceef5e90031a21779f83dc8562e6076680525b4970b2f11fe9b2b23c382768323\",\n    \"0x8e425a99b71677b04fe044625d338811fbb8ee32368a424f6ab2381c52e86ee7a6cecedf777dc97181519d41c351bc22\",\n    \"0x86b55b54d7adefc12954a9252ee23ae83efe8b5b4b9a7dc307904413e5d69868c7087a818b2833f9b004213d629be8ad\",\n    \"0xa14fda6b93923dd11e564ae4457a66f397741527166e0b16a8eb91c6701c244fd1c4b63f9dd3515193ec88fa6c266b35\",\n    \"0xa9b17c36ae6cd85a0ed7f6cabc5b47dc8f80ced605db327c47826476dc1fb8f8669aa7a7dc679fbd4ee3d8e8b4bd6a6f\",\n    \"0x82a0829469c1458d959c821148f15dacae9ea94bf56c59a6ab2d4dd8b3d16d73e313b5a3912a6c1f131d73a8f06730c4\",\n    \"0xb22d56d549a53eaef549595924bdb621ff807aa4513feedf3fdcbf7ba8b6b9cfa4481c2f67fc642db397a6b794a8b63a\",\n    \"0x974c59c24392e2cb9294006cbe3c52163e255f3bd0c2b457bdc68a6338e6d5b6f87f716854492f8d880a6b896ccf757c\",\n    \"0xb70d247ba7cad97c50b57f526c2ba915786e926a94e8f8c3eebc2e1be6f4255411b9670e382060049c8f4184302c40b2\",\n    \"0xad80201fe75ef21c3ddbd98cf23591e0d7a3ba1036dfe77785c32f44755a212c31f0ceb0a0b6f5ee9b6dc81f358d30c3\",\n    \"0x8c656e841f9bb90b9a42d425251f3fdbc022a604d75f5845f479ed4be23e02aaf9e6e56cde351dd7449c50574818a199\",\n    \"0x8b88dd3fa209d3063b7c5b058f7249ee9900fbc2287d16da61a0704a0a1d71e45d9c96e1cda7fdf9654534ec44558b22\",\n    \"0x961da00cc8750bd84d253c08f011970ae1b1158ad6778e8ed943d547bceaf52d6d5a212a7de3bf2706688c4389b827d2\",\n    \"0xa5dd379922549a956033e3d51a986a4b1508e575042b8eaa1df007aa77cf0b8c2ab23212f9c075702788fa9c53696133\",\n    \"0xac8fcfde3a349d1e93fc8cf450814e842005c545c4844c0401bc80e6b96cdb77f29285a14455e167c191d4f312e866cd\",\n    \"0xac63d79c799783a8466617030c59dd5a8f92ee6c5204676fd8d881ce5f7f8663bdbeb0379e480ea9b6340ab0dc88e574\",\n    \"0x805874fde19ce359041ae2bd52a39e2841acabfd31f965792f2737d7137f36d4e4722ede8340d8c95afa6af278af8acb\",\n    \"0x8d2f323a228aa8ba7b7dc1399138f9e6b41df1a16a7069003ab8104b8b68506a45141bc5fe66acf430e23e13a545190b\",\n    \"0xa1610c721a2d9af882bb6b39bea97cff1527a3aea041d25934de080214ae77c959e79957164440686d15ab301e897d4d\",\n    \"0xaba16d29a47fc36f12b654fde513896723e2c700c4190f11b26aa4011da57737ad717daa02794aa3246e4ae5f0b0cc3a\",\n    \"0xa406db2f15fdd135f346cc4846623c47edd195e80ba8c7cb447332095314d565e4040694ca924696bb5ee7f8996ea0ba\",\n    \"0x8b30e2cd9b47d75ba57b83630e40f832249af6c058d4f490416562af451993eec46f3e1f90bc4d389e4c06abd1b32a46\",\n    \"0xaacf9eb7036e248e209adbfc3dd7ce386569ea9b312caa4b240726549db3c68c4f1c8cbf8ed5ea9ea60c7e57c9df3b8e\",\n    \"0xb20fcac63bf6f5ee638a42d7f89be847f348c085ddcbec3fa318f4323592d136c230495f188ef2022aa355cc2b0da6f9\",\n    \"0x811eff750456a79ec1b1249d76d7c1547065b839d8d4aaad860f6d4528eb5b669473dcceeeea676cddbc3980b68461b7\",\n    \"0xb52d14ae33f4ab422f953392ae76a19c618cc31afc96290bd3fe2fb44c954b5c92c4789f3f16e8793f2c0c1691ade444\",\n    \"0xa7826dafeeba0db5b66c4dfcf2b17fd7b40507a5a53ac2e42942633a2cb30b95ba1739a6e9f3b7a0e0f1ec729bf274e2\",\n    \"0x8acfd83ddf7c60dd7c8b20c706a3b972c65d336b8f9b3d907bdd8926ced271430479448100050b1ef17578a49c8fa616\",\n    \"0xaf0c69f65184bb06868029ad46f8465d75c36814c621ac20a5c0b06a900d59305584f5a6709683d9c0e4b6cd08d650a6\",\n    \"0xb6cc8588191e00680ee6c3339bd0f0a17ad8fd7f4be57d5d7075bede0ea593a19e67f3d7c1a20114894ee5bfcab71063\",\n    \"0xa82fd4f58635129dbb6cc3eb9391cf2d28400018b105fc41500fbbd12bd890b918f97d3d359c29dd3b4c4e34391dfab0\",\n    \"0x92fc544ed65b4a3625cf03c41ddff7c039bc22d22c0d59dcc00efd5438401f2606adb125a1d5de294cca216ec8ac35a3\",\n    \"0x906f67e4a32582b71f15940523c0c7ce370336935e2646bdaea16a06995256d25e99df57297e39d6c39535e180456407\",\n    \"0x97510337ea5bbd5977287339197db55c60533b2ec35c94d0a460a416ae9f60e85cee39be82abeeacd5813cf54df05862\",\n    \"0x87e6894643815c0ea48cb96c607266c5ee4f1f82ba5fe352fb77f9b6ed14bfc2b8e09e80a99ac9047dfcf62b2ae26795\",\n    \"0xb6fd55dd156622ad7d5d51b7dde75e47bd052d4e542dd6449e72411f68275775c846dde301e84613312be8c7bce58b07\",\n    \"0xb98461ac71f554b2f03a94e429b255af89eec917e208a8e60edf5fc43b65f1d17a20de3f31d2ce9f0cb573c25f2f4d98\",\n    \"0x96f0dea40ca61cefbee41c4e1fe9a7d81fbe1f49bb153d083ab70f5d0488a1f717fd28cedcf6aa18d07cce2c62801898\",\n    \"0x8d7c3ab310184f7dc34b6ce4684e4d29a31e77b09940448ea4daac730b7eb308063125d4dd229046cf11bfd521b771e0\",\n    \"0x96f0564898fe96687918bbf0a6adead99cf72e3a35ea3347e124af9d006221f8e82e5a9d2fe80094d5e8d48e610f415e\",\n    \"0xad50fcb92c2675a398cf07d4c40a579e44bf8d35f27cc330b57e54d5ea59f7d898af0f75dccfe3726e5471133d70f92b\",\n    \"0x828beed62020361689ae7481dd8f116902b522fb0c6c122678e7f949fdef70ead011e0e6bffd25678e388744e17cdb69\",\n    \"0x8349decac1ca16599eee2efc95bcaabf67631107da1d34a2f917884bd70dfec9b4b08ab7bc4379d6c73b19c0b6e54fb8\",\n    \"0xb2a6a2e50230c05613ace9e58bb2e98d94127f196f02d9dddc53c43fc68c184549ca12d713cb1b025d8260a41e947155\",\n    \"0x94ff52181aadae832aed52fc3b7794536e2a31a21fc8be3ea312ca5c695750d37f08002f286b33f4023dba1e3253ecfa\",\n    \"0xa21d56153c7e5972ee9a319501be4faff199fdf09bb821ea9ce64aa815289676c00f105e6f00311b3a5b627091b0d0fc\",\n    \"0xa27a60d219f1f0c971db73a7f563b371b5c9fc3ed1f72883b2eac8a0df6698400c9954f4ca17d7e94e44bd4f95532afb\",\n    \"0xa2fc56fae99b1f18ba5e4fe838402164ce82f8a7f3193d0bbd360c2bac07c46f9330c4c7681ffb47074c6f81ee6e7ac6\",\n    \"0xb748e530cd3afb96d879b83e89c9f1a444f54e55372ab1dcd46a0872f95ce8f49cf2363fc61be82259e04f555937ed16\",\n    \"0x8bf8993e81080c7cbba1e14a798504af1e4950b2f186ab3335b771d6acaee4ffe92131ae9c53d74379d957cb6344d9cd\",\n    \"0x96774d0ef730d22d7ab6d9fb7f90b9ead44285219d076584a901960542756700a2a1603cdf72be4708b267200f6c36a9\",\n    \"0xb47703c2ab17be1e823cc7bf3460db1d6760c0e33862c90ca058845b2ff234b0f9834ddba2efb2ee1770eb261e7d8ffd\",\n    \"0x84319e67c37a9581f8b09b5e4d4ae88d0a7fb4cbb6908971ab5be28070c3830f040b1de83ee663c573e0f2f6198640e4\",\n    \"0x96811875fa83133e0b3c0e0290f9e0e28bca6178b77fdf5350eb19344d453dbd0d71e55a0ef749025a5a2ca0ad251e81\",\n    \"0x81a423423e9438343879f2bfd7ee9f1c74ebebe7ce3cfffc8a11da6f040cc4145c3b527bd3cf63f9137e714dbcb474ef\",\n    \"0xb8c3535701ddbeec2db08e17a4fa99ba6752d32ece5331a0b8743676f421fcb14798afc7c783815484f14693d2f70db8\",\n    \"0x81aee980c876949bf40782835eec8817d535f6f3f7e00bf402ddd61101fdcd60173961ae90a1cf7c5d060339a18c959d\",\n    \"0x87e67b928d97b62c49dac321ce6cb680233f3a394d4c9a899ac2e8db8ccd8e00418e66cdfd68691aa3cb8559723b580c\",\n    \"0x8eac204208d99a2b738648df96353bbb1b1065e33ee4f6bba174b540bbbd37d205855e1f1e69a6b7ff043ca377651126\",\n    \"0x848e6e7a54ad64d18009300b93ea6f459ce855971dddb419b101f5ac4c159215626fadc20cc3b9ab1701d8f6dfaddd8b\",\n    \"0x88aa123d9e0cf309d46dddb6acf634b1ade3b090a2826d6e5e78669fa1220d6df9a6697d7778cd9b627db17eea846126\",\n    \"0x9200c2a629b9144d88a61151b661b6c4256cc5dadfd1e59a8ce17a013c2d8f7e754aabe61663c3b30f1bc47784c1f8cf\",\n    \"0xb6e1a2827c3bdda91715b0e1b1f10dd363cef337e7c80cac1f34165fc0dea7c8b69747e310563db5818390146ce3e231\",\n    \"0x92c333e694f89f0d306d54105b2a5dcc912dbe7654d9e733edab12e8537350815be472b063e56cfde5286df8922fdecb\",\n    \"0xa6fac04b6d86091158ebb286586ccfec2a95c9786e14d91a9c743f5f05546073e5e3cc717635a0c602cad8334e922346\",\n    \"0xa581b4af77feebc1fb897d49b5b507c6ad513d8f09b273328efbb24ef0d91eb740d01b4d398f2738125dacfe550330cd\",\n    \"0x81c4860cccf76a34f8a2bc3f464b7bfd3e909e975cce0d28979f457738a56e60a4af8e68a3992cf273b5946e8d7f76e2\",\n    \"0x8d1eaa09a3180d8af1cbaee673db5223363cc7229a69565f592fa38ba0f9d582cedf91e15dabd06ebbf2862fc0feba54\",\n    \"0x9832f49b0147f4552402e54593cfa51f99540bffada12759b71fcb86734be8e500eea2d8b3d036710bdf04c901432de9\",\n    \"0x8bdb0e8ec93b11e5718e8c13cb4f5de545d24829fd76161216340108098dfe5148ed25e3b57a89a516f09fa79043734d\",\n    \"0xab96f06c4b9b0b2c0571740b24fca758e6976315053a7ecb20119150a9fa416db2d3a2e0f8168b390bb063f0c1caf785\",\n    \"0xab777f5c52acd62ecf4d1f168b9cc8e1a9b45d4ec6a8ff52c583e867c2239aba98d7d3af977289b367edce03d9c2dfb1\",\n    \"0xa09d3ce5e748da84802436951acc3d3ea5d8ec1d6933505ed724d6b4b0d69973ab0930daec9c6606960f6e541e4a3ce2\",\n    \"0x8ef94f7be4d85d5ad3d779a5cf4d7b2fc3e65c52fb8e1c3c112509a4af77a0b5be994f251e5e40fabeeb1f7d5615c22b\",\n    \"0xa7406a5bf5708d9e10922d3c5c45c03ef891b8d0d74ec9f28328a72be4cdc05b4f2703fa99366426659dfca25d007535\",\n    \"0xb7f52709669bf92a2e070bfe740f422f0b7127392c5589c7f0af71bb5a8428697c762d3c0d74532899da24ea7d8695c2\",\n    \"0xb9dfb0c8df84104dbf9239ccefa4672ef95ddabb8801b74997935d1b81a78a6a5669a3c553767ec19a1281f6e570f4ff\",\n    \"0xae4d5c872156061ce9195ac640190d8d71dd406055ee43ffa6f9893eb24b870075b74c94d65bc1d5a07a6573282b5520\",\n    \"0xafe6bd3eb72266d333f1807164900dcfa02a7eb5b1744bb3c86b34b3ee91e3f05e38fa52a50dc64eeb4bdb1dd62874b8\",\n    \"0x948043cf1bc2ef3c01105f6a78dc06487f57548a3e6ef30e6ebc51c94b71e4bf3ff6d0058c72b6f3ecc37efd7c7fa8c0\",\n    \"0xa22fd17c2f7ffe552bb0f23fa135584e8d2d8d75e3f742d94d04aded2a79e22a00dfe7acbb57d44e1cdb962fb22ae170\",\n    \"0x8cd0f4e9e4fb4a37c02c1bde0f69359c43ab012eb662d346487be0c3758293f1ca560122b059b091fddce626383c3a8f\",\n    \"0x90499e45f5b9c81426f3d735a52a564cafbed72711d9279fdd88de8038e953bc48c57b58cba85c3b2e4ce56f1ddb0e11\",\n    \"0x8c30e4c034c02958384564cac4f85022ef36ab5697a3d2feaf6bf105049675bbf23d01b4b6814711d3d9271abff04cac\",\n    \"0x81f7999e7eeea30f3e1075e6780bbf054f2fb6f27628a2afa4d41872a385b4216dd5f549da7ce6cf39049b2251f27fb7\",\n    \"0xb36a7191f82fc39c283ffe53fc1f5a9a00b4c64eee7792a8443475da9a4d226cf257f226ea9d66e329af15d8f04984ec\",\n    \"0xaad4da528fdbb4db504f3041c747455baff5fcd459a2efd78f15bdf3aea0bdb808343e49df88fe7a7c8620009b7964a3\",\n    \"0x99ebd8c6dd5dd299517fb6381cfc2a7f443e6e04a351440260dd7c2aee3f1d8ef06eb6c18820b394366ecdfd2a3ce264\",\n    \"0x8873725b81871db72e4ec3643084b1cdce3cbf80b40b834b092767728605825c19b6847ad3dcf328438607e8f88b4410\",\n    \"0xb008ee2f895daa6abd35bd39b6f7901ae4611a11a3271194e19da1cdcc7f1e1ea008fe5c5440e50d2c273784541ad9c5\",\n    \"0x9036feafb4218d1f576ef89d0e99124e45dacaa6d816988e34d80f454d10e96809791d5b78f7fd65f569e90d4d7238c5\",\n    \"0x92073c1d11b168e4fa50988b0288638b4868e48bbc668c5a6dddf5499875d53be23a285acb5e4bad60114f6cf6c556e9\",\n    \"0x88c87dfcb8ba6cbfe7e1be081ccfadbd589301db2cb7c99f9ee5d7db90aa297ed1538d5a867678a763f2deede5fd219a\",\n    \"0xb42a562805c661a50f5dea63108002c0f27c0da113da6a9864c9feb5552225417c0356c4209e8e012d9bcc9d182c7611\",\n    \"0x8e6317d00a504e3b79cd47feb4c60f9df186467fe9ca0f35b55c0364db30528f5ff071109dabb2fc80bb9cd4949f0c24\",\n    \"0xb7b1ea6a88694f8d2f539e52a47466695e39e43a5eb9c6f23bca15305fe52939d8755cc3ac9d6725e60f82f994a3772f\",\n    \"0xa3cd55161befe795af93a38d33290fb642b8d80da8b786c6e6fb02d393ea308fbe87f486994039cbd7c7b390414594b6\",\n    \"0xb416d2d45b44ead3b1424e92c73c2cf510801897b05d1724ff31cbd741920cd858282fb5d6040fe1f0aa97a65bc49424\",\n    \"0x950ee01291754feace97c2e933e4681e7ddfbc4fcd079eb6ff830b0e481d929c93d0c7fb479c9939c28ca1945c40da09\",\n    \"0x869bd916aee8d86efe362a49010382674825d49195b413b4b4018e88ce43fe091b475d0b863ff0ba2259400f280c2b23\",\n    \"0x9782f38cd9c9d3385ec286ebbc7cba5b718d2e65a5890b0a5906b10a89dc8ed80d417d71d7c213bf52f2af1a1f513ea7\",\n    \"0x91cd33bc2628d096269b23faf47ee15e14cb7fdc6a8e3a98b55e1031ea0b68d10ba30d97e660f7e967d24436d40fad73\",\n    \"0x8becc978129cc96737034c577ae7225372dd855da8811ae4e46328e020c803833b5bdbc4a20a93270e2b8bd1a2feae52\",\n    \"0xa36b1d8076783a9522476ce17f799d78008967728ce920531fdaf88303321bcaf97ecaa08e0c01f77bc32e53c5f09525\",\n    \"0xb4720e744943f70467983aa34499e76de6d59aa6fadf86f6b787fdce32a2f5b535b55db38fe2da95825c51002cfe142d\",\n    \"0x91ad21fc502eda3945f6de874d1b6bf9a9a7711f4d61354f9e5634fc73f9c06ada848de15ab0a75811d3250be862827d\",\n    \"0x84f78e2ebf5fc077d78635f981712daf17e2475e14c2a96d187913006ad69e234746184a51a06ef510c9455b38acb0d7\",\n    \"0x960aa7906e9a2f11db64a26b5892ac45f20d2ccb5480f4888d89973beb6fa0dfdc06d68d241ff5ffc7f1b82b1aac242d\",\n    \"0xa99365dcd1a00c66c9db6924b97c920f5c723380e823b250db85c07631b320ec4e92e586f7319e67a522a0578f7b6d6c\",\n    \"0xa25d92d7f70cf6a88ff317cfec071e13774516da664f5fac0d4ecaa65b8bf4eb87a64a4d5ef2bd97dfae98d388dbf5cc\",\n    \"0xa7af47cd0041295798f9779020a44653007444e8b4ef0712982b06d0dcdd434ec4e1f7c5f7a049326602cb605c9105b7\",\n    \"0xaefe172eac5568369a05980931cc476bebd9dea573ba276d59b9d8c4420784299df5a910033b7e324a6c2dfc62e3ef05\",\n    \"0xb69bc9d22ffa645baa55e3e02522e9892bb2daa7fff7c15846f13517d0799766883ee09ae0869df4139150c5b843ca8a\",\n    \"0x95a10856140e493354fdd12722c7fdded21b6a2ffbc78aa2697104af8ad0c8e2206f44b0bfee077ef3949d46bbf7c16b\",\n    \"0x891f2fcd2c47cbea36b7fa715968540c233313f05333f09d29aba23c193f462ed490dd4d00969656e89c53155fdfe710\",\n    \"0xa6c33e18115e64e385c843dde34e8a228222795c7ca90bc2cc085705d609025f3351d9be61822c69035a49fb3e48f2d5\",\n    \"0xb87fb12f12c0533b005adad0487f03393ff682e13575e3cb57280c3873b2c38ba96a63c49eef7a442753d26b7005230b\",\n    \"0xb905c02ba451bfd411c135036d92c27af3b0b1c9c2f1309d6948544a264b125f39dd41afeff4666b12146c545adc168a\",\n    \"0x8b29c513f43a78951cf742231cf5457a6d9d55edf45df5481a0f299a418d94effef561b15d2c1a01d1b8067e7153fda9\",\n    \"0xb9941cccd51dc645920d2781c81a317e5a33cb7cf76427b60396735912cb6d2ca9292bb4d36b6392467d390d2c58d9f3\",\n    \"0xa8546b627c76b6ef5c93c6a98538d8593dbe21cb7673fd383d5401b0c935eea0bdeeefeb1af6ad41bad8464fb87bbc48\",\n    \"0xaa286b27de2812de63108a1aec29d171775b69538dc6198640ac1e96767c2b83a50391f49259195957d457b493b667c9\",\n    \"0xa932fb229f641e9abbd8eb2bd874015d97b6658ab6d29769fc23b7db9e41dd4f850382d4c1f08af8f156c5937d524473\",\n    \"0xa1412840fcc86e2aeec175526f2fb36e8b3b8d21a78412b7266daf81e51b3f68584ed8bd42a66a43afdd8c297b320520\",\n    \"0x89c78be9efb624c97ebca4fe04c7704fa52311d183ffd87737f76b7dadc187c12c982bd8e9ed7cd8beb48cdaafd2fd01\",\n    \"0xa3f5ddec412a5bec0ce15e3bcb41c6214c2b05d4e9135a0d33c8e50a78eaba71e0a5a6ea8b45854dec5c2ed300971fc2\",\n    \"0x9721f9cec7a68b7758e3887548790de49fa6a442d0396739efa20c2f50352a7f91d300867556d11a703866def2d5f7b5\",\n    \"0xa23764e140a87e5991573521af039630dd28128bf56eed2edbed130fd4278e090b60cf5a1dca9de2910603d44b9f6d45\",\n    \"0xa1a6494a994215e48ab55c70efa8ffdddce6e92403c38ae7e8dd2f8288cad460c6c7db526bbdf578e96ca04d9fe12797\",\n    \"0xb1705ea4cb7e074efe0405fc7b8ee2ec789af0426142f3ec81241cacd4f7edcd88e39435e4e4d8e7b1df64f3880d6613\",\n    \"0x85595d061d677116089a6064418b93eb44ff79e68d12bd9625078d3bbc440a60d0b02944eff6054433ee34710ae6fbb4\",\n    \"0x9978d5e30bedb7526734f9a1febd973a70bfa20890490e7cc6f2f9328feab1e24f991285dbc3711d892514e2d7d005ad\",\n    \"0xaf30243c66ea43b9f87a061f947f7bce745f09194f6e95f379c7582b9fead920e5d6957eaf05c12ae1282ada4670652f\",\n    \"0xa1930efb473f88001e47aa0b2b2a7566848cccf295792e4544096ecd14ee5d7927c173a8576b405bfa2eec551cd67eb5\",\n    \"0xb0446d1c590ee5a45f7e22d269c044f3848c97aec1d226b44bfd0e94d9729c28a38bccddc3a1006cc5fe4e3c24f001f2\",\n    \"0xb8a8380172df3d84b06176df916cf557966d4f2f716d3e9437e415d75b646810f79f2b2b71d857181b7fc944018883a3\",\n    \"0xa563afec25b7817bfa26e19dc9908bc00aa8fc3d19be7d6de23648701659009d10e3e4486c28e9c6b13d48231ae29ac5\",\n    \"0xa5a8e80579de886fb7d6408f542791876885947b27ad6fa99a8a26e381f052598d7b4e647b0115d4b5c64297e00ce28e\",\n    \"0x8f87afcc7ad33c51ac719bade3cd92da671a37a82c14446b0a2073f4a0a23085e2c8d31913ed2d0be928f053297de8f6\",\n    \"0xa43c455ce377e0bc434386c53c752880687e017b2f5ae7f8a15c044895b242dffde4c92fb8f8bb50b18470b17351b156\",\n    \"0x8368f8b12a5bceb1dba25adb3a2e9c7dc9b1a77a1f328e5a693f5aec195cd1e06b0fe9476b554c1c25dac6c4a5b640a3\",\n    \"0x919878b27f3671fc78396f11531c032f3e2bd132d04cc234fa4858676b15fb1db3051c0b1db9b4fc49038216f11321ce\",\n    \"0xb48cd67fb7f1242696c1f877da4bdf188eac676cd0e561fbac1a537f7b8229aff5a043922441d603a26aae56a15faee4\",\n    \"0xa3e0fdfd4d29ea996517a16f0370b54787fefe543c2fe73bfc6f9e560c1fd30dad8409859e2d7fa2d44316f24746c712\",\n    \"0x8bb156ade8faf149df7bea02c140c7e392a4742ae6d0394d880a849127943e6f26312033336d3b9fdc0092d71b5efe87\",\n    \"0x8845e5d5cc555ca3e0523244300f2c8d7e4d02aaebcb5bd749d791208856c209a6f84dd99fd55968c9f0ab5f82916707\",\n    \"0xa3e90bb5c97b07789c2f32dff1aec61d0a2220928202f5ad5355ae71f8249237799d6c8a22602e32e572cb12eabe0c17\",\n    \"0xb150bcc391884c996149dc3779ce71f15dda63a759ee9cc05871f5a8379dcb62b047098922c0f26c7bd04deb394c33f9\",\n    \"0x95cd4ad88d51f0f2efcfd0c2df802fe252bb9704d1afbf9c26a248df22d55da87bdfaf41d7bc6e5df38bd848f0b13f42\",\n    \"0xa05a49a31e91dff6a52ac8b9c2cfdd646a43f0d488253f9e3cfbce52f26667166bbb9b608fc358763a65cbf066cd6d05\",\n    \"0xa59c3c1227fdd7c2e81f5e11ef5c406da44662987bac33caed72314081e2eed66055d38137e01b2268e58ec85dd986c0\",\n    \"0xb7020ec3bd73a99861f0f1d88cf5a19abab1cbe14b7de77c9868398c84bb8e18dbbe9831838a96b6d6ca06e82451c67b\",\n    \"0x98d1ff2525e9718ee59a21d8900621636fcd873d9a564b8dceb4be80a194a0148daf1232742730b3341514b2e5a5436c\",\n    \"0x886d97b635975fc638c1b6afc493e5998ca139edba131b75b65cfe5a8e814f11bb678e0eeee5e6e5cd913ad3f2fefdfc\",\n    \"0x8fb9fd928d38d5d813b671c924edd56601dd7163b686c13f158645c2f869d9250f3859aa5463a39258c90fef0f41190a\",\n    \"0xaac35e1cd655c94dec3580bb3800bd9c2946c4a9856f7d725af15fbea6a2d8ca51c8ad2772abed60ee0e3fb9cb24046b\",\n    \"0xb8d71fa0fa05ac9e443c9b4929df9e7f09a919be679692682e614d24227e04894bfc14a5c73a62fb927fedff4a0e4aa7\",\n    \"0xa45a19f11fbbb531a704badbb813ed8088ab827c884ee4e4ebf363fa1132ff7cfa9d28be9c85b143e4f7cdbc94e7cf1a\",\n    \"0x82b54703a4f295f5471b255ab59dce00f0fe90c9fb6e06b9ee48b15c91d43f4e2ef4a96c3118aeb03b08767be58181bb\",\n    \"0x8283264c8e6d2a36558f0d145c18576b6600ff45ff99cc93eca54b6c6422993cf392668633e5df396b9331e873d457e5\",\n    \"0x8c549c03131ead601bc30eb6b9537b5d3beb7472f5bb1bcbbfd1e9f3704477f7840ab3ab7f7dc13bbbbcdff886a462d4\",\n    \"0xafbb0c520ac1b5486513587700ad53e314cb74bfbc12e0b5fbdcfdaac36d342e8b59856196a0d84a25cff6e6e1d17e76\",\n    \"0x89e4c22ffb51f2829061b3c7c1983c5c750cad158e3a825d46f7cf875677da5d63f653d8a297022b5db5845c9271b32b\",\n    \"0xafb27a86c4c2373088c96b9adf4433f2ebfc78ac5c526e9f0510670b6e4e5e0057c0a4f75b185e1a30331b9e805c1c15\",\n    \"0xa18e16b57445f88730fc5d3567bf5a176861dc14c7a08ed2996fe80eed27a0e7628501bcb78a1727c5e9ac55f29c12c4\",\n    \"0x93d61bf88b192d6825cf4e1120af1c17aa0f994d158b405e25437eaeefae049f7b721a206e7cc8a04fdc29d3c42580a1\",\n    \"0xa99f2995a2e3ed2fd1228d64166112038de2f516410aa439f4c507044e2017ea388604e2d0f7121256fadf7fbe7023d1\",\n    \"0x914fd91cffc23c32f1c6d0e98bf660925090d873367d543034654389916f65f552e445b0300b71b61b721a72e9a5983c\",\n    \"0xb42a578a7787b71f924e7def425d849c1c777156b1d4170a8ee7709a4a914e816935131afd9a0412c4cb952957b20828\",\n    \"0x82fb30590e84b9e45db1ec475a39971cf554dc01bcc7050bc89265740725c02e2be5a972168c5170c86ae83e5b0ad2c0\",\n    \"0xb14f8d8e1e93a84976289e0cf0dfa6f3a1809e98da16ee5c4932d0e1ed6bf8a07697fdd4dd86a3df84fb0003353cdcc0\",\n    \"0x85d7a2f4bda31aa2cb208b771fe03291a4ebdaf6f1dc944c27775af5caec412584c1f45bc741fca2a6a85acb3f26ad7d\",\n    \"0xaf02e56ce886ff2253bc0a68faad76f25ead84b2144e5364f3fb9b648f03a50ee9dc0b2c33ebacf7c61e9e43201ef9ef\",\n    \"0x87e025558c8a0b0abd06dfc350016847ea5ced7af2d135a5c9eec9324a4858c4b21510fb0992ec52a73447f24945058e\",\n    \"0x80fff0bafcd058118f5e7a4d4f1ae0912efeb281d2cbe4d34ba8945cc3dbe5d8baf47fb077343b90b8d895c90b297aca\",\n    \"0xb6edcf3a40e7b1c3c0148f47a263cd819e585a51ef31c2e35a29ce6f04c53e413f743034c0d998d9c00a08ba00166f31\",\n    \"0xabb87ed86098c0c70a76e557262a494ff51a30fb193f1c1a32f8e35eafa34a43fcc07aa93a3b7a077d9e35afa07b1a3d\",\n    \"0xa280214cd3bb0fb7ecd2d8bcf518cbd9078417f2b91d2533ec2717563f090fb84f2a5fcfdbbeb2a2a1f8a71cc5aa5941\",\n    \"0xa63083ca7238ea2b57d15a475963cf1d4f550d8cd76db290014a0461b90351f1f26a67d674c837b0b773b330c7c3d534\",\n    \"0xa8fa39064cb585ece5263e2f42f430206476bf261bd50f18d2b694889bd79d04d56410664cecad62690e5c5a20b3f6ff\",\n    \"0x85ba52ce9d700a5dcf6c5b00559acbe599d671ce5512467ff4b6179d7fad550567ce2a9c126a50964e3096458ea87920\",\n    \"0xb913501e1008f076e5eac6d883105174f88b248e1c9801e568fefaffa1558e4909364fc6d9512aa4d125cbd7cc895f05\",\n    \"0x8eb33b5266c8f2ed4725a6ad147a322e44c9264cf261c933cbbe230a43d47fca0f29ec39756b20561dabafadd5796494\",\n    \"0x850ebc8b661a04318c9db5a0515066e6454fa73865aa4908767a837857ecd717387f614acb614a88e075d4edc53a2f5a\",\n    \"0xa08d6b92d866270f29f4ce23a3f5d99b36b1e241a01271ede02817c8ec3f552a5c562db400766c07b104a331835c0c64\",\n    \"0x8131804c89bb3e74e9718bfc4afa547c1005ff676bd4db9604335032b203390cfa54478d45c6c78d1fe31a436ed4be9f\",\n    \"0x9106d94f23cc1eacec8316f16d6f0a1cc160967c886f51981fdb9f3f12ee1182407d2bb24e5b873de58cb1a3ee915a6b\",\n    \"0xa13806bfc3eae7a7000c9d9f1bd25e10218d4e67f59ae798b145b098bca3edad2b1040e3fc1e6310e612fb8818f459ac\",\n    \"0x8c69fbca502046cb5f6db99900a47b34117aef3f4b241690cdb3b84ca2a2fc7833e149361995dc41fa78892525bce746\",\n    \"0x852c473150c91912d58ecb05769222fa18312800c3f56605ad29eec9e2d8667b0b81c379048d3d29100ed2773bb1f3c5\",\n    \"0xb1767f6074426a00e01095dbb1795beb4e4050c6411792cbad6537bc444c3165d1058bafd1487451f9c5ddd209e0ae7e\",\n    \"0x80c600a5fe99354ce59ff0f84c760923dc8ff66a30bf47dc0a086181785ceb01f9b951c4e66df800ea6d705e8bc47055\",\n    \"0xb5cf19002fbc88a0764865b82afcb4d64a50196ea361e5c71dff7de084f4dcbbc34ec94a45cc9e0247bd51da565981aa\",\n    \"0x93e67a254ea8ce25e112d93cc927fadaa814152a2c4ec7d9a56eaa1ed47aec99b7e9916b02e64452cc724a6641729bbb\",\n    \"0xace70b32491bda18eee4a4d041c3bc9effae9340fe7e6c2f5ad975ee0874c17f1a7da7c96bd85fccff9312c518fac6e9\",\n    \"0xab4cfa02065017dd7f1aadc66f2c92f78f0f11b8597c03a5d69d82cb2eaf95a4476a836ac102908f137662472c8d914b\",\n    \"0xa40b8cd8deb8ae503d20364d64cab7c2801b7728a9646ed19c65edea6a842756a2f636283494299584ad57f4bb12cd0b\",\n    \"0x8594e11d5fc2396bcd9dbf5509ce4816dbb2b7305168021c426171fb444d111da5a152d6835ad8034542277011c26c0e\",\n    \"0x8024de98c26b4c994a66628dc304bb737f4b6859c86ded552c5abb81fd4c6c2e19d5a30beed398a694b9b2fdea1dd06a\",\n    \"0x8843f5872f33f54df8d0e06166c1857d733995f67bc54abb8dfa94ad92407cf0179bc91b0a50bbb56cdc2b350d950329\",\n    \"0xb8bab44c7dd53ef9edf497dcb228e2a41282c90f00ba052fc52d57e87b5c8ab132d227af1fcdff9a12713d1f980bcaae\",\n    \"0x982b4d7b29aff22d527fd82d2a52601d95549bfb000429bb20789ed45e5abf1f4b7416c7b7c4b79431eb3574b29be658\",\n    \"0x8eb1f571b6a1878e11e8c1c757e0bc084bab5e82e897ca9be9b7f4b47b91679a8190bf0fc8f799d9b487da5442415857\",\n    \"0xa6e74b588e5af935c8b243e888582ef7718f8714569dd4992920740227518305eb35fab674d21a5551cca44b3e511ef2\",\n    \"0xa30fc2f3a4cb4f50566e82307de73cd7bd8fe2c1184e9293c136a9b9e926a018d57c6e4f308c95b9eb8299e94d90a2a1\",\n    \"0xa50c5869ca5d2b40722c056a32f918d47e0b65ca9d7863ca7d2fb4a7b64fe523fe9365cf0573733ceaadebf20b48fff8\",\n    \"0x83bbdd32c04d17581418cf360749c7a169b55d54f2427390defd9f751f100897b2d800ce6636c5bbc046c47508d60c8c\",\n    \"0xa82904bdf614de5d8deaff688c8a5e7ac5b3431687acbcda8fa53960b7c417a39c8b2e462d7af91ce6d79260f412db8e\",\n    \"0xa4362e31ff4b05d278b033cf5eebea20de01714ae16d4115d04c1da4754269873afc8171a6f56c5104bfd7b0db93c3e7\",\n    \"0xb5b8daa63a3735581e74a021b684a1038cea77168fdb7fdf83c670c2cfabcfc3ab2fc7359069b5f9048188351aef26b5\",\n    \"0xb48d723894b7782d96ac8433c48faca1bdfa5238019c451a7f47d958097cce3ae599b876cf274269236b9d6ff8b6d7ca\",\n    \"0x98ffff6a61a3a6205c7820a91ca2e7176fab5dba02bc194c4d14942ac421cb254183c705506ab279e4f8db066f941c6c\",\n    \"0xae7db24731da2eaa6efc4f7fcba2ecc26940ddd68038dce43acf2cee15b72dc4ef42a7bfdd32946d1ed78786dd7696b3\",\n    \"0xa656db14f1de9a7eb84f6301b4acb2fbf78bfe867f48a270e416c974ab92821eb4df1cb881b2d600cfed0034ac784641\",\n    \"0xaa315f8ecba85a5535e9a49e558b15f39520fce5d4bf43131bfbf2e2c9dfccc829074f9083e8d49f405fb221d0bc4c3c\",\n    \"0x90bffba5d9ff40a62f6c8e9fc402d5b95f6077ed58d030c93e321b8081b77d6b8dac3f63a92a7ddc01585cf2c127d66c\",\n    \"0xabdd733a36e0e0f05a570d0504e73801bf9b5a25ff2c78786f8b805704997acb2e6069af342538c581144d53149fa6d3\",\n    \"0xb4a723bb19e8c18a01bd449b1bb3440ddb2017f10bb153da27deb7a6a60e9bb37619d6d5435fbb1ba617687838e01dd0\",\n    \"0x870016b4678bab3375516db0187a2108b2e840bae4d264b9f4f27dbbc7cc9cac1d7dc582d7a04d6fd1ed588238e5e513\",\n    \"0x80d33d2e20e8fc170aa3cb4f69fffb72aeafb3b5bb4ea0bc79ab55da14142ca19b2d8b617a6b24d537366e3b49cb67c3\",\n    \"0xa7ee76aec273aaae03b3b87015789289551969fb175c11557da3ab77e39ab49d24634726f92affae9f4d24003050d974\",\n    \"0x8415ea4ab69d779ebd42d0fe0c6aef531d6a465a5739e429b1fcf433ec45aa8296c527e965a20f0ec9f340c9273ea3cf\",\n    \"0x8c7662520794e8b4405d0b33b5cac839784bc86a5868766c06cbc1fa306dbe334978177417b31baf90ce7b0052a29c56\",\n    \"0x902b2abecc053a3dbdea9897ee21e74821f3a1b98b2d560a514a35799f4680322550fd3a728d4f6d64e1de98033c32b8\",\n    \"0xa05e84ed9ecab8d508d670c39f2db61ad6e08d2795ec32a3c9d0d3737ef3801618f4fc2a95f90ec2f068606131e076c5\",\n    \"0x8b9208ff4d5af0c2e3f53c9375da666773ac57197dfabb0d25b1c8d0588ba7f3c15ee9661bb001297f322ea2fbf6928b\",\n    \"0xa3c827741b34a03254d4451b5ab74a96f2b9f7fb069e2f5adaf54fd97cc7a4d516d378db5ca07da87d8566d6eef13726\",\n    \"0x8509d8a3f4a0ed378e0a1e28ea02f6bf1d7f6c819c6c2f5297c7df54c895b848f841653e32ba2a2c22c2ff739571acb8\",\n    \"0xa0ce988b7d3c40b4e496aa83a09e4b5472a2d98679622f32bea23e6d607bc7de1a5374fb162bce0549a67dad948519be\",\n    \"0xaa8a3dd12bd60e3d2e05f9c683cdcb8eab17fc59134815f8d197681b1bcf65108cba63ac5c58ee632b1e5ed6bba5d474\",\n    \"0x8b955f1d894b3aefd883fb4b65f14cd37fc2b9db77db79273f1700bef9973bf3fd123897ea2b7989f50003733f8f7f21\",\n    \"0xac79c00ddac47f5daf8d9418d798d8af89fc6f1682e7e451f71ea3a405b0d36af35388dd2a332af790bc83ca7b819328\",\n    \"0xa0d44dd2a4438b809522b130d0938c3fe7c5c46379365dbd1810a170a9aa5818e1c783470dd5d0b6d4ac7edbb7330910\",\n    \"0xa30b69e39ad43dd540a43c521f05b51b5f1b9c4eed54b8162374ae11eac25da4f5756e7b70ce9f3c92c2eeceee7431ed\",\n    \"0xac43220b762c299c7951222ea19761ab938bf38e4972deef58ed84f4f9c68c230647cf7506d7cbfc08562fcca55f0485\",\n    \"0xb28233b46a8fb424cfa386a845a3b5399d8489ceb83c8f3e05c22c934798d639c93718b7b68ab3ce24c5358339e41cbb\",\n    \"0xac30d50ee8ce59a10d4b37a3a35e62cdb2273e5e52232e202ca7d7b8d09d28958ee667fae41a7bb6cdc6fe8f6e6c9c85\",\n    \"0xb199842d9141ad169f35cc7ff782b274cbaa645fdb727761e0a89edbf0d781a15f8218b4bf4eead326f2903dd88a9cc1\",\n    \"0x85e018c7ddcad34bb8285a737c578bf741ccd547e68c734bdb3808380e12c5d4ef60fc896b497a87d443ff9abd063b38\",\n    \"0x8c856e6ba4a815bdb891e1276f93545b7072f6cb1a9aa6aa5cf240976f29f4dee01878638500a6bf1daf677b96b54343\",\n    \"0xb8a47555fa8710534150e1a3f13eab33666017be6b41005397afa647ea49708565f2b86b77ad4964d140d9ced6b4d585\",\n    \"0x8cd1f1db1b2f4c85a3f46211599caf512d5439e2d8e184663d7d50166fd3008f0e9253272f898d81007988435f715881\",\n    \"0xb1f34b14612c973a3eceb716dc102b82ab18afef9de7630172c2780776679a7706a4874e1df3eaadf541fb009731807f\",\n    \"0xb25464af9cff883b55be2ff8daf610052c02df9a5e147a2cf4df6ce63edcdee6dc535c533590084cc177da85c5dc0baa\",\n    \"0x91c3c4b658b42d8d3448ae1415d4541d02379a40dc51e36a59bd6e7b9ba3ea51533f480c7c6e8405250ee9b96a466c29\",\n    \"0x86dc027b95deb74c36a58a1333a03e63cb5ae22d3b29d114cfd2271badb05268c9d0c819a977f5e0c6014b00c1512e3a\",\n    \"0xae0e6ff58eb5fa35da5107ebeacf222ab8f52a22bb1e13504247c1dfa65320f40d97b0e6b201cb6613476687cb2f0681\",\n    \"0x8f13415d960b9d7a1d93ef28afc2223e926639b63bdefce0f85e945dfc81670a55df288893a0d8b3abe13c5708f82f91\",\n    \"0x956f67ca49ad27c1e3a68c1faad5e7baf0160c459094bf6b7baf36b112de935fdfd79fa4a9ea87ea8de0ac07272969f4\",\n    \"0x835e45e4a67df9fb51b645d37840b3a15c171d571a10b03a406dd69d3c2f22df3aa9c5cbe1e73f8d767ce01c4914ea9a\",\n    \"0x919b938e56d4b32e2667469d0bdccb95d9dda3341aa907683ee70a14bbbe623035014511c261f4f59b318b610ac90aa3\",\n    \"0x96b48182121ccd9d689bf1dfdc228175564cd68dc904a99c808a7f0053a6f636c9d953e12198bdf2ea49ea92772f2e18\",\n    \"0xac5e5a941d567fa38fdbcfa8cf7f85bb304e3401c52d88752bcd516d1fa9bac4572534ea2205e38423c1df065990790f\",\n    \"0xac0bd594fb85a8d4fc26d6df0fa81f11919401f1ecf9168b891ec7f061a2d9368af99f7fd8d9b43b2ce361e7b8482159\",\n    \"0x83d92c69ca540d298fe80d8162a1c7af3fa9b49dfb69e85c1d136a3ec39fe419c9fa78e0bb6d96878771fbd37fe92e40\",\n    \"0xb35443ae8aa66c763c2db9273f908552fe458e96696b90e41dd509c17a5c04ee178e3490d9c6ba2dc0b8f793c433c134\",\n    \"0x923b2d25aa45b2e580ffd94cbb37dc8110f340f0f011217ee1bd81afb0714c0b1d5fb4db86006cdd2457563276f59c59\",\n    \"0x96c9125d38fca1a61ac21257b696f8ac3dae78def50285e44d90ea293d591d1c58f703540a7e4e99e070afe4646bbe15\",\n    \"0xb57946b2332077fbcdcb406b811779aefd54473b5559a163cd65cb8310679b7e2028aa55c12a1401fdcfcac0e6fae29a\",\n    \"0x845daedc5cf972883835d7e13c937b63753c2200324a3b8082a6c4abb4be06c5f7c629d4abe4bfaf1d80a1f073eb6ce6\",\n    \"0x91a55dfd0efefcd03dc6dacc64ec93b8d296cb83c0ee72400a36f27246e7f2a60e73b7b70ba65819e9cfb73edb7bd297\",\n    \"0x8874606b93266455fe8fdd25df9f8d2994e927460af06f2e97dd4d2d90db1e6b06d441b72c2e76504d753badca87fb37\",\n    \"0x8ee99e6d231274ff9252c0f4e84549da173041299ad1230929c3e3d32399731c4f20a502b4a307642cac9306ccd49d3c\",\n    \"0x8836497714a525118e20849d6933bb8535fb6f72b96337d49e3133d936999c90a398a740f42e772353b5f1c63581df6d\",\n    \"0xa6916945e10628f7497a6cdc5e2de113d25f7ade3e41e74d3de48ccd4fce9f2fa9ab69645275002e6f49399b798c40af\",\n    \"0x9597706983107eb23883e0812e1a2c58af7f3499d50c6e29b455946cb9812fde1aa323d9ed30d1c0ffd455abe32303cd\",\n    \"0xa24ee89f7f515cc33bdbdb822e7d5c1877d337f3b2162303cfc2dae028011c3a267c5cb4194afa63a4856a6e1c213448\",\n    \"0x8cd25315e4318801c2776824ae6e7d543cb85ed3bc2498ba5752df2e8142b37653cf9e60104d674be3aeb0a66912e97a\",\n    \"0xb5085ecbe793180b40dbeb879f4c976eaaccaca3a5246807dced5890e0ed24d35f3f86955e2460e14fb44ff5081c07ba\",\n    \"0x960188cc0b4f908633a6840963a6fa2205fc42c511c6c309685234911c5304ef4c304e3ae9c9c69daa2fb6a73560c256\",\n    \"0xa32d0a70bf15d569b4cda5aebe3e41e03c28bf99cdd34ffa6c5d58a097f322772acca904b3a47addb6c7492a7126ebac\",\n    \"0x977f72d06ad72d4aa4765e0f1f9f4a3231d9f030501f320fe7714cc5d329d08112789fa918c60dd7fdb5837d56bb7fc6\",\n    \"0x99fa038bb0470d45852bb871620d8d88520adb701712fcb1f278fed2882722b9e729e6cdce44c82caafad95e37d0e6f7\",\n    \"0xb855e8f4fc7634ada07e83b6c719a1e37acb06394bc8c7dcab7747a8c54e5df3943915f021364bd019fdea103864e55f\",\n    \"0x88bc2cd7458532e98c596ef59ea2cf640d7cc31b4c33cef9ed065c078d1d4eb49677a67de8e6229cc17ea48bace8ee5a\",\n    \"0xaaa78a3feaa836d944d987d813f9b9741afb076e6aca1ffa42682ab06d46d66e0c07b8f40b9dbd63e75e81efa1ef7b08\",\n    \"0xb7b080420cc4d808723b98b2a5b7b59c81e624ab568ecdfdeb8bf3aa151a581b6f56e983ef1b6f909661e25db40b0c69\",\n    \"0xabee85c462ac9a2c58e54f06c91b3e5cd8c5f9ab5b5deb602b53763c54826ed6deb0d6db315a8d7ad88733407e8d35e2\",\n    \"0x994d075c1527407547590df53e9d72dd31f037c763848d1662eebd4cefec93a24328c986802efa80e038cb760a5300f5\",\n    \"0xab8777640116dfb6678e8c7d5b36d01265dfb16321abbfc277da71556a34bb3be04bc4ae90124ed9c55386d2bfb3bda0\",\n    \"0x967e3a828bc59409144463bcf883a3a276b5f24bf3cbfdd7a42343348cba91e00b46ac285835a9b91eef171202974204\",\n    \"0x875a9f0c4ffe5bb1d8da5e3c8e41d0397aa6248422a628bd60bfae536a651417d4e8a7d2fb98e13f2dad3680f7bd86d3\",\n    \"0xacaa330c3e8f95d46b1880126572b238dbb6d04484d2cd4f257ab9642d8c9fc7b212188b9c7ac9e0fd135c520d46b1bf\",\n    \"0xaceb762edbb0f0c43dfcdb01ea7a1ac5918ca3882b1e7ebc4373521742f1ed5250d8966b498c00b2b0f4d13212e6dd0b\",\n    \"0x81d072b4ad258b3646f52f399bced97c613b22e7ad76373453d80b1650c0ca87edb291a041f8253b649b6e5429bb4cff\",\n    \"0x980a47d27416ac39c7c3a0ebe50c492f8c776ea1de44d5159ac7d889b6d554357f0a77f0e5d9d0ff41aae4369eba1fc2\",\n    \"0x8b4dfd5ef5573db1476d5e43aacfb5941e45d6297794508f29c454fe50ea622e6f068b28b3debe8635cf6036007de2e3\",\n    \"0xa60831559d6305839515b68f8c3bc7abbd8212cc4083502e19dd682d56ca37c9780fc3ce4ec2eae81ab23b221452dc57\",\n    \"0x951f6b2c1848ced9e8a2339c65918e00d3d22d3e59a0a660b1eca667d18f8430d737884e9805865ef3ed0fe1638a22d9\",\n    \"0xb02e38fe790b492aa5e89257c4986c9033a8b67010fa2add9787de857d53759170fdd67715ca658220b4e14b0ca48124\",\n    \"0xa51007e4346060746e6b0e4797fc08ef17f04a34fe24f307f6b6817edbb8ce2b176f40771d4ae8a60d6152cbebe62653\",\n    \"0xa510005b05c0b305075b27b243c9d64bcdce85146b6ed0e75a3178b5ff9608213f08c8c9246f2ca6035a0c3e31619860\",\n    \"0xaaff4ef27a7a23be3419d22197e13676d6e3810ceb06a9e920d38125745dc68a930f1741c9c2d9d5c875968e30f34ab5\",\n    \"0x864522a9af9857de9814e61383bebad1ba9a881696925a0ea6bfc6eff520d42c506bbe5685a9946ed710e889765be4a0\",\n    \"0xb63258c080d13f3b7d5b9f3ca9929f8982a6960bdb1b0f8676f4dca823971601672f15e653917bf5d3746bb220504913\",\n    \"0xb51ce0cb10869121ae310c7159ee1f3e3a9f8ad498827f72c3d56864808c1f21fa2881788f19ece884d3f705cd7bd0c5\",\n    \"0x95d9cecfc018c6ed510e441cf84c712d9909c778c16734706c93222257f64dcd2a9f1bd0b400ca271e22c9c487014274\",\n    \"0x8beff4d7d0140b86380ff4842a9bda94c2d2be638e20ac68a4912cb47dbe01a261857536375208040c0554929ced1ddc\",\n    \"0x891ff49258749e2b57c1e9b8e04b12c77d79c3308b1fb615a081f2aacdfb4b39e32d53e069ed136fdbd43c53b87418fa\",\n    \"0x9625cad224e163d387738825982d1e40eeff35fe816d10d7541d15fdc4d3eee48009090f3faef4024b249205b0b28f72\",\n    \"0x8f3947433d9bd01aa335895484b540a9025a19481a1c40b4f72dd676bfcf332713714fd4010bde936eaf9470fd239ed0\",\n    \"0xa00ec2d67789a7054b53f0e858a8a232706ccc29a9f3e389df7455f1a51a2e75801fd78469a13dbc25d28399ae4c6182\",\n    \"0xa3f65884506d4a62b8775a0ea0e3d78f5f46bc07910a93cd604022154eabdf1d73591e304d61edc869e91462951975e1\",\n    \"0xa14eef4fd5dfac311713f0faa9a60415e3d30b95a4590cbf95f2033dffb4d16c02e7ceff3dcd42148a4e3bc49cce2dd4\",\n    \"0x8afa11c0eef3c540e1e3460bc759bb2b6ea90743623f88e62950c94e370fe4fd01c22b6729beba4dcd4d581198d9358f\",\n    \"0xafb05548a69f0845ffcc5f5dc63e3cdb93cd270f5655173b9a950394b0583663f2b7164ba6df8d60c2e775c1d9f120af\",\n    \"0x97f179e01a947a906e1cbeafa083960bc9f1bade45742a3afee488dfb6011c1c6e2db09a355d77f5228a42ccaa7bdf8e\",\n    \"0x8447fca4d35f74b3efcbd96774f41874ca376bf85b79b6e66c92fa3f14bdd6e743a051f12a7fbfd87f319d1c6a5ce217\",\n    \"0xa57ca39c23617cd2cf32ff93b02161bd7baf52c4effb4679d9d5166406e103bc8f3c6b5209e17c37dbb02deb8bc72ddd\",\n    \"0x9667c7300ff80f0140be002b0e36caab07aaee7cce72679197c64d355e20d96196acaf54e06e1382167d081fe6f739c1\",\n    \"0x828126bb0559ce748809b622677267ca896fa2ee76360fd2c02990e6477e06a667241379ca7e65d61a5b64b96d7867de\",\n    \"0x8b8835dea6ba8cf61c91f01a4b3d2f8150b687a4ee09b45f2e5fc8f80f208ae5d142d8e3a18153f0722b90214e60c5a7\",\n    \"0xa98e8ff02049b4da386e3ee93db23bbb13dfeb72f1cfde72587c7e6d962780b7671c63e8ac3fbaeb1a6605e8d79e2f29\",\n    \"0x87a4892a0026d7e39ef3af632172b88337cb03669dea564bcdb70653b52d744730ebb5d642e20cb627acc9dbb547a26b\",\n    \"0x877352a22fc8052878a57effc159dac4d75fe08c84d3d5324c0bab6d564cdf868f33ceee515eee747e5856b62cfa0cc7\",\n    \"0x8b801ba8e2ff019ee62f64b8cb8a5f601fc35423eb0f9494b401050103e1307dc584e4e4b21249cd2c686e32475e96c3\",\n    \"0xa9e7338d6d4d9bfec91b2af28a8ed13b09415f57a3a00e5e777c93d768fdb3f8e4456ae48a2c6626b264226e911a0e28\",\n    \"0x99c05fedf40ac4726ed585d7c1544c6e79619a0d3fb6bda75a08c7f3c0008e8d5e19ed4da48de3216135f34a15eba17c\",\n    \"0xa61cce8a1a8b13a4a650fdbec0eeea8297c352a8238fb7cac95a0df18ed16ee02a3daa2de108fa122aca733bd8ad7855\",\n    \"0xb97f37da9005b440b4cb05870dd881bf8491fe735844f2d5c8281818583b38e02286e653d9f2e7fa5e74c3c3eb616540\",\n    \"0xa72164a8554da8e103f692ac5ebb4aece55d5194302b9f74b6f2a05335b6e39beede0bf7bf8c5bfd4d324a784c5fb08c\",\n    \"0xb87e8221c5341cd9cc8bb99c10fe730bc105550f25ed4b96c0d45e6142193a1b2e72f1b3857373a659b8c09be17b3d91\",\n    \"0xa41fb1f327ef91dcb7ac0787918376584890dd9a9675c297c45796e32d6e5985b12f9b80be47fc3a8596c245f419d395\",\n    \"0x90dafa3592bdbb3465c92e2a54c2531822ba0459d45d3e7a7092fa6b823f55af28357cb51896d4ec2d66029c82f08e26\",\n    \"0xa0a9adc872ebc396557f484f1dd21954d4f4a21c4aa5eec543f5fa386fe590839735c01f236574f7ff95407cd12de103\",\n    \"0xb8c5c940d58be7538acf8672852b5da3af34f82405ef2ce8e4c923f1362f97fc50921568d0fd2fe846edfb0823e62979\",\n    \"0x85aaf06a8b2d0dac89dafd00c28533f35dbd074978c2aaa5bef75db44a7b12aeb222e724f395513b9a535809a275e30b\",\n    \"0x81f3cbe82fbc7028c26a6c1808c604c63ba023a30c9f78a4c581340008dbda5ec07497ee849a2183fcd9124f7936af32\",\n    \"0xa11ac738de75fd60f15a34209d3825d5e23385796a4c7fc5931822f3f380af977dd0f7b59fbd58eed7777a071e21b680\",\n    \"0x85a279c493de03db6fa6c3e3c1b1b29adc9a8c4effc12400ae1128da8421954fa8b75ad19e5388fe4543b76fb0812813\",\n    \"0x83a217b395d59ab20db6c4adb1e9713fc9267f5f31a6c936042fe051ce8b541f579442f3dcf0fa16b9e6de9fd3518191\",\n    \"0x83a0b86e7d4ed8f9ccdc6dfc8ff1484509a6378fa6f09ed908e6ab9d1073f03011dc497e14304e4e3d181b57de06a5ab\",\n    \"0xa63ad69c9d25704ce1cc8e74f67818e5ed985f8f851afa8412248b2df5f833f83b95b27180e9e7273833ed0d07113d3b\",\n    \"0x99b1bc2021e63b561fe44ddd0af81fcc8627a91bfeecbbc989b642bc859abc0c8d636399701aad7bbaf6a385d5f27d61\",\n    \"0xb53434adb66f4a807a6ad917c6e856321753e559b1add70824e5c1e88191bf6993fccb9b8b911fc0f473fb11743acacd\",\n    \"0x97ed3b9e6fb99bf5f945d4a41f198161294866aa23f2327818cdd55cb5dc4c1a8eff29dd8b8d04902d6cd43a71835c82\",\n    \"0xb1e808260e368a18d9d10bdea5d60223ba1713b948c782285a27a99ae50cc5fc2c53d407de07155ecc16fb8a36d744a0\",\n    \"0xa3eb4665f18f71833fec43802730e56b3ee5a357ea30a888ad482725b169d6f1f6ade6e208ee081b2e2633079b82ba7d\",\n    \"0xab8beb2c8353fc9f571c18fdd02bdb977fc883313469e1277b0372fbbb33b80dcff354ca41de436d98d2ed710faa467e\",\n    \"0xaa9071cfa971e4a335a91ad634c98f2be51544cb21f040f2471d01bb97e1df2277ae1646e1ea8f55b7ba9f5c8c599b39\",\n    \"0x80b7dbfdcaf40f0678012acc634eba44ea51181475180d9deb2050dc4f2de395289edd0223018c81057ec79b04b04c49\",\n    \"0x89623d7f6cb17aa877af14de842c2d4ab7fd576d61ddd7518b5878620a01ded40b6010de0da3cdf31d837eecf30e9847\",\n    \"0xa773bb024ae74dd24761f266d4fb27d6fd366a8634febe8235376b1ae9065c2fe12c769f1d0407867dfbe9f5272c352f\",\n    \"0x8455a561c3aaa6ba64c881a5e13921c592b3a02e968f4fb24a2243c36202795d0366d9cc1a24e916f84d6e158b7aeac7\",\n    \"0x81d8bfc4b283cf702a40b87a2b96b275bdbf0def17e67d04842598610b67ea08c804d400c3e69fa09ea001eaf345b276\",\n    \"0xb8f8f82cb11fea1c99467013d7e167ff03deb0c65a677fab76ded58826d1ba29aa7cf9fcd7763615735ea3ad38e28719\",\n    \"0x89a6a04baf9cccc1db55179e1650b1a195dd91fb0aebc197a25143f0f393524d2589975e3fbfc2547126f0bced7fd6f2\",\n    \"0xb81b2162df045390f04df07cbd0962e6b6ca94275a63edded58001a2f28b2ae2af2c7a6cba4ecd753869684e77e7e799\",\n    \"0xa3757f722776e50de45c62d9c4a2ee0f5655a512344c4cbec542d8045332806568dd626a719ef21a4eb06792ca70f204\",\n    \"0x8c5590df96ec22179a4e8786de41beb44f987a1dcc508eb341eecbc0b39236fdfad47f108f852e87179ccf4e10091e59\",\n    \"0x87502f026ed4e10167419130b88c3737635c5b9074c364e1dd247cef5ef0fc064b4ae99b187e33301e438bbd2fe7d032\",\n    \"0xaf925a2165e980ced620ff12289129fe17670a90ae0f4db9d4b39bd887ccb1f5d2514ac9ecf910f6390a8fc66bd5be17\",\n    \"0x857fca899828cf5c65d26e3e8a6e658542782fc72762b3b9c73514919f83259e0f849a9d4838b40dc905fe43024d0d23\",\n    \"0x87ffebdbfb69a9e1007ebac4ffcb4090ff13705967b73937063719aa97908986effcb7262fdadc1ae0f95c3690e3245d\",\n    \"0xa9ff6c347ac6f4c6ab993b748802e96982eaf489dc69032269568412fc9a79e7c2850dfc991b28211b3522ee4454344b\",\n    \"0xa65b3159df4ec48bebb67cb3663cd744027ad98d970d620e05bf6c48f230fa45bf17527fe726fdf705419bb7a1bb913e\",\n    \"0x84b97b1e6408b6791831997b03cd91f027e7660fd492a93d95daafe61f02427371c0e237c75706412f442991dfdff989\",\n    \"0xab761c26527439b209af0ae6afccd9340bbed5fbe098734c3145b76c5d2cd7115d9227b2eb523882b7317fbb09180498\",\n    \"0xa0479a8da06d7a69c0b0fee60df4e691c19c551f5e7da286dab430bfbcabf31726508e20d26ea48c53365a7f00a3ad34\",\n    \"0xa732dfc9baa0f4f40b5756d2e8d8937742999623477458e0bc81431a7b633eefc6f53b3b7939fe0a020018549c954054\",\n    \"0x901502436a1169ba51dc479a5abe7c8d84e0943b16bc3c6a627b49b92cd46263c0005bc324c67509edd693f28e612af1\",\n    \"0xb627aee83474e7f84d1bab9b7f6b605e33b26297ac6bbf52d110d38ba10749032bd551641e73a383a303882367af429b\",\n    \"0x95108866745760baef4a46ef56f82da6de7e81c58b10126ebd2ba2cd13d339f91303bf2fb4dd104a6956aa3b13739503\",\n    \"0x899ed2ade37236cec90056f3569bc50f984f2247792defafcceb49ad0ca5f6f8a2f06573705300e07f0de0c759289ff5\",\n    \"0xa9f5eee196d608efe4bcef9bf71c646d27feb615e21252cf839a44a49fd89da8d26a758419e0085a05b1d59600e2dc42\",\n    \"0xb36c6f68fed6e6c85f1f4a162485f24817f2843ec5cbee45a1ebfa367d44892e464949c6669f7972dc7167af08d55d25\",\n    \"0xaaaede243a9a1b6162afbc8f571a52671a5a4519b4062e3f26777664e245ba873ed13b0492c5dbf0258c788c397a0e9e\",\n    \"0x972b4fb39c31cbe127bf9a32a5cc10d621ebdd9411df5e5da3d457f03b2ab2cd1f6372d8284a4a9400f0b06ecdbfd38e\",\n    \"0x8f6ca1e110e959a4b1d9a5ce5f212893cec21db40d64d5ac4d524f352d72198f923416a850bf845bc5a22a79c0ea2619\",\n    \"0xa0f3c93b22134f66f04b2553a53b738644d1665ceb196b8494b315a4c28236fb492017e4a0de4224827c78e42f9908b7\",\n    \"0x807fb5ee74f6c8735b0b5ca07e28506214fe4047dbeb00045d7c24f7849e98706aea79771241224939cb749cf1366c7d\",\n    \"0x915eb1ff034224c0b645442cdb7d669303fdc00ca464f91aaf0b6fde0b220a3a74ff0cb043c26c9f3a5667b3fdaa9420\",\n    \"0x8fda6cef56ed33fefffa9e6ac8e6f76b1af379f89761945c63dd448801f7bb8ca970504a7105fac2f74f652ccff32327\",\n    \"0x87380cffdcffb1d0820fa36b63cc081e72187f86d487315177d4d04da4533eb19a0e2ff6115ceab528887819c44a5164\",\n    \"0x8cd89e03411a18e7f16f968b89fb500c36d47d229f6487b99e62403a980058db5925ce249206743333538adfad168330\",\n    \"0x974451b1df33522ce7056de9f03e10c70bf302c44b0741a59df3d6877d53d61a7394dcee1dd46e013d7cb9d73419c092\",\n    \"0x98c35ddf645940260c490f384a49496a7352bb8e3f686feed815b1d38f59ded17b1ad6e84a209e773ed08f7b8ff1e4c2\",\n    \"0x963f386cf944bb9b2ddebb97171b64253ea0a2894ac40049bdd86cda392292315f3a3d490ca5d9628c890cfb669f0acb\",\n    \"0x8d507712152babd6d142ee682638da8495a6f3838136088df9424ef50d5ec28d815a198c9a4963610b22e49b4cdf95e9\",\n    \"0x83d4bc6b0be87c8a4f1e9c53f257719de0c73d85b490a41f7420e777311640937320557ff2f1d9bafd1daaa54f932356\",\n    \"0x82f5381c965b7a0718441131c4d13999f4cdce637698989a17ed97c8ea2e5bdb5d07719c5f7be8688edb081b23ede0f4\",\n    \"0xa6ebecab0b72a49dfd01d69fa37a7f74d34fb1d4fef0aa10e3d6fceb9eccd671225c230af89f6eb514250e41a5f91f52\",\n    \"0x846d185bdad6e11e604df7f753b7a08a28b643674221f0e750ebdb6b86ec584a29c869e131bca868972a507e61403f6a\",\n    \"0x85a98332292acb744bd1c0fd6fdcf1f889a78a2c9624d79413ffa194cc8dfa7821a4b60cde8081d4b5f71f51168dd67f\",\n    \"0x8f7d97c3b4597880d73200d074eb813d95432306e82dafc70b580b8e08cb8098b70f2d07b4b3ac6a4d77e92d57035031\",\n    \"0x8185439c8751e595825d7053518cbe121f191846a38d4dbcb558c3f9d7a3104f3153401adaaaf27843bbe2edb504bfe3\",\n    \"0xb3c00d8ece1518fca6b1215a139b0a0e26d9cba1b3a424f7ee59f30ce800a5db967279ed60958dd1f3ee69cf4dd1b204\",\n    \"0xa2e6cb6978e883f9719c3c0d44cfe8de0cc6f644b98f98858433bea8bbe7b612c8aca5952fccce4f195f9d54f9722dc2\",\n    \"0x99663087e3d5000abbec0fbda4e7342ec38846cc6a1505191fb3f1a337cb369455b7f8531a6eb8b0f7b2c4baf83cbe2b\",\n    \"0xab0836c6377a4dbc7ca6a4d6cf021d4cd60013877314dd05f351706b128d4af6337711ed3443cb6ca976f40d74070a9a\",\n    \"0x87abfd5126152fd3bac3c56230579b489436755ea89e0566aa349490b36a5d7b85028e9fb0710907042bcde6a6f5d7e3\",\n    \"0x974ba1033f75f60e0cf7c718a57ae1da3721cf9d0fb925714c46f027632bdd84cd9e6de4cf4d00bc55465b1c5ebb7384\",\n    \"0xa607b49d73689ac64f25cec71221d30d53e781e1100d19a2114a21da6507a60166166369d860bd314acb226596525670\",\n    \"0xa7c2b0b915d7beba94954f2aa7dd08ec075813661e2a3ecca5d28a0733e59583247fed9528eb28aba55b972cdbaf06eb\",\n    \"0xb8b3123e44128cc8efbe3270f2f94e50ca214a4294c71c3b851f8cbb70cb67fe9536cf07d04bf7fe380e5e3a29dd3c15\",\n    \"0xa59a07e343b62ad6445a0859a32b58c21a593f9ddbfe52049650f59628c93715aa1f4e1f45b109321756d0eeec8a5429\",\n    \"0x94f51f8a4ed18a6030d0aaa8899056744bd0e9dc9ac68f62b00355cddab11da5da16798db75f0bfbce0e5bdfe750c0b6\",\n    \"0x97460a97ca1e1fa5ce243b81425edc0ec19b7448e93f0b55bc9785eedeeafe194a3c8b33a61a5c72990edf375f122777\",\n    \"0x8fa859a089bc17d698a7ee381f37ce9beadf4e5b44fce5f6f29762bc04f96faff5d58c48c73631290325f05e9a1ecf49\",\n    \"0xabdf38f3b20fc95eff31de5aa9ef1031abfa48f1305ee57e4d507594570401503476d3bcc493838fc24d6967a3082c7f\",\n    \"0xb8914bfb82815abb86da35c64d39ab838581bc0bf08967192697d9663877825f2b9d6fbdcf9b410463482b3731361aef\",\n    \"0xa8187f9d22b193a5f578999954d6ec9aa9b32338ccadb8a3e1ce5bad5ea361d69016e1cdfac44e9d6c54e49dd88561b9\",\n    \"0xaac262cb7cba7fd62c14daa7b39677cabc1ef0947dd06dd89cac8570006a200f90d5f0353e84f5ff03179e3bebe14231\",\n    \"0xa630ef5ece9733b8c46c0a2df14a0f37647a85e69c63148e79ffdcc145707053f9f9d305c3f1cf3c7915cb46d33abd07\",\n    \"0xb102c237cb2e254588b6d53350dfda6901bd99493a3fbddb4121d45e0b475cf2663a40d7b9a75325eda83e4ba1e68cb3\",\n    \"0x86a930dd1ddcc16d1dfa00aa292cb6c2607d42c367e470aa920964b7c17ab6232a7108d1c2c11fc40fb7496547d0bbf8\",\n    \"0xa832fdc4500683e72a96cce61e62ac9ee812c37fe03527ad4cf893915ca1962cee80e72d4f82b20c8fc0b764376635a1\",\n    \"0x88ad985f448dabb04f8808efd90f273f11f5e6d0468b5489a1a6a3d77de342992a73eb842d419034968d733f101ff683\",\n    \"0x98a8538145f0d86f7fbf9a81c9140f6095c5bdd8960b1c6f3a1716428cd9cca1bf8322e6d0af24e6169abcf7df2b0ff6\",\n    \"0x9048c6eba5e062519011e177e955a200b2c00b3a0b8615bdecdebc217559d41058d3315f6d05617be531ef0f6aef0e51\",\n    \"0x833bf225ab6fc68cdcacf1ec1b50f9d05f5410e6cdcd8d56a3081dc2be8a8d07b81534d1ec93a25c2e270313dfb99e3b\",\n    \"0xa84bcd24c3da5e537e64a811b93c91bfc84d7729b9ead7f79078989a6eb76717d620c1fad17466a0519208651e92f5ff\",\n    \"0xb7cdd0a3fbd79aed93e1b5a44ca44a94e7af5ed911e4492f332e3a5ed146c7286bde01b52276a2fcc02780d2109874dd\",\n    \"0x8a19a09854e627cb95750d83c20c67442b66b35896a476358f993ba9ac114d32c59c1b3d0b8787ee3224cf3888b56c64\",\n    \"0xa9abd5afb8659ee52ada8fa5d57e7dd355f0a7350276f6160bec5fbf70d5f99234dd179eb221c913e22a49ec6d267846\",\n    \"0x8c13c4274c0d30d184e73eaf812200094bbbd57293780bdadbceb262e34dee5b453991e7f37c7333a654fc71c69d6445\",\n    \"0xa4320d73296ff8176ce0127ca1921c450e2a9c06eff936681ebaffb5a0b05b17fded24e548454de89aca2dcf6d7a9de4\",\n    \"0xb2b8b3e15c1f645f07783e5628aba614e60157889db41d8161d977606788842b67f83f361eae91815dc0abd84e09abd5\",\n    \"0xad26c3aa35ddfddc15719b8bb6c264aaec7065e88ac29ba820eb61f220fef451609a7bb037f3722d022e6c86e4f1dc88\",\n    \"0xb8615bf43e13ae5d7b8dd903ce37190800cd490f441c09b22aa29d7a29ed2c0417b7a08ead417868f1de2589deaadd80\",\n    \"0x8d3425e1482cd1e76750a76239d33c06b3554c3c3c87c15cb7ab58b1cee86a4c5c4178b44e23f36928365a1b484bde02\",\n    \"0x806893a62e38c941a7dd6f249c83af16596f69877cc737d8f73f6b8cd93cbc01177a7a276b2b8c6b0e5f2ad864db5994\",\n    \"0x86618f17fa4b0d65496b661bbb5ba3bc3a87129d30a4b7d4f515b904f4206ca5253a41f49fd52095861e5e065ec54f21\",\n    \"0x9551915da1304051e55717f4c31db761dcdcf3a1366c89a4af800a9e99aca93a357bf928307f098e62b44a02cb689a46\",\n    \"0x8f79c4ec0ec1146cb2a523b52fe33def90d7b5652a0cb9c2d1c8808a32293e00aec6969f5b1538e3a94cd1efa3937f86\",\n    \"0xa0c03e329a707300081780f1e310671315b4c6a4cedcb29697aedfabb07a9d5df83f27b20e9c44cf6b16e39d9ded5b98\",\n    \"0x86a7cfa7c8e7ce2c01dd0baec2139e97e8e090ad4e7b5f51518f83d564765003c65968f85481bbb97cb18f005ccc7d9f\",\n    \"0xa33811770c6dfda3f7f74e6ad0107a187fe622d61b444bbd84fd7ef6e03302e693b093df76f6ab39bb4e02afd84a575a\",\n    \"0x85480f5c10d4162a8e6702b5e04f801874d572a62a130be94b0c02b58c3c59bdcd48cd05f0a1c2839f88f06b6e3cd337\",\n    \"0x8e181011564b17f7d787fe0e7f3c87f6b62da9083c54c74fd6c357a1f464c123c1d3d8ade3cf72475000b464b14e2be3\",\n    \"0x8ee178937294b8c991337e0621ab37e9ffa4ca2bdb3284065c5e9c08aad6785d50cf156270ff9daf9a9127289710f55b\",\n    \"0x8bd1e8e2d37379d4b172f1aec96f2e41a6e1393158d7a3dbd9a95c8dd4f8e0b05336a42efc11a732e5f22b47fc5c271d\",\n    \"0x8f3da353cd487c13136a85677de8cedf306faae0edec733cf4f0046f82fa4639db4745b0095ff33a9766aba50de0cbcf\",\n    \"0x8d187c1e97638df0e4792b78e8c23967dac43d98ea268ca4aabea4e0fa06cb93183fd92d4c9df74118d7cc27bf54415e\",\n    \"0xa4c992f08c2f8bac0b74b3702fb0c75c9838d2ce90b28812019553d47613c14d8ce514d15443159d700b218c5a312c49\",\n    \"0xa6fd1874034a34c3ea962a316c018d9493d2b3719bb0ec4edbc7c56b240802b2228ab49bee6f04c8a3e9f6f24a48c1c2\",\n    \"0xb2efed8e799f8a15999020900dc2c58ece5a3641c90811b86a5198e593d7318b9d53b167818ccdfbe7df2414c9c34011\",\n    \"0x995ff7de6181ddf95e3ead746089c6148da3508e4e7a2323c81785718b754d356789b902e7e78e2edc6b0cbd4ff22c78\",\n    \"0x944073d24750a9068cbd020b834afc72d2dde87efac04482b3287b40678ad07588519a4176b10f2172a2c463d063a5cd\",\n    \"0x99db4b1bb76475a6fd75289986ef40367960279524378cc917525fb6ba02a145a218c1e9caeb99332332ab486a125ac0\",\n    \"0x89fce4ecd420f8e477af4353b16faabb39e063f3f3c98fde2858b1f2d1ef6eed46f0975a7c08f233b97899bf60ccd60a\",\n    \"0x8c09a4f07a02b80654798bc63aada39fd638d3e3c4236ccd8a5ca280350c31e4a89e5f4c9aafb34116e71da18c1226b8\",\n    \"0x85325cfa7ded346cc51a2894257eab56e7488dbff504f10f99f4cd2b630d913003761a50f175ed167e8073f1b6b63fb0\",\n    \"0xb678b4fbec09a8cc794dcbca185f133578f29e354e99c05f6d07ac323be20aecb11f781d12898168e86f2e0f09aca15e\",\n    \"0xa249cfcbca4d9ba0a13b5f6aac72bf9b899adf582f9746bb2ad043742b28915607467eb794fca3704278f9136f7642be\",\n    \"0x9438e036c836a990c5e17af3d78367a75b23c37f807228362b4d13e3ddcb9e431348a7b552d09d11a2e9680704a4514f\",\n    \"0x925ab70450af28c21a488bfb5d38ac994f784cf249d7fd9ad251bb7fd897a23e23d2528308c03415074d43330dc37ef4\",\n    \"0xa290563904d5a8c0058fc8330120365bdd2ba1fdbaef7a14bc65d4961bb4217acfaed11ab82669e359531f8bf589b8db\",\n    \"0xa7e07a7801b871fc9b981a71e195a3b4ba6b6313bc132b04796a125157e78fe5c11a3a46cf731a255ac2d78a4ae78cd0\",\n    \"0xb26cd2501ee72718b0eebab6fb24d955a71f363f36e0f6dff0ab1d2d7836dab88474c0cef43a2cc32701fca7e82f7df3\",\n    \"0xa1dc3b6c968f3de00f11275092290afab65b2200afbcfa8ddc70e751fa19dbbc300445d6d479a81bda3880729007e496\",\n    \"0xa9bc213e28b630889476a095947d323b9ac6461dea726f2dc9084473ae8e196d66fb792a21905ad4ec52a6d757863e7d\",\n    \"0xb25d178df8c2df8051e7c888e9fa677fde5922e602a95e966db9e4a3d6b23ce043d7dc48a5b375c6b7c78e966893e8c3\",\n    \"0xa1c8d88d72303692eaa7adf68ea41de4febec40cc14ae551bb4012afd786d7b6444a3196b5d9d5040655a3366d96b7cd\",\n    \"0xb22bd44f9235a47118a9bbe2ba5a2ba9ec62476061be2e8e57806c1a17a02f9a51403e849e2e589520b759abd0117683\",\n    \"0xb8add766050c0d69fe81d8d9ea73e1ed05f0135d093ff01debd7247e42dbb86ad950aceb3b50b9af6cdc14ab443b238f\",\n    \"0xaf2cf95f30ef478f018cf81d70d47d742120b09193d8bb77f0d41a5d2e1a80bfb467793d9e2471b4e0ad0cb2c3b42271\",\n    \"0x8af5ef2107ad284e246bb56e20fef2a255954f72de791cbdfd3be09f825298d8466064f3c98a50496c7277af32b5c0bc\",\n    \"0x85dc19558572844c2849e729395a0c125096476388bd1b14fa7f54a7c38008fc93e578da3aac6a52ff1504d6ca82db05\",\n    \"0xae8c9b43c49572e2e166d704caf5b4b621a3b47827bb2a3bcd71cdc599bba90396fd9a405261b13e831bb5d44c0827d7\",\n    \"0xa7ba7efede25f02e88f6f4cbf70643e76784a03d97e0fbd5d9437c2485283ad7ca3abb638a5f826cd9f6193e5dec0b6c\",\n    \"0x94a9d122f2f06ef709fd8016fd4b712d88052245a65a301f5f177ce22992f74ad05552b1f1af4e70d1eac62cef309752\",\n    \"0x82d999b3e7cf563833b8bc028ff63a6b26eb357dfdb3fd5f10e33a1f80a9b2cfa7814d871b32a7ebfbaa09e753e37c02\",\n    \"0xaec6edcde234df502a3268dd2c26f4a36a2e0db730afa83173f9c78fcb2b2f75510a02b80194327b792811caefda2725\",\n    \"0x94c0bfa66c9f91d462e9194144fdd12d96f9bbe745737e73bab8130607ee6ea9d740e2cfcbbd00a195746edb6369ee61\",\n    \"0xab7573dab8c9d46d339e3f491cb2826cabe8b49f85f1ede78d845fc3995537d1b4ab85140b7d0238d9c24daf0e5e2a7e\",\n    \"0x87e8b16832843251fe952dadfd01d41890ed4bb4b8fa0254550d92c8cced44368225eca83a6c3ad47a7f81ff8a80c984\",\n    \"0x9189d2d9a7c64791b19c0773ad4f0564ce6bea94aa275a917f78ad987f150fdb3e5e26e7fef9982ac184897ecc04683f\",\n    \"0xb3661bf19e2da41415396ae4dd051a9272e8a2580b06f1a1118f57b901fa237616a9f8075af1129af4eabfefedbe2f1c\",\n    \"0xaf43c86661fb15daf5d910a4e06837225e100fb5680bd3e4b10f79a2144c6ec48b1f8d6e6b98e067d36609a5d038889a\",\n    \"0x82ac0c7acaa83ddc86c5b4249aae12f28155989c7c6b91e5137a4ce05113c6cbc16f6c44948b0efd8665362d3162f16a\",\n    \"0x8f268d1195ab465beeeb112cd7ffd5d5548559a8bc01261106d3555533fc1971081b25558d884d552df0db1cddda89d8\",\n    \"0x8ef7caa5521f3e037586ce8ac872a4182ee20c7921c0065ed9986c047e3dda08294da1165f385d008b40d500f07d895f\",\n    \"0x8c2f98f6880550573fad46075d3eba26634b5b025ce25a0b4d6e0193352c8a1f0661064027a70fe8190b522405f9f4e3\",\n    \"0xb7653f353564feb164f0f89ec7949da475b8dad4a4d396d252fc2a884f6932d027b7eb2dc4d280702c74569319ed701a\",\n    \"0xa026904f4066333befd9b87a8fad791d014096af60cdd668ef919c24dbe295ff31f7a790e1e721ba40cf5105abca67f4\",\n    \"0x988f982004ada07a22dd345f2412a228d7a96b9cae2c487de42e392afe1e35c2655f829ce07a14629148ce7079a1f142\",\n    \"0x9616add009067ed135295fb74d5b223b006b312bf14663e547a0d306694ff3a8a7bb9cfc466986707192a26c0bce599f\",\n    \"0xad4c425de9855f6968a17ee9ae5b15e0a5b596411388cf976df62ecc6c847a6e2ddb2cea792a5f6e9113c2445dba3e5c\",\n    \"0xb698ac9d86afa3dc69ff8375061f88e3b0cff92ff6dfe747cebaf142e813c011851e7a2830c10993b715e7fd594604a9\",\n    \"0xa386fa189847bb3b798efca917461e38ead61a08b101948def0f82cd258b945ed4d45b53774b400af500670149e601b7\",\n    \"0x905c95abda2c68a6559d8a39b6db081c68cef1e1b4be63498004e1b2f408409be9350b5b5d86a30fd443e2b3e445640a\",\n    \"0x9116dade969e7ce8954afcdd43e5cab64dc15f6c1b8da9d2d69de3f02ba79e6c4f6c7f54d6bf586d30256ae405cd1e41\",\n    \"0xa3084d173eacd08c9b5084a196719b57e47a0179826fda73466758235d7ecdb87cbcf097bd6b510517d163a85a7c7edd\",\n    \"0x85bb00415ad3c9be99ff9ba83672cc59fdd24356b661ab93713a3c8eab34e125d8867f628a3c3891b8dc056e69cd0e83\",\n    \"0x8d58541f9f39ed2ee4478acce5d58d124031338ec11b0d55551f00a5a9a6351faa903a5d7c132dc5e4bb026e9cbd18e4\",\n    \"0xa622adf72dc250e54f672e14e128c700166168dbe0474cecb340da175346e89917c400677b1bc1c11fcc4cc26591d9db\",\n    \"0xb3f865014754b688ca8372e8448114fff87bf3ca99856ab9168894d0c4679782c1ced703f5b74e851b370630f5e6ee86\",\n    \"0xa7e490b2c40c2446fcd91861c020da9742c326a81180e38110558bb5d9f2341f1c1885e79b364e6419023d1cbdc47380\",\n    \"0xb3748d472b1062e54572badbb8e87ac36534407f74932e7fc5b8392d008e8e89758f1671d1e4d30ab0fa40551b13bb5e\",\n    \"0x89898a5c5ec4313aabc607b0049fd1ebad0e0c074920cf503c9275b564d91916c2c446d3096491c950b7af3ac5e4b0ed\",\n    \"0x8eb8c83fef2c9dd30ea44e286e9599ec5c20aba983f702e5438afe2e5b921884327ad8d1566c72395587efac79ca7d56\",\n    \"0xb92479599e806516ce21fb0bd422a1d1d925335ebe2b4a0a7e044dd275f30985a72b97292477053ac5f00e081430da80\",\n    \"0xa34ae450a324fe8a3c25a4d653a654f9580ed56bbea213b8096987bbad0f5701d809a17076435e18017fea4d69f414bc\",\n    \"0x81381afe6433d62faf62ea488f39675e0091835892ecc238e02acf1662669c6d3962a71a3db652f6fe3bc5f42a0e5dc5\",\n    \"0xa430d475bf8580c59111103316fe1aa79c523ea12f1d47a976bbfae76894717c20220e31cf259f08e84a693da6688d70\",\n    \"0xb842814c359754ece614deb7d184d679d05d16f18a14b288a401cef5dad2cf0d5ee90bad487b80923fc5573779d4e4e8\",\n    \"0x971d9a2627ff2a6d0dcf2af3d895dfbafca28b1c09610c466e4e2bff2746f8369de7f40d65b70aed135fe1d72564aa88\",\n    \"0x8f4ce1c59e22b1ce7a0664caaa7e53735b154cfba8d2c5cc4159f2385843de82ab58ed901be876c6f7fce69cb4130950\",\n    \"0x86cc9dc321b6264297987000d344fa297ef45bcc2a4df04e458fe2d907ad304c0ea2318e32c3179af639a9a56f3263cf\",\n    \"0x8229e0876dfe8f665c3fb19b250bd89d40f039bbf1b331468b403655be7be2e104c2fd07b9983580c742d5462ca39a43\",\n    \"0x99299d73066e8eb128f698e56a9f8506dfe4bd014931e86b6b487d6195d2198c6c5bf15cccb40ccf1f8ddb57e9da44a2\",\n    \"0xa3a3be37ac554c574b393b2f33d0a32a116c1a7cfeaf88c54299a4da2267149a5ecca71f94e6c0ef6e2f472b802f5189\",\n    \"0xa91700d1a00387502cdba98c90f75fbc4066fefe7cc221c8f0e660994c936badd7d2695893fde2260c8c11d5bdcdd951\",\n    \"0x8e03cae725b7f9562c5c5ab6361644b976a68bada3d7ca508abca8dfc80a469975689af1fba1abcf21bc2a190dab397d\",\n    \"0xb01461ad23b2a8fa8a6d241e1675855d23bc977dbf4714add8c4b4b7469ccf2375cec20e80cedfe49361d1a30414ac5b\",\n    \"0xa2673bf9bc621e3892c3d7dd4f1a9497f369add8cbaa3472409f4f86bd21ac67cfac357604828adfee6ada1835365029\",\n    \"0xa042dff4bf0dfc33c178ba1b335e798e6308915128de91b12e5dbbab7c4ac8d60a01f6aea028c3a6d87b9b01e4e74c01\",\n    \"0x86339e8a75293e4b3ae66b5630d375736b6e6b6b05c5cda5e73fbf7b2f2bd34c18a1d6cefede08625ce3046e77905cb8\",\n    \"0xaf2ebe1b7d073d03e3d98bc61af83bf26f7a8c130fd607aa92b75db22d14d016481b8aa231e2c9757695f55b7224a27f\",\n    \"0xa00ee882c9685e978041fd74a2c465f06e2a42ffd3db659053519925be5b454d6f401e3c12c746e49d910e4c5c9c5e8c\",\n    \"0x978a781c0e4e264e0dad57e438f1097d447d891a1e2aa0d5928f79a9d5c3faae6f258bc94fdc530b7b2fa6a9932bb193\",\n    \"0xaa4b7ce2e0c2c9e9655bf21e3e5651c8503bce27483017b0bf476be743ba06db10228b3a4c721219c0779747f11ca282\",\n    \"0xb003d1c459dacbcf1a715551311e45d7dbca83a185a65748ac74d1800bbeaba37765d9f5a1a221805c571910b34ebca8\",\n    \"0x95b6e531b38648049f0d19de09b881baa1f7ea3b2130816b006ad5703901a05da57467d1a3d9d2e7c73fb3f2e409363c\",\n    \"0xa6cf9c06593432d8eba23a4f131bb7f72b9bd51ab6b4b772a749fe03ed72b5ced835a349c6d9920dba2a39669cb7c684\",\n    \"0xaa3d59f6e2e96fbb66195bc58c8704e139fa76cd15e4d61035470bd6e305db9f98bcbf61ac1b95e95b69ba330454c1b3\",\n    \"0xb57f97959c208361de6d7e86dff2b873068adb0f158066e646f42ae90e650079798f165b5cd713141cd3a2a90a961d9a\",\n    \"0xa76ee8ed9052f6a7a8c69774bb2597be182942f08115baba03bf8faaeaee526feba86120039fe8ca7b9354c3b6e0a8e6\",\n    \"0x95689d78c867724823f564627d22d25010f278674c6d2d0cdb10329169a47580818995d1d727ce46c38a1e47943ebb89\",\n    \"0xab676d2256c6288a88e044b3d9ffd43eb9d5aaee00e8fc60ac921395fb835044c71a26ca948e557fed770f52d711e057\",\n    \"0x96351c72785c32e5d004b6f4a1259fb8153d631f0c93fed172f18e8ba438fbc5585c1618deeabd0d6d0b82173c2e6170\",\n    \"0x93dd8d3db576418e22536eba45ab7f56967c6c97c64260d6cddf38fb19c88f2ec5cd0e0156f50e70855eee8a2b879ffd\",\n    \"0xad6ff16f40f6de3d7a737f8e6cebd8416920c4ff89dbdcd75eabab414af9a6087f83ceb9aff7680aa86bff98bd09c8cc\",\n    \"0x84de53b11671abc9c38710e19540c5c403817562aeb22a88404cdaff792c1180f717dbdfe8f54940c062c4d032897429\",\n    \"0x872231b9efa1cdd447b312099a5c164c560440a9441d904e70f5abfc3b2a0d16be9a01aca5e0a2599a61e19407587e3d\",\n    \"0x88f44ac27094a2aa14e9dc40b099ee6d68f97385950f303969d889ee93d4635e34dff9239103bdf66a4b7cbba3e7eb7a\",\n    \"0xa59afebadf0260e832f6f44468443562f53fbaf7bcb5e46e1462d3f328ac437ce56edbca617659ac9883f9e13261fad7\",\n    \"0xb1990e42743a88de4deeacfd55fafeab3bc380cb95de43ed623d021a4f2353530bcab9594389c1844b1c5ea6634c4555\",\n    \"0x85051e841149a10e83f56764e042182208591396d0ce78c762c4a413e6836906df67f38c69793e158d64fef111407ba3\",\n    \"0x9778172bbd9b1f2ec6bbdd61829d7b39a7df494a818e31c654bf7f6a30139899c4822c1bf418dd4f923243067759ce63\",\n    \"0x9355005b4878c87804fc966e7d24f3e4b02bed35b4a77369d01f25a3dcbff7621b08306b1ac85b76fe7b4a3eb5f839b1\",\n    \"0x8f9dc6a54fac052e236f8f0e1f571ac4b5308a43acbe4cc8183bce26262ddaf7994e41cf3034a4cbeca2c505a151e3b1\",\n    \"0x8cc59c17307111723fe313046a09e0e32ea0cce62c13814ab7c6408c142d6a0311d801be4af53fc9240523f12045f9ef\",\n    \"0x8e6057975ed40a1932e47dd3ac778f72ee2a868d8540271301b1aa6858de1a5450f596466494a3e0488be4fbeb41c840\",\n    \"0x812145efbd6559ae13325d56a15940ca4253b17e72a9728986b563bb5acc13ec86453796506ac1a8f12bd6f9e4a288c3\",\n    \"0x911da0a6d6489eb3dab2ec4a16e36127e8a291ae68a6c2c9de33e97f3a9b1f00da57a94e270a0de79ecc5ecb45d19e83\",\n    \"0xb72ea85973f4b2a7e6e71962b0502024e979a73c18a9111130e158541fa47bbaaf53940c8f846913a517dc69982ba9e1\",\n    \"0xa7a56ad1dbdc55f177a7ad1d0af78447dc2673291e34e8ab74b26e2e2e7d8c5fe5dc89e7ef60f04a9508847b5b3a8188\",\n    \"0xb52503f6e5411db5d1e70f5fb72ccd6463fa0f197b3e51ca79c7b5a8ab2e894f0030476ada72534fa4eb4e06c3880f90\",\n    \"0xb51c7957a3d18c4e38f6358f2237b3904618d58b1de5dec53387d25a63772e675a5b714ad35a38185409931157d4b529\",\n    \"0xb86b4266e719d29c043d7ec091547aa6f65bbf2d8d831d1515957c5c06513b72aa82113e9645ad38a7bc3f5383504fa6\",\n    \"0xb95b547357e6601667b0f5f61f261800a44c2879cf94e879def6a105b1ad2bbf1795c3b98a90d588388e81789bd02681\",\n    \"0xa58fd4c5ae4673fa350da6777e13313d5d37ed1dafeeb8f4f171549765b84c895875d9d3ae6a9741f3d51006ef81d962\",\n    \"0x9398dc348d078a604aadc154e6eef2c0be1a93bb93ba7fe8976edc2840a3a318941338cc4d5f743310e539d9b46613d2\",\n    \"0x902c9f0095014c4a2f0dccaaab543debba6f4cc82c345a10aaf4e72511725dbed7a34cd393a5f4e48a3e5142b7be84ed\",\n    \"0xa7c0447849bb44d04a0393a680f6cd390093484a79a147dd238f5d878030d1c26646d88211108e59fe08b58ad20c6fbd\",\n    \"0x80db045535d6e67a422519f5c89699e37098449d249698a7cc173a26ccd06f60238ae6cc7242eb780a340705c906790c\",\n    \"0x8e52b451a299f30124505de2e74d5341e1b5597bdd13301cc39b05536c96e4380e7f1b5c7ef076f5b3005a868657f17c\",\n    \"0x824499e89701036037571761e977654d2760b8ce21f184f2879fda55d3cda1e7a95306b8abacf1caa79d3cc075b9d27f\",\n    \"0x9049b956b77f8453d2070607610b79db795588c0cec12943a0f5fe76f358dea81e4f57a4692112afda0e2c05c142b26f\",\n    \"0x81911647d818a4b5f4990bfd4bc13bf7be7b0059afcf1b6839333e8569cdb0172fd2945410d88879349f677abaed5eb3\",\n    \"0xad4048f19b8194ed45b6317d9492b71a89a66928353072659f5ce6c816d8f21e69b9d1817d793effe49ca1874daa1096\",\n    \"0x8d22f7b2ddb31458661abd34b65819a374a1f68c01fc6c9887edeba8b80c65bceadb8f57a3eb686374004b836261ef67\",\n    \"0x92637280c259bc6842884db3d6e32602a62252811ae9b019b3c1df664e8809ffe86db88cfdeb8af9f46435c9ee790267\",\n    \"0xa2f416379e52e3f5edc21641ea73dc76c99f7e29ea75b487e18bd233856f4c0183429f378d2bfc6cd736d29d6cadfa49\",\n    \"0x882cb6b76dbdc188615dcf1a8439eba05ffca637dd25197508156e03c930b17b9fed2938506fdd7b77567cb488f96222\",\n    \"0xb68b621bb198a763fb0634eddb93ed4b5156e59b96c88ca2246fd1aea3e6b77ed651e112ac41b30cd361fadc011d385e\",\n    \"0xa3cb22f6b675a29b2d1f827cacd30df14d463c93c3502ef965166f20d046af7f9ab7b2586a9c64f4eae4fad2d808a164\",\n    \"0x8302d9ce4403f48ca217079762ce42cee8bc30168686bb8d3a945fbd5acd53b39f028dce757b825eb63af2d5ae41169d\",\n    \"0xb2eef1fbd1a176f1f4cd10f2988c7329abe4eb16c7405099fb92baa724ab397bc98734ef7d4b24c0f53dd90f57520d04\",\n    \"0xa1bbef0bd684a3f0364a66bde9b29326bac7aa3dde4caed67f14fb84fed3de45c55e406702f1495a3e2864d4ee975030\",\n    \"0x976acdb0efb73e3a3b65633197692dedc2adaed674291ae3df76b827fc866d214e9cac9ca46baefc4405ff13f953d936\",\n    \"0xb9fbf71cc7b6690f601f0b1c74a19b7d14254183a2daaafec7dc3830cba5ae173d854bbfebeca985d1d908abe5ef0cda\",\n    \"0x90591d7b483598c94e38969c4dbb92710a1a894bcf147807f1bcbd8aa3ac210b9f2be65519aa829f8e1ccdc83ad9b8cf\",\n    \"0xa30568577c91866b9c40f0719d46b7b3b2e0b4a95e56196ac80898a2d89cc67880e1229933f2cd28ee3286f8d03414d7\",\n    \"0x97589a88c3850556b359ec5e891f0937f922a751ac7c95949d3bbc7058c172c387611c0f4cb06351ef02e5178b3dd9e4\",\n    \"0x98e7bbe27a1711f4545df742f17e3233fbcc63659d7419e1ca633f104cb02a32c84f2fac23ca2b84145c2672f68077ab\",\n    \"0xa7ddb91636e4506d8b7e92aa9f4720491bb71a72dadc47c7f4410e15f93e43d07d2b371951a0e6a18d1bd087aa96a5c4\",\n    \"0xa7c006692227a06db40bceac3d5b1daae60b5692dd9b54772bedb5fea0bcc91cbcdb530cac31900ffc70c5b3ffadc969\",\n    \"0x8d3ec6032778420dfa8be52066ba0e623467df33e4e1901dbadd586c5d750f4ccde499b5197e26b9ea43931214060f69\",\n    \"0x8d9a8410518ea64f89df319bfd1fc97a0971cdb9ad9b11d1f8fe834042ea7f8dce4db56eeaf179ff8dda93b6db93e5ce\",\n    \"0xa3c533e9b3aa04df20b9ff635cb1154ce303e045278fcf3f10f609064a5445552a1f93989c52ce852fd0bbd6e2b6c22e\",\n    \"0x81934f3a7f8c1ae60ec6e4f212986bcc316118c760a74155d06ce0a8c00a9b9669ec4e143ca214e1b995e41271774fd9\",\n    \"0xab8e2d01a71192093ef8fafa7485e795567cc9db95a93fb7cc4cf63a391ef89af5e2bfad4b827fffe02b89271300407f\",\n    \"0x83064a1eaa937a84e392226f1a60b7cfad4efaa802f66de5df7498962f7b2649924f63cd9962d47906380b97b9fe80e1\",\n    \"0xb4f5e64a15c6672e4b55417ee5dc292dcf93d7ea99965a888b1cc4f5474a11e5b6520eacbcf066840b343f4ceeb6bf33\",\n    \"0xa63d278b842456ef15c278b37a6ea0f27c7b3ffffefca77c7a66d2ea06c33c4631eb242bbb064d730e70a8262a7b848a\",\n    \"0x83a41a83dbcdf0d22dc049de082296204e848c453c5ab1ba75aa4067984e053acf6f8b6909a2e1f0009ed051a828a73b\",\n    \"0x819485b036b7958508f15f3c19436da069cbe635b0318ebe8c014cf1ef9ab2df038c81161b7027475bcfa6fff8dd9faf\",\n    \"0xaa40e38172806e1e045e167f3d1677ef12d5dcdc89b43639a170f68054bd196c4fae34c675c1644d198907a03f76ba57\",\n    \"0x969bae484883a9ed1fbed53b26b3d4ee4b0e39a6c93ece5b3a49daa01444a1c25727dabe62518546f36b047b311b177c\",\n    \"0x80a9e73a65da99664988b238096a090d313a0ee8e4235bc102fa79bb337b51bb08c4507814eb5baec22103ec512eaab0\",\n    \"0x86604379aec5bddda6cbe3ef99c0ac3a3c285b0b1a15b50451c7242cd42ae6b6c8acb717dcca7917838432df93a28502\",\n    \"0xa23407ee02a495bed06aa7e15f94cfb05c83e6d6fba64456a9bbabfa76b2b68c5c47de00ba169e710681f6a29bb41a22\",\n    \"0x98cff5ecc73b366c6a01b34ac9066cb34f7eeaf4f38a5429bad2d07e84a237047e2a065c7e8a0a6581017dadb4695deb\",\n    \"0x8de9f68a938f441f3b7ab84bb1f473c5f9e5c9e139e42b7ccee1d254bd57d0e99c2ccda0f3198f1fc5737f6023dd204e\",\n    \"0xb0ce48d815c2768fb472a315cad86aa033d0e9ca506f146656e2941829e0acb735590b4fbc713c2d18d3676db0a954ac\",\n    \"0x82f485cdefd5642a6af58ac6817991c49fac9c10ace60f90b27f1788cc026c2fe8afc83cf499b3444118f9f0103598a8\",\n    \"0x82c24550ed512a0d53fc56f64cc36b553823ae8766d75d772dacf038c460f16f108f87a39ceef7c66389790f799dbab3\",\n    \"0x859ffcf1fe9166388316149b9acc35694c0ea534d43f09dae9b86f4aa00a23b27144dda6a352e74b9516e8c8d6fc809c\",\n    \"0xb8f7f353eec45da77fb27742405e5ad08d95ec0f5b6842025be9def3d9892f85eb5dd0921b41e6eff373618dba215bca\",\n    \"0x8ccca4436f9017e426229290f5cd05eac3f16571a4713141a7461acfe8ae99cd5a95bf5b6df129148693c533966145da\",\n    \"0xa2c67ecc19c0178b2994846fea4c34c327a5d786ac4b09d1d13549d5be5996d8a89021d63d65cb814923388f47cc3a03\",\n    \"0xaa0ff87d676b418ec08f5cbf577ac7e744d1d0e9ebd14615b550eb86931eafd2a36d4732cc5d6fab1713fd7ab2f6f7c0\",\n    \"0x8aef4730bb65e44efd6bb9441c0ae897363a2f3054867590a2c2ecf4f0224e578c7a67f10b40f8453d9f492ac15a9b2d\",\n    \"0x86a187e13d8fba5addcfdd5b0410cedd352016c930f913addd769ee09faa6be5ca3e4b1bdb417a965c643a99bd92be42\",\n    \"0xa0a4e9632a7a094b14b29b78cd9c894218cdf6783e61671e0203865dc2a835350f465fbaf86168f28af7c478ca17bc89\",\n    \"0xa8c7b02d8deff2cd657d8447689a9c5e2cd74ef57c1314ac4d69084ac24a7471954d9ff43fe0907d875dcb65fd0d3ce5\",\n    \"0x97ded38760aa7be6b6960b5b50e83b618fe413cbf2bcc1da64c05140bcc32f5e0e709cd05bf8007949953fac5716bad9\",\n    \"0xb0d293835a24d64c2ae48ce26e550b71a8c94a0883103757fb6b07e30747f1a871707d23389ba2b2065fa6bafe220095\",\n    \"0x8f9e291bf849feaa575592e28e3c8d4b7283f733d41827262367ea1c40f298c7bcc16505255a906b62bf15d9f1ba85fb\",\n    \"0x998f4e2d12708b4fd85a61597ca2eddd750f73c9e0c9b3cf0825d8f8e01f1628fd19797dcaed3b16dc50331fc6b8b821\",\n    \"0xb30d1f8c115d0e63bf48f595dd10908416774c78b3bbb3194192995154d80ea042d2e94d858de5f8aa0261b093c401fd\",\n    \"0xb5d9c75bb41f964cbff3f00e96d9f1480c91df8913f139f0d385d27a19f57a820f838eb728e46823cbff00e21c660996\",\n    \"0xa6edec90b5d25350e2f5f0518777634f9e661ec9d30674cf5b156c4801746d62517751d90074830ac0f4b09911c262f1\",\n    \"0x82f98da1264b6b75b8fbeb6a4d96d6a05b25c24db0d57ba3a38efe3a82d0d4e331b9fc4237d6494ccfe4727206457519\",\n    \"0xb89511843453cf4ecd24669572d6371b1e529c8e284300c43e0d5bb6b3aaf35aeb634b3cb5c0a2868f0d5e959c1d0772\",\n    \"0xa82bf065676583e5c1d3b81987aaae5542f522ba39538263a944bb33ea5b514c649344a96c0205a3b197a3f930fcda6c\",\n    \"0xa37b47ea527b7e06c460776aa662d9a49ff4149d3993f1a974b0dd165f7171770d189b0e2ea54fd5fccb6a14b116e68a\",\n    \"0xa1017677f97dda818274d47556d09d0e4ccacb23a252f82a6cfe78c630ad46fb9806307445a59fb61262182de3a2b29c\",\n    \"0xb01e9fcac239ba270e6877b79273ddd768bf8a51d2ed8a051b1c11e18eff3de5920e2fcbfbd26f06d381eddd3b1f1e1b\",\n    \"0x82fcd53d803b1c8e4ed76adc339b7f3a5962d37042b9683aabac7513ac68775d4a566a9460183926a6a95dbe7d551a1f\",\n    \"0xa763e78995d55cd21cdb7ef75d9642d6e1c72453945e346ab6690c20a4e1eeec61bb848ef830ae4b56182535e3c71d8f\",\n    \"0xb769f4db602251d4b0a1186782799bdcef66de33c110999a5775c50b349666ffd83d4c89714c4e376f2efe021a5cfdb2\",\n    \"0xa59cbd1b785efcfa6e83fc3b1d8cf638820bc0c119726b5368f3fba9dce8e3414204fb1f1a88f6c1ff52e87961252f97\",\n    \"0x95c8c458fd01aa23ecf120481a9c6332ebec2e8bb70a308d0576926a858457021c277958cf79017ddd86a56cacc2d7db\",\n    \"0x82eb41390800287ae56e77f2e87709de5b871c8bdb67c10a80fc65f3acb9f7c29e8fa43047436e8933f27449ea61d94d\",\n    \"0xb3ec25e3545eb83aed2a1f3558d1a31c7edde4be145ecc13b33802654b77dc049b4f0065069dd9047b051e52ab11dcdd\",\n    \"0xb78a0c715738f56f0dc459ab99e252e3b579b208142836b3c416b704ca1de640ca082f29ebbcee648c8c127df06f6b1e\",\n    \"0xa4083149432eaaf9520188ebf4607d09cf664acd1f471d4fb654476e77a9eaae2251424ffda78d09b6cb880df35c1219\",\n    \"0x8c52857d68d6e9672df3db2df2dbf46b516a21a0e8a18eec09a6ae13c1ef8f369d03233320dd1c2c0bbe00abfc1ea18b\",\n    \"0x8c856089488803066bff3f8d8e09afb9baf20cecc33c8823c1c0836c3d45498c3de37e87c016b705207f60d2b00f8609\",\n    \"0x831a3df39be959047b2aead06b4dcd3012d7b29417f642b83c9e8ce8de24a3dbbd29c6fdf55e2db3f7ea04636c94e403\",\n    \"0xaed84d009f66544addabe404bf6d65af7779ce140dc561ff0c86a4078557b96b2053b7b8a43432ffb18cd814f143b9da\",\n    \"0x93282e4d72b0aa85212a77b336007d8ba071eea17492da19860f1ad16c1ea8867ccc27ef5c37c74b052465cc11ea4f52\",\n    \"0xa7b78b8c8d057194e8d68767f1488363f77c77bddd56c3da2bc70b6354c7aa76247c86d51f7371aa38a4aa7f7e3c0bb7\",\n    \"0xb1c77283d01dcd1bde649b5b044eac26befc98ff57cbee379fb5b8e420134a88f2fc7f0bf04d15e1fbd45d29e7590fe6\",\n    \"0xa4aa8de70330a73b2c6458f20a1067eed4b3474829b36970a8df125d53bbdda4f4a2c60063b7cccb0c80fc155527652f\",\n    \"0x948a6c79ba1b8ad7e0bed2fae2f0481c4e41b4d9bbdd9b58164e28e9065700e83f210c8d5351d0212e0b0b68b345b3a5\",\n    \"0x86a48c31dcbbf7b082c92d28e1f613a2378a910677d7db3a349dc089e4a1e24b12eee8e8206777a3a8c64748840b7387\",\n    \"0x976adb1af21e0fc34148917cf43d933d7bfd3fd12ed6c37039dcd5a4520e3c6cf5868539ba5bf082326430deb8a4458d\",\n    \"0xb93e1a4476f2c51864bb4037e7145f0635eb2827ab91732b98d49b6c07f6ac443111aa1f1da76d1888665cb897c3834e\",\n    \"0x8afd46fb23bf869999fa19784b18a432a1f252d09506b8dbb756af900518d3f5f244989b3d7c823d9029218c655d3dc6\",\n    \"0x83f1e59e3abeed18cdc632921672673f1cb6e330326e11c4e600e13e0d5bc11bdc970ae12952e15103a706fe720bf4d6\",\n    \"0x90ce4cc660714b0b673d48010641c09c00fc92a2c596208f65c46073d7f349dd8e6e077ba7dcef9403084971c3295b76\",\n    \"0x8b09b0f431a7c796561ecf1549b85048564de428dac0474522e9558b6065fede231886bc108539c104ce88ebd9b5d1b0\",\n    \"0x85d6e742e2fb16a7b0ba0df64bc2c0dbff9549be691f46a6669bca05e89c884af16822b85faefefb604ec48c8705a309\",\n    \"0xa87989ee231e468a712c66513746fcf03c14f103aadca0eac28e9732487deb56d7532e407953ab87a4bf8961588ef7b0\",\n    \"0xb00da10efe1c29ee03c9d37d5918e391ae30e48304e294696b81b434f65cf8c8b95b9d1758c64c25e534d045ba28696f\",\n    \"0x91c0e1fb49afe46c7056400baa06dbb5f6e479db78ee37e2d76c1f4e88994357e257b83b78624c4ef6091a6c0eb8254d\",\n    \"0x883fb797c498297ccbf9411a3e727c3614af4eccde41619b773dc7f3259950835ee79453debf178e11dec4d3ada687a0\",\n    \"0xa14703347e44eb5059070b2759297fcfcfc60e6893c0373eea069388eba3950aa06f1c57cd2c30984a2d6f9e9c92c79e\",\n    \"0xafebc7585b304ceba9a769634adff35940e89cd32682c78002822aab25eec3edc29342b7f5a42a56a1fec67821172ad5\",\n    \"0xaea3ff3822d09dba1425084ca95fd359718d856f6c133c5fabe2b2eed8303b6e0ba0d8698b48b93136a673baac174fd9\",\n    \"0xaf2456a09aa777d9e67aa6c7c49a1845ea5cdda2e39f4c935c34a5f8280d69d4eec570446998cbbe31ede69a91e90b06\",\n    \"0x82cada19fed16b891ef3442bafd49e1f07c00c2f57b2492dd4ee36af2bd6fd877d6cb41188a4d6ce9ec8d48e8133d697\",\n    \"0x82a21034c832287f616619a37c122cee265cc34ae75e881fcaea4ea7f689f3c2bc8150bbf7dbcfd123522bfb7f7b1d68\",\n    \"0x86877217105f5d0ec3eeff0289fc2a70d505c9fdf7862e8159553ef60908fb1a27bdaf899381356a4ef4649072a9796c\",\n    \"0x82b196e49c6e861089a427c0b4671d464e9d15555ffb90954cd0d630d7ae02eb3d98ceb529d00719c2526cd96481355a\",\n    \"0xa29b41d0d43d26ce76d4358e0db2b77df11f56e389f3b084d8af70a636218bd3ac86b36a9fe46ec9058c26a490f887f7\",\n    \"0xa4311c4c20c4d7dd943765099c50f2fd423e203ccfe98ff00087d205467a7873762510cac5fdce7a308913ed07991ed7\",\n    \"0xb1f040fc5cc51550cb2c25cf1fd418ecdd961635a11f365515f0cb4ffb31da71f48128c233e9cc7c0cf3978d757ec84e\",\n    \"0xa9ebae46f86d3bd543c5f207ed0d1aed94b8375dc991161d7a271f01592912072e083e2daf30c146430894e37325a1b9\",\n    \"0x826418c8e17ad902b5fe88736323a47e0ca7a44bce4cbe27846ec8fe81de1e8942455dda6d30e192cdcc73e11df31256\",\n    \"0x85199db563427c5edcbac21f3d39fec2357be91fb571982ddcdc4646b446ad5ced84410de008cb47b3477ee0d532daf8\",\n    \"0xb7eed9cd400b2ca12bf1d9ae008214b8561fb09c8ad9ff959e626ffde00fee5ff2f5b6612e231f2a1a9b1646fcc575e3\",\n    \"0x8b40bf12501dcbac78f5a314941326bfcddf7907c83d8d887d0bb149207f85d80cd4dfbd7935439ea7b14ea39a3fded7\",\n    \"0x83e3041af302485399ba6cd5120e17af61043977083887e8d26b15feec4a6b11171ac5c06e6ad0971d4b58a81ff12af3\",\n    \"0x8f5b9a0eecc589dbf8c35a65d5e996a659277ef6ea509739c0cb7b3e2da9895e8c8012de662e5b23c5fa85d4a8f48904\",\n    \"0x835d71ed5e919d89d8e6455f234f3ff215462c4e3720c371ac8c75e83b19dfe3ae15a81547e4dc1138e5f5997f413cc9\",\n    \"0x8b7d2e4614716b1db18e9370176ea483e6abe8acdcc3dcdf5fb1f4d22ca55d652feebdccc171c6de38398d9f7bfdec7a\",\n    \"0x93eace72036fe57d019676a02acf3d224cf376f166658c1bf705db4f24295881d477d6fdd7916efcfceff8c7a063deda\",\n    \"0xb1ac460b3d516879a84bc886c54f020a9d799e7c49af3e4d7de5bf0d2793c852254c5d8fe5616147e6659512e5ccb012\",\n    \"0xacd0947a35cb167a48bcd9667620464b54ac0e78f9316b4aa92dcaab5422d7a732087e52e1c827faa847c6b2fe6e7766\",\n    \"0x94ac33d21c3d12ff762d32557860e911cd94d666609ddcc42161b9c16f28d24a526e8b10bb03137257a92cec25ae637d\",\n    \"0x832e02058b6b994eadd8702921486241f9a19e68ed1406dad545e000a491ae510f525ccf9d10a4bba91c68f2c53a0f58\",\n    \"0x9471035d14f78ff8f463b9901dd476b587bb07225c351161915c2e9c6114c3c78a501379ab6fb4eb03194c457cbd22bf\",\n    \"0xab64593e034c6241d357fcbc32d8ea5593445a5e7c24cac81ad12bd2ef01843d477a36dc1ba21dbe63b440750d72096a\",\n    \"0x9850f3b30045e927ad3ec4123a32ed2eb4c911f572b6abb79121873f91016f0d80268de8b12e2093a4904f6e6cab7642\",\n    \"0x987212c36b4722fe2e54fa30c52b1e54474439f9f35ca6ad33c5130cd305b8b54b532dd80ffd2c274105f20ce6d79f6e\",\n    \"0x8b4d0c6abcb239b5ed47bef63bc17efe558a27462c8208fa652b056e9eae9665787cd1aee34fbb55beb045c8bfdb882b\",\n    \"0xa9f3483c6fee2fe41312d89dd4355d5b2193ac413258993805c5cbbf0a59221f879386d3e7a28e73014f10e65dd503d9\",\n    \"0xa2225da3119b9b7c83d514b9f3aeb9a6d9e32d9cbf9309cbb971fd53c4b2c001d10d880a8ad8a7c281b21d85ceca0b7c\",\n    \"0xa050be52e54e676c151f7a54453bbb707232f849beab4f3bf504b4d620f59ed214409d7c2bd3000f3ff13184ccda1c35\",\n    \"0xadbccf681e15b3edb6455a68d292b0a1d0f5a4cb135613f5e6db9943f02181341d5755875db6ee474e19ace1c0634a28\",\n    \"0x8b6eff675632a6fad0111ec72aacc61c7387380eb87933fd1d098856387d418bd38e77d897e65d6fe35951d0627c550b\",\n    \"0xaabe2328ddf90989b15e409b91ef055cb02757d34987849ae6d60bef2c902bf8251ed21ab30acf39e500d1d511e90845\",\n    \"0x92ba4eb1f796bc3d8b03515f65c045b66e2734c2da3fc507fdd9d6b5d1e19ab3893726816a32141db7a31099ca817d96\",\n    \"0x8a98b3cf353138a1810beb60e946183803ef1d39ac4ea92f5a1e03060d35a4774a6e52b14ead54f6794d5f4022b8685c\",\n    \"0x909f8a5c13ec4a59b649ed3bee9f5d13b21d7f3e2636fd2bb3413c0646573fdf9243d63083356f12f5147545339fcd55\",\n    \"0x9359d914d1267633141328ed0790d81c695fea3ddd2d406c0df3d81d0c64931cf316fe4d92f4353c99ff63e2aefc4e34\",\n    \"0xb88302031681b54415fe8fbfa161c032ea345c6af63d2fb8ad97615103fd4d4281c5a9cae5b0794c4657b97571a81d3b\",\n    \"0x992c80192a519038082446b1fb947323005b275e25f2c14c33cc7269e0ec038581cc43705894f94bad62ae33a8b7f965\",\n    \"0xa78253e3e3eece124bef84a0a8807ce76573509f6861d0b6f70d0aa35a30a123a9da5e01e84969708c40b0669eb70aa6\",\n    \"0x8d5724de45270ca91c94792e8584e676547d7ac1ac816a6bb9982ee854eb5df071d20545cdfd3771cd40f90e5ba04c8e\",\n    \"0x825a6f586726c68d45f00ad0f5a4436523317939a47713f78fd4fe81cd74236fdac1b04ecd97c2d0267d6f4981d7beb1\"\n  ],\n  \"g2_monomial\": [\n    \"0x93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8\",\n    \"0xb5bfd7dd8cdeb128843bc287230af38926187075cbfbefa81009a2ce615ac53d2914e5870cb452d2afaaab24f3499f72185cbfee53492714734429b7b38608e23926c911cceceac9a36851477ba4c60b087041de621000edc98edada20c1def2\",\n    \"0xb5337ba0ce5d37224290916e268e2060e5c14f3f9fc9e1ec3af5a958e7a0303122500ce18f1a4640bf66525bd10e763501fe986d86649d8d45143c08c3209db3411802c226e9fe9a55716ac4a0c14f9dcef9e70b2bb309553880dc5025eab3cc\",\n    \"0xb3c1dcdc1f62046c786f0b82242ef283e7ed8f5626f72542aa2c7a40f14d9094dd1ebdbd7457ffdcdac45fd7da7e16c51200b06d791e5e43e257e45efdf0bd5b06cd2333beca2a3a84354eb48662d83aef5ecf4e67658c851c10b13d8d87c874\",\n    \"0x954d91c7688983382609fca9e211e461f488a5971fd4e40d7e2892037268eacdfd495cfa0a7ed6eb0eb11ac3ae6f651716757e7526abe1e06c64649d80996fd3105c20c4c94bc2b22d97045356fe9d791f21ea6428ac48db6f9e68e30d875280\",\n    \"0x88a6b6bb26c51cf9812260795523973bb90ce80f6820b6c9048ab366f0fb96e48437a7f7cb62aedf64b11eb4dfefebb0147608793133d32003cb1f2dc47b13b5ff45f1bb1b2408ea45770a08dbfaec60961acb8119c47b139a13b8641e2c9487\",\n    \"0x85cd7be9728bd925d12f47fb04b32d9fad7cab88788b559f053e69ca18e463113ecc8bbb6dbfb024835f901b3a957d3108d6770fb26d4c8be0a9a619f6e3a4bf15cbfd48e61593490885f6cee30e4300c5f9cf5e1c08e60a2d5b023ee94fcad0\",\n    \"0x80477dba360f04399821a48ca388c0fa81102dd15687fea792ee8c1114e00d1bc4839ad37ac58900a118d863723acfbe08126ea883be87f50e4eabe3b5e72f5d9e041db8d9b186409fd4df4a7dde38c0e0a3b1ae29b098e5697e7f110b6b27e4\",\n    \"0xb7a6aec08715a9f8672a2b8c367e407be37e59514ac19dd4f0942a68007bba3923df22da48702c63c0d6b3efd3c2d04e0fe042d8b5a54d562f9f33afc4865dcbcc16e99029e25925580e87920c399e710d438ac1ce3a6dc9b0d76c064a01f6f7\",\n    \"0xac1b001edcea02c8258aeffbf9203114c1c874ad88dae1184fadd7d94cd09053649efd0ca413400e6e9b5fa4eac33261000af88b6bd0d2abf877a4f0355d2fb4d6007adb181695201c5432e50b850b51b3969f893bddf82126c5a71b042b7686\",\n    \"0x90043fda4de53fb364fab2c04be5296c215599105ecff0c12e4917c549257125775c29f2507124d15f56e30447f367db0596c33237242c02d83dfd058735f1e3c1ff99069af55773b6d51d32a68bf75763f59ec4ee7267932ae426522b8aaab6\",\n    \"0xa8660ce853e9dc08271bf882e29cd53397d63b739584dda5263da4c7cc1878d0cf6f3e403557885f557e184700575fee016ee8542dec22c97befe1d10f414d22e84560741cdb3e74c30dda9b42eeaaf53e27822de2ee06e24e912bf764a9a533\",\n    \"0x8fe3921a96d0d065e8aa8fce9aa42c8e1461ca0470688c137be89396dd05103606dab6cdd2a4591efd6addf72026c12e065da7be276dee27a7e30afa2bd81c18f1516e7f068f324d0bad9570b95f6bd02c727cd2343e26db0887c3e4e26dceda\",\n    \"0x8ae1ad97dcb9c192c9a3933541b40447d1dc4eebf380151440bbaae1e120cc5cdf1bcea55180b128d8e180e3af623815191d063cc0d7a47d55fb7687b9d87040bf7bc1a7546b07c61db5ccf1841372d7c2fe4a5431ffff829f3c2eb590b0b710\",\n    \"0x8c2fa96870a88150f7876c931e2d3cc2adeaaaf5c73ef5fa1cf9dfa0991ae4819f9321af7e916e5057d87338e630a2f21242c29d76963cf26035b548d2a63d8ad7bd6efefa01c1df502cbdfdfe0334fb21ceb9f686887440f713bf17a89b8081\",\n    \"0xb9aa98e2f02bb616e22ee5dd74c7d1049321ac9214d093a738159850a1dbcc7138cb8d26ce09d8296368fd5b291d74fa17ac7cc1b80840fdd4ee35e111501e3fa8485b508baecda7c1ab7bd703872b7d64a2a40b3210b6a70e8a6ffe0e5127e3\",\n    \"0x9292db67f8771cdc86854a3f614a73805bf3012b48f1541e704ea4015d2b6b9c9aaed36419769c87c49f9e3165f03edb159c23b3a49c4390951f78e1d9b0ad997129b17cdb57ea1a6638794c0cca7d239f229e589c5ae4f9fe6979f7f8cba1d7\",\n    \"0x91cd9e86550f230d128664f7312591fee6a84c34f5fc7aed557bcf986a409a6de722c4330453a305f06911d2728626e611acfdf81284f77f60a3a1595053a9479964fd713117e27c0222cc679674b03bc8001501aaf9b506196c56de29429b46\",\n    \"0xa9516b73f605cc31b89c68b7675dc451e6364595243d235339437f556cf22d745d4250c1376182273be2d99e02c10eee047410a43eff634d051aeb784e76cb3605d8e079b9eb6ad1957dfdf77e1cd32ce4a573c9dfcc207ca65af6eb187f6c3d\",\n    \"0xa9667271f7d191935cc8ad59ef3ec50229945faea85bfdfb0d582090f524436b348aaa0183b16a6231c00332fdac2826125b8c857a2ed9ec66821cfe02b3a2279be2412441bc2e369b255eb98614e4be8490799c4df22f18d47d24ec70bba5f7\",\n    \"0xa4371144d2aa44d70d3cb9789096d3aa411149a6f800cb46f506461ee8363c8724667974252f28aea61b6030c05930ac039c1ee64bb4bd56532a685cae182bf2ab935eee34718cffcb46cae214c77aaca11dbb1320faf23c47247db1da04d8dc\",\n    \"0x89a7eb441892260b7e81168c386899cd84ffc4a2c5cad2eae0d1ab9e8b5524662e6f660fe3f8bfe4c92f60b060811bc605b14c5631d16709266886d7885a5eb5930097127ec6fb2ebbaf2df65909cf48f253b3d5e22ae48d3e9a2fd2b01f447e\",\n    \"0x9648c42ca97665b5eccb49580d8532df05eb5a68db07f391a2340769b55119eaf4c52fe4f650c09250fa78a76c3a1e271799b8333cc2628e3d4b4a6a3e03da1f771ecf6516dd63236574a7864ff07e319a6f11f153406280d63af9e2b5713283\",\n    \"0x9663bf6dd446ea7a90658ee458578d4196dc0b175ef7fcfa75f44d41670850774c2e46c5a6be132a2c072a3c0180a24f0305d1acac49d2d79878e5cda80c57feda3d01a6af12e78b5874e2a4b3717f11c97503b41a4474e2e95b179113726199\",\n    \"0xb212aeb4814e0915b432711b317923ed2b09e076aaf558c3ae8ef83f9e15a83f9ea3f47805b2750ab9e8106cb4dc6ad003522c84b03dc02829978a097899c773f6fb31f7fe6b8f2d836d96580f216fec20158f1590c3e0d7850622e15194db05\",\n    \"0x925f005059bf07e9ceccbe66c711b048e236ade775720d0fe479aebe6e23e8af281225ad18e62458dc1b03b42ad4ca290d4aa176260604a7aad0d9791337006fbdebe23746f8060d42876f45e4c83c3643931392fde1cd13ff8bddf8111ef974\",\n    \"0x9553edb22b4330c568e156a59ef03b26f5c326424f830fe3e8c0b602f08c124730ffc40bc745bec1a22417adb22a1a960243a10565c2be3066bfdb841d1cd14c624cd06e0008f4beb83f972ce6182a303bee3fcbcabc6cfe48ec5ae4b7941bfc\",\n    \"0x935f5a404f0a78bdcce709899eda0631169b366a669e9b58eacbbd86d7b5016d044b8dfc59ce7ed8de743ae16c2343b50e2f925e88ba6319e33c3fc76b314043abad7813677b4615c8a97eb83cc79de4fedf6ccbcfa4d4cbf759a5a84e4d9742\",\n    \"0xa5b014ab936eb4be113204490e8b61cd38d71da0dec7215125bcd131bf3ab22d0a32ce645bca93e7b3637cf0c2db3d6601a0ddd330dc46f9fae82abe864ffc12d656c88eb50c20782e5bb6f75d18760666f43943abb644b881639083e122f557\",\n    \"0x935b7298ae52862fa22bf03bfc1795b34c70b181679ae27de08a9f5b4b884f824ef1b276b7600efa0d2f1d79e4a470d51692fd565c5cf8343dd80e5d3336968fc21c09ba9348590f6206d4424eb229e767547daefa98bc3aa9f421158dee3f2a\",\n    \"0x9830f92446e708a8f6b091cc3c38b653505414f8b6507504010a96ffda3bcf763d5331eb749301e2a1437f00e2415efb01b799ad4c03f4b02de077569626255ac1165f96ea408915d4cf7955047620da573e5c439671d1fa5c833fb11de7afe6\",\n    \"0x840dcc44f673fff3e387af2bb41e89640f2a70bcd2b92544876daa92143f67c7512faf5f90a04b7191de01f3e2b1bde00622a20dc62ca23bbbfaa6ad220613deff43908382642d4d6a86999f662efd64b1df448b68c847cfa87630a3ffd2ec76\",\n    \"0x92950c895ed54f7f876b2fda17ecc9c41b7accfbdd42c210cc5b475e0737a7279f558148531b5c916e310604a1de25a80940c94fe5389ae5d6a5e9c371be67bceea1877f5401725a6595bcf77ece60905151b6dfcb68b75ed2e708c73632f4fd\",\n    \"0x8010246bf8e94c25fd029b346b5fbadb404ef6f44a58fd9dd75acf62433d8cc6db66974f139a76e0c26dddc1f329a88214dbb63276516cf325c7869e855d07e0852d622c332ac55609ba1ec9258c45746a2aeb1af0800141ee011da80af175d4\",\n    \"0xb0f1bad257ebd187bdc3f37b23f33c6a5d6a8e1f2de586080d6ada19087b0e2bf23b79c1b6da1ee82271323f5bdf3e1b018586b54a5b92ab6a1a16bb3315190a3584a05e6c37d5ca1e05d702b9869e27f513472bcdd00f4d0502a107773097da\",\n    \"0x9636d24f1ede773ce919f309448dd7ce023f424afd6b4b69cb98c2a988d849a283646dc3e469879daa1b1edae91ae41f009887518e7eb5578f88469321117303cd3ac2d7aee4d9cb5f82ab9ae3458e796dfe7c24284b05815acfcaa270ff22e2\",\n    \"0xb373feb5d7012fd60578d7d00834c5c81df2a23d42794fed91aa9535a4771fde0341c4da882261785e0caca40bf83405143085e7f17e55b64f6c5c809680c20b050409bf3702c574769127c854d27388b144b05624a0e24a1cbcc4d08467005b\",\n    \"0xb15680648949ce69f82526e9b67d9b55ce5c537dc6ab7f3089091a9a19a6b90df7656794f6edc87fb387d21573ffc847062623685931c2790a508cbc8c6b231dd2c34f4d37d4706237b1407673605a604bcf6a50cc0b1a2db20485e22b02c17e\",\n    \"0x8817e46672d40c8f748081567b038a3165f87994788ec77ee8daea8587f5540df3422f9e120e94339be67f186f50952504cb44f61e30a5241f1827e501b2de53c4c64473bcc79ab887dd277f282fbfe47997a930dd140ac08b03efac88d81075\",\n    \"0xa6e4ef6c1d1098f95aae119905f87eb49b909d17f9c41bcfe51127aa25fee20782ea884a7fdf7d5e9c245b5a5b32230b07e0dbf7c6743bf52ee20e2acc0b269422bd6cf3c07115df4aa85b11b2c16630a07c974492d9cdd0ec325a3fabd95044\",\n    \"0x8634aa7c3d00e7f17150009698ce440d8e1b0f13042b624a722ace68ead870c3d2212fbee549a2c190e384d7d6ac37ce14ab962c299ea1218ef1b1489c98906c91323b94c587f1d205a6edd5e9d05b42d591c26494a6f6a029a2aadb5f8b6f67\",\n    \"0x821a58092900bdb73decf48e13e7a5012a3f88b06288a97b855ef51306406e7d867d613d9ec738ebacfa6db344b677d21509d93f3b55c2ebf3a2f2a6356f875150554c6fff52e62e3e46f7859be971bf7dd9d5b3e1d799749c8a97c2e04325df\",\n    \"0x8dba356577a3a388f782e90edb1a7f3619759f4de314ad5d95c7cc6e197211446819c4955f99c5fc67f79450d2934e3c09adefc91b724887e005c5190362245eec48ce117d0a94d6fa6db12eda4ba8dde608fbbd0051f54dcf3bb057adfb2493\",\n    \"0xa32a690dc95c23ed9fb46443d9b7d4c2e27053a7fcc216d2b0020a8cf279729c46114d2cda5772fd60a97016a07d6c5a0a7eb085a18307d34194596f5b541cdf01b2ceb31d62d6b55515acfd2b9eec92b27d082fbc4dc59fc63b551eccdb8468\",\n    \"0xa040f7f4be67eaf0a1d658a3175d65df21a7dbde99bfa893469b9b43b9d150fc2e333148b1cb88cfd0447d88fa1a501d126987e9fdccb2852ecf1ba907c2ca3d6f97b055e354a9789854a64ecc8c2e928382cf09dda9abde42bbdf92280cdd96\",\n    \"0x864baff97fa60164f91f334e0c9be00a152a416556b462f96d7c43b59fe1ebaff42f0471d0bf264976f8aa6431176eb905bd875024cf4f76c13a70bede51dc3e47e10b9d5652d30d2663b3af3f08d5d11b9709a0321aba371d2ef13174dcfcaf\",\n    \"0x95a46f32c994133ecc22db49bad2c36a281d6b574c83cfee6680b8c8100466ca034b815cfaedfbf54f4e75188e661df901abd089524e1e0eb0bf48d48caa9dd97482d2e8c1253e7e8ac250a32fd066d5b5cb08a8641bdd64ecfa48289dca83a3\",\n    \"0xa2cce2be4d12144138cb91066e0cd0542c80b478bf467867ebef9ddaf3bd64e918294043500bf5a9f45ee089a8d6ace917108d9ce9e4f41e7e860cbce19ac52e791db3b6dde1c4b0367377b581f999f340e1d6814d724edc94cb07f9c4730774\",\n    \"0xb145f203eee1ac0a1a1731113ffa7a8b0b694ef2312dabc4d431660f5e0645ef5838e3e624cfe1228cfa248d48b5760501f93e6ab13d3159fc241427116c4b90359599a4cb0a86d0bb9190aa7fabff482c812db966fd2ce0a1b48cb8ac8b3bca\",\n    \"0xadabe5d215c608696e03861cbd5f7401869c756b3a5aadc55f41745ad9478145d44393fec8bb6dfc4ad9236dc62b9ada0f7ca57fe2bae1b71565dbf9536d33a68b8e2090b233422313cc96afc7f1f7e0907dc7787806671541d6de8ce47c4cd0\",\n    \"0xae7845fa6b06db53201c1080e01e629781817f421f28956589c6df3091ec33754f8a4bd4647a6bb1c141ac22731e3c1014865d13f3ed538dcb0f7b7576435133d9d03be655f8fbb4c9f7d83e06d1210aedd45128c2b0c9bab45a9ddde1c862a5\",\n    \"0x9159eaa826a24adfa7adf6e8d2832120ebb6eccbeb3d0459ffdc338548813a2d239d22b26451fda98cc0c204d8e1ac69150b5498e0be3045300e789bcb4e210d5cd431da4bdd915a21f407ea296c20c96608ded0b70d07188e96e6c1a7b9b86b\",\n    \"0xa9fc6281e2d54b46458ef564ffaed6944bff71e389d0acc11fa35d3fcd8e10c1066e0dde5b9b6516f691bb478e81c6b20865281104dcb640e29dc116daae2e884f1fe6730d639dbe0e19a532be4fb337bf52ae8408446deb393d224eee7cfa50\",\n    \"0x84291a42f991bfb36358eedead3699d9176a38f6f63757742fdbb7f631f2c70178b1aedef4912fed7b6cf27e88ddc7eb0e2a6aa4b999f3eb4b662b93f386c8d78e9ac9929e21f4c5e63b12991fcde93aa64a735b75b535e730ff8dd2abb16e04\",\n    \"0xa1b7fcacae181495d91765dfddf26581e8e39421579c9cbd0dd27a40ea4c54af3444a36bf85a11dda2114246eaddbdd619397424bb1eb41b5a15004b902a590ede5742cd850cf312555be24d2df8becf48f5afba5a8cd087cb7be0a521728386\",\n    \"0x92feaaf540dbd84719a4889a87cdd125b7e995a6782911931fef26da9afcfbe6f86aaf5328fe1f77631491ce6239c5470f44c7791506c6ef1626803a5794e76d2be0af92f7052c29ac6264b7b9b51f267ad820afc6f881460521428496c6a5f1\",\n    \"0xa525c925bfae1b89320a5054acc1fa11820f73d0cf28d273092b305467b2831fab53b6daf75fb926f332782d50e2522a19edcd85be5eb72f1497193c952d8cd0bcc5d43b39363b206eae4cb1e61668bde28a3fb2fc1e0d3d113f6dfadb799717\",\n    \"0x98752bb6f5a44213f40eda6aa4ff124057c1b13b6529ab42fe575b9afa66e59b9c0ed563fb20dff62130c436c3e905ee17dd8433ba02c445b1d67182ab6504a90bbe12c26a754bbf734665c622f76c62fe2e11dd43ce04fd2b91a8463679058b\",\n    \"0xa9aa9a84729f7c44219ff9e00e651e50ddea3735ef2a73fdf8ed8cd271961d8ed7af5cd724b713a89a097a3fe65a3c0202f69458a8b4c157c62a85668b12fc0d3957774bc9b35f86c184dd03bfefd5c325da717d74192cc9751c2073fe9d170e\",\n    \"0xb221c1fd335a4362eff504cd95145f122bf93ea02ae162a3fb39c75583fc13a932d26050e164da97cff3e91f9a7f6ff80302c19dd1916f24acf6b93b62f36e9665a8785413b0c7d930c7f1668549910f849bca319b00e59dd01e5dec8d2edacc\",\n    \"0xa71e2b1e0b16d754b848f05eda90f67bedab37709550171551050c94efba0bfc282f72aeaaa1f0330041461f5e6aa4d11537237e955e1609a469d38ed17f5c2a35a1752f546db89bfeff9eab78ec944266f1cb94c1db3334ab48df716ce408ef\",\n    \"0xb990ae72768779ba0b2e66df4dd29b3dbd00f901c23b2b4a53419226ef9232acedeb498b0d0687c463e3f1eead58b20b09efcefa566fbfdfe1c6e48d32367936142d0a734143e5e63cdf86be7457723535b787a9cfcfa32fe1d61ad5a2617220\",\n    \"0x8d27e7fbff77d5b9b9bbc864d5231fecf817238a6433db668d5a62a2c1ee1e5694fdd90c3293c06cc0cb15f7cbeab44d0d42be632cb9ff41fc3f6628b4b62897797d7b56126d65b694dcf3e298e3561ac8813fbd7296593ced33850426df42db\",\n    \"0xa92039a08b5502d5b211a7744099c9f93fa8c90cedcb1d05e92f01886219dd464eb5fb0337496ad96ed09c987da4e5f019035c5b01cc09b2a18b8a8dd419bc5895388a07e26958f6bd26751929c25f89b8eb4a299d822e2d26fec9ef350e0d3c\",\n    \"0x92dcc5a1c8c3e1b28b1524e3dd6dbecd63017c9201da9dbe077f1b82adc08c50169f56fc7b5a3b28ec6b89254de3e2fd12838a761053437883c3e01ba616670cea843754548ef84bcc397de2369adcca2ab54cd73c55dc68d87aec3fc2fe4f10\"\n  ]\n}"
  },
  {
    "path": "testing/networks/80094/spec.toml",
    "content": "# Mainnet Chain Spec Configuration\n\n# Gwei value constants\nmax-effective-balance = 10_000_000_000_000_000\neffective-balance-increment = 10_000_000_000_000\n\n# Hysteresis parameters\nhysteresis-quotient = 4\nhysteresis-downward-multiplier = 1\nhysteresis-upward-multiplier = 5\n\n# Time parameters\nslots-per-epoch = 192\nslots-per-historical-root = 8\nmin-epochs-to-inactivity-penalty = 4\n\n# Signature domains\ndomain-type-beacon-proposer = \"0x00000000\"\ndomain-type-beacon-attester = \"0x01000000\"\ndomain-type-randao = \"0x02000000\"\ndomain-type-deposit = \"0x03000000\"\ndomain-type-voluntary-exit = \"0x04000000\"\ndomain-type-selection-proof = \"0x05000000\"\ndomain-type-aggregate-and-proof = \"0x06000000\"\ndomain-type-application-mask = \"0x00000001\"\n\n# Eth1-related values\ndeposit-contract-address = \"0x4242424242424242424242424242424242424242\"\nmax-deposits-per-block = 16\ndeposit-eth1-chain-id = 80094\neth1-follow-distance = 1\ntarget-seconds-per-eth1-block = 2\n\n# Fork-related values\ngenesis-time = 1_737_381_600\ndeneb-one-fork-time = 1_738_415_507\nelectra-fork-time = 1_749_056_400\nelectra-one-fork-time = 1_756_915_200\nfulu-fork-time = 9_999_999_999_999_999\n\n# State list lengths\nepochs-per-historical-vector = 8\nepochs-per-slashings-vector = 8\nhistorical-roots-limit = 8\nvalidator-registry-limit = 1_099_511_627_776\n\n# Capella values\nmax-withdrawals-per-payload = 16\nmax-validators-per-withdrawals-sweep = 31\n\n# Deneb values\nmin-epochs-for-blobs-sidecars-request = 4096\nmax-blob-commitments-per-block = 4096\nmax-blobs-per-block = 6\nfield-elements-per-blob = 4096\nbytes-per-blob = 131072\n\n# Berachain genesis values\nvalidator-set-cap = 69\nevm-inflation-address = \"0x0000000000000000000000000000000000000000\"\nevm-inflation-per-block = 0\n\n# Deneb1 value changes\nevm-inflation-address-deneb-one = \"0x656b95E550C07a9ffe548bd4085c72418Ceb1dba\"\nevm-inflation-per-block-deneb-one = 5_750_000_000\n\n# Electra values\nmin-activation-balance = 250_000_000_000_000\nmin-validator-withdrawability-delay = 256\n\n# Fulu values (BRIP-0008 hysteresis + PoL vNext -- TODO: update values)\nhysteresis-quotient-fulu = 100\nhysteresis-upward-multiplier-fulu = 10\nevm-inflation-address-fulu = \"0x0000000000000000000000000000000000000000\"\nevm-inflation-per-block-fulu = 0\n\n[block-delay-configuration]\nmax-block-delay = 300_000_000_000\ntarget-block-time = 2_000_000_000\nconst-block-delay = 500_000_000\nconsensus-update-height = 9_983_085\nconsensus-enable-height = 9_983_086"
  },
  {
    "path": "testing/quick/compare_test.go",
    "content": "//go:build quick\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage compare_test\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\t\"testing/quick\"\n\n\tdatypes \"github.com/berachain/beacon-kit/da/types\"\n\tzspec \"github.com/protolambda/zrnt/eth2/configs\"\n\tztree \"github.com/protolambda/ztyp/tree\"\n\tpprim \"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives\"\n\tpethpb \"github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1\"\n)\n\nvar (\n\tc    = quick.Config{MaxCount: 10_000}\n\thFn  = ztree.GetHashFn()\n\tspec = zspec.Mainnet\n)\n\n// TODO: None of the iterations makes it to `HashTreeRoot` as they all get caught by the nil checks.\n// A custom generator is required like TestExecPayload. Test is skipped for now as it is not useful as is.\nfunc TestBlobSidecarTreeRootPrysm(t *testing.T) {\n\tt.Parallel()\n\tt.Skip()\n\tf := func(sidecar *datypes.BlobSidecar) bool {\n\t\t// skip these cases lest we trigger a\n\t\t// nil-pointer dereference in fastssz\n\t\tif sidecar == nil ||\n\t\t\tsidecar.InclusionProof == nil ||\n\t\t\tsidecar.SignedBeaconBlockHeader == nil ||\n\t\t\tsidecar.SignedBeaconBlockHeader.Header == nil ||\n\n\t\t\t// prysm allows only sidecars whose InclusionProof has\n\t\t\t// length 17, while beaconKit allows different length.\n\t\t\t// We only keep 17 long Inclusion proofs for proper comparison\n\t\t\tlen(sidecar.InclusionProof) != 17 {\n\t\t\treturn true\n\t\t}\n\n\t\tsBlkHeader := sidecar.SignedBeaconBlockHeader\n\t\tblkHeader := sBlkHeader.Header\n\n\t\tpBlobSidecar := &pethpb.BlobSidecar{\n\t\t\tIndex:         sidecar.Index,\n\t\t\tBlob:          sidecar.Blob[:],\n\t\t\tKzgCommitment: sidecar.KzgCommitment[:],\n\t\t\tKzgProof:      sidecar.KzgProof[:],\n\t\t\tSignedBlockHeader: &pethpb.SignedBeaconBlockHeader{\n\t\t\t\tHeader: &pethpb.BeaconBlockHeader{\n\t\t\t\t\tSlot:          pprim.Slot(blkHeader.Slot),\n\t\t\t\t\tProposerIndex: pprim.ValidatorIndex(blkHeader.ProposerIndex),\n\t\t\t\t\tParentRoot:    blkHeader.ParentBlockRoot[:],\n\t\t\t\t\tStateRoot:     blkHeader.StateRoot[:],\n\t\t\t\t\tBodyRoot:      blkHeader.BodyRoot[:],\n\t\t\t\t},\n\t\t\t\tSignature: sBlkHeader.Signature[:],\n\t\t\t},\n\t\t}\n\n\t\t// Setup inclusion proofs\n\t\tinclusionProofs := sidecar.InclusionProof\n\t\tpBlobSidecar.CommitmentInclusionProof = make([][]byte, len(inclusionProofs))\n\t\tfor i, proof := range inclusionProofs {\n\t\t\tpBlobSidecar.CommitmentInclusionProof[i] = proof[:]\n\t\t}\n\n\t\tbeaconRoot := sidecar.HashTreeRoot()\n\t\tprysmRoot, err := pBlobSidecar.HashTreeRoot()\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\n\t\treturn bytes.Equal(prysmRoot[:], beaconRoot[:])\n\t}\n\tif err := quick.Check(f, &c); err != nil {\n\t\tt.Error(err)\n\t}\n}\n"
  },
  {
    "path": "testing/quick/execution_payload_test.go",
    "content": "//go:build quick\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage compare_test\n\nimport (\n\t\"bytes\"\n\t\"math/rand\"\n\t\"reflect\"\n\t\"testing\"\n\t\"testing/quick\"\n\t\"unsafe\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\tbytesprimitives \"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\tzcommon \"github.com/protolambda/zrnt/eth2/beacon/common\"\n\tzdeneb \"github.com/protolambda/zrnt/eth2/beacon/deneb\"\n\tztree \"github.com/protolambda/ztyp/tree\"\n\tzview \"github.com/protolambda/ztyp/view\"\n)\n\n// --- Helper Struct ---\n// execPayloadExported mirrors the exported fields of ExecutionPayload.\n// Note that forkVersion is unexported and omitted.\ntype execPayloadExported struct {\n\t// ParentHash is the hash of the parent block.\n\tParentHash common.ExecutionHash `json:\"parentHash\"`\n\t// FeeRecipient is the address of the fee recipient.\n\tFeeRecipient common.ExecutionAddress `json:\"feeRecipient\"`\n\t// StateRoot is the root of the state trie.\n\tStateRoot common.Bytes32 `json:\"stateRoot\"`\n\t// ReceiptsRoot is the root of the receipts trie.\n\tReceiptsRoot common.Bytes32 `json:\"receiptsRoot\"`\n\t// LogsBloom is the bloom filter for the logs.\n\tLogsBloom bytesprimitives.B256 `json:\"logsBloom\"`\n\t// Random is the prevRandao value.\n\tRandom common.Bytes32 `json:\"prevRandao\"`\n\t// Number is the block number.\n\tNumber math.U64 `json:\"blockNumber\"`\n\t// GasLimit is the gas limit for the block.\n\tGasLimit math.U64 `json:\"gasLimit\"`\n\t// GasUsed is the amount of gas used in the block.\n\tGasUsed math.U64 `json:\"gasUsed\"`\n\t// Timestamp is the timestamp of the block.\n\tTimestamp math.U64 `json:\"timestamp\"`\n\t// ExtraData is the extra data of the block.\n\tExtraData bytesprimitives.Bytes `json:\"extraData\"`\n\t// BaseFeePerGas is the base fee per gas.\n\tBaseFeePerGas *math.U256 `json:\"baseFeePerGas\"`\n\t// BlockHash is the hash of the block.\n\tBlockHash common.ExecutionHash `json:\"blockHash\"`\n\t// Transactions is the list of transactions in the block.\n\tTransactions engineprimitives.Transactions `json:\"transactions\"`\n\t// Withdrawals is the list of withdrawals in the block.\n\tWithdrawals []*engineprimitives.Withdrawal `json:\"withdrawals\"`\n\t// BlobGasUsed is the amount of blob gas used in the block.\n\tBlobGasUsed math.U64 `json:\"blobGasUsed\"`\n\t// ExcessBlobGas is the amount of excess blob gas in the block.\n\tExcessBlobGas math.U64 `json:\"excessBlobGas\"`\n}\n\n// --- Local Alias Type ---\n// TestExecPayload is our alias for ExecutionPayload.\ntype TestExecPayload ctypes.ExecutionPayload\n\n// generateWithdrawals generates a slice of *engineprimitives.Withdrawal\n// with a random length up to maxLen.\nfunc generateWithdrawals(r *rand.Rand, maxLen int) []*engineprimitives.Withdrawal {\n\tn := r.Intn(maxLen + 1) // length between 0 and maxLen\n\twithdrawals := make([]*engineprimitives.Withdrawal, n)\n\t// For each element, use quick.Value to generate a withdrawal.\n\twithdrawalType := reflect.TypeOf(engineprimitives.Withdrawal{})\n\tfor i := 0; i < n; i++ {\n\t\tv, ok := quick.Value(withdrawalType, r)\n\t\tif !ok {\n\t\t\tpanic(\"failed to generate withdrawal\")\n\t\t}\n\t\tw := v.Interface().(engineprimitives.Withdrawal)\n\t\twithdrawals[i] = &w\n\t}\n\treturn withdrawals\n}\n\n// Generate implements quick.Generator for *TestExecPayload.\nfunc (p *TestExecPayload) Generate(r *rand.Rand, size int) reflect.Value {\n\t// Step 1: Generate a value for the helper struct, which contains only exported fields.\n\tvar exp execPayloadExported\n\tv, ok := quick.Value(reflect.TypeOf(exp), r)\n\tif !ok {\n\t\tpanic(\"failed to generate execPayloadExported\")\n\t}\n\texp = v.Interface().(execPayloadExported)\n\n\t// Step 2: Copy exported fields from exp into our alias.\n\tvar tep TestExecPayload\n\ttep.ParentHash = exp.ParentHash\n\ttep.FeeRecipient = exp.FeeRecipient\n\ttep.StateRoot = exp.StateRoot\n\ttep.ReceiptsRoot = exp.ReceiptsRoot\n\ttep.LogsBloom = exp.LogsBloom\n\ttep.Random = exp.Random\n\ttep.Number = exp.Number\n\ttep.GasLimit = exp.GasLimit\n\ttep.GasUsed = exp.GasUsed\n\ttep.Timestamp = exp.Timestamp\n\ttep.ExtraData = exp.ExtraData\n\ttep.BaseFeePerGas = exp.BaseFeePerGas\n\ttep.BlockHash = exp.BlockHash\n\ttep.Transactions = exp.Transactions\n\ttep.Withdrawals = exp.Withdrawals\n\ttep.BlobGasUsed = exp.BlobGasUsed\n\ttep.ExcessBlobGas = exp.ExcessBlobGas\n\n\t// Step 3: Generate withdrawals. Default withdrawals generation only generates a maximum length of 1 so we need a custom helper.\n\ttep.Withdrawals = generateWithdrawals(r, int(constants.MaxWithdrawalsPerPayload))\n\n\t// Step 4: Set the unexported forkVersion via the setter.\n\t// Convert our alias pointer to the production *ctypes.ExecutionPayload.\n\torig := (*ctypes.ExecutionPayload)(&tep)\n\tsupported := version.GetSupportedVersions()\n\torig.Versionable = ctypes.NewVersionable(supported[r.Intn(len(supported))])\n\n\t// Step 5 set a fixed value for BaseFee to avoid panicks. Could be its own generator.\n\torig.BaseFeePerGas = math.NewU256(123)\n\n\t// Return a reflect.Value representing a pointer to our alias.\n\treturn reflect.ValueOf(&tep)\n}\n\nfunc TestExecutionPayloadHashTreeRootZrnt(t *testing.T) {\n\tt.Parallel()\n\tf := func(testPayload *TestExecPayload) bool {\n\t\t// Convert the generated value back to the production type.\n\t\tpayload := (*ctypes.ExecutionPayload)(testPayload)\n\t\ttypeRoot := payload.HashTreeRoot()\n\n\t\tbaseFeePerGas := zview.Uint256View{}\n\t\tbaseFeePerGas.SetFromBig(payload.BaseFeePerGas.ToBig())\n\t\tzpayload := zdeneb.ExecutionPayload{\n\t\t\tParentHash:    ztree.Root(payload.ParentHash),\n\t\t\tFeeRecipient:  zcommon.Eth1Address(payload.FeeRecipient),\n\t\t\tStateRoot:     ztree.Root(payload.StateRoot),\n\t\t\tReceiptsRoot:  ztree.Root(payload.ReceiptsRoot),\n\t\t\tLogsBloom:     zcommon.LogsBloom(payload.LogsBloom),\n\t\t\tPrevRandao:    ztree.Root(payload.Random),\n\t\t\tBlockNumber:   zview.Uint64View(payload.Number),\n\t\t\tGasLimit:      zview.Uint64View(payload.GasLimit),\n\t\t\tGasUsed:       zview.Uint64View(payload.GasUsed),\n\t\t\tTimestamp:     zcommon.Timestamp(payload.Timestamp),\n\t\t\tExtraData:     []byte(payload.ExtraData),\n\t\t\tBaseFeePerGas: baseFeePerGas,\n\t\t\tBlockHash:     ztree.Root(payload.BlockHash),\n\t\t\tTransactions: *(*zcommon.PayloadTransactions)(\n\t\t\t\tunsafe.Pointer(&payload.Transactions)),\n\t\t\tBlobGasUsed:   zview.Uint64View(payload.BlobGasUsed.Unwrap()),\n\t\t\tExcessBlobGas: zview.Uint64View(payload.ExcessBlobGas.Unwrap()),\n\t\t}\n\t\tvar zWithdrawals zcommon.Withdrawals\n\t\tfor _, withdrawal := range payload.Withdrawals {\n\t\t\tzWithdrawal := zcommon.Withdrawal{\n\t\t\t\tIndex:          zcommon.WithdrawalIndex(withdrawal.Index),\n\t\t\t\tValidatorIndex: zcommon.ValidatorIndex(withdrawal.Validator),\n\t\t\t\tAddress:        zcommon.Eth1Address(withdrawal.Address),\n\t\t\t\tAmount:         zcommon.Gwei(withdrawal.Amount),\n\t\t\t}\n\t\t\tzWithdrawals = append(zWithdrawals, zWithdrawal)\n\t\t}\n\t\tzpayload.Withdrawals = zWithdrawals\n\n\t\tzRoot := zpayload.HashTreeRoot(spec, hFn)\n\t\tcontainerRoot := payload.HashTreeRoot()\n\t\treturn bytes.Equal(typeRoot[:], containerRoot[:]) &&\n\t\t\tbytes.Equal(typeRoot[:], zRoot[:])\n\t}\n\tif err := quick.Check(f, &c); err != nil {\n\t\tt.Error(err)\n\t}\n}\n"
  },
  {
    "path": "testing/simulated/chaos_test.go",
    "content": "//go:build simulated\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage simulated_test\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/execution/client\"\n\t\"github.com/cometbft/cometbft/abci/types\"\n)\n\n// TestProcessProposal_CrashedExecutionClient_Errors effectively serves as a test for how a valid node would react to\n// a valid block being proposed but the execution client has crashed.\nfunc (s *SimulatedSuite) TestProcessProposal_CrashedExecutionClient_Errors() {\n\tconst blockHeight = 1\n\tconst coreLoopIterations = 1\n\n\t// Initialize the chain state.\n\ts.InitializeChain(s.T(), 1)\n\tnodeAddress, err := s.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\t// Test happens post Deneb1 fork.\n\tstartTime := time.Now()\n\n\t// Go through 1 iteration of the core loop to bypass any startup specific edge cases such as sync head on startup.\n\tproposals, _, proposalTime := s.MoveChainToHeight(s.T(), blockHeight, coreLoopIterations, nodeAddress, startTime)\n\ts.Require().Len(proposals, coreLoopIterations)\n\n\tcurrentHeight := int64(blockHeight + coreLoopIterations)\n\n\t// Prepare a valid block proposal.\n\tproposal, err := s.SimComet.Comet.PrepareProposal(s.CtxComet, &types.PrepareProposalRequest{\n\t\tHeight:          currentHeight,\n\t\tTime:            proposalTime,\n\t\tProposerAddress: nodeAddress,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotEmpty(proposal)\n\n\t// Reset the log buffer to discard old logs we don't care about.\n\ts.LogBuffer.Reset()\n\t// Kill the execution client.\n\terr = s.ElHandle.Close()\n\ts.Require().NoError(err)\n\t// Process the proposal containing the valid block.\n\tprocessResp, err := s.SimComet.Comet.ProcessProposal(s.CtxComet, &types.ProcessProposalRequest{\n\t\tTxs:             proposal.Txs,\n\t\tHeight:          currentHeight,\n\t\tProposerAddress: nodeAddress,\n\t\tTime:            proposalTime,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_REJECT, processResp.Status)\n\ts.Require().Contains(s.LogBuffer.String(), client.ErrBadConnection.Error())\n}\n\n// TestContextHandling_SIGINT_SafeShutdown mimicks the expected outcome of a SIGINT by calling context cancel and stop services.\nfunc (s *SimulatedSuite) TestContextHandling_SIGINT_SafeShutdown() {\n\tconst blockHeight = 1\n\tconst coreLoopIterations = 1\n\n\t// Initialize the chain state.\n\ts.InitializeChain(s.T(), 1)\n\tnodeAddress, err := s.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\t// Test happens post Deneb1 fork.\n\tstartTime := time.Now()\n\n\t// Run through core loop iterations to bypass any startup edge cases.\n\tproposals, _, proposalTime := s.MoveChainToHeight(s.T(), blockHeight, coreLoopIterations, nodeAddress, startTime)\n\ts.Require().Len(proposals, coreLoopIterations)\n\n\tcurrentHeight := int64(blockHeight + coreLoopIterations)\n\n\ts.LogBuffer.Reset()\n\t// Kill the EL (execution layer)\n\terr = s.ElHandle.Close()\n\ts.Require().NoError(err)\n\n\ttype proposalResult struct {\n\t\tproposal *types.PrepareProposalResponse\n\t\terr      error\n\t}\n\t// Capture result of prepare proposal\n\tresultCh := make(chan proposalResult, 1)\n\n\t// Prepare proposal in a separate goroutine since it will block due to retrying on the crashed EL.\n\tgo func() {\n\t\tproposal, err := s.SimComet.Comet.PrepareProposal(s.CtxComet, &types.PrepareProposalRequest{\n\t\t\tHeight:          currentHeight,\n\t\t\tTime:            proposalTime,\n\t\t\tProposerAddress: nodeAddress,\n\t\t})\n\t\tresultCh <- proposalResult{\n\t\t\tproposal: proposal,\n\t\t\terr:      err,\n\t\t}\n\t}()\n\n\t// Mimic the behavior of the shutdown function when a SIGINT is observed.\n\ts.CtxAppCancelFn()\n\ts.TestNode.ServiceRegistry.StopAll()\n\n\t// Wait 2 seconds for PrepareProposal to return its result.\n\tselect {\n\tcase res := <-resultCh:\n\t\ts.Require().NoError(res.err)\n\t\ts.Require().Empty(res.proposal)\n\t\t// Shutdown is the last service that is completed and indicates\n\t\ts.Require().Contains(s.LogBuffer.String(), \"All services stopped\")\n\tcase <-time.After(2 * time.Second):\n\t\ts.T().Error(\"PrepareProposal did not finish within 2 seconds after shutdown\")\n\t}\n}\n\n// TestContextHandling_CancelledContext_Rejected tests that ABCI requests are rejected if the context is cancelled\nfunc (s *SimulatedSuite) TestContextHandling_CancelledContext_Rejected() {\n\tconst blockHeight = 1\n\tconst coreLoopIterations = 1\n\n\t// Initialize the chain state.\n\ts.InitializeChain(s.T(), 1)\n\tnodeAddress, err := s.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\t// Test happens post Deneb1 fork.\n\tstartTime := time.Now()\n\n\t// Go through 1 iteration of the core loop to bypass any startup specific edge cases such as sync head on startup.\n\tproposals, _, proposalTime := s.MoveChainToHeight(s.T(), blockHeight, coreLoopIterations, nodeAddress, startTime)\n\ts.Require().Len(proposals, coreLoopIterations)\n\n\tcurrentHeight := int64(blockHeight + coreLoopIterations)\n\n\t// Kill the EL\n\terr = s.ElHandle.Close()\n\ts.Require().NoError(err)\n\n\t// Cancel the App\n\ts.CtxAppCancelFn()\n\n\ts.LogBuffer.Reset()\n\tproposal, err := s.SimComet.Comet.PrepareProposal(s.CtxComet, &types.PrepareProposalRequest{\n\t\tHeight:          currentHeight,\n\t\tTime:            proposalTime,\n\t\tProposerAddress: nodeAddress,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().Empty(proposal)\n\n\tprocessResp, err := s.SimComet.Comet.ProcessProposal(s.CtxComet, &types.ProcessProposalRequest{\n\t\tTxs:             proposal.Txs,\n\t\tHeight:          currentHeight,\n\t\tProposerAddress: nodeAddress,\n\t\tTime:            proposalTime,\n\t})\n\ts.Require().Error(err, context.Canceled)\n\ts.Require().Nil(processResp)\n\n\tfinalizeResp, err := s.SimComet.Comet.FinalizeBlock(s.CtxComet, &types.FinalizeBlockRequest{\n\t\tTxs:             proposal.Txs,\n\t\tHeight:          currentHeight,\n\t\tProposerAddress: nodeAddress,\n\t\tTime:            proposalTime,\n\t})\n\ts.Require().Error(err, context.Canceled)\n\ts.Require().Nil(finalizeResp)\n\n\t_, err = s.SimComet.Comet.Commit(s.CtxComet, &types.CommitRequest{})\n\ts.Require().Error(err, context.Canceled)\n}\n"
  },
  {
    "path": "testing/simulated/components.go",
    "content": "//go:build simulated\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage simulated\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/config/spec\"\n\t\"github.com/berachain/beacon-kit/node-core/components\"\n)\n\nfunc FixedComponents(t *testing.T) []any {\n\tt.Helper()\n\tc := []any{\n\t\tcomponents.ProvideAttributesFactory,\n\t\tcomponents.ProvideAvailabilityStore,\n\t\tcomponents.ProvideDepositContract,\n\t\tcomponents.ProvideBlockStore,\n\t\tcomponents.ProvideBlsSigner,\n\t\tcomponents.ProvideBlobProcessor,\n\t\tcomponents.ProvideBlobProofVerifier,\n\t\tcomponents.ProvideChainService,\n\t\tcomponents.ProvideNode,\n\t\tcomponents.ProvideConfig,\n\t\tcomponents.ProvideServerConfig,\n\t\tcomponents.ProvideDepositStore,\n\t\tcomponents.ProvideEngineClient,\n\t\tcomponents.ProvideExecutionEngine,\n\t\tcomponents.ProvideJWTSecret,\n\t\tcomponents.ProvideLocalBuilder,\n\t\tcomponents.ProvideReportingService,\n\t\tcomponents.ProvideServiceRegistry,\n\t\tcomponents.ProvideSidecarFactory,\n\t\tcomponents.ProvideStateProcessor,\n\t\tcomponents.ProvideKVStore,\n\t\tcomponents.ProvideStorageBackend,\n\t\tcomponents.ProvideTelemetrySink,\n\t\tcomponents.ProvideTelemetryService,\n\t\tcomponents.ProvideTrustedSetup,\n\t\tcomponents.ProvideValidatorService,\n\t\tcomponents.ProvideNodeAPIServer,\n\t\tcomponents.ProvideShutDownService,\n\t}\n\treturn c\n}\n\n// ProvideElectraGenesisChainSpec provides a chain spec with pectra as the genesis.\nfunc ProvideElectraGenesisChainSpec() (chain.Spec, error) {\n\tspecData := spec.TestnetChainSpecData()\n\t// Both Deneb1 and Electra happen in genesis.\n\tspecData.GenesisTime = 0\n\tspecData.Deneb1ForkTime = 0\n\tspecData.ElectraForkTime = 0\n\tspecData.Electra1ForkTime = 9223372036854775807\n\tspecData.FuluForkTime = 9223372036854775807\n\t// We set slots per epoch to 2 for faster observation of withdrawal behaviour\n\tspecData.SlotsPerEpoch = 2\n\t// We set this to 4 so tests are faster\n\tspecData.MinValidatorWithdrawabilityDelay = 4\n\n\tchainSpec, err := chain.NewSpec(specData)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn chainSpec, nil\n}\n\n// ProvideSimulationChainSpec provides a default chain-spec equivalent to testnet.\n// Bypasses the need for environment variables.\nfunc ProvideSimulationChainSpec() (chain.Spec, error) {\n\tspecData := spec.TestnetChainSpecData()\n\tspecData.GenesisTime = 0\n\t// Arbitrary number\n\tspecData.Deneb1ForkTime = 30\n\t// High number as we don't want to activate electra.\n\tspecData.ElectraForkTime = 9999999999999999\n\tspecData.Electra1ForkTime = 9999999999999999\n\tspecData.FuluForkTime = 9999999999999999\n\tchainSpec, err := chain.NewSpec(specData)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn chainSpec, nil\n}\n\n// ProvidePectraForkTestChainSpec provides a chain spec with pectra at timestamp 10\nfunc ProvidePectraForkTestChainSpec() (chain.Spec, error) {\n\tspecData := spec.TestnetChainSpecData()\n\tspecData.GenesisTime = 0\n\tspecData.Deneb1ForkTime = 0\n\tspecData.ElectraForkTime = 10\n\tspecData.Electra1ForkTime = 9223372036854775807\n\tspecData.FuluForkTime = 9223372036854775807\n\tchainSpec, err := chain.NewSpec(specData)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn chainSpec, nil\n}\n\n// ProvidePectraWithdrawalTestChainSpec provides a chain spec used for withdrawal testing\nfunc ProvidePectraWithdrawalTestChainSpec() (chain.Spec, error) {\n\tspecData := spec.TestnetChainSpecData()\n\tspecData.GenesisTime = 0\n\tspecData.Deneb1ForkTime = 0\n\tspecData.ElectraForkTime = 10\n\tspecData.Electra1ForkTime = 9223372036854775807\n\tspecData.FuluForkTime = 9223372036854775807\n\t// We set slots per epoch to 1 for faster observation of withdrawal behaviour\n\tspecData.SlotsPerEpoch = 1\n\t// We set this to 4 so tests are faster\n\tspecData.MinValidatorWithdrawabilityDelay = 4\n\t// Reduced validator set cap so eviction withdrawals are easier to trigger\n\tspecData.ValidatorSetCap = 1\n\tchainSpec, err := chain.NewSpec(specData)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn chainSpec, nil\n}\n"
  },
  {
    "path": "testing/simulated/el-genesis-files/eth-genesis.json",
    "content": "{\n  \"config\": {\n    \"chainId\": 80069,\n    \"homesteadBlock\": 0,\n    \"daoForkBlock\": 0,\n    \"daoForkSupport\": true,\n    \"eip150Block\": 0,\n    \"eip155Block\": 0,\n    \"eip158Block\": 0,\n    \"byzantiumBlock\": 0,\n    \"constantinopleBlock\": 0,\n    \"petersburgBlock\": 0,\n    \"istanbulBlock\": 0,\n    \"muirGlacierBlock\": 0,\n    \"berlinBlock\": 0,\n    \"londonBlock\": 0,\n    \"arrowGlacierBlock\": 0,\n    \"grayGlacierBlock\": 0,\n    \"mergeNetsplitBlock\": 0,\n    \"shanghaiTime\": 0,\n    \"cancunTime\": 0,\n    \"terminalTotalDifficulty\": 0,\n    \"terminalTotalDifficultyPassed\": true,\n    \"ethash\": {},\n    \"blobSchedule\": {\n      \"cancun\": {\n        \"target\": 3,\n        \"max\": 6,\n        \"baseFeeUpdateFraction\": 3338477\n      }\n    },\n    \"berachain\": {\n      \"prague1\": {\n        \"time\": 9223372036854775807,\n        \"baseFeeChangeDenominator\": 48,\n        \"minimumBaseFeeWei\": 10000000000,\n        \"polDistributorAddress\": \"0x4200000000000000000000000000000000000042\"\n      },\n      \"prague2\": {\n        \"time\": 9223372036854775807,\n        \"minimumBaseFeeWei\": 0\n      }\n    }\n  },\n  \"coinbase\": \"0x0000000000000000000000000000000000000000\",\n  \"difficulty\": \"0x0\",\n  \"extraData\": \"0x0000000000000000000000000000000000000000000000000000000000000000658bdf435d810c91414ec09147daa6db624063790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n  \"gasLimit\": \"0x1c9c380\",\n  \"nonce\": \"0x0000000000000000\",\n  \"timestamp\": \"0x0\",\n  \"alloc\": {\n    \"0x20f33ce90a13a4b5e7697e3544c3083b8f8a51d4\": {\n      \"balance\": \"0x123450000000000000000\"\n    },\n    \"0x56898d1aFb10cad584961eb96AcD476C6826e41E\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1e2e53c2451d0f9ED4B7952991BE0c95165D5c01\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3bd0E8f1B1E8Ec99a4E1762F4058F9884C93af31\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xD073a84e2ccDF91a9025179330438485E886D206\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x8a88215ae882dfA519730c40109556c1C235729f\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1a0A57e5e6a66aD732295ddAF0aed286a4e64310\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x185F4Eebd01614aE3d12a5E49b184B054C46d37B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xdb96E9cDD1e457b602f97d33e51736D7a5216496\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x44a5FBfa7d6f3Fd92cca01f6764509f8Fc33dfa5\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3649839562C8dA64E6215EB0f5371629Ead9729D\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x51e15e71c865FE702C9347610667f83658A20e00\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xBC9BC89b295a14F3976234Cc37C73e3D286f3a49\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x12De044207a90709Ef2602D3D9D945d64dAe6147\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x4Afe0DFDAcc91F0fA2AEe39F9eAd66b64d03EbD6\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xBC3c03b4185A6F10618CC4E7B9f4AdD59AB5FbbA\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xDc6De65f6070b409125217a12Cf576A208Cc1998\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xF60fD8632Fc77E19b3A0637d115d0fdd06F36968\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xbcC90AD39D377cA0b7b4F36eC463103E2728C33F\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x6F69542fC88fF84C480FFf510aB7108120447247\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2f6eB3D9a41157322dE01A6E707F6F118Cb00A7b\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x187bE38A1f448b0F42423151A683dCAea949008B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xA1d283f1a11A36D20FF38F29e12CA8F7Cf8709c1\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x868a33C94F91398B6245e1f0E4CF128B2F28714B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x67c942Ef50Fc690eA779067a6A0d444a8234baB5\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xDE8E0E641E2Fb52c22460e6a1533c6BD13A00B37\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x9beFa0FB7a1A9E6cC7596204DbB8962E87091D64\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x62cB9bF32EA104f6D5eBf6879e876439f9492E4B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xdb9cB94B166DfdC9F337EA63b32B448d993d7008\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7c4d7dB81c544B768E1f4782011077202B74B5C0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xaEf63D7F7e2637c99FeA1B63366b244B4da12D70\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3DFb4173ec41EB976260fd689E5AB9772C66beaf\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x5145b1B855bca67A119CB02A42aF4Bdbc66B725C\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf4b2eb959A4C4b0E148340676999FC0446D446D4\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xb86d37333072eFb48cEaa46C67271A27CA5Bda82\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x6CBcF4198fDA91D00fD469340E6DF6df086159e3\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xE7F444b5f772281384117674002d540131e533Ca\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x719Be866A77CeEc1BaC4FD37910c0975eFd52f55\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x0e10cDAd84D788843aF48673C5b260A02ef78742\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xcB6632daA65e6c921c2963C37320f63f54fC8fE3\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xDe5C7198e2416baB7e7a1EA758858Cd7301740bF\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x25fc16D8E2314B305dF05C032E617638284801D6\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xD2a3b89AE8D2c3bD39E2F24612ecFCD8600360C9\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2F4fD8a82A1400E654eeEC59b0e588445ffE0F96\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x10FdFa4EFc83d6CC42F5ef14c13da8b98E458214\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x49cE37B2019bb2d0B8b6a094ef87a6Dd625454A0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x800830F031ab1dd5895a5ec5B561427AD18f9ea8\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3124d9885b11B52c56A2aee610AfCf5740d484F0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xA6177defF3b768b1D678EdF7583b8cf210C777c0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xF99139D2FCc5E25F57B0B91fd382a21B3AFF9cbA\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xC4DD08191B4d5173e3698491A11e05b63F9Ee097\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xB8865B4B8C56861534CC07ebBD2EA569a9a16323\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2B9935698dc5c19Ab7414AE22f27Da5F4478008a\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xAC3c80F41C3049A89Aba8072FFbFc38a90fb6D8c\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xD6D4Fb22B91FAa54700852a05698B37d45514166\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xAf325Ccc92ae883DEF1634D499d8B093192D7a0c\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7469CeEf99FB67e4990c5F1c085a1B39b2902331\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x14DA5251a1EB236238969575ccE943e2Fb0f4AA1\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xF9f58a87C3f0B3A4a0592938c80C41a7c659f855\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1CF7e940A657eE706718CF180eb21864DE9672C3\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x440C37b22e8D7469128Ea7De6ac2f31419B4A8b1\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x4bD04ABA9fc709835b1EE4789195d10E9e8E53F5\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x4dC3aC871b22F8a98197B0aae976a8dE08e5Bebe\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1f1D0FCa7e19b799c315d4fDf31bA50e6A2AB153\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x28879749Dda99387bdB43295B28bdF251d999F3b\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xC4eD09A472B82516daa3A4d8D1E38AE94CF4855C\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf22FbA9cBeB75ED353931418E9eca71EF1Ab9921\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xC59D8935c0570E75BA0E55E3C661f535C86e368B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf97a36c417D33D1fC60a9163A8715e1aecb29102\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x4245537d9e3fb36fBBf054247FfFB28b0d931503\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xFeb1eafa0154D291e28e393FAF10Bc89e5cCbB22\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf11D16e2EE6BefED82Fbca0b005906E09303aB95\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x9C75eD1A37ae420b4FC0a1F4c26B673227Fd3AFa\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x6a354C708fd248FD778F6adF75E41AA554700F68\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xea94749deFcc40dC5992687974b1C84B1bB9D6df\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7689BE67b205EB5d32811d95D60587Eae4F3036F\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xdBfb742BD2e0e6E353cb61E75B9e11257aC8fB1A\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2E5f031578e8FF82199aaF16f42c44D43Fe61819\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x611a42A2EF62c2461D123e3F0B64b93938bc4781\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1a0c826048DF0E4661E3c53bBd447d497E3f701F\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7f0E54bc3C1a72405646F5dFbBE0D4565c649fe2\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x54e1F990Dc0B7367F1E8eD96dA63BC4bca0E8061\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xbE651bc261b9Da5499a24Bf4214fD494c6e1F5Ac\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xD3c5dAC705289cD005C402C79C8445a47502d8be\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xE5981AA0807eb05611cDb666e32e53b2001bd61d\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x0fb648Cb08e21602AF61AF53fE104E29d46433F7\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x0474f52d25529c4db5f4E72F43303dA71B3541C6\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xe3024d098953661638d59E06f7FcD0B61c424854\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x8b1e58f651CacaAa40291d2a6E0a6404d7Ed99e6\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x8724C57fb8f38A1FccA7177543dd1D8FcD49E5aa\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xd0F043dED28773953562f824334C4cbb84210AE7\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xE3d2b9191EaBD3636A5dd057D522335cfae8c7CF\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3f51B3BB6A18141282Ba002F7709c7E2f337F961\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf6B6A52aA9BD788837c6682f47ACE009BD84b6fc\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x795B761Db5969B7ba53472d5D37c230C859a472F\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7d7f187C2A05cDDCF700dCF2E02c96E7eF03f9B0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2d88ECD4d8F4b0A954886eE8C0802aE14684cd07\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x92B3feac5b7816Dcef96a303c1D5112271A70D2c\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x5DD7bc3BEE395831ce499315ecAFE81DE0556F99\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x5227aaebCA3E5e893547A667666E2e4e12Ca20e0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x47575DAE85403cD408d4639068D1187C427B9897\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xE69ac59e1DF47291AaB8DEc540C796f81De7c892\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xb87fb371Bd3C2093b608cd0E7a8dDD60Bb05C995\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02\": {\n      \"balance\": \"0x0\",\n      \"nonce\": \"0x1\",\n      \"code\": \"0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500\"\n    },\n    \"0x4e59b44847b379578588920cA78FbF26c0B4956C\": {\n      \"balance\": \"0x0\",\n      \"nonce\": \"0x1\",\n      \"code\": \"0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3\"\n    },\n    \"0x4242424242424242424242424242424242424242\": {\n      \"balance\": \"0x0\",\n      \"nonce\": \"0x1\",\n      \"code\": \"0x608060405260043610610093575f3560e01c8063577212fe11610066578063c53925d91161004c578063c53925d914610231578063e12cf4cb14610250578063fea7ab7714610263575f80fd5b8063577212fe146101cc5780639eaffa96146101ed575f80fd5b806301ffc9a7146100975780632dfdf0b5146100cb5780633523f9bd14610103578063560036ec14610126575b5f80fd5b3480156100a2575f80fd5b506100b66100b1366004610bb7565b610282565b60405190151581526020015b60405180910390f35b3480156100d6575f80fd5b505f546100ea9067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016100c2565b34801561010e575f80fd5b5061011860015481565b6040519081526020016100c2565b348015610131575f80fd5b50610193610140366004610c2a565b80516020818301810180516003825292820191909301209152546bffffffffffffffffffffffff8116906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1682565b604080516bffffffffffffffffffffffff909316835273ffffffffffffffffffffffffffffffffffffffff9091166020830152016100c2565b3480156101d7575f80fd5b506101eb6101e6366004610d5f565b61031a565b005b3480156101f8575f80fd5b5061020c610207366004610d5f565b6103e7565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c2565b34801561023c575f80fd5b506101eb61024b366004610d5f565b610428565b6101eb61025e366004610dc1565b61063d565b34801561026e575f80fd5b506101eb61027d366004610e70565b61095c565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f136f920d00000000000000000000000000000000000000000000000000000000145b92915050565b6002828260405161032c929190610ec0565b908152604051908190036020019020543373ffffffffffffffffffffffffffffffffffffffff90911614610383576103837f7c214f0400000000000000000000000000000000000000000000000000000000610afc565b60038282604051610395929190610ec0565b9081526040519081900360200181205f90556103b49083908390610ec0565b604051908190038120907f1c0a7e1bd09da292425c039309671a03de56b89a0858598aab6df6ce84b006db905f90a25050565b5f600283836040516103fa929190610ec0565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff16905092915050565b5f6003838360405161043b929190610ec0565b908152604051908190036020019020805490915073ffffffffffffffffffffffffffffffffffffffff6c01000000000000000000000000820416906bffffffffffffffffffffffff163382146104b4576104b47f819a0d0b00000000000000000000000000000000000000000000000000000000610afc565b6bffffffffffffffffffffffff42166104d06201518083610efc565b6bffffffffffffffffffffffff16111561050d5761050d7fe8966d7a00000000000000000000000000000000000000000000000000000000610afc565b5f60028686604051610520929190610ec0565b9081526040519081900360200181205473ffffffffffffffffffffffffffffffffffffffff169150839060029061055a9089908990610ec0565b908152604051908190036020018120805473ffffffffffffffffffffffffffffffffffffffff939093167fffffffffffffffffffffffff0000000000000000000000000000000000000000909316929092179091556003906105bf9088908890610ec0565b9081526040519081900360200181205f90556105de9087908790610ec0565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff808716845284166020840152917f0adffd98d3072c48341843974dffd7a910bb849ba6ca04163d43bb26feb17403910160405180910390a2505050505050565b6030861461066e5761066e7f9f10647200000000000000000000000000000000000000000000000000000000610afc565b6020841461069f5761069f7fb39bca1600000000000000000000000000000000000000000000000000000000610afc565b606082146106d0576106d07f4be6321b00000000000000000000000000000000000000000000000000000000610afc565b5f73ffffffffffffffffffffffffffffffffffffffff16600288886040516106f9929190610ec0565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff16036108375773ffffffffffffffffffffffffffffffffffffffff8116610768576107687f51969a7a00000000000000000000000000000000000000000000000000000000610afc565b806002888860405161077b929190610ec0565b908152604051908190036020018120805473ffffffffffffffffffffffffffffffffffffffff939093167fffffffffffffffffffffffff0000000000000000000000000000000000000000909316929092179091556107dd9088908890610ec0565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff841683525f6020840152917f0adffd98d3072c48341843974dffd7a910bb849ba6ca04163d43bb26feb17403910160405180910390a261087c565b73ffffffffffffffffffffffffffffffffffffffff81161561087c5761087c7fc4142b4100000000000000000000000000000000000000000000000000000000610afc565b5f610885610b04565b90506509184e72a00067ffffffffffffffff821610156108c8576108c87f0e1eddda00000000000000000000000000000000000000000000000000000000610afc565b5f80547f68af751683498a9f9be59fe8b0d52a64dd155255d85cdb29fea30b1e3f891d46918a918a918a918a9187918b918b9167ffffffffffffffff16908061091083610f20565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060405161094a989796959493929190610f93565b60405180910390a15050505050505050565b5f6002848460405161096f929190610ec0565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff1690503381146109c7576109c77f7c214f0400000000000000000000000000000000000000000000000000000000610afc565b73ffffffffffffffffffffffffffffffffffffffff8216610a0b57610a0b7fd92e233d00000000000000000000000000000000000000000000000000000000610afc565b5f60038585604051610a1e929190610ec0565b908152604051908190036020018120426bffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff86166c01000000000000000000000000027fffffffffffffffffffffffffffffffffffffffff000000000000000000000000161781559150610a969086908690610ec0565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff8681168452851660208401524283830152905190917f7640ec3c8c4695deadda414dd20400acf275297a7c38715f9237657e97ddba5f919081900360600190a25050505050565b805f5260045ffd5b5f610b13633b9aca003461102b565b15610b4157610b417f40567b3800000000000000000000000000000000000000000000000000000000610afc565b5f610b50633b9aca003461103e565b905067ffffffffffffffff811115610b8b57610b8b7f2aa6673400000000000000000000000000000000000000000000000000000000610afc565b610b955f34610b9a565b919050565b5f385f3884865af1610bb35763b12d13eb5f526004601cfd5b5050565b5f60208284031215610bc7575f80fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610bf6575f80fd5b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f60208284031215610c3a575f80fd5b813567ffffffffffffffff811115610c50575f80fd5b8201601f81018413610c60575f80fd5b803567ffffffffffffffff811115610c7a57610c7a610bfd565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160116810181811067ffffffffffffffff82111715610ce657610ce6610bfd565b604052818152828201602001861015610cfd575f80fd5b816020840160208301375f91810160200191909152949350505050565b5f8083601f840112610d2a575f80fd5b50813567ffffffffffffffff811115610d41575f80fd5b602083019150836020828501011115610d58575f80fd5b9250929050565b5f8060208385031215610d70575f80fd5b823567ffffffffffffffff811115610d86575f80fd5b610d9285828601610d1a565b90969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610b95575f80fd5b5f805f805f805f6080888a031215610dd7575f80fd5b873567ffffffffffffffff811115610ded575f80fd5b610df98a828b01610d1a565b909850965050602088013567ffffffffffffffff811115610e18575f80fd5b610e248a828b01610d1a565b909650945050604088013567ffffffffffffffff811115610e43575f80fd5b610e4f8a828b01610d1a565b9094509250610e62905060608901610d9e565b905092959891949750929550565b5f805f60408486031215610e82575f80fd5b833567ffffffffffffffff811115610e98575f80fd5b610ea486828701610d1a565b9094509250610eb7905060208501610d9e565b90509250925092565b818382375f9101908152919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b6bffffffffffffffffffffffff818116838216019081111561031457610314610ecf565b5f67ffffffffffffffff821667ffffffffffffffff8103610f4357610f43610ecf565b60010192915050565b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60a081525f610fa660a083018a8c610f4c565b8281036020840152610fb981898b610f4c565b905067ffffffffffffffff871660408401528281036060840152610fde818688610f4c565b91505067ffffffffffffffff831660808301529998505050505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f8261103957611039610ffe565b500690565b5f8261104c5761104c610ffe565b50049056fea164736f6c634300081a000a\"\n    },\n    \"0x4200000000000000000000000000000000000042\": {\n      \"code\": \"0x608060405234801561000f575f80fd5b5060043610610034575f3560e01c8063163db71b1461003857806360644a6b14610052575b5f80fd5b6100405f5481565b60405190815260200160405180910390f35b610065610060366004610137565b610067565b005b336002600160a01b031461008e57604051632f3a162d60e11b815260040160405180910390fd5b5f8054908061009c836101a5565b909155505060405163999da65b60e01b81526043602160991b019063999da65b906100cd90859085906004016101c9565b5f604051808303815f87803b1580156100e4575f80fd5b505af11580156100f6573d5f803e3d5ffd5b505050507f60b106db8802e863a4a9dc4af78cb0dd63feb55ad4ee60f0453c13309bfdbdd4828260405161012b9291906101c9565b60405180910390a15050565b5f8060208385031215610148575f80fd5b823567ffffffffffffffff81111561015e575f80fd5b8301601f8101851361016e575f80fd5b803567ffffffffffffffff811115610184575f80fd5b856020828401011115610195575f80fd5b6020919091019590945092505050565b5f600182016101c257634e487b7160e01b5f52601160045260245ffd5b5060010190565b60208152816020820152818360408301375f818301604090810191909152601f909201601f1916010191905056fea2646970667358221220c2930abe9036c3b4b2592fab2f2fd516d3698f5c696d82745ddc0af43f7096a764736f6c634300081a0033\",\n      \"nonce\": \"0x1\",\n      \"balance\": \"0x0\"\n    },\n    \"0x4200000000000000000000000000000000000043\": {\n      \"code\": \"0x608060405234801561000f575f80fd5b5060043610610034575f3560e01c80634b28f9a214610038578063999da65b14610052575b5f80fd5b6100405f5481565b60405190815260200160405180910390f35b6100656100603660046100b8565b610067565b005b5f8054908061007583610126565b91905055507fb3a8fa51f8d3759f320e88b7f8d3fb73a2a51b31b3324b37833c4816cf41e7c45f546040516100ac91815260200190565b60405180910390a15050565b5f80602083850312156100c9575f80fd5b823567ffffffffffffffff8111156100df575f80fd5b8301601f810185136100ef575f80fd5b803567ffffffffffffffff811115610105575f80fd5b856020828401011115610116575f80fd5b6020919091019590945092505050565b5f6001820161014357634e487b7160e01b5f52601160045260245ffd5b506001019056fea2646970667358221220350dbb7eed9e4d6e4ff72594b0582b0b2e4c1d6b11c3e5ad382201b47a638cc664736f6c634300081a0033\",\n      \"nonce\": \"0x1\",\n      \"balance\": \"0x0\"\n    }\n  }\n}"
  },
  {
    "path": "testing/simulated/el-genesis-files/pectra-eth-genesis.json",
    "content": "{\n  \"config\": {\n    \"chainId\": 80069,\n    \"homesteadBlock\": 0,\n    \"daoForkBlock\": 0,\n    \"daoForkSupport\": true,\n    \"eip150Block\": 0,\n    \"eip155Block\": 0,\n    \"eip158Block\": 0,\n    \"byzantiumBlock\": 0,\n    \"constantinopleBlock\": 0,\n    \"petersburgBlock\": 0,\n    \"istanbulBlock\": 0,\n    \"muirGlacierBlock\": 0,\n    \"berlinBlock\": 0,\n    \"londonBlock\": 0,\n    \"arrowGlacierBlock\": 0,\n    \"grayGlacierBlock\": 0,\n    \"mergeNetsplitBlock\": 0,\n    \"shanghaiTime\": 0,\n    \"cancunTime\": 0,\n    \"pragueTime\": 0,\n    \"terminalTotalDifficulty\": 0,\n    \"terminalTotalDifficultyPassed\": true,\n    \"ethash\": {},\n    \"blobSchedule\": {\n      \"cancun\": {\n        \"target\": 3,\n        \"max\": 6,\n        \"baseFeeUpdateFraction\": 3338477\n      },\n      \"prague\": {\n        \"target\": 3,\n        \"max\": 6,\n        \"baseFeeUpdateFraction\": 3338477\n      }\n    },\n    \"berachain\": {\n      \"prague1\": {\n        \"time\": 9223372036854775807,\n        \"baseFeeChangeDenominator\": 48,\n        \"minimumBaseFeeWei\": 10000000000,\n        \"polDistributorAddress\": \"0x4200000000000000000000000000000000000042\"\n      },\n      \"prague2\": {\n        \"time\": 9223372036854775807,\n        \"minimumBaseFeeWei\": 0\n      }\n    }\n  },\n  \"coinbase\": \"0x0000000000000000000000000000000000000000\",\n  \"difficulty\": \"0x0\",\n  \"extraData\": \"0x0000000000000000000000000000000000000000000000000000000000000000658bdf435d810c91414ec09147daa6db624063790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n  \"gasLimit\": \"0x1c9c380\",\n  \"nonce\": \"0x0000000000000000\",\n  \"timestamp\": \"0x0\",\n  \"alloc\": {\n    \"0x00000961Ef480Eb55e80D19ad83579A64c007002\": {\n      \"code\": \"0x3373fffffffffffffffffffffffffffffffffffffffe1460cb5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f457600182026001905f5b5f82111560685781019083028483029004916001019190604d565b909390049250505036603814608857366101f457346101f4575f5260205ff35b34106101f457600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160df575060105b5f5b8181146101835782810160030260040181604c02815460601b8152601401816001015481526020019060020154807fffffffffffffffffffffffffffffffff00000000000000000000000000000000168252906010019060401c908160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160e1565b910180921461019557906002556101a0565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101cd57505f5b6001546002828201116101e25750505f6101e8565b01600290035b5f555f600155604c025ff35b5f5ffd\",\n      \"nonce\": \"0x1\",\n      \"balance\": \"0x0\",\n      \"storage\": {\n        \"0x0000000000000000000000000000000000000000000000000000000000000000\": \"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"\n      }\n    },\n    \"0x0000BBdDc7CE488642fb579F8B00f3a590007251\": {\n      \"code\": \"0x3373fffffffffffffffffffffffffffffffffffffffe1460d35760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f82111560685781019083028483029004916001019190604d565b9093900492505050366060146088573661019a573461019a575f5260205ff35b341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060021160e7575060025b5f5b8181146101295782810160040260040181607402815460601b815260140181600101548152602001816002015481526020019060030154905260010160e9565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd\",\n      \"nonce\": \"0x1\",\n      \"balance\": \"0x0\",\n      \"storage\": {\n        \"0x0000000000000000000000000000000000000000000000000000000000000000\": \"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"\n      }\n    },\n    \"0x20f33ce90a13a4b5e7697e3544c3083b8f8a51d4\": {\n      \"balance\": \"0x123450000000000000000\"\n    },\n    \"0x56898d1aFb10cad584961eb96AcD476C6826e41E\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1e2e53c2451d0f9ED4B7952991BE0c95165D5c01\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3bd0E8f1B1E8Ec99a4E1762F4058F9884C93af31\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xD073a84e2ccDF91a9025179330438485E886D206\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x8a88215ae882dfA519730c40109556c1C235729f\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1a0A57e5e6a66aD732295ddAF0aed286a4e64310\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x185F4Eebd01614aE3d12a5E49b184B054C46d37B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xdb96E9cDD1e457b602f97d33e51736D7a5216496\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x44a5FBfa7d6f3Fd92cca01f6764509f8Fc33dfa5\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3649839562C8dA64E6215EB0f5371629Ead9729D\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x51e15e71c865FE702C9347610667f83658A20e00\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xBC9BC89b295a14F3976234Cc37C73e3D286f3a49\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x12De044207a90709Ef2602D3D9D945d64dAe6147\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x4Afe0DFDAcc91F0fA2AEe39F9eAd66b64d03EbD6\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xBC3c03b4185A6F10618CC4E7B9f4AdD59AB5FbbA\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xDc6De65f6070b409125217a12Cf576A208Cc1998\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xF60fD8632Fc77E19b3A0637d115d0fdd06F36968\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xbcC90AD39D377cA0b7b4F36eC463103E2728C33F\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x6F69542fC88fF84C480FFf510aB7108120447247\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2f6eB3D9a41157322dE01A6E707F6F118Cb00A7b\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x187bE38A1f448b0F42423151A683dCAea949008B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xA1d283f1a11A36D20FF38F29e12CA8F7Cf8709c1\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x868a33C94F91398B6245e1f0E4CF128B2F28714B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x67c942Ef50Fc690eA779067a6A0d444a8234baB5\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xDE8E0E641E2Fb52c22460e6a1533c6BD13A00B37\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x9beFa0FB7a1A9E6cC7596204DbB8962E87091D64\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x62cB9bF32EA104f6D5eBf6879e876439f9492E4B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xdb9cB94B166DfdC9F337EA63b32B448d993d7008\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7c4d7dB81c544B768E1f4782011077202B74B5C0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xaEf63D7F7e2637c99FeA1B63366b244B4da12D70\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3DFb4173ec41EB976260fd689E5AB9772C66beaf\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x5145b1B855bca67A119CB02A42aF4Bdbc66B725C\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf4b2eb959A4C4b0E148340676999FC0446D446D4\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xb86d37333072eFb48cEaa46C67271A27CA5Bda82\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x6CBcF4198fDA91D00fD469340E6DF6df086159e3\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xE7F444b5f772281384117674002d540131e533Ca\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x719Be866A77CeEc1BaC4FD37910c0975eFd52f55\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x0e10cDAd84D788843aF48673C5b260A02ef78742\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xcB6632daA65e6c921c2963C37320f63f54fC8fE3\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xDe5C7198e2416baB7e7a1EA758858Cd7301740bF\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x25fc16D8E2314B305dF05C032E617638284801D6\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xD2a3b89AE8D2c3bD39E2F24612ecFCD8600360C9\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2F4fD8a82A1400E654eeEC59b0e588445ffE0F96\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x10FdFa4EFc83d6CC42F5ef14c13da8b98E458214\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x49cE37B2019bb2d0B8b6a094ef87a6Dd625454A0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x800830F031ab1dd5895a5ec5B561427AD18f9ea8\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3124d9885b11B52c56A2aee610AfCf5740d484F0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xA6177defF3b768b1D678EdF7583b8cf210C777c0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xF99139D2FCc5E25F57B0B91fd382a21B3AFF9cbA\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xC4DD08191B4d5173e3698491A11e05b63F9Ee097\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xB8865B4B8C56861534CC07ebBD2EA569a9a16323\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2B9935698dc5c19Ab7414AE22f27Da5F4478008a\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xAC3c80F41C3049A89Aba8072FFbFc38a90fb6D8c\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xD6D4Fb22B91FAa54700852a05698B37d45514166\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xAf325Ccc92ae883DEF1634D499d8B093192D7a0c\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7469CeEf99FB67e4990c5F1c085a1B39b2902331\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x14DA5251a1EB236238969575ccE943e2Fb0f4AA1\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xF9f58a87C3f0B3A4a0592938c80C41a7c659f855\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1CF7e940A657eE706718CF180eb21864DE9672C3\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x440C37b22e8D7469128Ea7De6ac2f31419B4A8b1\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x4bD04ABA9fc709835b1EE4789195d10E9e8E53F5\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x4dC3aC871b22F8a98197B0aae976a8dE08e5Bebe\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1f1D0FCa7e19b799c315d4fDf31bA50e6A2AB153\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x28879749Dda99387bdB43295B28bdF251d999F3b\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xC4eD09A472B82516daa3A4d8D1E38AE94CF4855C\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf22FbA9cBeB75ED353931418E9eca71EF1Ab9921\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xC59D8935c0570E75BA0E55E3C661f535C86e368B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf97a36c417D33D1fC60a9163A8715e1aecb29102\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x4245537d9e3fb36fBBf054247FfFB28b0d931503\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xFeb1eafa0154D291e28e393FAF10Bc89e5cCbB22\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf11D16e2EE6BefED82Fbca0b005906E09303aB95\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x9C75eD1A37ae420b4FC0a1F4c26B673227Fd3AFa\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x6a354C708fd248FD778F6adF75E41AA554700F68\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xea94749deFcc40dC5992687974b1C84B1bB9D6df\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7689BE67b205EB5d32811d95D60587Eae4F3036F\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xdBfb742BD2e0e6E353cb61E75B9e11257aC8fB1A\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2E5f031578e8FF82199aaF16f42c44D43Fe61819\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x611a42A2EF62c2461D123e3F0B64b93938bc4781\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1a0c826048DF0E4661E3c53bBd447d497E3f701F\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7f0E54bc3C1a72405646F5dFbBE0D4565c649fe2\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x54e1F990Dc0B7367F1E8eD96dA63BC4bca0E8061\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xbE651bc261b9Da5499a24Bf4214fD494c6e1F5Ac\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xD3c5dAC705289cD005C402C79C8445a47502d8be\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xE5981AA0807eb05611cDb666e32e53b2001bd61d\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x0fb648Cb08e21602AF61AF53fE104E29d46433F7\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x0474f52d25529c4db5f4E72F43303dA71B3541C6\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xe3024d098953661638d59E06f7FcD0B61c424854\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x8b1e58f651CacaAa40291d2a6E0a6404d7Ed99e6\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x8724C57fb8f38A1FccA7177543dd1D8FcD49E5aa\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xd0F043dED28773953562f824334C4cbb84210AE7\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xE3d2b9191EaBD3636A5dd057D522335cfae8c7CF\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3f51B3BB6A18141282Ba002F7709c7E2f337F961\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf6B6A52aA9BD788837c6682f47ACE009BD84b6fc\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x795B761Db5969B7ba53472d5D37c230C859a472F\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7d7f187C2A05cDDCF700dCF2E02c96E7eF03f9B0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2d88ECD4d8F4b0A954886eE8C0802aE14684cd07\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x92B3feac5b7816Dcef96a303c1D5112271A70D2c\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x5DD7bc3BEE395831ce499315ecAFE81DE0556F99\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x5227aaebCA3E5e893547A667666E2e4e12Ca20e0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x47575DAE85403cD408d4639068D1187C427B9897\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xE69ac59e1DF47291AaB8DEc540C796f81De7c892\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xb87fb371Bd3C2093b608cd0E7a8dDD60Bb05C995\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02\": {\n      \"balance\": \"0x0\",\n      \"nonce\": \"0x1\",\n      \"code\": \"0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500\"\n    },\n    \"0x4e59b44847b379578588920cA78FbF26c0B4956C\": {\n      \"balance\": \"0x0\",\n      \"nonce\": \"0x1\",\n      \"code\": \"0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3\"\n    },\n    \"0x4242424242424242424242424242424242424242\": {\n      \"balance\": \"0x0\",\n      \"nonce\": \"0x1\",\n      \"code\": \"0x608060405260043610610093575f3560e01c8063577212fe11610066578063c53925d91161004c578063c53925d914610231578063e12cf4cb14610250578063fea7ab7714610263575f80fd5b8063577212fe146101cc5780639eaffa96146101ed575f80fd5b806301ffc9a7146100975780632dfdf0b5146100cb5780633523f9bd14610103578063560036ec14610126575b5f80fd5b3480156100a2575f80fd5b506100b66100b1366004610bb7565b610282565b60405190151581526020015b60405180910390f35b3480156100d6575f80fd5b505f546100ea9067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016100c2565b34801561010e575f80fd5b5061011860015481565b6040519081526020016100c2565b348015610131575f80fd5b50610193610140366004610c2a565b80516020818301810180516003825292820191909301209152546bffffffffffffffffffffffff8116906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1682565b604080516bffffffffffffffffffffffff909316835273ffffffffffffffffffffffffffffffffffffffff9091166020830152016100c2565b3480156101d7575f80fd5b506101eb6101e6366004610d5f565b61031a565b005b3480156101f8575f80fd5b5061020c610207366004610d5f565b6103e7565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c2565b34801561023c575f80fd5b506101eb61024b366004610d5f565b610428565b6101eb61025e366004610dc1565b61063d565b34801561026e575f80fd5b506101eb61027d366004610e70565b61095c565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f136f920d00000000000000000000000000000000000000000000000000000000145b92915050565b6002828260405161032c929190610ec0565b908152604051908190036020019020543373ffffffffffffffffffffffffffffffffffffffff90911614610383576103837f7c214f0400000000000000000000000000000000000000000000000000000000610afc565b60038282604051610395929190610ec0565b9081526040519081900360200181205f90556103b49083908390610ec0565b604051908190038120907f1c0a7e1bd09da292425c039309671a03de56b89a0858598aab6df6ce84b006db905f90a25050565b5f600283836040516103fa929190610ec0565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff16905092915050565b5f6003838360405161043b929190610ec0565b908152604051908190036020019020805490915073ffffffffffffffffffffffffffffffffffffffff6c01000000000000000000000000820416906bffffffffffffffffffffffff163382146104b4576104b47f819a0d0b00000000000000000000000000000000000000000000000000000000610afc565b6bffffffffffffffffffffffff42166104d06201518083610efc565b6bffffffffffffffffffffffff16111561050d5761050d7fe8966d7a00000000000000000000000000000000000000000000000000000000610afc565b5f60028686604051610520929190610ec0565b9081526040519081900360200181205473ffffffffffffffffffffffffffffffffffffffff169150839060029061055a9089908990610ec0565b908152604051908190036020018120805473ffffffffffffffffffffffffffffffffffffffff939093167fffffffffffffffffffffffff0000000000000000000000000000000000000000909316929092179091556003906105bf9088908890610ec0565b9081526040519081900360200181205f90556105de9087908790610ec0565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff808716845284166020840152917f0adffd98d3072c48341843974dffd7a910bb849ba6ca04163d43bb26feb17403910160405180910390a2505050505050565b6030861461066e5761066e7f9f10647200000000000000000000000000000000000000000000000000000000610afc565b6020841461069f5761069f7fb39bca1600000000000000000000000000000000000000000000000000000000610afc565b606082146106d0576106d07f4be6321b00000000000000000000000000000000000000000000000000000000610afc565b5f73ffffffffffffffffffffffffffffffffffffffff16600288886040516106f9929190610ec0565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff16036108375773ffffffffffffffffffffffffffffffffffffffff8116610768576107687f51969a7a00000000000000000000000000000000000000000000000000000000610afc565b806002888860405161077b929190610ec0565b908152604051908190036020018120805473ffffffffffffffffffffffffffffffffffffffff939093167fffffffffffffffffffffffff0000000000000000000000000000000000000000909316929092179091556107dd9088908890610ec0565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff841683525f6020840152917f0adffd98d3072c48341843974dffd7a910bb849ba6ca04163d43bb26feb17403910160405180910390a261087c565b73ffffffffffffffffffffffffffffffffffffffff81161561087c5761087c7fc4142b4100000000000000000000000000000000000000000000000000000000610afc565b5f610885610b04565b90506509184e72a00067ffffffffffffffff821610156108c8576108c87f0e1eddda00000000000000000000000000000000000000000000000000000000610afc565b5f80547f68af751683498a9f9be59fe8b0d52a64dd155255d85cdb29fea30b1e3f891d46918a918a918a918a9187918b918b9167ffffffffffffffff16908061091083610f20565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060405161094a989796959493929190610f93565b60405180910390a15050505050505050565b5f6002848460405161096f929190610ec0565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff1690503381146109c7576109c77f7c214f0400000000000000000000000000000000000000000000000000000000610afc565b73ffffffffffffffffffffffffffffffffffffffff8216610a0b57610a0b7fd92e233d00000000000000000000000000000000000000000000000000000000610afc565b5f60038585604051610a1e929190610ec0565b908152604051908190036020018120426bffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff86166c01000000000000000000000000027fffffffffffffffffffffffffffffffffffffffff000000000000000000000000161781559150610a969086908690610ec0565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff8681168452851660208401524283830152905190917f7640ec3c8c4695deadda414dd20400acf275297a7c38715f9237657e97ddba5f919081900360600190a25050505050565b805f5260045ffd5b5f610b13633b9aca003461102b565b15610b4157610b417f40567b3800000000000000000000000000000000000000000000000000000000610afc565b5f610b50633b9aca003461103e565b905067ffffffffffffffff811115610b8b57610b8b7f2aa6673400000000000000000000000000000000000000000000000000000000610afc565b610b955f34610b9a565b919050565b5f385f3884865af1610bb35763b12d13eb5f526004601cfd5b5050565b5f60208284031215610bc7575f80fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610bf6575f80fd5b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f60208284031215610c3a575f80fd5b813567ffffffffffffffff811115610c50575f80fd5b8201601f81018413610c60575f80fd5b803567ffffffffffffffff811115610c7a57610c7a610bfd565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160116810181811067ffffffffffffffff82111715610ce657610ce6610bfd565b604052818152828201602001861015610cfd575f80fd5b816020840160208301375f91810160200191909152949350505050565b5f8083601f840112610d2a575f80fd5b50813567ffffffffffffffff811115610d41575f80fd5b602083019150836020828501011115610d58575f80fd5b9250929050565b5f8060208385031215610d70575f80fd5b823567ffffffffffffffff811115610d86575f80fd5b610d9285828601610d1a565b90969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610b95575f80fd5b5f805f805f805f6080888a031215610dd7575f80fd5b873567ffffffffffffffff811115610ded575f80fd5b610df98a828b01610d1a565b909850965050602088013567ffffffffffffffff811115610e18575f80fd5b610e248a828b01610d1a565b909650945050604088013567ffffffffffffffff811115610e43575f80fd5b610e4f8a828b01610d1a565b9094509250610e62905060608901610d9e565b905092959891949750929550565b5f805f60408486031215610e82575f80fd5b833567ffffffffffffffff811115610e98575f80fd5b610ea486828701610d1a565b9094509250610eb7905060208501610d9e565b90509250925092565b818382375f9101908152919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b6bffffffffffffffffffffffff818116838216019081111561031457610314610ecf565b5f67ffffffffffffffff821667ffffffffffffffff8103610f4357610f43610ecf565b60010192915050565b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60a081525f610fa660a083018a8c610f4c565b8281036020840152610fb981898b610f4c565b905067ffffffffffffffff871660408401528281036060840152610fde818688610f4c565b91505067ffffffffffffffff831660808301529998505050505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f8261103957611039610ffe565b500690565b5f8261104c5761104c610ffe565b50049056fea164736f6c634300081a000a\"\n    },\n    \"0x4200000000000000000000000000000000000042\": {\n      \"code\": \"0x608060405234801561000f575f80fd5b5060043610610034575f3560e01c8063163db71b1461003857806360644a6b14610052575b5f80fd5b6100405f5481565b60405190815260200160405180910390f35b610065610060366004610137565b610067565b005b336002600160a01b031461008e57604051632f3a162d60e11b815260040160405180910390fd5b5f8054908061009c836101a5565b909155505060405163999da65b60e01b81526043602160991b019063999da65b906100cd90859085906004016101c9565b5f604051808303815f87803b1580156100e4575f80fd5b505af11580156100f6573d5f803e3d5ffd5b505050507f60b106db8802e863a4a9dc4af78cb0dd63feb55ad4ee60f0453c13309bfdbdd4828260405161012b9291906101c9565b60405180910390a15050565b5f8060208385031215610148575f80fd5b823567ffffffffffffffff81111561015e575f80fd5b8301601f8101851361016e575f80fd5b803567ffffffffffffffff811115610184575f80fd5b856020828401011115610195575f80fd5b6020919091019590945092505050565b5f600182016101c257634e487b7160e01b5f52601160045260245ffd5b5060010190565b60208152816020820152818360408301375f818301604090810191909152601f909201601f1916010191905056fea2646970667358221220c2930abe9036c3b4b2592fab2f2fd516d3698f5c696d82745ddc0af43f7096a764736f6c634300081a0033\",\n      \"nonce\": \"0x1\",\n      \"balance\": \"0x0\"\n    },\n    \"0x4200000000000000000000000000000000000043\": {\n      \"code\": \"0x608060405234801561000f575f80fd5b5060043610610034575f3560e01c80634b28f9a214610038578063999da65b14610052575b5f80fd5b6100405f5481565b60405190815260200160405180910390f35b6100656100603660046100b8565b610067565b005b5f8054908061007583610126565b91905055507fb3a8fa51f8d3759f320e88b7f8d3fb73a2a51b31b3324b37833c4816cf41e7c45f546040516100ac91815260200190565b60405180910390a15050565b5f80602083850312156100c9575f80fd5b823567ffffffffffffffff8111156100df575f80fd5b8301601f810185136100ef575f80fd5b803567ffffffffffffffff811115610105575f80fd5b856020828401011115610116575f80fd5b6020919091019590945092505050565b5f6001820161014357634e487b7160e01b5f52601160045260245ffd5b506001019056fea2646970667358221220350dbb7eed9e4d6e4ff72594b0582b0b2e4c1d6b11c3e5ad382201b47a638cc664736f6c634300081a0033\",\n      \"nonce\": \"0x1\",\n      \"balance\": \"0x0\"\n    }\n  }\n}"
  },
  {
    "path": "testing/simulated/el-genesis-files/pectra-fork-genesis.json",
    "content": "{\n  \"config\": {\n    \"chainId\": 80069,\n    \"homesteadBlock\": 0,\n    \"daoForkBlock\": 0,\n    \"daoForkSupport\": true,\n    \"eip150Block\": 0,\n    \"eip155Block\": 0,\n    \"eip158Block\": 0,\n    \"byzantiumBlock\": 0,\n    \"constantinopleBlock\": 0,\n    \"petersburgBlock\": 0,\n    \"istanbulBlock\": 0,\n    \"muirGlacierBlock\": 0,\n    \"berlinBlock\": 0,\n    \"londonBlock\": 0,\n    \"arrowGlacierBlock\": 0,\n    \"grayGlacierBlock\": 0,\n    \"mergeNetsplitBlock\": 0,\n    \"shanghaiTime\": 0,\n    \"cancunTime\": 0,\n    \"pragueTime\": 10,\n    \"terminalTotalDifficulty\": 0,\n    \"terminalTotalDifficultyPassed\": true,\n    \"ethash\": {},\n    \"blobSchedule\": {\n      \"cancun\": {\n        \"target\": 3,\n        \"max\": 6,\n        \"baseFeeUpdateFraction\": 3338477\n      },\n      \"prague\": {\n        \"target\": 3,\n        \"max\": 6,\n        \"baseFeeUpdateFraction\": 3338477\n      }\n    },\n    \"berachain\": {\n      \"prague1\": {\n        \"time\": 9223372036854775807,\n        \"baseFeeChangeDenominator\": 48,\n        \"minimumBaseFeeWei\": 10000000000,\n        \"polDistributorAddress\": \"0x4200000000000000000000000000000000000042\"\n      },\n      \"prague2\": {\n        \"time\": 9223372036854775807,\n        \"minimumBaseFeeWei\": 0\n      }\n    }\n  },\n  \"coinbase\": \"0x0000000000000000000000000000000000000000\",\n  \"difficulty\": \"0x0\",\n  \"extraData\": \"0x0000000000000000000000000000000000000000000000000000000000000000658bdf435d810c91414ec09147daa6db624063790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n  \"gasLimit\": \"0x1c9c380\",\n  \"nonce\": \"0x0000000000000000\",\n  \"timestamp\": \"0x0\",\n  \"alloc\": {\n    \"0x00000961Ef480Eb55e80D19ad83579A64c007002\": {\n      \"code\": \"0x3373fffffffffffffffffffffffffffffffffffffffe1460cb5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f457600182026001905f5b5f82111560685781019083028483029004916001019190604d565b909390049250505036603814608857366101f457346101f4575f5260205ff35b34106101f457600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160df575060105b5f5b8181146101835782810160030260040181604c02815460601b8152601401816001015481526020019060020154807fffffffffffffffffffffffffffffffff00000000000000000000000000000000168252906010019060401c908160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160e1565b910180921461019557906002556101a0565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101cd57505f5b6001546002828201116101e25750505f6101e8565b01600290035b5f555f600155604c025ff35b5f5ffd\",\n      \"nonce\": \"0x1\",\n      \"balance\": \"0x0\",\n      \"storage\": {\n        \"0x0000000000000000000000000000000000000000000000000000000000000000\": \"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"\n      }\n    },\n    \"0x0000BBdDc7CE488642fb579F8B00f3a590007251\": {\n      \"code\": \"0x3373fffffffffffffffffffffffffffffffffffffffe1460d35760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f82111560685781019083028483029004916001019190604d565b9093900492505050366060146088573661019a573461019a575f5260205ff35b341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060021160e7575060025b5f5b8181146101295782810160040260040181607402815460601b815260140181600101548152602001816002015481526020019060030154905260010160e9565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd\",\n      \"nonce\": \"0x1\",\n      \"balance\": \"0x0\",\n      \"storage\": {\n        \"0x0000000000000000000000000000000000000000000000000000000000000000\": \"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\"\n      }\n    },\n    \"0x20f33ce90a13a4b5e7697e3544c3083b8f8a51d4\": {\n      \"balance\": \"0x84595161401484a000000\"\n    },\n    \"0x56898d1aFb10cad584961eb96AcD476C6826e41E\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1e2e53c2451d0f9ED4B7952991BE0c95165D5c01\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3bd0E8f1B1E8Ec99a4E1762F4058F9884C93af31\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xD073a84e2ccDF91a9025179330438485E886D206\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x8a88215ae882dfA519730c40109556c1C235729f\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1a0A57e5e6a66aD732295ddAF0aed286a4e64310\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x185F4Eebd01614aE3d12a5E49b184B054C46d37B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xdb96E9cDD1e457b602f97d33e51736D7a5216496\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x44a5FBfa7d6f3Fd92cca01f6764509f8Fc33dfa5\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3649839562C8dA64E6215EB0f5371629Ead9729D\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x51e15e71c865FE702C9347610667f83658A20e00\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xBC9BC89b295a14F3976234Cc37C73e3D286f3a49\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x12De044207a90709Ef2602D3D9D945d64dAe6147\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x4Afe0DFDAcc91F0fA2AEe39F9eAd66b64d03EbD6\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xBC3c03b4185A6F10618CC4E7B9f4AdD59AB5FbbA\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xDc6De65f6070b409125217a12Cf576A208Cc1998\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xF60fD8632Fc77E19b3A0637d115d0fdd06F36968\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xbcC90AD39D377cA0b7b4F36eC463103E2728C33F\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x6F69542fC88fF84C480FFf510aB7108120447247\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2f6eB3D9a41157322dE01A6E707F6F118Cb00A7b\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x187bE38A1f448b0F42423151A683dCAea949008B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xA1d283f1a11A36D20FF38F29e12CA8F7Cf8709c1\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x868a33C94F91398B6245e1f0E4CF128B2F28714B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x67c942Ef50Fc690eA779067a6A0d444a8234baB5\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xDE8E0E641E2Fb52c22460e6a1533c6BD13A00B37\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x9beFa0FB7a1A9E6cC7596204DbB8962E87091D64\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x62cB9bF32EA104f6D5eBf6879e876439f9492E4B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xdb9cB94B166DfdC9F337EA63b32B448d993d7008\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7c4d7dB81c544B768E1f4782011077202B74B5C0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xaEf63D7F7e2637c99FeA1B63366b244B4da12D70\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3DFb4173ec41EB976260fd689E5AB9772C66beaf\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x5145b1B855bca67A119CB02A42aF4Bdbc66B725C\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf4b2eb959A4C4b0E148340676999FC0446D446D4\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xb86d37333072eFb48cEaa46C67271A27CA5Bda82\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x6CBcF4198fDA91D00fD469340E6DF6df086159e3\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xE7F444b5f772281384117674002d540131e533Ca\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x719Be866A77CeEc1BaC4FD37910c0975eFd52f55\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x0e10cDAd84D788843aF48673C5b260A02ef78742\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xcB6632daA65e6c921c2963C37320f63f54fC8fE3\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xDe5C7198e2416baB7e7a1EA758858Cd7301740bF\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x25fc16D8E2314B305dF05C032E617638284801D6\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xD2a3b89AE8D2c3bD39E2F24612ecFCD8600360C9\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2F4fD8a82A1400E654eeEC59b0e588445ffE0F96\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x10FdFa4EFc83d6CC42F5ef14c13da8b98E458214\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x49cE37B2019bb2d0B8b6a094ef87a6Dd625454A0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x800830F031ab1dd5895a5ec5B561427AD18f9ea8\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3124d9885b11B52c56A2aee610AfCf5740d484F0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xA6177defF3b768b1D678EdF7583b8cf210C777c0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xF99139D2FCc5E25F57B0B91fd382a21B3AFF9cbA\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xC4DD08191B4d5173e3698491A11e05b63F9Ee097\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xB8865B4B8C56861534CC07ebBD2EA569a9a16323\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2B9935698dc5c19Ab7414AE22f27Da5F4478008a\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xAC3c80F41C3049A89Aba8072FFbFc38a90fb6D8c\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xD6D4Fb22B91FAa54700852a05698B37d45514166\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xAf325Ccc92ae883DEF1634D499d8B093192D7a0c\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7469CeEf99FB67e4990c5F1c085a1B39b2902331\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x14DA5251a1EB236238969575ccE943e2Fb0f4AA1\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xF9f58a87C3f0B3A4a0592938c80C41a7c659f855\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1CF7e940A657eE706718CF180eb21864DE9672C3\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x440C37b22e8D7469128Ea7De6ac2f31419B4A8b1\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x4bD04ABA9fc709835b1EE4789195d10E9e8E53F5\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x4dC3aC871b22F8a98197B0aae976a8dE08e5Bebe\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1f1D0FCa7e19b799c315d4fDf31bA50e6A2AB153\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x28879749Dda99387bdB43295B28bdF251d999F3b\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xC4eD09A472B82516daa3A4d8D1E38AE94CF4855C\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf22FbA9cBeB75ED353931418E9eca71EF1Ab9921\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xC59D8935c0570E75BA0E55E3C661f535C86e368B\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf97a36c417D33D1fC60a9163A8715e1aecb29102\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x4245537d9e3fb36fBBf054247FfFB28b0d931503\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xFeb1eafa0154D291e28e393FAF10Bc89e5cCbB22\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf11D16e2EE6BefED82Fbca0b005906E09303aB95\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x9C75eD1A37ae420b4FC0a1F4c26B673227Fd3AFa\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x6a354C708fd248FD778F6adF75E41AA554700F68\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xea94749deFcc40dC5992687974b1C84B1bB9D6df\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7689BE67b205EB5d32811d95D60587Eae4F3036F\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xdBfb742BD2e0e6E353cb61E75B9e11257aC8fB1A\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2E5f031578e8FF82199aaF16f42c44D43Fe61819\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x611a42A2EF62c2461D123e3F0B64b93938bc4781\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x1a0c826048DF0E4661E3c53bBd447d497E3f701F\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7f0E54bc3C1a72405646F5dFbBE0D4565c649fe2\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x54e1F990Dc0B7367F1E8eD96dA63BC4bca0E8061\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xbE651bc261b9Da5499a24Bf4214fD494c6e1F5Ac\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xD3c5dAC705289cD005C402C79C8445a47502d8be\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xE5981AA0807eb05611cDb666e32e53b2001bd61d\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x0fb648Cb08e21602AF61AF53fE104E29d46433F7\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x0474f52d25529c4db5f4E72F43303dA71B3541C6\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xe3024d098953661638d59E06f7FcD0B61c424854\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x8b1e58f651CacaAa40291d2a6E0a6404d7Ed99e6\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x8724C57fb8f38A1FccA7177543dd1D8FcD49E5aa\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xd0F043dED28773953562f824334C4cbb84210AE7\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xE3d2b9191EaBD3636A5dd057D522335cfae8c7CF\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x3f51B3BB6A18141282Ba002F7709c7E2f337F961\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xf6B6A52aA9BD788837c6682f47ACE009BD84b6fc\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x795B761Db5969B7ba53472d5D37c230C859a472F\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x7d7f187C2A05cDDCF700dCF2E02c96E7eF03f9B0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x2d88ECD4d8F4b0A954886eE8C0802aE14684cd07\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x92B3feac5b7816Dcef96a303c1D5112271A70D2c\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x5DD7bc3BEE395831ce499315ecAFE81DE0556F99\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x5227aaebCA3E5e893547A667666E2e4e12Ca20e0\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x47575DAE85403cD408d4639068D1187C427B9897\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xE69ac59e1DF47291AaB8DEc540C796f81De7c892\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0xb87fb371Bd3C2093b608cd0E7a8dDD60Bb05C995\": {\n      \"balance\": \"0x12345000000000000000000\"\n    },\n    \"0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02\": {\n      \"balance\": \"0x0\",\n      \"nonce\": \"0x1\",\n      \"code\": \"0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500\"\n    },\n    \"0x4e59b44847b379578588920cA78FbF26c0B4956C\": {\n      \"balance\": \"0x0\",\n      \"nonce\": \"0x1\",\n      \"code\": \"0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3\"\n    },\n    \"0x4242424242424242424242424242424242424242\": {\n      \"balance\": \"0x0\",\n      \"nonce\": \"0x1\",\n      \"code\": \"0x608060405260043610610093575f3560e01c8063577212fe11610066578063c53925d91161004c578063c53925d914610231578063e12cf4cb14610250578063fea7ab7714610263575f80fd5b8063577212fe146101cc5780639eaffa96146101ed575f80fd5b806301ffc9a7146100975780632dfdf0b5146100cb5780633523f9bd14610103578063560036ec14610126575b5f80fd5b3480156100a2575f80fd5b506100b66100b1366004610bb7565b610282565b60405190151581526020015b60405180910390f35b3480156100d6575f80fd5b505f546100ea9067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016100c2565b34801561010e575f80fd5b5061011860015481565b6040519081526020016100c2565b348015610131575f80fd5b50610193610140366004610c2a565b80516020818301810180516003825292820191909301209152546bffffffffffffffffffffffff8116906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1682565b604080516bffffffffffffffffffffffff909316835273ffffffffffffffffffffffffffffffffffffffff9091166020830152016100c2565b3480156101d7575f80fd5b506101eb6101e6366004610d5f565b61031a565b005b3480156101f8575f80fd5b5061020c610207366004610d5f565b6103e7565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100c2565b34801561023c575f80fd5b506101eb61024b366004610d5f565b610428565b6101eb61025e366004610dc1565b61063d565b34801561026e575f80fd5b506101eb61027d366004610e70565b61095c565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000148061031457507fffffffff0000000000000000000000000000000000000000000000000000000082167f136f920d00000000000000000000000000000000000000000000000000000000145b92915050565b6002828260405161032c929190610ec0565b908152604051908190036020019020543373ffffffffffffffffffffffffffffffffffffffff90911614610383576103837f7c214f0400000000000000000000000000000000000000000000000000000000610afc565b60038282604051610395929190610ec0565b9081526040519081900360200181205f90556103b49083908390610ec0565b604051908190038120907f1c0a7e1bd09da292425c039309671a03de56b89a0858598aab6df6ce84b006db905f90a25050565b5f600283836040516103fa929190610ec0565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff16905092915050565b5f6003838360405161043b929190610ec0565b908152604051908190036020019020805490915073ffffffffffffffffffffffffffffffffffffffff6c01000000000000000000000000820416906bffffffffffffffffffffffff163382146104b4576104b47f819a0d0b00000000000000000000000000000000000000000000000000000000610afc565b6bffffffffffffffffffffffff42166104d06201518083610efc565b6bffffffffffffffffffffffff16111561050d5761050d7fe8966d7a00000000000000000000000000000000000000000000000000000000610afc565b5f60028686604051610520929190610ec0565b9081526040519081900360200181205473ffffffffffffffffffffffffffffffffffffffff169150839060029061055a9089908990610ec0565b908152604051908190036020018120805473ffffffffffffffffffffffffffffffffffffffff939093167fffffffffffffffffffffffff0000000000000000000000000000000000000000909316929092179091556003906105bf9088908890610ec0565b9081526040519081900360200181205f90556105de9087908790610ec0565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff808716845284166020840152917f0adffd98d3072c48341843974dffd7a910bb849ba6ca04163d43bb26feb17403910160405180910390a2505050505050565b6030861461066e5761066e7f9f10647200000000000000000000000000000000000000000000000000000000610afc565b6020841461069f5761069f7fb39bca1600000000000000000000000000000000000000000000000000000000610afc565b606082146106d0576106d07f4be6321b00000000000000000000000000000000000000000000000000000000610afc565b5f73ffffffffffffffffffffffffffffffffffffffff16600288886040516106f9929190610ec0565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff16036108375773ffffffffffffffffffffffffffffffffffffffff8116610768576107687f51969a7a00000000000000000000000000000000000000000000000000000000610afc565b806002888860405161077b929190610ec0565b908152604051908190036020018120805473ffffffffffffffffffffffffffffffffffffffff939093167fffffffffffffffffffffffff0000000000000000000000000000000000000000909316929092179091556107dd9088908890610ec0565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff841683525f6020840152917f0adffd98d3072c48341843974dffd7a910bb849ba6ca04163d43bb26feb17403910160405180910390a261087c565b73ffffffffffffffffffffffffffffffffffffffff81161561087c5761087c7fc4142b4100000000000000000000000000000000000000000000000000000000610afc565b5f610885610b04565b90506509184e72a00067ffffffffffffffff821610156108c8576108c87f0e1eddda00000000000000000000000000000000000000000000000000000000610afc565b5f80547f68af751683498a9f9be59fe8b0d52a64dd155255d85cdb29fea30b1e3f891d46918a918a918a918a9187918b918b9167ffffffffffffffff16908061091083610f20565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060405161094a989796959493929190610f93565b60405180910390a15050505050505050565b5f6002848460405161096f929190610ec0565b9081526040519081900360200190205473ffffffffffffffffffffffffffffffffffffffff1690503381146109c7576109c77f7c214f0400000000000000000000000000000000000000000000000000000000610afc565b73ffffffffffffffffffffffffffffffffffffffff8216610a0b57610a0b7fd92e233d00000000000000000000000000000000000000000000000000000000610afc565b5f60038585604051610a1e929190610ec0565b908152604051908190036020018120426bffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff86166c01000000000000000000000000027fffffffffffffffffffffffffffffffffffffffff000000000000000000000000161781559150610a969086908690610ec0565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff8681168452851660208401524283830152905190917f7640ec3c8c4695deadda414dd20400acf275297a7c38715f9237657e97ddba5f919081900360600190a25050505050565b805f5260045ffd5b5f610b13633b9aca003461102b565b15610b4157610b417f40567b3800000000000000000000000000000000000000000000000000000000610afc565b5f610b50633b9aca003461103e565b905067ffffffffffffffff811115610b8b57610b8b7f2aa6673400000000000000000000000000000000000000000000000000000000610afc565b610b955f34610b9a565b919050565b5f385f3884865af1610bb35763b12d13eb5f526004601cfd5b5050565b5f60208284031215610bc7575f80fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610bf6575f80fd5b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f60208284031215610c3a575f80fd5b813567ffffffffffffffff811115610c50575f80fd5b8201601f81018413610c60575f80fd5b803567ffffffffffffffff811115610c7a57610c7a610bfd565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160116810181811067ffffffffffffffff82111715610ce657610ce6610bfd565b604052818152828201602001861015610cfd575f80fd5b816020840160208301375f91810160200191909152949350505050565b5f8083601f840112610d2a575f80fd5b50813567ffffffffffffffff811115610d41575f80fd5b602083019150836020828501011115610d58575f80fd5b9250929050565b5f8060208385031215610d70575f80fd5b823567ffffffffffffffff811115610d86575f80fd5b610d9285828601610d1a565b90969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610b95575f80fd5b5f805f805f805f6080888a031215610dd7575f80fd5b873567ffffffffffffffff811115610ded575f80fd5b610df98a828b01610d1a565b909850965050602088013567ffffffffffffffff811115610e18575f80fd5b610e248a828b01610d1a565b909650945050604088013567ffffffffffffffff811115610e43575f80fd5b610e4f8a828b01610d1a565b9094509250610e62905060608901610d9e565b905092959891949750929550565b5f805f60408486031215610e82575f80fd5b833567ffffffffffffffff811115610e98575f80fd5b610ea486828701610d1a565b9094509250610eb7905060208501610d9e565b90509250925092565b818382375f9101908152919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b6bffffffffffffffffffffffff818116838216019081111561031457610314610ecf565b5f67ffffffffffffffff821667ffffffffffffffff8103610f4357610f43610ecf565b60010192915050565b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60a081525f610fa660a083018a8c610f4c565b8281036020840152610fb981898b610f4c565b905067ffffffffffffffff871660408401528281036060840152610fde818688610f4c565b91505067ffffffffffffffff831660808301529998505050505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f8261103957611039610ffe565b500690565b5f8261104c5761104c610ffe565b50049056fea164736f6c634300081a000a\"\n    },\n    \"0x4200000000000000000000000000000000000042\": {\n      \"code\": \"0x608060405234801561000f575f80fd5b5060043610610034575f3560e01c8063163db71b1461003857806360644a6b14610052575b5f80fd5b6100405f5481565b60405190815260200160405180910390f35b610065610060366004610137565b610067565b005b336002600160a01b031461008e57604051632f3a162d60e11b815260040160405180910390fd5b5f8054908061009c836101a5565b909155505060405163999da65b60e01b81526043602160991b019063999da65b906100cd90859085906004016101c9565b5f604051808303815f87803b1580156100e4575f80fd5b505af11580156100f6573d5f803e3d5ffd5b505050507f60b106db8802e863a4a9dc4af78cb0dd63feb55ad4ee60f0453c13309bfdbdd4828260405161012b9291906101c9565b60405180910390a15050565b5f8060208385031215610148575f80fd5b823567ffffffffffffffff81111561015e575f80fd5b8301601f8101851361016e575f80fd5b803567ffffffffffffffff811115610184575f80fd5b856020828401011115610195575f80fd5b6020919091019590945092505050565b5f600182016101c257634e487b7160e01b5f52601160045260245ffd5b5060010190565b60208152816020820152818360408301375f818301604090810191909152601f909201601f1916010191905056fea2646970667358221220c2930abe9036c3b4b2592fab2f2fd516d3698f5c696d82745ddc0af43f7096a764736f6c634300081a0033\",\n      \"nonce\": \"0x1\",\n      \"balance\": \"0x0\"\n    },\n    \"0x4200000000000000000000000000000000000043\": {\n      \"code\": \"0x608060405234801561000f575f80fd5b5060043610610034575f3560e01c80634b28f9a214610038578063999da65b14610052575b5f80fd5b6100405f5481565b60405190815260200160405180910390f35b6100656100603660046100b8565b610067565b005b5f8054908061007583610126565b91905055507fb3a8fa51f8d3759f320e88b7f8d3fb73a2a51b31b3324b37833c4816cf41e7c45f546040516100ac91815260200190565b60405180910390a15050565b5f80602083850312156100c9575f80fd5b823567ffffffffffffffff8111156100df575f80fd5b8301601f810185136100ef575f80fd5b803567ffffffffffffffff811115610105575f80fd5b856020828401011115610116575f80fd5b6020919091019590945092505050565b5f6001820161014357634e487b7160e01b5f52601160045260245ffd5b506001019056fea2646970667358221220350dbb7eed9e4d6e4ff72594b0582b0b2e4c1d6b11c3e5ad382201b47a638cc664736f6c634300081a0033\",\n      \"nonce\": \"0x1\",\n      \"balance\": \"0x0\"\n    }\n  }\n}"
  },
  {
    "path": "testing/simulated/execution/execnode.go",
    "content": "//go:build simulated\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage execution\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/primitives/net/url\"\n\t\"github.com/ory/dockertest\"\n\t\"github.com/ory/dockertest/docker\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// ExecNode represents a test instance of an execution client node running inside a Docker container.\n// The CmdStrBuilder field is used to generate the command string that initializes and runs the node.\ntype ExecNode struct {\n\thomeDir       string\n\timage         docker.PullImageOptions\n\tCmdStrBuilder func(genesisFile string) string\n}\n\n// NewExecNode returns a new ExecNode instance configured with the given home directory,\n// Docker image options, and a command string builder.\nfunc NewExecNode(homeDir string, image docker.PullImageOptions, builder func(genesisFile string) string) *ExecNode {\n\treturn &ExecNode{\n\t\thomeDir:       homeDir,\n\t\timage:         image,\n\t\tCmdStrBuilder: builder,\n\t}\n}\n\n// Start launches the execution client container using dockertest, waits until the client is ready,\n// and returns the container resource along with the connection URL for the Auth RPC endpoint.\nfunc (e *ExecNode) Start(t *testing.T, genesisFile string) (*Resource, *url.ConnectionURL, *url.ConnectionURL) {\n\tt.Helper()\n\n\t// Create a new Docker pool.\n\tpool, err := dockertest.NewPool(\"\")\n\trequire.NoError(t, err, \"failed to create Docker pool\")\n\trequire.NotNil(t, pool, \"Docker pool is nil\")\n\n\t// Verify that we can connect to the Docker daemon.\n\terr = pool.Client.Ping()\n\trequire.NoErrorf(t, err, \"could not connect to Docker: %s\", err)\n\n\t// Pull the image if it is not already present.\n\terr = pool.Client.PullImage(e.image, docker.AuthConfiguration{})\n\trequire.NoError(t, err, \"failed to pull image\")\n\n\t// Resolve the absolute path to the local test files.\n\tabsPath, err := filepath.Abs(\"../files\")\n\trequire.NoError(t, err, \"failed to determine absolute path for test files\")\n\n\trequire.NotNil(t, e.CmdStrBuilder, \"CmdStrBuilder is nil\")\n\tcmdStr := e.CmdStrBuilder(genesisFile)\n\n\t// Run the container with custom commands that initialize and run the client.\n\tresource, err := pool.RunWithOptions(&dockertest.RunOptions{\n\t\tRepository: e.image.Repository,\n\t\tTag:        e.image.Tag,\n\t\t// Override the default entrypoint to use /bin/sh so we can chain commands.\n\t\tEntrypoint: []string{\"/bin/sh\"},\n\t\tCmd: []string{\n\t\t\t\"-c\",\n\t\t\tcmdStr,\n\t\t},\n\t\t// Expose required ports for EL RPC, Auth RPC, and P2P communication.\n\t\tExposedPorts: []string{\"8545/tcp\", \"8551/tcp\", \"30303/tcp\"},\n\t\t// Bind mount the local test data and JWT files to the container.\n\t\tMounts: []string{\n\t\t\tfmt.Sprintf(\"%s:/%s\", e.homeDir, \"testdata\"),\n\t\t\tfmt.Sprintf(\"%s:/%s\", absPath, \"testing/files\"),\n\t\t},\n\t})\n\trequire.NoError(t, err, \"failed to run container\")\n\n\t// Build the connection URLs for EL RPC and Auth RPC.\n\telRPC, err := url.NewFromRaw(\"http://\" + resource.GetHostPort(\"8545/tcp\"))\n\trequire.NoError(t, err, \"failed to create EL RPC URL\")\n\tauthRPC, err := url.NewFromRaw(\"http://\" + resource.GetHostPort(\"8551/tcp\"))\n\trequire.NoError(t, err, \"failed to create Auth RPC URL\")\n\n\tt.Logf(\"Auth RPC URL: %s\", authRPC.String())\n\n\t// Wait until the EL RPC endpoint is available by retrying HTTP GET requests.\n\terr = pool.Retry(func() error {\n\t\tresp, httpErr := http.Get(elRPC.String())\n\t\tif httpErr != nil {\n\t\t\treturn httpErr\n\t\t}\n\t\tdefer resp.Body.Close()\n\t\treturn nil\n\t})\n\trequire.NoError(t, err, \"Container did not become ready in time\")\n\n\treturn &Resource{Resource: resource}, authRPC, elRPC\n}\n"
  },
  {
    "path": "testing/simulated/execution/geth.go",
    "content": "//go:build simulated\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage execution\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/ory/dockertest/docker\"\n)\n\n// NewGethNode creates a new execution node configured for Geth by using the default Geth command builder.\nfunc NewGethNode(homeDir string, image docker.PullImageOptions) *ExecNode {\n\treturn NewExecNode(homeDir, image, defaultGethCmdStrBuilder)\n}\n\n// ValidGethImage returns the default Docker image options for the Geth node.\nfunc ValidGethImage() docker.PullImageOptions {\n\treturn docker.PullImageOptions{\n\t\tRepository: \"ghcr.io/berachain/bera-geth\",\n\t\tTag:        \"latest\",\n\t}\n}\n\n// defaultGethCmdStrBuilder returns a command string tailored for running a Geth node.\nfunc defaultGethCmdStrBuilder(genesisFile string) string {\n\treturn fmt.Sprintf(`\n\t\tbera-geth init --datadir /tmp/gethdata /testdata/%s && \n\t\tbera-geth --http --http.addr 0.0.0.0 --http.api eth,net,web3,debug \\\n\t\t\t--authrpc.addr 0.0.0.0 \\\n\t\t\t--authrpc.jwtsecret /testing/files/jwt.hex \\\n\t\t\t--authrpc.vhosts '*' \\\n\t\t\t--datadir /tmp/gethdata \\\n\t\t\t--ipcpath /tmp/gethdata/bera-geth.ipc \\\n\t\t\t--syncmode full \\\n\t\t\t--verbosity 4 \\\n\t\t\t--nodiscover\n\t`, genesisFile)\n}\n"
  },
  {
    "path": "testing/simulated/execution/resource.go",
    "content": "//go:build simulated\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage execution\n\nimport \"github.com/ory/dockertest\"\n\n// Resource manages a *dockertest.Resource with added utility.\ntype Resource struct {\n\t*dockertest.Resource\n\tisClosed bool\n}\n\nfunc (r *Resource) Close() error {\n\tif r.isClosed {\n\t\treturn nil\n\t}\n\n\tr.isClosed = true\n\treturn r.Resource.Close()\n}\n"
  },
  {
    "path": "testing/simulated/execution/reth.go",
    "content": "//go:build simulated\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage execution\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/ory/dockertest/docker\"\n)\n\n// NewRethNode creates a new execution node configured for Reth by using the default Reth command builder.\nfunc NewRethNode(homeDir string, image docker.PullImageOptions) *ExecNode {\n\treturn NewExecNode(homeDir, image, defaultRethCmdStrBuilder)\n}\n\n// NewRethNodeWithEngineOverride creates a new execution node configured for Reth by using the Reth\n// command builder with the --engine.always-process-payload-attributes-on-canonical-head flag.\nfunc NewRethNodeWithEngineOverride(homeDir string, image docker.PullImageOptions) *ExecNode {\n\treturn NewExecNode(homeDir, image, rethWithEngineOverrideFlagCmdStrBuilder)\n}\n\n// ValidRethImage returns the default Docker image options for the Reth node.\nfunc ValidRethImage() docker.PullImageOptions {\n\treturn docker.PullImageOptions{\n\t\tRepository: \"ghcr.io/berachain/bera-reth\",\n\t\tTag:        \"nightly\",\n\t}\n}\n\n// defaultRethCmdStrBuilder returns a command string tailored for running a Reth node.\nfunc defaultRethCmdStrBuilder(genesisFile string) string {\n\treturn fmt.Sprintf(`\n\t\tbera-reth node --http --http.addr 0.0.0.0 --http.api eth,net,web3,debug \\\n\t\t\t --chain=/testdata/%s \\\n\t\t\t --authrpc.addr 0.0.0.0 \\\n\t\t\t --authrpc.jwtsecret /testing/files/jwt.hex \\\n\t\t\t --datadir /tmp/rethdata \\\n\t\t\t --full \\\n\t\t\t --engine.persistence-threshold=0 \\\n\t\t\t --engine.memory-block-buffer-target=0 \\\n\t\t\t -vvvv \\\n\t`, genesisFile)\n}\n\n// rethWithEngineOverrideFlagCmdStrBuilder returns a command string tailored for running a Reth node\n// with the --engine.always-process-payload-attributes-on-canonical-head flag.\nfunc rethWithEngineOverrideFlagCmdStrBuilder(genesisFile string) string {\n\treturn fmt.Sprintf(`\n\t\tbera-reth node --http --http.addr 0.0.0.0 --http.api eth,net,web3,debug \\\n\t\t\t --chain=/testdata/%s \\\n\t\t\t --authrpc.addr 0.0.0.0 \\\n\t\t\t --authrpc.jwtsecret /testing/files/jwt.hex \\\n\t\t\t --datadir /tmp/rethdata \\\n\t\t\t --full \\\n\t\t\t --engine.persistence-threshold=0 \\\n\t\t\t --engine.memory-block-buffer-target=0 \\\n\t\t\t --engine.always-process-payload-attributes-on-canonical-head \\\n\t\t\t -vvvv \\\n\t`, genesisFile)\n}\n"
  },
  {
    "path": "testing/simulated/execution/simulation_client.go",
    "content": "//go:build simulated\n\n//\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage execution\n\nimport (\n\t\"context\"\n\t\"math/big\"\n\n\t\"github.com/berachain/beacon-kit/execution/client\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/json\"\n\t\"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-ethereum/common/hexutil\"\n\t\"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/ethereum/go-ethereum/crypto/kzg4844\"\n)\n\n// SimulationClient calls `eth_simulateV1` on a Geth node.\ntype SimulationClient struct {\n\tengineClient *client.EngineClient\n}\n\n// TransactionArgs represents the fields needed to construct a dynamic-fee transaction.\ntype TransactionArgs struct {\n\tFrom                 common.Address  `json:\"from\"`\n\tTo                   common.Address  `json:\"to\"`\n\tGas                  *hexutil.Uint64 `json:\"gas\"`\n\tGasPrice             *hexutil.Big    `json:\"gasPrice\"`\n\tMaxFeePerGas         *hexutil.Big    `json:\"maxFeePerGas\"`\n\tMaxPriorityFeePerGas *hexutil.Big    `json:\"maxPriorityFeePerGas\"`\n\tValue                *hexutil.Big    `json:\"value\"`\n\tNonce                *hexutil.Uint64 `json:\"nonce\"`\n\tInput                *hexutil.Bytes  `json:\"input\"`\n\n\tAccessList types.AccessList `json:\"accessList,omitempty\"`\n\tChainID    *hexutil.Big     `json:\"chainId,omitempty\"`\n\n\t// BlobTxType fields.\n\tBlobFeeCap  *hexutil.Big  `json:\"maxFeePerBlobGas\"`\n\tBlobHashes  []common.Hash `json:\"blobVersionedHashes,omitempty\"`\n\tBlobs       []kzg4844.Blob\n\tCommitments []kzg4844.Commitment\n\tProofs      []kzg4844.Proof\n}\n\n// BlockOverrides holds optional block-level overrides for simulation.\ntype BlockOverrides struct {\n\tNumber        *hexutil.Big    `json:\"number,omitempty\"`\n\tDifficulty    *hexutil.Big    `json:\"difficulty,omitempty\"`\n\tTime          *hexutil.Uint64 `json:\"time,omitempty\"`\n\tGasLimit      *hexutil.Uint64 `json:\"gasLimit,omitempty\"`\n\tFeeRecipient  *common.Address `json:\"feeRecipient,omitempty\"`\n\tPrevRandao    *common.Hash    `json:\"prevRandao,omitempty\"`\n\tBaseFeePerGas *hexutil.Big    `json:\"baseFeePerGas,omitempty\"`\n\tBlobBaseFee   *hexutil.Big    `json:\"blobBaseFee,omitempty\"`\n\tBeaconRoot    *common.Hash    `json:\"beaconRoot,omitempty\"`\n\tWithdrawals   types.Withdrawals\n}\n\n// SimBlock is a block containing calls and optional overrides for simulation.\ntype SimBlock struct {\n\tCalls          []TransactionArgs `json:\"calls\"`\n\tBlockOverrides *BlockOverrides   `json:\"blockOverrides\"`\n}\n\n// SimOpts groups all parameters for `eth_simulateV1`.\ntype SimOpts struct {\n\tBlockStateCalls []*SimBlock `json:\"blockStateCalls\"`\n\tValidation      bool        `json:\"validation\"`\n\tTraceTransfers  bool        `json:\"traceTransfers\"`\n}\n\n// CallResult describes the outcome of an individual simulated transaction.\ntype CallResult struct {\n\tReturnData hexutil.Bytes   `json:\"returnData\"`\n\tLogs       json.RawMessage `json:\"logs\"`\n\tGasUsed    *hexutil.Uint64 `json:\"gasUsed\"`\n\tStatus     hexutil.Uint64  `json:\"status\"`\n}\n\n// SimulatedBlock is the response structure returned by `eth_simulateV1`.\ntype SimulatedBlock struct {\n\tBaseFeePerGas         *hexutil.Big      `json:\"baseFeePerGas\"`\n\tBlobGasUsed           *hexutil.Big      `json:\"blobGasUsed\"`\n\tCalls                 []CallResult      `json:\"calls\"`\n\tDifficulty            *hexutil.Big      `json:\"difficulty\"`\n\tExcessBlobGas         *hexutil.Big      `json:\"excessBlobGas\"`\n\tExtraData             hexutil.Bytes     `json:\"extraData\"`\n\tGasLimit              *hexutil.Uint64   `json:\"gasLimit\"`\n\tGasUsed               *hexutil.Uint64   `json:\"gasUsed\"`\n\tHash                  common.Hash       `json:\"hash\"`\n\tLogsBloom             hexutil.Bytes     `json:\"logsBloom\"`\n\tMiner                 common.Address    `json:\"miner\"`\n\tMixHash               common.Hash       `json:\"mixHash\"`\n\tNonce                 hexutil.Bytes     `json:\"nonce\"`\n\tNumber                *hexutil.Big      `json:\"number\"`\n\tParentBeaconBlockRoot common.Hash       `json:\"parentBeaconBlockRoot\"`\n\tParentHash            common.Hash       `json:\"parentHash\"`\n\tReceiptsRoot          common.Hash       `json:\"receiptsRoot\"`\n\tSha3Uncles            common.Hash       `json:\"sha3Uncles\"`\n\tSize                  *hexutil.Uint64   `json:\"size\"`\n\tStateRoot             common.Hash       `json:\"stateRoot\"`\n\tTimestamp             *hexutil.Uint64   `json:\"timestamp\"`\n\tTransactions          []common.Hash     `json:\"transactions\"`\n\tTransactionsRoot      common.Hash       `json:\"transactionsRoot\"`\n\tUncles                []common.Hash     `json:\"uncles\"`\n\tWithdrawals           types.Withdrawals `json:\"withdrawals\"`\n\tWithdrawalsRoot       common.Hash       `json:\"withdrawalsRoot\"`\n}\n\n// NewSimulationClient returns a client for eth_simulateV1 calls.\nfunc NewSimulationClient(cli *client.EngineClient) *SimulationClient {\n\treturn &SimulationClient{cli}\n}\n\n// Simulate calls `eth_simulateV1` with the provided block number and options.\nfunc (c *SimulationClient) Simulate(\n\tctx context.Context,\n\tblockNumber int64,\n\topts *SimOpts,\n) ([]*SimulatedBlock, error) {\n\n\tvar result []*SimulatedBlock\n\tblockNumberInput := hexutil.Uint64(blockNumber)\n\n\tif err := c.engineClient.Call(ctx, &result, \"eth_simulateV1\", opts, blockNumberInput); err != nil {\n\t\treturn nil, err\n\t}\n\treturn result, nil\n}\n\n// TxsToTransactionArgs converts a slice of Geth transactions to TransactionArgs suitable for simulation.\n// The transactions must be dynamic-fee (EIP-1559 or EIP-4844) type.\n// TODO: use the LatestSigner based on a Geth ChainConfig parsed from an EL Genesis File as have currently hardcoded Cancun Signer.\nfunc TxsToTransactionArgs(chainID uint64, txs []*types.Transaction) ([]TransactionArgs, error) {\n\tsigner := types.NewCancunSigner(big.NewInt(int64(chainID)))\n\targs := make([]TransactionArgs, len(txs))\n\n\tfor i, tx := range txs {\n\t\tsender, err := signer.Sender(tx)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tgas := hexutil.Uint64(tx.Gas())\n\t\tfeeCap := hexutil.Big(*tx.GasFeeCap())\n\t\ttipCap := hexutil.Big(*tx.GasTipCap())\n\t\tval := hexutil.Big(*tx.Value())\n\t\tnonce := hexutil.Uint64(tx.Nonce())\n\t\tdata := hexutil.Bytes(tx.Data())\n\t\tchainIDHex := hexutil.Big(*big.NewInt(int64(chainID)))\n\n\t\tcall := TransactionArgs{\n\t\t\tFrom:                 sender,\n\t\t\tTo:                   *tx.To(),\n\t\t\tGas:                  &gas,\n\t\t\tMaxFeePerGas:         &feeCap,\n\t\t\tMaxPriorityFeePerGas: &tipCap,\n\t\t\tValue:                &val,\n\t\t\tNonce:                &nonce,\n\t\t\tInput:                &data,\n\t\t\tAccessList:           tx.AccessList(),\n\t\t\tChainID:              &chainIDHex,\n\t\t}\n\n\t\tif sidecar := tx.BlobTxSidecar(); sidecar != nil {\n\t\t\tblobCap := hexutil.Big(*tx.BlobGasFeeCap())\n\t\t\tcall.BlobHashes = tx.BlobHashes()\n\t\t\tcall.BlobFeeCap = &blobCap\n\t\t\tcall.Blobs = sidecar.Blobs\n\t\t\tcall.Commitments = sidecar.Commitments\n\t\t\tcall.Proofs = sidecar.Proofs\n\t\t}\n\n\t\targs[i] = call\n\t}\n\treturn args, nil\n}\n"
  },
  {
    "path": "testing/simulated/homedir.go",
    "content": "//go:build simulated\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage simulated\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/cli/commands/genesis\"\n\t\"github.com/berachain/beacon-kit/cli/commands/initialize\"\n\t\"github.com/berachain/beacon-kit/cli/commands/server/types\"\n\tgenesisutils \"github.com/berachain/beacon-kit/cli/utils/genesis\"\n\tcometbft \"github.com/berachain/beacon-kit/consensus/cometbft/service\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\t\"github.com/cosmos/cosmos-sdk/client\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nconst TestnetBeaconChainID = \"testnet-beacon-80069\"\n\nconst WithdrawalExecutionAddress = \"0x20f33ce90a13a4b5e7697e3544c3083b8f8a51d4\"\n\n// InitializeHomeDirs sets up one or more temporary home directories with the\n// necessary genesis state and configuration files for testing. It returns a\n// CometBFT config per home directory along with the computed genesis validators\n// root. When multiple directories are provided, premined deposits are\n// consolidated into the first directory and the resulting genesis file is\n// replicated to all others.\nfunc InitializeHomeDirs(\n\tt *testing.T,\n\tchainSpec chain.Spec,\n\telGenesisPath string,\n\ttempHomeDirs ...string,\n) ([]*cmtcfg.Config, common.Root) {\n\tt.Helper()\n\trequire.NotEmpty(t, tempHomeDirs, \"at least one home directory is required\")\n\n\tn := len(tempHomeDirs)\n\tt.Logf(\"Initializing %d home director(ies): %v\", n, tempHomeDirs)\n\n\tconfigs := make([]*cmtcfg.Config, n)\n\tfor i, dir := range tempHomeDirs {\n\t\tconfigs[i] = createCometConfig(t, dir)\n\t\tinitCommand(t, chainSpec, configs[i].RootDir)\n\t}\n\n\tdepositAmount := chainSpec.MaxEffectiveBalance()\n\twithdrawalAddress, err := common.NewExecutionAddressFromHex(WithdrawalExecutionAddress)\n\trequire.NoError(t, err, \"failed to create withdrawal address\")\n\n\tfor i, cfg := range configs {\n\t\tsigner := GetBlsSigner(cfg.RootDir)\n\t\terr = genesis.AddGenesisDeposit(chainSpec, cfg, signer, depositAmount, withdrawalAddress, \"\")\n\t\trequire.NoError(t, err, \"failed to add genesis deposit %d\", i+1)\n\t}\n\n\tprimaryDir := filepath.Join(configs[0].RootDir, \"config\", \"premined-deposits\")\n\tfor i := 1; i < n; i++ {\n\t\tcopyMissingFiles(t, filepath.Join(configs[i].RootDir, \"config\", \"premined-deposits\"), primaryDir)\n\t}\n\n\terr = genesis.CollectGenesisDeposits(configs[0])\n\trequire.NoError(t, err, \"failed to collect genesis deposits\")\n\n\tif n > 1 {\n\t\tsrcGenesis := filepath.Join(configs[0].RootDir, \"config\", \"genesis.json\")\n\t\tdata, readErr := os.ReadFile(srcGenesis)\n\t\trequire.NoError(t, readErr, \"failed to read genesis file: %s\", srcGenesis)\n\t\tfor i := 1; i < n; i++ {\n\t\t\tdst := filepath.Join(configs[i].RootDir, \"config\", \"genesis.json\")\n\t\t\trequire.NoError(t, os.WriteFile(dst, data, 0o600), \"failed to write genesis file: %s\", dst)\n\t\t}\n\t}\n\n\tfor i, cfg := range configs {\n\t\terr = genesis.SetDepositStorage(chainSpec, cfg, elGenesisPath)\n\t\trequire.NoError(t, err, \"failed to set deposit storage %d\", i+1)\n\n\t\terr = genesis.AddExecutionPayload(chainSpec, path.Join(cfg.RootDir, filepath.Base(elGenesisPath)), cfg)\n\t\trequire.NoError(t, err, \"failed to add execution payload %d\", i+1)\n\t}\n\n\tgenesisValidatorsRoot, err := genesisutils.ComputeValidatorsRootFromFile(\n\t\tpath.Join(configs[0].RootDir, \"config/genesis.json\"),\n\t\tchainSpec,\n\t)\n\trequire.NoError(t, err, \"failed to compute validators root\")\n\tfor i := 1; i < n; i++ {\n\t\troot, rootErr := genesisutils.ComputeValidatorsRootFromFile(\n\t\t\tpath.Join(configs[i].RootDir, \"config/genesis.json\"),\n\t\t\tchainSpec,\n\t\t)\n\t\trequire.NoError(t, rootErr, \"failed to compute validators root %d\", i+1)\n\t\trequire.Equal(t, genesisValidatorsRoot, root, \"validators' roots should be equal\")\n\t}\n\n\treturn configs, genesisValidatorsRoot\n}\n\nfunc CopyHomeDir(t *testing.T, sourceHomeDir, targetHomeDir string) {\n\tt.Logf(\"Copying home directory to: %s\", targetHomeDir)\n\tsrcPath := filepath.Join(filepath.Clean(sourceHomeDir), \".\")\n\tcmd := exec.Command(\"sh\", \"-c\", fmt.Sprintf(\"cp -r %s/* %s\", srcPath, targetHomeDir))\n\terr := cmd.Run()\n\trequire.NoError(t, err)\n}\n\n// createCometConfig creates a default CometBFT configuration with the home directory set.\nfunc createCometConfig(t *testing.T, tempHomeDir string) *cmtcfg.Config {\n\tt.Helper()\n\tcmtCfg := cometbft.DefaultConfig()\n\tcmtCfg.RootDir = tempHomeDir\n\treturn cmtCfg\n}\n\n// initCommand runs the initialization command to prepare the home directory.\n// This function emulates the 'beacond init' command.\nfunc initCommand(t *testing.T, spec chain.Spec, homeDir string) {\n\tt.Helper()\n\n\t// Create a Cosmos SDK client context with the provided home directory and chain ID.\n\tclientCtx := client.Context{}.\n\t\tWithHomeDir(homeDir).\n\t\tWithChainID(TestnetBeaconChainID)\n\n\t// Ensure necessary directories exist.\n\terr := os.MkdirAll(path.Join(homeDir, \"config\"), 0700)\n\trequire.NoError(t, err, \"failed to create config directory\")\n\n\terr = os.MkdirAll(path.Join(homeDir, \"data\"), 0700)\n\trequire.NoError(t, err, \"failed to create data directory\")\n\n\t// Initialize the command to set up the home directory.\n\tinitCMD := initialize.InitCmd(func(_ types.AppOptions) (chain.Spec, error) { return spec, nil }, &cometbft.Service{})\n\tinitCMD.SetArgs([]string{\"test-moniker\"})\n\n\t// Set the command context; required to work around a Cosmos SDK issue.\n\tinitCMD.SetContext(context.Background())\n\terr = client.SetCmdClientContextHandler(clientCtx, initCMD)\n\trequire.NoError(t, err, \"failed to set client context handler\")\n\n\t// Allow unknown flags to enable running tests from IDEs without extra configuration.\n\tinitCMD.FParseErrWhitelist.UnknownFlags = true\n\n\t// Execute the initialization command.\n\terr = initCMD.Execute()\n\trequire.NoError(t, err, \"failed to execute init command\")\n}\n\n// copyMissingFiles copies files that exist in srcDir but not in dstDir.\nfunc copyMissingFiles(t *testing.T, srcDir, dstDir string) {\n\tt.Helper()\n\n\t// Ensure destination directory exists.\n\trequire.NoError(t, os.MkdirAll(dstDir, 0o700))\n\n\tsrcEntries, err := os.ReadDir(srcDir)\n\trequire.NoError(t, err, \"failed to read source directory: %s\", srcDir)\n\n\tfor _, e := range srcEntries {\n\t\tif e.IsDir() {\n\t\t\tcontinue\n\t\t}\n\t\tsrcPath := filepath.Join(srcDir, e.Name())\n\t\tdstPath := filepath.Join(dstDir, e.Name())\n\n\t\tif _, err := os.Stat(dstPath); err == nil {\n\t\t\t// Already exists.\n\t\t\tcontinue\n\t\t}\n\n\t\tsrcFile, err := os.Open(srcPath)\n\t\trequire.NoError(t, err, \"failed to open src file: %s\", srcPath)\n\t\tdefer srcFile.Close()\n\n\t\tdstFile, err := os.Create(dstPath)\n\t\trequire.NoError(t, err, \"failed to create dst file: %s\", dstPath)\n\t\t_, err = io.Copy(dstFile, srcFile)\n\t\trequire.NoError(t, err, \"failed to copy to dst file: %s\", dstPath)\n\t\trequire.NoError(t, dstFile.Close())\n\t}\n}\n"
  },
  {
    "path": "testing/simulated/malicious_consensus_test.go",
    "content": "//go:build simulated\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage simulated_test\n\nimport (\n\t\"math/big\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\n\t\"github.com/berachain/beacon-kit/beacon/blockchain\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/encoding\"\n\t\"github.com/berachain/beacon-kit/engine-primitives/errors\"\n\t\"github.com/berachain/beacon-kit/testing/simulated\"\n\t\"github.com/cometbft/cometbft/abci/types\"\n\tgethcommon \"github.com/ethereum/go-ethereum/common\"\n\tgethtypes \"github.com/ethereum/go-ethereum/core/types\"\n)\n\n// TestFinalizeBlock_BadBlock_Errors effectively serves as a test for how a valid node would react to\n// a malicious consensus majority agreeing to a block with an invalid EVM transaction.\nfunc (s *SimulatedSuite) TestFinalizeBlock_BadBlock_Errors() {\n\tconst blockHeight = 1\n\tconst coreLoopIterations = 1\n\n\t// Initialize the chain state.\n\ts.InitializeChain(s.T(), 1)\n\n\t// Retrieve the BLS signer and proposer address.\n\tblsSigner := simulated.GetBlsSigner(s.HomeDir)\n\tpubkey, err := blsSigner.GetPubKey()\n\ts.Require().NoError(err)\n\tnodeAddress := pubkey.Address()\n\ts.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\t// Test happens on Deneb, pre Deneb1 fork.\n\tstartTime := time.Unix(0, 0)\n\n\t// Go through 1 iteration of the core loop to bypass any startup specific edge cases such as sync head on startup.\n\tproposals, _, proposalTime := s.MoveChainToHeight(s.T(), blockHeight, coreLoopIterations, nodeAddress, startTime)\n\ts.Require().Len(proposals, coreLoopIterations)\n\n\t// We expected this test to happen during Pre-Deneb1 fork.\n\tcurrentHeight := int64(blockHeight + coreLoopIterations)\n\n\t// Prepare a block proposal.\n\tproposal, err := s.SimComet.Comet.PrepareProposal(s.CtxComet, &types.PrepareProposalRequest{\n\t\tHeight:          currentHeight,\n\t\tTime:            proposalTime,\n\t\tProposerAddress: nodeAddress,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotEmpty(proposal)\n\n\t// Unmarshal the proposal block.\n\tproposedBlock, err := encoding.UnmarshalBeaconBlockFromABCIRequest(\n\t\tproposal.Txs,\n\t\tblockchain.BeaconBlockTxIndex,\n\t\ts.TestNode.ChainSpec.ActiveForkVersionForTimestamp(math.U64(proposalTime.Unix())),\n\t)\n\ts.Require().NoError(err)\n\n\t// Sign a malicious transaction that is expected to fail.\n\tmaliciousTx, err := gethtypes.SignNewTx(\n\t\tsimulated.GetTestKey(s.T()),\n\t\tgethtypes.NewCancunSigner(big.NewInt(int64(s.TestNode.ChainSpec.DepositEth1ChainID()))),\n\t\t&gethtypes.DynamicFeeTx{\n\t\t\tNonce:     0,\n\t\t\tTo:        &gethcommon.Address{1},\n\t\t\tValue:     big.NewInt(100000000000),\n\t\t\tGas:       21000,\n\t\t\tGasTipCap: big.NewInt(10000000),\n\t\t\tGasFeeCap: big.NewInt(10000000),\n\t\t\tData:      []byte{},\n\t\t},\n\t)\n\ts.Require().NoError(err, \"failed to sign malicious transaction\")\n\t// Initialize the slice with the malicious transaction.\n\tmaliciousTxs := []*gethtypes.Transaction{maliciousTx}\n\n\t// Create a malicious block by injecting an invalid transaction.\n\tmaliciousBlock := simulated.ComputeAndSetInvalidExecutionBlock(\n\t\ts.T(), proposedBlock.GetBeaconBlock(), s.TestNode.ChainSpec, maliciousTxs, nil,\n\t)\n\n\t// Re-sign the block\n\tmaliciousBlockSigned, err := ctypes.NewSignedBeaconBlock(\n\t\tmaliciousBlock,\n\t\t&ctypes.ForkData{\n\t\t\tCurrentVersion:        s.TestNode.ChainSpec.ActiveForkVersionForTimestamp(maliciousBlock.GetTimestamp()),\n\t\t\tGenesisValidatorsRoot: s.GenesisValidatorsRoot,\n\t\t},\n\t\ts.TestNode.ChainSpec,\n\t\tblsSigner,\n\t)\n\ts.Require().NoError(err)\n\n\tmaliciousBlockBytes, err := maliciousBlockSigned.MarshalSSZ()\n\ts.Require().NoError(err)\n\n\t// Replace the valid block with the malicious block in the proposal.\n\tproposal.Txs[0] = maliciousBlockBytes\n\n\t// Reset the log buffer to discard old logs we don't care about\n\ts.LogBuffer.Reset()\n\t// Finalize the proposal containing the malicious block.\n\tfinalizeResp, err := s.SimComet.Comet.FinalizeBlock(s.CtxComet, &types.FinalizeBlockRequest{\n\t\tTxs:             proposal.Txs,\n\t\tHeight:          currentHeight,\n\t\tProposerAddress: nodeAddress,\n\t\tTime:            proposalTime,\n\t})\n\ts.Require().ErrorIs(err, errors.ErrInvalidPayloadStatus)\n\ts.Require().Nil(finalizeResp)\n\ts.Require().Contains(s.LogBuffer.String(), \"max fee per gas less than block base fee: address 0x20f33CE90A13a4b5E7697E3544c3083B8F8A51D4, maxFeePerGas: 10000000, baseFee: 765625000\")\n}\n"
  },
  {
    "path": "testing/simulated/malicious_proposer_test.go",
    "content": "//go:build simulated\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage simulated_test\n\nimport (\n\t\"math/big\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/beacon/blockchain\"\n\tpayloadtime \"github.com/berachain/beacon-kit/beacon/payload-time\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/encoding\"\n\tdablob \"github.com/berachain/beacon-kit/da/blob\"\n\tdatypes \"github.com/berachain/beacon-kit/da/types\"\n\t\"github.com/berachain/beacon-kit/engine-primitives/errors\"\n\t\"github.com/berachain/beacon-kit/node-core/components/metrics\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/testing/simulated\"\n\t\"github.com/cometbft/cometbft/abci/types\"\n\tgethcommon \"github.com/ethereum/go-ethereum/common\"\n\tgethtypes \"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/ethereum/go-ethereum/crypto/kzg4844\"\n\t\"github.com/holiman/uint256\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// TestProcessProposal_BadBlock_IsRejected effectively serves as a test for how a valid node would react to\n// a malicious proposer proposing a block with an invalid EVM transaction.\nfunc (s *SimulatedSuite) TestProcessProposal_BadBlock_IsRejected() {\n\tconst blockHeight = 1\n\tconst coreLoopIterations = 1\n\n\t// Initialize the chain state.\n\ts.InitializeChain(s.T(), 1)\n\n\t// Retrieve the BLS signer and proposer address.\n\tblsSigner := simulated.GetBlsSigner(s.HomeDir)\n\tpubkey, err := blsSigner.GetPubKey()\n\ts.Require().NoError(err)\n\tnodeAddress := pubkey.Address()\n\ts.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\t// Test happens on Deneb, pre Deneb1 fork.\n\tstartTime := time.Unix(0, 0)\n\n\t// Go through 1 iteration of the core loop to bypass any startup specific edge cases such as sync head on startup.\n\tproposals, _, proposalTime := s.MoveChainToHeight(s.T(), blockHeight, coreLoopIterations, nodeAddress, startTime)\n\ts.Require().Len(proposals, coreLoopIterations)\n\n\t// We expected this test to happen during Pre-Deneb1 fork.\n\tcurrentHeight := int64(blockHeight + coreLoopIterations)\n\n\t// Prepare a block proposal.\n\tproposal, err := s.SimComet.Comet.PrepareProposal(s.CtxComet, &types.PrepareProposalRequest{\n\t\tHeight:          currentHeight,\n\t\tTime:            proposalTime,\n\t\tProposerAddress: nodeAddress,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotEmpty(proposal)\n\n\t// Unmarshal the proposal block.\n\tproposedBlock, err := encoding.UnmarshalBeaconBlockFromABCIRequest(\n\t\tproposal.Txs,\n\t\tblockchain.BeaconBlockTxIndex,\n\t\ts.TestNode.ChainSpec.ActiveForkVersionForTimestamp(math.U64(proposalTime.Unix())),\n\t)\n\ts.Require().NoError(err)\n\n\t// Sign a malicious transaction that is expected to fail.\n\trecipientAddress := gethcommon.HexToAddress(\"0x56898d1aFb10cad584961eb96AcD476C6826e41E\")\n\tmaliciousTx, err := gethtypes.SignNewTx(\n\t\tsimulated.GetTestKey(s.T()),\n\t\tgethtypes.NewCancunSigner(big.NewInt(int64(s.TestNode.ChainSpec.DepositEth1ChainID()))),\n\t\t&gethtypes.DynamicFeeTx{\n\t\t\tNonce:     0,\n\t\t\tTo:        &recipientAddress,\n\t\t\tValue:     big.NewInt(0),\n\t\t\tGas:       21016,\n\t\t\tGasTipCap: big.NewInt(10000000),\n\t\t\tGasFeeCap: big.NewInt(10000000),\n\t\t\tData:      []byte{},\n\t\t},\n\t)\n\n\t// Initialize the slice with the malicious transaction.\n\tmaliciousTxs := []*gethtypes.Transaction{maliciousTx}\n\n\t// Create a malicious block by injecting an invalid transaction.\n\tmaliciousBlock := simulated.ComputeAndSetInvalidExecutionBlock(\n\t\ts.T(), proposedBlock.GetBeaconBlock(), s.TestNode.ChainSpec, maliciousTxs, nil,\n\t)\n\n\t// Re-sign the block\n\tmaliciousBlockSigned, err := ctypes.NewSignedBeaconBlock(\n\t\tmaliciousBlock,\n\t\t&ctypes.ForkData{\n\t\t\tCurrentVersion:        s.TestNode.ChainSpec.ActiveForkVersionForTimestamp(maliciousBlock.GetTimestamp()),\n\t\t\tGenesisValidatorsRoot: s.GenesisValidatorsRoot,\n\t\t},\n\t\ts.TestNode.ChainSpec,\n\t\tblsSigner,\n\t)\n\ts.Require().NoError(err)\n\n\tmaliciousBlockBytes, err := maliciousBlockSigned.MarshalSSZ()\n\ts.Require().NoError(err)\n\n\t// Replace the valid block with the malicious block in the proposal.\n\tproposal.Txs[0] = maliciousBlockBytes\n\n\t// Reset the log buffer to discard old logs we don't care about\n\ts.LogBuffer.Reset()\n\t// Process the proposal containing the malicious block.\n\tprocessResp, err := s.SimComet.Comet.ProcessProposal(s.CtxComet, &types.ProcessProposalRequest{\n\t\tTxs:             proposal.Txs,\n\t\tHeight:          currentHeight,\n\t\tProposerAddress: nodeAddress,\n\t\tTime:            proposalTime,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_REJECT, processResp.Status)\n\n\t// Verify that the log contains the expected error message.\n\ts.Require().Contains(s.LogBuffer.String(), errors.ErrInvalidPayloadStatus.Error())\n\t// Note this error message may change across execution clients. Base fee changes with number of core loop iterations.\n\ts.Require().Contains(s.LogBuffer.String(), \"max fee per gas less than block base fee: address 0x20f33CE90A13a4b5E7697E3544c3083B8F8A51D4, maxFeePerGas: 10000000, baseFee: 765625000\")\n}\n\n// TestProcessProposal_InvalidTimestamps_Errors effectively serves as a test for how a valid node would react to\n// a malicious proposer attempting to use a future timestamp in the block that does not match the consensus timestamp.\nfunc (s *SimulatedSuite) TestProcessProposal_InvalidTimestamps_Errors() {\n\tconst blockHeight = 1\n\tconst coreLoopIterations = 1\n\n\t// Initialize the chain state.\n\ts.InitializeChain(s.T(), 1)\n\tnodeAddress, err := s.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\t// Test happens post Deneb1 fork.\n\tstartTime := time.Now()\n\n\t// Go through 1 iteration of the core loop to bypass any startup specific edge cases such as sync head on startup.\n\tproposals, _, correctConsensusTime := s.MoveChainToHeight(s.T(), blockHeight, coreLoopIterations, nodeAddress, startTime)\n\ts.Require().Len(proposals, coreLoopIterations)\n\tcurrentHeight := int64(blockHeight + coreLoopIterations)\n\n\t// Prepare a block proposal. This will create a valid payload due to optimistic payload building.\n\t// It is called to flush the payload cache.\n\tvalidProposal, err := s.SimComet.Comet.PrepareProposal(s.CtxComet, &types.PrepareProposalRequest{\n\t\tHeight:          currentHeight,\n\t\tTime:            correctConsensusTime,\n\t\tProposerAddress: nodeAddress,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotEmpty(validProposal)\n\n\t// Build a block with a malicious proposal time\n\tmaliciousPayloadTime := correctConsensusTime.Add(2 * time.Second)\n\tmaliciousProposalTxs := testBuildInvalidBlock(\n\t\ts.Require(),\n\t\ts.SharedAccessors,\n\t\t&types.PrepareProposalRequest{\n\t\t\tTxs:    validProposal.Txs,\n\t\t\tHeight: currentHeight,\n\t\t\tTime:   correctConsensusTime,\n\t\t},\n\t\tfunc(sb *ctypes.SignedBeaconBlock) {\n\t\t\tblk := sb.BeaconBlock\n\t\t\tblk.Body.ExecutionPayload.Timestamp = math.U64(maliciousPayloadTime.Unix())\n\t\t},\n\t)\n\n\t// Reset the log buffer to discard old logs we don't care about\n\ts.LogBuffer.Reset()\n\t// Process the proposal containing the malicious block.\n\tprocessResp, err := s.SimComet.Comet.ProcessProposal(s.CtxComet, &types.ProcessProposalRequest{\n\t\tTxs:             maliciousProposalTxs,\n\t\tHeight:          currentHeight,\n\t\tProposerAddress: nodeAddress,\n\t\t// Use the correct time as the actual consensus time, which mismatches the proposal time.\n\t\tTime: correctConsensusTime,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_REJECT, processResp.Status)\n\ts.Require().Contains(s.LogBuffer.String(), payloadtime.ErrTooFarInTheFuture.Error())\n}\n\n// TestProcessProposal_InvalidBlobCommitment_Errors effectively serves as a test for a malicious blobs.\n// Specifically, to bypass the commitment count check, we put 2 commitments into 1 tx and leave the\n// other tx with zero commitments. This ultimately gets rejected by the execution client.\nfunc (s *SimulatedSuite) TestProcessProposal_InvalidBlobCommitment_Errors() {\n\tconst blockHeight = 1\n\tconst coreLoopIterations = 1\n\n\t// Initialize the chain state.\n\ts.InitializeChain(s.T(), 1)\n\n\t// Retrieve the BLS signer and proposer address.\n\tblsSigner := simulated.GetBlsSigner(s.HomeDir)\n\tpubkey, err := blsSigner.GetPubKey()\n\ts.Require().NoError(err)\n\tnodeAddress := pubkey.Address()\n\ts.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\t// Test happens on Deneb, pre Deneb1 fork.\n\tstartTime := time.Unix(0, 0)\n\n\t// Go through 1 iteration of the core loop to bypass any startup specific edge cases such as sync head on startup.\n\tproposals, _, consensusTime := s.MoveChainToHeight(s.T(), blockHeight, coreLoopIterations, nodeAddress, startTime)\n\ts.Require().Len(proposals, coreLoopIterations)\n\n\t// We expected this test to happen during Pre-Deneb1 fork.\n\tcurrentHeight := int64(blockHeight + coreLoopIterations)\n\n\t// Prepare a block proposal.\n\tproposal, err := s.SimComet.Comet.PrepareProposal(s.CtxComet, &types.PrepareProposalRequest{\n\t\tHeight:          currentHeight,\n\t\tTime:            consensusTime,\n\t\tProposerAddress: nodeAddress,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotEmpty(proposal)\n\n\t// Unmarshal the proposal block.\n\tproposedBlock, err := encoding.UnmarshalBeaconBlockFromABCIRequest(\n\t\tproposal.Txs,\n\t\tblockchain.BeaconBlockTxIndex,\n\t\ts.TestNode.ChainSpec.ActiveForkVersionForTimestamp(math.U64(consensusTime.Unix())),\n\t)\n\ts.Require().NoError(err)\n\n\t// Create the Blobs, with proofs and commitments\n\t// Each blob will go into 1 transaction.\n\tblobs := []*eip4844.Blob{{1, 2, 3}, {4, 5, 6}}\n\tproofs, commitments := simulated.GetProofAndCommitmentsForBlobs(require.New(s.T()), blobs, s.TestNode.KZGVerifier)\n\ts.Require().Len(proofs, len(blobs))\n\ts.Require().Len(commitments, len(blobs))\n\n\t// Here is where we act malicious.\n\tblobVersionedHash0 := commitments[0].ToVersionedHash()\n\tblobVersionedHash1 := commitments[1].ToVersionedHash()\n\tversionedHashesForBlob := [][]gethcommon.Hash{\n\t\t{blobVersionedHash0, blobVersionedHash1}, // index 0\n\t\tnil,                                      // index 1 is nil\n\t}\n\t// Sign blob transactions\n\tblobTxs := make([]*gethtypes.Transaction, len(blobs))\n\tfor i := range blobs {\n\t\tblobCommitment := commitments[i]\n\t\ttxSidecar := &gethtypes.BlobTxSidecar{\n\t\t\tBlobs:       []kzg4844.Blob{kzg4844.Blob(blobs[i][:])},\n\t\t\tCommitments: []kzg4844.Commitment{kzg4844.Commitment(blobCommitment)},\n\t\t\tProofs:      []kzg4844.Proof{kzg4844.Proof(proofs[i])},\n\t\t}\n\t\tblobTx, err := gethtypes.SignNewTx(\n\t\t\tsimulated.GetTestKey(s.T()),\n\t\t\tgethtypes.NewCancunSigner(big.NewInt(int64(s.TestNode.ChainSpec.DepositEth1ChainID()))),\n\t\t\t&gethtypes.BlobTx{\n\t\t\t\tNonce: uint64(i),\n\t\t\t\t// Set to 875000000 as that is the tx base fee\n\t\t\t\tGasTipCap: uint256.NewInt(875000000),\n\t\t\t\tGasFeeCap: uint256.NewInt(875000000),\n\t\t\t\t// Set to 21000 for minimum intrinsic gas\n\t\t\t\tGas:        210000,\n\t\t\t\tValue:      uint256.NewInt(0),\n\t\t\t\tData:       []byte{},\n\t\t\t\tAccessList: nil,\n\t\t\t\tBlobFeeCap: uint256.NewInt(10),\n\t\t\t\t// If we have 1 tx with multiple blobs, we must add the blob hashes here.\n\t\t\t\tBlobHashes: versionedHashesForBlob[i],\n\t\t\t\t// Sidecar must be set to nil here or Geth will error with \"unexpected blob sidecar in transaction\"\n\t\t\t\tSidecar: nil,\n\t\t\t},\n\t\t)\n\t\ts.Require().NoError(err)\n\n\t\t// Once we've signed the Tx, we tag the blob with the tx purely for association between tx and sidecars.\n\t\t// In this case, each 1 tx has a sidecar with 1 blob, even though 1 tx could have more than 1 blob.\n\t\tblobTx = blobTx.WithBlobTxSidecar(txSidecar)\n\t\tblobTxs[i] = blobTx\n\t}\n\n\tproposedBlockMessage := simulated.ComputeAndSetValidExecutionBlock(\n\t\ts.T(),\n\t\tproposedBlock.GetBeaconBlock(),\n\t\ts.SimulationClient,\n\t\ts.TestNode.ChainSpec,\n\t\tblobTxs,\n\t)\n\tproposedBlockMessage.GetBody().SetBlobKzgCommitments(commitments)\n\n\t// Finalize the block by applying the state transition to update its state root.\n\tqueryCtx, err := s.SimComet.CreateQueryContext(currentHeight-1, false)\n\ts.Require().NoError(err)\n\n\tproposedBlockMessage, err = simulated.ComputeAndSetStateRoot(queryCtx, consensusTime, nodeAddress, s.TestNode.StateProcessor, s.TestNode.StorageBackend, proposedBlockMessage)\n\ts.Require().NoError(err)\n\n\tnewSignedBlock, err := ctypes.NewSignedBeaconBlock(\n\t\tproposedBlockMessage,\n\t\t&ctypes.ForkData{\n\t\t\tCurrentVersion:        s.TestNode.ChainSpec.ActiveForkVersionForTimestamp(proposedBlockMessage.GetTimestamp()),\n\t\t\tGenesisValidatorsRoot: s.GenesisValidatorsRoot,\n\t\t},\n\t\ts.TestNode.ChainSpec,\n\t\tblsSigner,\n\t)\n\ts.Require().NoError(err)\n\n\t// Inject the new block\n\tnewSignedBlockBytes, err := newSignedBlock.MarshalSSZ()\n\ts.Require().NoError(err)\n\tproposal.Txs[0] = newSignedBlockBytes\n\n\t// Create the beaconBlock Header for the sidecar\n\tblockWithCommitmentsSignedHeader := ctypes.NewSignedBeaconBlockHeader(\n\t\tnewSignedBlock.GetHeader(),\n\t\tnewSignedBlock.GetSignature(),\n\t)\n\n\tsidecarsSlice := make([]*datypes.BlobSidecar, len(blobs))\n\t// Build Inclusion Proofs for Sidecars\n\tsidecarFactory := dablob.NewSidecarFactory(metrics.NewNoOpTelemetrySink())\n\tfor i := range blobs {\n\t\tinclusionProof, err := sidecarFactory.BuildKZGInclusionProof(proposedBlockMessage.GetBody(), math.U64(i))\n\t\ts.Require().NoError(err)\n\t\tsidecar := datypes.BuildBlobSidecar(\n\t\t\tmath.U64(i),\n\t\t\tblockWithCommitmentsSignedHeader,\n\t\t\tblobs[i],\n\t\t\tcommitments[i],\n\t\t\tproofs[i],\n\t\t\tinclusionProof,\n\t\t)\n\t\tsidecarsSlice[i] = sidecar\n\t}\n\tsidecars := datypes.BlobSidecars(sidecarsSlice)\n\t// Inject the sidecar\n\tsidecarBytes, err := sidecars.MarshalSSZ()\n\ts.Require().NoError(err)\n\n\tproposal.Txs[1] = sidecarBytes\n\n\t// Reset the log buffer to discard old logs we don't care about\n\ts.LogBuffer.Reset()\n\t// Process the proposal containing the block.\n\tprocessResp, err := s.SimComet.Comet.ProcessProposal(s.CtxComet, &types.ProcessProposalRequest{\n\t\tTxs:             proposal.Txs,\n\t\tHeight:          currentHeight,\n\t\tProposerAddress: nodeAddress,\n\t\tTime:            consensusTime,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_REJECT, processResp.Status)\n\ts.Require().Contains(s.LogBuffer.String(), \"could not apply tx 1 [0xdbbf691e9271a8bc3de5e64405337972fb4a5185cc3df160bac310c515f7d768]: blob transaction missing blob hashes\")\n}\n\n// TestProcessProposal_InvalidBlobInclusionProof_Errors effectively serves as a test for a malicious blobs.\n// Specifically, we tweak the KZG commitment inclusion proof such that it is invalid and must be rejected.\nfunc (s *SimulatedSuite) TestProcessProposal_InvalidBlobInclusionProof_Errors() {\n\tconst blockHeight = 1\n\tconst coreLoopIterations = 1\n\n\t// Initialize the chain state.\n\ts.InitializeChain(s.T(), 1)\n\n\t// Retrieve the BLS signer and proposer address.\n\tblsSigner := simulated.GetBlsSigner(s.HomeDir)\n\tpubkey, err := blsSigner.GetPubKey()\n\ts.Require().NoError(err)\n\tnodeAddress := pubkey.Address()\n\ts.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\t// Test happens on Deneb, pre Deneb1 fork.\n\tstartTime := time.Unix(0, 0)\n\n\t// Go through 1 iteration of the core loop to bypass any startup specific edge cases such as sync head on startup.\n\tproposals, _, consensusTime := s.MoveChainToHeight(s.T(), blockHeight, coreLoopIterations, nodeAddress, startTime)\n\ts.Require().Len(proposals, coreLoopIterations)\n\n\t// We expected this test to happen during Pre-Deneb1 fork.\n\tcurrentHeight := int64(blockHeight + coreLoopIterations)\n\n\t// Prepare a block proposal.\n\tproposal, err := s.SimComet.Comet.PrepareProposal(s.CtxComet, &types.PrepareProposalRequest{\n\t\tHeight:          currentHeight,\n\t\tTime:            consensusTime,\n\t\tProposerAddress: nodeAddress,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotEmpty(proposal)\n\n\t// Unmarshal the proposal block.\n\tproposedBlock, err := encoding.UnmarshalBeaconBlockFromABCIRequest(\n\t\tproposal.Txs,\n\t\tblockchain.BeaconBlockTxIndex,\n\t\ts.TestNode.ChainSpec.ActiveForkVersionForTimestamp(math.U64(consensusTime.Unix())),\n\t)\n\ts.Require().NoError(err)\n\n\t// Create the Blobs, with proofs and commitments\n\t// Each blob will go into 1 transaction.\n\tblobs := []*eip4844.Blob{{1, 2, 3}, {4, 5, 6}}\n\tproofs, commitments := simulated.GetProofAndCommitmentsForBlobs(require.New(s.T()), blobs, s.TestNode.KZGVerifier)\n\ts.Require().Len(proofs, len(blobs))\n\ts.Require().Len(commitments, len(blobs))\n\n\t// Sign blob transactions\n\tblobTxs := make([]*gethtypes.Transaction, len(blobs))\n\tfor i := range blobs {\n\t\tblobCommitment := commitments[i]\n\t\tblobHash := blobCommitment.ToVersionedHash()\n\t\ttxSidecar := &gethtypes.BlobTxSidecar{\n\t\t\tBlobs:       []kzg4844.Blob{kzg4844.Blob(blobs[i][:])},\n\t\t\tCommitments: []kzg4844.Commitment{kzg4844.Commitment(blobCommitment)},\n\t\t\tProofs:      []kzg4844.Proof{kzg4844.Proof(proofs[i])},\n\t\t}\n\t\tblobTx, err := gethtypes.SignNewTx(\n\t\t\tsimulated.GetTestKey(s.T()),\n\t\t\tgethtypes.NewCancunSigner(big.NewInt(int64(s.TestNode.ChainSpec.DepositEth1ChainID()))),\n\t\t\t&gethtypes.BlobTx{\n\t\t\t\tNonce: uint64(i),\n\t\t\t\t// Set to 875000000 as that is the tx base fee\n\t\t\t\tGasTipCap: uint256.NewInt(875000000),\n\t\t\t\tGasFeeCap: uint256.NewInt(875000000),\n\t\t\t\t// Set to 21000 for minimum intrinsic gas\n\t\t\t\tGas:        210000,\n\t\t\t\tValue:      uint256.NewInt(0),\n\t\t\t\tData:       []byte{},\n\t\t\t\tAccessList: nil,\n\t\t\t\tBlobFeeCap: uint256.NewInt(10),\n\t\t\t\t// If we have 1 tx with multiple blobs, we must add the blob hashes here.\n\t\t\t\tBlobHashes: []gethcommon.Hash{blobHash},\n\t\t\t\t// Sidecar must be set to nil here or Geth will error with \"unexpected blob sidecar in transaction\"\n\t\t\t\tSidecar: nil,\n\t\t\t},\n\t\t)\n\t\ts.Require().NoError(err)\n\t\t// Once we've signed the Tx, we tag the blob with the tx purely for association between tx and sidecars.\n\t\t// In this case, each 1 tx has a sidecar with 1 blob, even though 1 tx could have more than 1 blob.\n\t\tblobTx = blobTx.WithBlobTxSidecar(txSidecar)\n\t\tblobTxs[i] = blobTx\n\t}\n\n\tproposedBlockMessage := simulated.ComputeAndSetValidExecutionBlock(\n\t\ts.T(),\n\t\tproposedBlock.GetBeaconBlock(),\n\t\ts.SimulationClient,\n\t\ts.TestNode.ChainSpec,\n\t\tblobTxs,\n\t)\n\tproposedBlockMessage.GetBody().SetBlobKzgCommitments(commitments)\n\n\t// Finalize the block by applying the state transition to update its state root.\n\tqueryCtx, err := s.SimComet.CreateQueryContext(currentHeight-1, false)\n\ts.Require().NoError(err)\n\n\tproposedBlockMessage, err = simulated.ComputeAndSetStateRoot(queryCtx, consensusTime, nodeAddress, s.TestNode.StateProcessor, s.TestNode.StorageBackend, proposedBlockMessage)\n\ts.Require().NoError(err)\n\n\tnewSignedBlock, err := ctypes.NewSignedBeaconBlock(\n\t\tproposedBlockMessage,\n\t\t&ctypes.ForkData{\n\t\t\tCurrentVersion:        s.TestNode.ChainSpec.ActiveForkVersionForTimestamp(proposedBlockMessage.GetTimestamp()),\n\t\t\tGenesisValidatorsRoot: s.GenesisValidatorsRoot,\n\t\t},\n\t\ts.TestNode.ChainSpec,\n\t\tblsSigner,\n\t)\n\ts.Require().NoError(err)\n\n\t// Inject the new block\n\tnewSignedBlockBytes, err := newSignedBlock.MarshalSSZ()\n\ts.Require().NoError(err)\n\tproposal.Txs[0] = newSignedBlockBytes\n\n\t// Create the beaconBlock Header for the sidecar\n\tblockWithCommitmentsSignedHeader := ctypes.NewSignedBeaconBlockHeader(\n\t\tnewSignedBlock.GetHeader(),\n\t\tnewSignedBlock.GetSignature(),\n\t)\n\n\tsidecarsSlice := make([]*datypes.BlobSidecar, len(blobs))\n\t// Build Inclusion Proofs for Sidecars\n\tsidecarFactory := dablob.NewSidecarFactory(metrics.NewNoOpTelemetrySink())\n\tfor i := range blobs {\n\t\tinclusionProof, err := sidecarFactory.BuildKZGInclusionProof(proposedBlockMessage.GetBody(), math.U64(i))\n\t\ts.Require().NoError(err)\n\t\t// Malicious point: We tweak the inclusion proof\n\t\tinclusionProof[len(inclusionProof)-1] = common.Root{}\n\t\tsidecar := datypes.BuildBlobSidecar(\n\t\t\tmath.U64(i),\n\t\t\tblockWithCommitmentsSignedHeader,\n\t\t\tblobs[i],\n\t\t\tcommitments[i],\n\t\t\tproofs[i],\n\t\t\tinclusionProof,\n\t\t)\n\t\tsidecarsSlice[i] = sidecar\n\t}\n\tsidecars := datypes.BlobSidecars(sidecarsSlice)\n\t// Inject theI sidecar\n\tsidecarBytes, err := sidecars.MarshalSSZ()\n\ts.Require().NoError(err)\n\n\tproposal.Txs[1] = sidecarBytes\n\n\t// Reset the log buffer to discard old logs we don't care about\n\ts.LogBuffer.Reset()\n\t// Process the proposal containing the block.\n\tprocessResp, err := s.SimComet.Comet.ProcessProposal(s.CtxComet, &types.ProcessProposalRequest{\n\t\tTxs:             proposal.Txs,\n\t\tHeight:          currentHeight,\n\t\tProposerAddress: nodeAddress,\n\t\tTime:            consensusTime,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_REJECT, processResp.Status)\n\ts.Require().Contains(s.LogBuffer.String(), \"invalid KZG commitment inclusion proof\")\n}\n\n// testBuildInvalidBlock builds an invalid block, modifying it along what it is\n// specified in modifyBlock function. It is then properly resigned.\nfunc testBuildInvalidBlock(\n\tr *require.Assertions,\n\tbuilder simulated.SharedAccessors,\n\tPrepReq *types.PrepareProposalRequest,\n\tmodifyBlock func(*ctypes.SignedBeaconBlock),\n) [][]byte {\n\tblsSigner := simulated.GetBlsSigner(builder.HomeDir)\n\tpubkey, err := blsSigner.GetPubKey()\n\tr.NoError(err)\n\n\tsignedBlk, sidecars, err := builder.SimComet.Comet.Blockchain.ParseBeaconBlock(\n\t\t&types.ProcessProposalRequest{\n\t\t\tTxs:             PrepReq.Txs,\n\t\t\tHeight:          PrepReq.Height,\n\t\t\tProposerAddress: pubkey.Address(),\n\t\t\tTime:            PrepReq.Time,\n\t\t},\n\t)\n\tr.NoError(err)\n\n\tmodifyBlock(signedBlk)\n\n\tblk := signedBlk.BeaconBlock\n\treSignedBlk, err := ctypes.NewSignedBeaconBlock( // resign to make sure signature checks pass\n\t\tblk,\n\t\tctypes.NewForkData(\n\t\t\tbuilder.TestNode.ChainSpec.ActiveForkVersionForTimestamp(blk.GetTimestamp()),\n\t\t\tbuilder.GenesisValidatorsRoot,\n\t\t),\n\t\tbuilder.TestNode.ChainSpec,\n\t\tblsSigner,\n\t)\n\tr.NoError(err)\n\n\tsignedBlkBytes, bbErr := reSignedBlk.MarshalSSZ()\n\tr.NoError(bbErr)\n\n\tres := make([][]byte, len(PrepReq.Txs))\n\tres[0] = signedBlkBytes\n\n\tsidecarsBytes, scErr := sidecars.MarshalSSZ()\n\tr.NoError(scErr)\n\tres[1] = sidecarsBytes\n\n\treturn res\n}\n"
  },
  {
    "path": "testing/simulated/orphaned_blobs_test.go",
    "content": "//go:build simulated\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN \"AS IS\" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage simulated_test\n\nimport (\n\t\"time\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/da/kzg\"\n\tdatypes \"github.com/berachain/beacon-kit/da/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/testing/simulated\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// TestOrphanedBlobCleanup tests that orphaned blob sidecars are properly cleaned up on node restart.\n// This simulates the scenario where sidecars are saved to disk but the block finalization fails.\nfunc (s *SimulatedSuite) TestOrphanedBlobCleanup() {\n\t// Initialize chain and move forward two blocks.\n\ts.InitializeChain(s.T(), 1)\n\tnodeAddress, err := s.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\t_, _, proposalTime := s.MoveChainToHeight(s.T(), 1, 2, nodeAddress, time.Now())\n\n\t// Get the last committed block height.\n\tlastBlockHeight := s.SimComet.Comet.CommitMultiStore().LastCommitID().Version\n\torphanedSlot := math.Slot(lastBlockHeight + 1)\n\n\t// Create and persist orphaned blob sidecars.\n\t// This simulates FinalizeSidecars succeeding but finalizeBeaconBlock failing.\n\torphanedSidecars := createOrphanedSidecars(s.T(), orphanedSlot, s.TestNode.KZGVerifier)\n\terr = s.TestNode.StorageBackend.AvailabilityStore().Persist(orphanedSidecars)\n\ts.Require().NoError(err)\n\n\t// Verify orphaned blobs exist.\n\tsidecars, err := s.TestNode.StorageBackend.AvailabilityStore().GetBlobSidecars(orphanedSlot)\n\ts.Require().NoError(err)\n\ts.Require().Len(sidecars, 1)\n\n\t// Simulate node restart by calling PruneOrphanedBlobs.\n\terr = s.TestNode.Blockchain.PruneOrphanedBlobs(lastBlockHeight)\n\ts.Require().NoError(err)\n\n\t// Verify orphaned blobs were cleaned up.\n\tsidecars, err = s.TestNode.StorageBackend.AvailabilityStore().GetBlobSidecars(orphanedSlot)\n\ts.Require().NoError(err)\n\ts.Require().Empty(sidecars)\n\n\t// Verify chain continues normally.\n\tproposals, _, _ := s.MoveChainToHeight(s.T(), 3, 1, nodeAddress, proposalTime)\n\ts.Require().Len(proposals, 1)\n}\n\n// createOrphanedSidecars creates fake blob sidecars for testing orphaned blob cleanup.\nfunc createOrphanedSidecars(\n\tt require.TestingT,\n\tslot math.Slot,\n\tverifier kzg.BlobProofVerifier,\n) datypes.BlobSidecars {\n\tblobs := []*eip4844.Blob{{1, 2, 3}}\n\tproofs, commitments := simulated.GetProofAndCommitmentsForBlobs(require.New(t), blobs, verifier)\n\n\tsidecars := make(datypes.BlobSidecars, len(blobs))\n\tfor i := range blobs {\n\t\tsidecars[i] = datypes.BuildBlobSidecar(\n\t\t\tmath.U64(i),\n\t\t\t&ctypes.SignedBeaconBlockHeader{\n\t\t\t\tHeader:    &ctypes.BeaconBlockHeader{Slot: slot},\n\t\t\t\tSignature: crypto.BLSSignature{},\n\t\t\t},\n\t\t\tblobs[i],\n\t\t\tcommitments[i],\n\t\t\tproofs[i],\n\t\t\tmake([]common.Root, ctypes.KZGInclusionProofDepth),\n\t\t)\n\t}\n\treturn sidecars\n}\n"
  },
  {
    "path": "testing/simulated/payload_cache_test.go",
    "content": "//go:build simulated\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage simulated_test\n\nimport (\n\t\"context\"\n\t\"math/big\"\n\t\"path\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/beacon/blockchain\"\n\tsvcencoding \"github.com/berachain/beacon-kit/consensus/cometbft/service/encoding\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/berachain/beacon-kit/primitives/net/url\"\n\t\"github.com/berachain/beacon-kit/testing/simulated\"\n\t\"github.com/berachain/beacon-kit/testing/simulated/execution\"\n\t\"github.com/cometbft/cometbft/abci/types\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\tgethcommon \"github.com/ethereum/go-ethereum/common\"\n\tgethtypes \"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/ethereum/go-ethereum/crypto\"\n\t\"github.com/ethereum/go-ethereum/crypto/kzg4844\"\n\t\"github.com/holiman/uint256\"\n\t\"github.com/spf13/viper\"\n\t\"github.com/stretchr/testify/require\"\n\t\"github.com/stretchr/testify/suite\"\n)\n\n// PayloadCacheSuite defines our test suite for Pectra related work using simulated Comet component.\ntype PayloadCacheSuite struct {\n\tsuite.Suite\n\tGeth  simulated.SharedAccessors\n\tReth  simulated.SharedAccessors\n\tReth2 simulated.SharedAccessors\n}\n\n// TestPayloadCacheSuite runs the test suite.\nfunc TestPayloadCacheSuite(t *testing.T) {\n\tsuite.Run(t, new(PayloadCacheSuite))\n}\n\n// SetupTest initializes the test environment.\nfunc (s *PayloadCacheSuite) SetupTest() {\n\ttestName := s.T().Name()\n\tuseThirdValidatorSetup := strings.Contains(\n\t\ttestName,\n\t\t\"TestReth_MisorderedBlobSidecarsCachedEnvelope_IsSuccessful\",\n\t)\n\n\t// Create a cancellable context for the duration of the test.\n\ts.Geth.CtxApp, s.Geth.CtxAppCancelFn = context.WithCancel(context.Background())\n\ts.Reth.CtxApp, s.Reth.CtxAppCancelFn = context.WithCancel(context.Background())\n\tif useThirdValidatorSetup {\n\t\ts.Reth2.CtxApp, s.Reth2.CtxAppCancelFn = context.WithCancel(context.Background())\n\t}\n\n\t// CometBFT uses context.TODO() for all ABCI calls, so we replicate that.\n\ts.Geth.CtxComet = context.TODO()\n\ts.Geth.HomeDir = s.T().TempDir()\n\n\ts.Reth.CtxComet = context.TODO()\n\ts.Reth.HomeDir = s.T().TempDir()\n\n\tif useThirdValidatorSetup {\n\t\ts.Reth2.CtxComet = context.TODO()\n\t\ts.Reth2.HomeDir = s.T().TempDir()\n\t}\n\n\t// Initialize the home directory, Comet configuration, and genesis info.\n\tconst elGenesisPath = \"./el-genesis-files/pectra-fork-genesis.json\"\n\tchainSpecFunc := simulated.ProvidePectraForkTestChainSpec\n\t// Create the chainSpec.\n\tchainSpec, err := chainSpecFunc()\n\ts.Require().NoError(err)\n\tvar (\n\t\tgethCmtCfg  *cmtcfg.Config\n\t\trethCmtCfg  *cmtcfg.Config\n\t\treth2CmtCfg *cmtcfg.Config\n\t)\n\tif useThirdValidatorSetup {\n\t\tconfigs, root := simulated.InitializeHomeDirs(\n\t\t\ts.T(), chainSpec, elGenesisPath, s.Geth.HomeDir, s.Reth.HomeDir, s.Reth2.HomeDir,\n\t\t)\n\t\tgethCmtCfg, rethCmtCfg, reth2CmtCfg = configs[0], configs[1], configs[2]\n\t\ts.Geth.GenesisValidatorsRoot = root\n\t\ts.Reth.GenesisValidatorsRoot = root\n\t\ts.Reth2.GenesisValidatorsRoot = root\n\t} else {\n\t\tconfigs, root := simulated.InitializeHomeDirs(\n\t\t\ts.T(), chainSpec, elGenesisPath, s.Geth.HomeDir, s.Reth.HomeDir,\n\t\t)\n\t\tgethCmtCfg, rethCmtCfg = configs[0], configs[1]\n\t\ts.Geth.GenesisValidatorsRoot = root\n\t\ts.Reth.GenesisValidatorsRoot = root\n\t}\n\n\t// Start the EL (execution layer) Geth node.\n\tgethNode := execution.NewGethNode(s.Geth.HomeDir, execution.ValidGethImage())\n\telHandle, authRPC, elRPC := gethNode.Start(s.T(), path.Base(elGenesisPath))\n\ts.Geth.ElHandle = elHandle\n\n\t// Choose the reth node to run. 2 specific tests require the engine api override flag.\n\tvar (\n\t\trethNode  *execution.ExecNode\n\t\treth2Node *execution.ExecNode\n\t)\n\tif strings.Contains(testName, \"TestReth_MustRebuildPostForkPayload_IsSuccessful\") ||\n\t\tstrings.Contains(testName, \"TestReth_MustRebuildPreForkPayload_IsSuccessful\") {\n\t\trethNode = execution.NewRethNodeWithEngineOverride(s.Reth.HomeDir, execution.ValidRethImage())\n\t\tif useThirdValidatorSetup {\n\t\t\treth2Node = execution.NewRethNodeWithEngineOverride(s.Reth2.HomeDir, execution.ValidRethImage())\n\t\t}\n\t} else {\n\t\trethNode = execution.NewRethNode(s.Reth.HomeDir, execution.ValidRethImage())\n\t\tif useThirdValidatorSetup {\n\t\t\treth2Node = execution.NewRethNode(s.Reth2.HomeDir, execution.ValidRethImage())\n\t\t}\n\t}\n\trethHandle, rethAuthRPC, rethRPC := rethNode.Start(s.T(), path.Base(elGenesisPath))\n\ts.Reth.ElHandle = rethHandle\n\tvar (\n\t\treth2Handle  *execution.Resource\n\t\treth2AuthRPC *url.ConnectionURL\n\t\treth2RPC     *url.ConnectionURL\n\t)\n\tif useThirdValidatorSetup {\n\t\treth2Handle, reth2AuthRPC, reth2RPC = reth2Node.Start(s.T(), path.Base(elGenesisPath))\n\t\ts.Reth2.ElHandle = reth2Handle\n\t}\n\n\t// Prepare a logger backed by a buffer to capture logs for assertions.\n\ts.Geth.LogBuffer = &simulated.SyncBuffer{}\n\tlogger := phuslu.NewLogger(s.Geth.LogBuffer, nil)\n\n\ts.Reth.LogBuffer = &simulated.SyncBuffer{}\n\trethLogger := phuslu.NewLogger(s.Reth.LogBuffer, nil)\n\n\tvar reth2Logger *phuslu.Logger\n\tif useThirdValidatorSetup {\n\t\ts.Reth2.LogBuffer = &simulated.SyncBuffer{}\n\t\treth2Logger = phuslu.NewLogger(s.Reth2.LogBuffer, nil)\n\t}\n\n\t// Build the Beacon node with the simulated Comet component and electra genesis chain spec\n\tcomponents := simulated.FixedComponents(s.T())\n\tcomponents = append(components, simulated.ProvideSimComet)\n\tcomponents = append(components, chainSpecFunc)\n\n\ts.Geth.TestNode = simulated.NewTestNode(s.T(), simulated.TestNodeInput{\n\t\tTempHomeDir: s.Geth.HomeDir,\n\t\tCometConfig: gethCmtCfg,\n\t\tAuthRPC:     authRPC,\n\t\tClientRPC:   elRPC,\n\t\tLogger:      logger,\n\t\tAppOpts:     viper.New(),\n\t\tComponents:  components,\n\t})\n\ts.Geth.SimComet = s.Geth.TestNode.SimComet\n\tnodeAddress, err := s.Geth.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.Geth.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\ts.Reth.TestNode = simulated.NewTestNode(s.T(), simulated.TestNodeInput{\n\t\tTempHomeDir: s.Reth.HomeDir,\n\t\tCometConfig: rethCmtCfg,\n\t\tAuthRPC:     rethAuthRPC,\n\t\tClientRPC:   rethRPC,\n\t\tLogger:      rethLogger,\n\t\tAppOpts:     viper.New(),\n\t\tComponents:  components,\n\t})\n\ts.Reth.SimComet = s.Reth.TestNode.SimComet\n\tnodeAddress, err = s.Reth.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.Reth.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\tif useThirdValidatorSetup {\n\t\ts.Reth2.TestNode = simulated.NewTestNode(s.T(), simulated.TestNodeInput{\n\t\t\tTempHomeDir: s.Reth2.HomeDir,\n\t\t\tCometConfig: reth2CmtCfg,\n\t\t\tAuthRPC:     reth2AuthRPC,\n\t\t\tClientRPC:   reth2RPC,\n\t\t\tLogger:      reth2Logger,\n\t\t\tAppOpts:     viper.New(),\n\t\t\tComponents:  components,\n\t\t})\n\t\ts.Reth2.SimComet = s.Reth2.TestNode.SimComet\n\t\tnodeAddress, err = s.Reth2.SimComet.GetNodeAddress()\n\t\ts.Require().NoError(err)\n\t\ts.Reth2.SimComet.Comet.SetNodeAddress(nodeAddress)\n\t}\n\n\t// Start the Beacon node in a separate goroutine.\n\tgo func() {\n\t\t_ = s.Geth.TestNode.Start(s.Geth.CtxApp)\n\t}()\n\t// Start the Beacon node in a separate goroutine.\n\tgo func() {\n\t\t_ = s.Reth.TestNode.Start(s.Reth.CtxApp)\n\t}()\n\tif useThirdValidatorSetup {\n\t\tgo func() {\n\t\t\t_ = s.Reth2.TestNode.Start(s.Reth2.CtxApp)\n\t\t}()\n\t}\n\n\ts.Geth.SimulationClient = execution.NewSimulationClient(s.Geth.TestNode.EngineClient)\n\t// Reth does not have a simulation API\n\ttimeOut := 10 * time.Second\n\tinterval := 50 * time.Millisecond\n\terr = simulated.WaitTillServicesStarted(s.Geth.LogBuffer, timeOut, interval)\n\ts.Require().NoError(err)\n\terr = simulated.WaitTillServicesStarted(s.Reth.LogBuffer, timeOut, interval)\n\ts.Require().NoError(err)\n\tif useThirdValidatorSetup {\n\t\terr = simulated.WaitTillServicesStarted(s.Reth2.LogBuffer, timeOut, interval)\n\t\ts.Require().NoError(err)\n\t}\n}\n\n// TearDownTest cleans up the test environment.\nfunc (s *PayloadCacheSuite) TearDownTest() {\n\ts.Geth.CleanupTestWithLabel(s.T(), \"GETH\")\n\ts.Reth.CleanupTestWithLabel(s.T(), \"RETH\")\n\ts.Reth2.CleanupTestWithLabel(s.T(), \"RETH2\")\n}\n\n// This tests a reth validator proposing a block. It then accepts the proposal in\n// process proposal. But the block is not finalized by consensus. Then this\n// validator is chosen to propose at a subsequent round. It should just get the old\n// payload from its cache.\nfunc (s *PayloadCacheSuite) TestReth_ReusePayload_IsSuccessful() {\n\t// Initialize the chain state.\n\ts.Reth.InitializeChain(s.T(), 2) // 1 reth validator\n\tnodeAddress, err := s.Reth.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.Reth.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\t// Next block is height 1.\n\tnextBlockHeight := int64(1)\n\tconsensusTime := time.Unix(int64(s.Reth.TestNode.ChainSpec.ElectraForkTime()), 0)\n\n\t{\n\t\t// Prepare the proposal.\n\t\tproposal, prepareErr := s.Reth.SimComet.Comet.PrepareProposal(s.Reth.CtxComet, &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: nodeAddress,\n\t\t})\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\t// Process the proposal.\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     nodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: nodeAddress,\n\t\t}\n\t\t// This will trigger a optimistic payload build for block height 2.\n\t\tprocessResp, respErr := s.Reth.SimComet.Comet.ProcessProposal(s.Reth.CtxComet, processRequest)\n\t\ts.Require().NoError(respErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT, processResp.Status)\n\t}\n\n\t// For some reason, the supermajority does not finalize the block.\n\t// Next round is height 1, but simulating consensus time is 1 second after previous round.\n\ttime.Sleep(200 * time.Millisecond) // This lets the optimistic build complete.\n\tconsensusTime = time.Unix(int64(s.Reth.TestNode.ChainSpec.ElectraForkTime())+1, 0)\n\t{\n\t\t// Prepare the proposal. Bkit cached the payload ID, so we just get the old one from reth.\n\t\tproposal, prepareErr := s.Reth.SimComet.Comet.PrepareProposal(s.Reth.CtxComet, &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: nodeAddress,\n\t\t})\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\t// Process the proposal.\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     nodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: nodeAddress,\n\t\t}\n\n\t\t// Process the proposal.\n\t\tprocessResp, processErr := s.Reth.SimComet.Comet.ProcessProposal(s.Reth.CtxComet, processRequest)\n\t\ts.Require().NoError(processErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT, processResp.Status)\n\n\t\t// Now the block is finalized and committed.\n\t\tfinalizeRequest := &types.FinalizeBlockRequest{\n\t\t\tTxs:             proposal.Txs,\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tProposerAddress: nodeAddress,\n\t\t\tTime:            consensusTime,\n\t\t}\n\t\t_, finalizeErr := s.Reth.SimComet.Comet.FinalizeBlock(s.Reth.CtxComet, finalizeRequest)\n\t\ts.Require().NoError(finalizeErr)\n\t\t_, commitErr := s.Reth.SimComet.Comet.Commit(s.Reth.CtxComet, &types.CommitRequest{})\n\t\ts.Require().NoError(commitErr)\n\t}\n}\n\n// This tests a geth validator proposing a block. It then accepts the proposal in\n// process proposal. But the block is not finalized by consensus. Then this\n// validator is chosen to propose at a subsequent round. It should just get the old\n// payload from its cache.\nfunc (s *PayloadCacheSuite) TestGeth_ReusePayload_IsSuccessful() {\n\t// Initialize the chain state.\n\ts.Geth.InitializeChain(s.T(), 2) // 1 geth validator\n\tnodeAddress, err := s.Geth.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.Geth.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\t// Next block is height 1.\n\tnextBlockHeight := int64(1)\n\tconsensusTime := time.Unix(int64(s.Geth.TestNode.ChainSpec.ElectraForkTime()), 0)\n\n\t{\n\t\t// Prepare the proposal.\n\t\tproposal, prepareErr := s.Geth.SimComet.Comet.PrepareProposal(s.Geth.CtxComet, &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: nodeAddress,\n\t\t})\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\t// Process the proposal.\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     nodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: nodeAddress,\n\t\t}\n\t\t// This will trigger a optimistic payload build for block height 2.\n\t\tprocessResp, respErr := s.Geth.SimComet.Comet.ProcessProposal(s.Geth.CtxComet, processRequest)\n\t\ts.Require().NoError(respErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT, processResp.Status)\n\t}\n\n\t// For some reason, the supermajority does not finalize the block.\n\t// Next round is height 1, but simulating consensus time is 1 second after previous round.\n\ttime.Sleep(200 * time.Millisecond) // This lets the optimistic build complete.\n\tconsensusTime = time.Unix(int64(s.Geth.TestNode.ChainSpec.ElectraForkTime())+1, 0)\n\t{\n\t\t// Prepare the proposal. Bkit cached the payload ID, so we just get the old one from geth.\n\t\tproposal, prepareErr := s.Geth.SimComet.Comet.PrepareProposal(s.Geth.CtxComet, &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: nodeAddress,\n\t\t})\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\t// Process the proposal.\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     nodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: nodeAddress,\n\t\t}\n\n\t\t// Process the proposal.\n\t\tprocessResp, processErr := s.Geth.SimComet.Comet.ProcessProposal(s.Geth.CtxComet, processRequest)\n\t\ts.Require().NoError(processErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT, processResp.Status)\n\n\t\t// Now the block is finalized and committed.\n\t\tfinalizeRequest := &types.FinalizeBlockRequest{\n\t\t\tTxs:             proposal.Txs,\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tProposerAddress: nodeAddress,\n\t\t\tTime:            consensusTime,\n\t\t}\n\t\t_, finalizeErr := s.Geth.SimComet.Comet.FinalizeBlock(s.Geth.CtxComet, finalizeRequest)\n\t\ts.Require().NoError(finalizeErr)\n\t\t_, commitErr := s.Geth.SimComet.Comet.Commit(s.Geth.CtxComet, &types.CommitRequest{})\n\t\ts.Require().NoError(commitErr)\n\t}\n}\n\n// This tests a reth validator proposing a invalid block. The proposal is rejected. Then this\n// validator is chosen to propose at a subsequent round. It should now be forced to\n// rebuild a new payload (and not reuse the old one from its cache).\nfunc (s *PayloadCacheSuite) TestReth_RebuildPayload_IsSuccessful() {\n\t// Initialize the chain state.\n\ts.Reth.InitializeChain(s.T(), 2) // 1 reth validator\n\tnodeAddress, err := s.Reth.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.Reth.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\t// Next block is height 1.\n\tnextBlockHeight := int64(1)\n\tconsensusTime := time.Unix(int64(s.Reth.TestNode.ChainSpec.ElectraForkTime()), 0)\n\n\t{\n\t\t// Prepare an invalid proposal.\n\t\tfaultyConsensusTime := time.Unix(int64(s.Reth.TestNode.ChainSpec.ElectraForkTime())-1, 0)\n\t\tproposal, prepareErr := s.Reth.SimComet.Comet.PrepareProposal(s.Reth.CtxComet, &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            faultyConsensusTime,\n\t\t\tProposerAddress: nodeAddress,\n\t\t})\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\t// Process the proposal.\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     nodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: nodeAddress,\n\t\t}\n\t\t// As we reject our own built proposal, bkit should evict this payload from its cache.\n\t\tprocessResp, respErr := s.Reth.SimComet.Comet.ProcessProposal(s.Reth.CtxComet, processRequest)\n\t\ts.Require().NoError(respErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_REJECT, processResp.Status)\n\t\ts.Require().Contains(\n\t\t\ts.Reth.LogBuffer.String(),\n\t\t\t\"failed decoding *types.SignedBeaconBlock: ssz: offset smaller than previous\",\n\t\t)\n\t}\n\n\t// Subsequent round where we are selected to propose again.\n\t{\n\t\t// Prepare the valid proposal. This should now request the EL for a new payload.\n\t\tproposal, prepareErr := s.Reth.SimComet.Comet.PrepareProposal(s.Reth.CtxComet, &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: nodeAddress,\n\t\t})\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\t// Process the proposal.\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     nodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: nodeAddress,\n\t\t}\n\n\t\t// Process the proposal.\n\t\tprocessResp, processErr := s.Reth.SimComet.Comet.ProcessProposal(s.Reth.CtxComet, processRequest)\n\t\ts.Require().NoError(processErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT, processResp.Status)\n\n\t\t// Now the block is finalized and committed.\n\t\tfinalizeRequest := &types.FinalizeBlockRequest{\n\t\t\tTxs:             proposal.Txs,\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tProposerAddress: nodeAddress,\n\t\t\tTime:            consensusTime,\n\t\t}\n\t\t_, finalizeErr := s.Reth.SimComet.Comet.FinalizeBlock(s.Reth.CtxComet, finalizeRequest)\n\t\ts.Require().NoError(finalizeErr)\n\t\t_, commitErr := s.Reth.SimComet.Comet.Commit(s.Reth.CtxComet, &types.CommitRequest{})\n\t\ts.Require().NoError(commitErr)\n\t}\n}\n\n// This tests a geth validator proposing a invalid block. The proposal is rejected. Then this\n// validator is chosen to propose at a subsequent round. It should now be forced to\n// rebuild a new payload (and not reuse the old one from its cache).\nfunc (s *PayloadCacheSuite) TestGeth_RebuildPayload_IsSuccessful() {\n\t// Initialize the chain state.\n\ts.Geth.InitializeChain(s.T(), 2) // 1 geth validator\n\tnodeAddress, err := s.Geth.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.Geth.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\t// Next block is height 1.\n\tnextBlockHeight := int64(1)\n\tconsensusTime := time.Unix(int64(s.Geth.TestNode.ChainSpec.ElectraForkTime()), 0)\n\n\t{\n\t\t// Prepare an invalid proposal.\n\t\tfaultyConsensusTime := time.Unix(int64(s.Geth.TestNode.ChainSpec.ElectraForkTime())-1, 0)\n\t\tproposal, prepareErr := s.Geth.SimComet.Comet.PrepareProposal(s.Geth.CtxComet, &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            faultyConsensusTime,\n\t\t\tProposerAddress: nodeAddress,\n\t\t})\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\t// Process the proposal.\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     nodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: nodeAddress,\n\t\t}\n\t\t// As we reject our own built proposal, bkit should evict this payload from its cache.\n\t\tprocessResp, respErr := s.Geth.SimComet.Comet.ProcessProposal(s.Geth.CtxComet, processRequest)\n\t\ts.Require().NoError(respErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_REJECT, processResp.Status)\n\t\ts.Require().Contains(\n\t\t\ts.Geth.LogBuffer.String(),\n\t\t\t\"failed decoding *types.SignedBeaconBlock: ssz: offset smaller than previous\",\n\t\t)\n\t}\n\n\t// Subsequent round where we are selected to propose again.\n\t{\n\t\t// Prepare the valid proposal. This should now request the EL for a new payload.\n\t\tproposal, prepareErr := s.Geth.SimComet.Comet.PrepareProposal(s.Geth.CtxComet, &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: nodeAddress,\n\t\t})\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\t// Process the proposal.\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     nodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: nodeAddress,\n\t\t}\n\n\t\t// Process the proposal.\n\t\tprocessResp, processErr := s.Geth.SimComet.Comet.ProcessProposal(s.Geth.CtxComet, processRequest)\n\t\ts.Require().NoError(processErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT, processResp.Status)\n\n\t\t// Now the block is finalized and committed.\n\t\tfinalizeRequest := &types.FinalizeBlockRequest{\n\t\t\tTxs:             proposal.Txs,\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tProposerAddress: nodeAddress,\n\t\t\tTime:            consensusTime,\n\t\t}\n\t\t_, finalizeErr := s.Geth.SimComet.Comet.FinalizeBlock(s.Geth.CtxComet, finalizeRequest)\n\t\ts.Require().NoError(finalizeErr)\n\t\t_, commitErr := s.Geth.SimComet.Comet.Commit(s.Geth.CtxComet, &types.CommitRequest{})\n\t\ts.Require().NoError(commitErr)\n\t}\n}\n\n// Test a scenario where the first proposed block is pre-fork and accepted initially but never\n// finalized by the network (which triggeres optimistic builds). The subsequent rounds are now\n// post-fork. Only reth with the flag can force rebuild a payload.\n//\n// NOTE: this test requires reth with the --engine.always-process-payload-attributes-on-canonical-head flag.\nfunc (s *PayloadCacheSuite) TestReth_MustRebuildPostForkPayload_IsSuccessful() {\n\t// Initialize the chain state.\n\ts.Geth.InitializeChain(s.T(), 2) // 1 geth validator\n\tgethNodeAddress, err := s.Geth.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.Geth.SimComet.Comet.SetNodeAddress(gethNodeAddress)\n\ts.Reth.InitializeChain(s.T(), 2) // 1 reth validator\n\trethNodeAddress, err := s.Reth.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.Reth.SimComet.Comet.SetNodeAddress(rethNodeAddress)\n\n\t// Next block is height 1.\n\tnextBlockHeight := int64(1)\n\tconsensusTime := time.Unix(int64(s.Reth.TestNode.ChainSpec.ElectraForkTime()-1), 0)\n\t{\n\t\t// Prepare the proposal.\n\t\tproposal, prepareErr := s.Geth.SimComet.Comet.PrepareProposal(s.Geth.CtxComet, &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: gethNodeAddress,\n\t\t})\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\t// Process the proposal, with no payload eviction from bkit cache.\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     gethNodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: gethNodeAddress,\n\t\t}\n\t\t// This will trigger a optimistic payload build for block height 2.\n\t\tprocessResp, respErr := s.Geth.SimComet.Comet.ProcessProposal(s.Geth.CtxComet, processRequest)\n\t\ts.Require().NoError(respErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT, processResp.Status)\n\n\t\t// Reth also prepares proposal.\n\t\tproposal, prepareErr = s.Reth.SimComet.Comet.PrepareProposal(s.Reth.CtxComet, &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: rethNodeAddress,\n\t\t})\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\t// Process the proposal, with no payload eviction from bkit cache.\n\t\tprocessRequest = &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     rethNodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: rethNodeAddress,\n\t\t}\n\t\t// This will trigger a optimistic payload build for block height 2.\n\t\tprocessResp, respErr = s.Reth.SimComet.Comet.ProcessProposal(s.Reth.CtxComet, processRequest)\n\t\ts.Require().NoError(respErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT, processResp.Status)\n\t}\n\n\t// For some reason, the supermajority does not finalize the block.\n\t// We are now crossing over into post-fork time.\n\t// Next round is height 1, but simulating consensus time is 1 second after previous round.\n\ttime.Sleep(10 * time.Millisecond) // Next round.\n\t{\n\t\t// Try to build a new (pre-fork) payload from geth EL.\n\t\t// NOTE: this will fail because geth does not allow re-building a payload for a height\n\t\t// that has already been marked safe/finalized\n\t\tconsensusTime := time.Unix(int64(s.Geth.TestNode.ChainSpec.ElectraForkTime()), 0)\n\t\tproposal, prepareErr := s.Geth.SimComet.Comet.PrepareProposal(s.Geth.CtxComet, &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: gethNodeAddress,\n\t\t})\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 0) // Geth returns an empty proposal.\n\t}\n\n\ttime.Sleep(10 * time.Millisecond) // Next round.\n\t{\n\t\t// Try to build a new post-fork payload from reth EL. This works because the reth flag\n\t\t// allows us to rebuild a payload that has already been marked safe/finalized.\n\t\tconsensusTime := time.Unix(int64(s.Reth.TestNode.ChainSpec.ElectraForkTime()), 0)\n\t\tproposal, prepareErr := s.Reth.SimComet.Comet.PrepareProposal(s.Reth.CtxComet, &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: rethNodeAddress,\n\t\t})\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\t// Process the proposal.\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     rethNodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: rethNodeAddress,\n\t\t}\n\t\tprocessResp, respErr := s.Reth.SimComet.Comet.ProcessProposal(s.Reth.CtxComet, processRequest)\n\t\ts.Require().NoError(respErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT, processResp.Status)\n\t\tprocessResp, respErr = s.Geth.SimComet.Comet.ProcessProposal(s.Geth.CtxComet, processRequest)\n\t\ts.Require().NoError(respErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT, processResp.Status)\n\t}\n}\n\n// Test a scenario where the first proposed block is post-fork and accepted initially but never\n// finalized by the network (which triggeres optimistic builds). The subsequent rounds are actually\n// pre-fork. Only reth with the flag can force rebuild a payload.\n//\n// NOTE: this test requires reth with the --engine.always-process-payload-attributes-on-canonical-head flag\n// to propose the valid pre-fork block.\nfunc (s *PayloadCacheSuite) TestReth_MustRebuildPreForkPayload_IsSuccessful() {\n\t// Initialize the chain state.\n\ts.Geth.InitializeChain(s.T(), 2)\n\tgethNodeAddress, err := s.Geth.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.Reth.InitializeChain(s.T(), 2)\n\trethNodeAddress, err := s.Reth.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\n\tnextBlockHeight := int64(1)\n\t// Both reth and geth prepare and propose a post-fork block without finalizing.\n\t{\n\t\tconsensusTime := time.Unix(int64(s.Geth.TestNode.ChainSpec.ElectraForkTime()), 0)\n\n\t\t// Geth builds.\n\t\tproposal, prepareErr := s.Geth.SimComet.Comet.PrepareProposal(s.Geth.CtxComet, &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: gethNodeAddress,\n\t\t})\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\t// Geth processes the proposal. No bkit payload eviction here.\n\t\t// Optimistically build the next height's payload.\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     gethNodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: gethNodeAddress,\n\t\t}\n\t\ts.Geth.LogBuffer.Reset()\n\t\tprocessResp, respErr := s.Geth.SimComet.Comet.ProcessProposal(s.Geth.CtxComet, processRequest)\n\t\ts.Require().NoError(respErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT.String(), processResp.Status.String())\n\n\t\t// Reth also builds.\n\t\tproposal, prepareErr = s.Reth.SimComet.Comet.PrepareProposal(s.Reth.CtxComet, &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: rethNodeAddress,\n\t\t})\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\t// Reth processes the proposal. No bkit payload eviction here.\n\t\t// Optimistically build the next height's payload.\n\t\tprocessRequest = &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     rethNodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: rethNodeAddress,\n\t\t}\n\t\ts.Reth.LogBuffer.Reset()\n\t\tprocessResp, respErr = s.Reth.SimComet.Comet.ProcessProposal(s.Reth.CtxComet, processRequest)\n\t\ts.Require().NoError(respErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT.String(), processResp.Status.String())\n\t}\n\n\ttime.Sleep(100 * time.Millisecond) // Next round.\n\t// The previous payload in cache has been evicted. The optimistic builds for next height\n\t// should have completed by now.\n\t{\n\t\t// Try to build a new (pre-fork) payload from geth EL.\n\t\t// NOTE: this will fail because geth does not allow re-building a payload for a height\n\t\t// that has already been marked safe/finalized\n\t\tconsensusTime := time.Unix(int64(s.Geth.TestNode.ChainSpec.ElectraForkTime())-2, 0)\n\t\tprepareReq := &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: gethNodeAddress,\n\t\t}\n\t\tproposal, prepareErr := s.Geth.SimComet.Comet.PrepareProposal(s.Geth.CtxComet, prepareReq)\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 0) // Geth returns an empty proposal.\n\t}\n\n\ttime.Sleep(10 * time.Millisecond) // Next round.\n\t// The next block the proposer proposes with a pre-fork timestamp will actually have a pre-fork time\n\t// Since the previous payload in cache has been evicted, a new payload is built and retrieved.\n\t{\n\t\t// Force build a new (pre-fork) payload from reth EL.\n\t\t// NOTE: this requires --engine.always-process-payload-attributes-on-canonical-head.\n\t\tconsensusTime := time.Unix(int64(s.Reth.TestNode.ChainSpec.ElectraForkTime())-1, 0)\n\t\tproposal, prepareErr := s.Reth.SimComet.Comet.PrepareProposal(s.Reth.CtxComet, &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: rethNodeAddress,\n\t\t})\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     rethNodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: gethNodeAddress,\n\t\t}\n\n\t\t// Process the proposal. No bkit payload eviction here from cache. Also trigger an optimistic\n\t\t// build for next height.\n\t\ts.Geth.LogBuffer.Reset()\n\t\tprocessResp, processErr := s.Geth.SimComet.Comet.ProcessProposal(s.Geth.CtxComet, processRequest)\n\t\ts.Require().NoError(processErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT.String(), processResp.Status.String())\n\n\t\t// Reth also process proposal and does not evict payload from bkit cache.\n\t\ts.Reth.LogBuffer.Reset()\n\t\tprocessResp, processErr = s.Reth.SimComet.Comet.ProcessProposal(s.Reth.CtxComet, processRequest)\n\t\ts.Require().NoError(processErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT, processResp.Status)\n\n\t\t// Finalize the block. Evict bkit payload here because finalize is accepted.\n\t\tfinalizeRequest := &types.FinalizeBlockRequest{\n\t\t\tTxs:             proposal.Txs,\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tProposerAddress: rethNodeAddress,\n\t\t\tTime:            consensusTime,\n\t\t}\n\t\t_, finalizeErr := s.Geth.SimComet.Comet.FinalizeBlock(s.Geth.CtxComet, finalizeRequest)\n\t\ts.Require().NoError(finalizeErr)\n\t\t_, finalizeErr = s.Reth.SimComet.Comet.FinalizeBlock(s.Reth.CtxComet, finalizeRequest)\n\t\ts.Require().NoError(finalizeErr)\n\n\t\t// Commit the block.\n\t\t_, err := s.Geth.SimComet.Comet.Commit(s.Geth.CtxComet, &types.CommitRequest{})\n\t\ts.Require().NoError(err)\n\t\ts.Geth.LogBuffer.Reset()\n\t\t_, err = s.Reth.SimComet.Comet.Commit(s.Reth.CtxComet, &types.CommitRequest{})\n\t\ts.Require().NoError(err)\n\t\ts.Reth.LogBuffer.Reset()\n\t}\n\n\t// Finally, we cross the fork and show no issues. Geth uses the optimistic build which has the\n\t// correct payload time and consequently is built correctly for post-fork.\n\tnextBlockHeight++\n\ttime.Sleep(100 * time.Millisecond) // The optimistic build for next height should have completed by now.\n\t{\n\t\tconsensusTime := time.Unix(int64(s.Geth.TestNode.ChainSpec.ElectraForkTime()), 0)\n\t\tproposal, prepareErr := s.Geth.SimComet.Comet.PrepareProposal(s.Geth.CtxComet, &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: gethNodeAddress,\n\t\t})\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:             proposal.Txs,\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tProposerAddress: gethNodeAddress,\n\t\t\tTime:            consensusTime,\n\t\t}\n\t\t// Process the proposal.\n\t\tprocessResp, processErr := s.Geth.SimComet.Comet.ProcessProposal(s.Geth.CtxComet, processRequest)\n\t\ts.Require().NoError(processErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT.String(), processResp.Status.String())\n\t\ts.Require().Contains(s.Geth.LogBuffer.String(), \"Processing execution requests\")\n\t\tprocessResp, processErr = s.Reth.SimComet.Comet.ProcessProposal(s.Reth.CtxComet, processRequest)\n\t\ts.Require().NoError(processErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT, processResp.Status)\n\t\ts.Require().Contains(s.Reth.LogBuffer.String(), \"Processing execution requests\")\n\t}\n}\n\n// This tests a malicious proposer that reorders blob sidecars in a proposal.\n// Another validator accepts and caches the payload envelope without finalizing.\n// In a subsequent round at the same height, the caching validator proposes again\n// from cache and a third validator accepts that proposal.\nfunc (s *PayloadCacheSuite) TestReth_MisorderedBlobSidecarsCachedEnvelope_IsSuccessful() {\n\t// Initialize chain state with 3 validators.\n\ts.Geth.InitializeChain(s.T(), 3)\n\ts.Reth.InitializeChain(s.T(), 3)\n\ts.Reth2.InitializeChain(s.T(), 3)\n\n\t// validator A: malicious proposer.\n\tmaliciousProposerAddress, err := s.Geth.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.Geth.SimComet.Comet.SetNodeAddress(maliciousProposerAddress)\n\n\t// validator B: verifies malicious proposal and later proposes from cache.\n\tcachingValidatorAddress, err := s.Reth.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.Reth.SimComet.Comet.SetNodeAddress(cachingValidatorAddress)\n\n\t// validator C: verifies validator B's subsequent proposal.\n\tverifyingValidatorAddress, err := s.Reth2.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.Reth2.SimComet.Comet.SetNodeAddress(verifyingValidatorAddress)\n\n\tnextBlockHeight := int64(1)\n\tconsensusTime := time.Unix(int64(s.Reth.TestNode.ChainSpec.ElectraForkTime()), 0)\n\n\t// Seed proposer A's EL with blob txs so the proposal has reorderable sidecars.\n\ts.submitBlobTransactions(s.Geth, 2)\n\n\tvar (\n\t\tproposal    *types.PrepareProposalResponse\n\t\treorderedTx bool\n\t)\n\tfor i := 0; i < 10; i++ {\n\t\tproposal, err = s.Geth.SimComet.Comet.PrepareProposal(\n\t\t\ts.Geth.CtxComet, &types.PrepareProposalRequest{\n\t\t\t\tHeight:          nextBlockHeight,\n\t\t\t\tTime:            consensusTime,\n\t\t\t\tProposerAddress: maliciousProposerAddress,\n\t\t\t},\n\t\t)\n\t\ts.Require().NoError(err)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\tsidecars, scErr := svcencoding.UnmarshalBlobSidecarsFromABCIRequest(\n\t\t\tproposal.Txs,\n\t\t\tblockchain.BlobSidecarsTxIndex,\n\t\t)\n\t\ts.Require().NoError(scErr)\n\t\tif len(sidecars) < 2 {\n\t\t\ttime.Sleep(200 * time.Millisecond)\n\t\t\tcontinue // NOTE: we retry at most 10 times, with 200ms delay between retries.\n\t\t}\n\n\t\t// Maliciously reorder two sidecars in the proposal.\n\t\tsidecars[0], sidecars[1] = sidecars[1], sidecars[0]\n\t\tsidecarBytes, marshalErr := sidecars.MarshalSSZ()\n\t\ts.Require().NoError(marshalErr)\n\t\tproposal.Txs[blockchain.BlobSidecarsTxIndex] = sidecarBytes\n\t\treorderedTx = true\n\t\tbreak\n\t}\n\ts.Require().True(\n\t\treorderedTx,\n\t\t\"expected at least 2 blob sidecars so the malicious proposer can reorder them\",\n\t)\n\n\t// validator B verifies and accepts the maliciously-ordered proposal. This caches the\n\t// payload envelope, but the block never finalizes.\n\tprocessResp, err := s.Reth.SimComet.Comet.ProcessProposal(\n\t\ts.Reth.CtxComet, &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     maliciousProposerAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: cachingValidatorAddress,\n\t\t},\n\t)\n\ts.Require().NoError(err)\n\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT, processResp.Status)\n\n\t// Next round at same height; validator B now proposes from cached envelope.\n\ttime.Sleep(200 * time.Millisecond)\n\tconsensusTime = consensusTime.Add(time.Second)\n\tcachedProposal, err := s.Reth.SimComet.Comet.PrepareProposal(\n\t\ts.Reth.CtxComet, &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: cachingValidatorAddress,\n\t\t},\n\t)\n\ts.Require().NoError(err)\n\ts.Require().Len(cachedProposal.Txs, 2)\n\n\t// Ensure the proposal from cache carries sidecars in canonical index order.\n\tcachedSidecars, err := svcencoding.UnmarshalBlobSidecarsFromABCIRequest(\n\t\tcachedProposal.Txs,\n\t\tblockchain.BlobSidecarsTxIndex,\n\t)\n\ts.Require().NoError(err)\n\ts.Require().GreaterOrEqual(len(cachedSidecars), 2)\n\tfor i := 1; i < len(cachedSidecars); i++ {\n\t\ts.Require().GreaterOrEqual(\n\t\t\tcachedSidecars[i].GetIndex(),\n\t\t\tcachedSidecars[i-1].GetIndex(),\n\t\t)\n\t}\n\n\t// validator C verifies the cached proposal and accepts it.\n\tprocessResp, err = s.Reth2.SimComet.Comet.ProcessProposal(\n\t\ts.Reth2.CtxComet, &types.ProcessProposalRequest{\n\t\t\tTxs:                 cachedProposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     cachingValidatorAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: verifyingValidatorAddress,\n\t\t},\n\t)\n\ts.Require().NoError(err)\n\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT, processResp.Status)\n}\n\nfunc (s *PayloadCacheSuite) submitBlobTransactions(node simulated.SharedAccessors, numBlobs int) {\n\ts.T().Helper()\n\ts.Require().GreaterOrEqual(numBlobs, 2)\n\n\tblobs := make([]*eip4844.Blob, numBlobs)\n\tfor i := range blobs {\n\t\tblob := &eip4844.Blob{}\n\t\tblob[0] = byte(i + 1)\n\t\tblob[1] = byte(i + 2)\n\t\tblobs[i] = blob\n\t}\n\n\tproofs, commitments := simulated.GetProofAndCommitmentsForBlobs(\n\t\trequire.New(s.T()),\n\t\tblobs,\n\t\tnode.TestNode.KZGVerifier,\n\t)\n\n\ttestKey := simulated.GetTestKey(s.T())\n\tchainID := node.TestNode.ChainSpec.DepositEth1ChainID()\n\tsigner := gethtypes.NewCancunSigner(big.NewInt(int64(chainID)))\n\tsenderAddress := crypto.PubkeyToAddress(testKey.PublicKey)\n\trecipientAddress := gethcommon.HexToAddress(simulated.WithdrawalExecutionAddress)\n\n\tnextNonce, err := node.TestNode.ContractBackend.PendingNonceAt(node.CtxApp, senderAddress)\n\ts.Require().NoError(err)\n\n\tfor i := 0; i < numBlobs; i++ {\n\t\ttxSidecar := &gethtypes.BlobTxSidecar{\n\t\t\tBlobs:       []kzg4844.Blob{kzg4844.Blob(blobs[i][:])},\n\t\t\tCommitments: []kzg4844.Commitment{kzg4844.Commitment(commitments[i])},\n\t\t\tProofs:      []kzg4844.Proof{kzg4844.Proof(proofs[i])},\n\t\t}\n\t\tblobHash := commitments[i].ToVersionedHash()\n\n\t\tblobTx, signErr := gethtypes.SignNewTx(\n\t\t\ttestKey,\n\t\t\tsigner,\n\t\t\t&gethtypes.BlobTx{\n\t\t\t\tChainID:    uint256.NewInt(chainID),\n\t\t\t\tNonce:      nextNonce + uint64(i),\n\t\t\t\tGasTipCap:  uint256.NewInt(10_000_000_000),\n\t\t\t\tGasFeeCap:  uint256.NewInt(10_000_000_000),\n\t\t\t\tGas:        210000,\n\t\t\t\tTo:         recipientAddress,\n\t\t\t\tValue:      uint256.NewInt(0),\n\t\t\t\tData:       []byte{},\n\t\t\t\tAccessList: nil,\n\t\t\t\tBlobFeeCap: uint256.NewInt(10_000_000_000),\n\t\t\t\tBlobHashes: []gethcommon.Hash{blobHash},\n\t\t\t\t// Sidecar must be nil on signing; we attach it immediately after.\n\t\t\t\tSidecar: nil,\n\t\t\t},\n\t\t)\n\t\ts.Require().NoError(signErr)\n\n\t\tblobTx = blobTx.WithBlobTxSidecar(txSidecar)\n\t\tsendErr := node.TestNode.ContractBackend.SendTransaction(node.CtxApp, blobTx)\n\t\ts.Require().NoError(sendErr)\n\t}\n\n\tfor i := 0; i < 10; i++ {\n\t\tpendingNonce, nonceErr := node.TestNode.ContractBackend.PendingNonceAt(node.CtxApp, senderAddress)\n\t\ts.Require().NoError(nonceErr)\n\t\tif pendingNonce >= nextNonce+uint64(numBlobs) {\n\t\t\treturn\n\t\t}\n\t\ttime.Sleep(100 * time.Millisecond)\n\t}\n\n\ts.T().Fatalf(\"blob transactions did not enter txpool in time\")\n}\n"
  },
  {
    "path": "testing/simulated/pectra_fork_test.go",
    "content": "//go:build simulated\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage simulated_test\n\nimport (\n\t\"context\"\n\t\"math/big\"\n\t\"path\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/beacon/blockchain\"\n\tpayloadtime \"github.com/berachain/beacon-kit/beacon/payload-time\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/encoding\"\n\t\"github.com/berachain/beacon-kit/execution/requests/eip7251\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/testing/simulated\"\n\t\"github.com/berachain/beacon-kit/testing/simulated/execution\"\n\t\"github.com/cometbft/cometbft/abci/types\"\n\t\"github.com/ethereum/go-ethereum/common/hexutil\"\n\tgethtypes \"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/ethereum/go-ethereum/crypto\"\n\t\"github.com/ethereum/go-ethereum/params\"\n\t\"github.com/spf13/viper\"\n\t\"github.com/stretchr/testify/require\"\n\t\"github.com/stretchr/testify/suite\"\n)\n\n// PectraForkSuite defines our test suite for Pectra related work using simulated Comet component.\ntype PectraForkSuite struct {\n\tsuite.Suite\n\tGeth simulated.SharedAccessors\n\tReth simulated.SharedAccessors\n}\n\n// TestPectraForkSuite runs the test suite.\nfunc TestPectraForkSuite(t *testing.T) {\n\tsuite.Run(t, new(PectraForkSuite))\n}\n\n// SetupTest initializes the test environment.\nfunc (s *PectraForkSuite) SetupTest() {\n\t// Create a cancellable context for the duration of the test.\n\ts.Geth.CtxApp, s.Geth.CtxAppCancelFn = context.WithCancel(context.Background())\n\ts.Reth.CtxApp, s.Reth.CtxAppCancelFn = context.WithCancel(context.Background())\n\n\t// CometBFT uses context.TODO() for all ABCI calls, so we replicate that.\n\ts.Geth.CtxComet = context.TODO()\n\ts.Geth.HomeDir = s.T().TempDir()\n\n\ts.Reth.CtxComet = context.TODO()\n\ts.Reth.HomeDir = s.T().TempDir()\n\n\t// Initialize the home directory, Comet configuration, and genesis info.\n\tconst elGenesisPath = \"./el-genesis-files/pectra-fork-genesis.json\"\n\tchainSpecFunc := simulated.ProvidePectraForkTestChainSpec\n\t// Create the chainSpec.\n\tchainSpec, err := chainSpecFunc()\n\ts.Require().NoError(err)\n\tconfigs, genesisValidatorsRoot := simulated.InitializeHomeDirs(s.T(), chainSpec, elGenesisPath, s.Geth.HomeDir)\n\tcometConfig := configs[0]\n\ts.Geth.GenesisValidatorsRoot = genesisValidatorsRoot\n\ts.Reth.GenesisValidatorsRoot = genesisValidatorsRoot\n\n\t// Copy the home dir for the Reth Node\n\tsimulated.CopyHomeDir(s.T(), s.Geth.HomeDir, s.Reth.HomeDir)\n\n\t// Start the EL (execution layer) Geth node.\n\tgethNode := execution.NewGethNode(s.Geth.HomeDir, execution.ValidGethImage())\n\telHandle, authRPC, elRPC := gethNode.Start(s.T(), path.Base(elGenesisPath))\n\ts.Geth.ElHandle = elHandle\n\n\trethNode := execution.NewRethNode(s.Reth.HomeDir, execution.ValidRethImage())\n\trethHandle, rethAuthRPC, elRPC := rethNode.Start(s.T(), path.Base(elGenesisPath))\n\ts.Reth.ElHandle = rethHandle\n\n\t// Prepare a logger backed by a buffer to capture logs for assertions.\n\ts.Geth.LogBuffer = &simulated.SyncBuffer{}\n\tlogger := phuslu.NewLogger(s.Geth.LogBuffer, nil)\n\n\ts.Reth.LogBuffer = &simulated.SyncBuffer{}\n\trethLogger := phuslu.NewLogger(s.Reth.LogBuffer, nil)\n\n\t// Build the Beacon node with the simulated Comet component and electra genesis chain spec\n\tcomponents := simulated.FixedComponents(s.T())\n\tcomponents = append(components, simulated.ProvideSimComet)\n\tcomponents = append(components, chainSpecFunc)\n\n\ts.Geth.TestNode = simulated.NewTestNode(s.T(), simulated.TestNodeInput{\n\t\tTempHomeDir: s.Geth.HomeDir,\n\t\tCometConfig: cometConfig,\n\t\tAuthRPC:     authRPC,\n\t\tClientRPC:   elRPC,\n\t\tLogger:      logger,\n\t\tAppOpts:     viper.New(),\n\t\tComponents:  components,\n\t})\n\ts.Geth.SimComet = s.Geth.TestNode.SimComet\n\n\ts.Reth.TestNode = simulated.NewTestNode(s.T(), simulated.TestNodeInput{\n\t\tTempHomeDir: s.Reth.HomeDir,\n\t\tCometConfig: cometConfig,\n\t\tAuthRPC:     rethAuthRPC,\n\t\tClientRPC:   elRPC,\n\t\tLogger:      rethLogger,\n\t\tAppOpts:     viper.New(),\n\t\tComponents:  components,\n\t})\n\ts.Reth.SimComet = s.Reth.TestNode.SimComet\n\n\t// Start the Beacon node in a separate goroutine.\n\tgo func() {\n\t\t_ = s.Geth.TestNode.Start(s.Geth.CtxApp)\n\t}()\n\t// Start the Beacon node in a separate goroutine.\n\tgo func() {\n\t\t_ = s.Reth.TestNode.Start(s.Reth.CtxApp)\n\t}()\n\n\ts.Geth.SimulationClient = execution.NewSimulationClient(s.Geth.TestNode.EngineClient)\n\t// Reth does not have a simulation API\n\ttimeOut := 10 * time.Second\n\tinterval := 50 * time.Millisecond\n\terr = simulated.WaitTillServicesStarted(s.Geth.LogBuffer, timeOut, interval)\n\ts.Require().NoError(err)\n\terr = simulated.WaitTillServicesStarted(s.Reth.LogBuffer, timeOut, interval)\n\ts.Require().NoError(err)\n}\n\n// TearDownTest cleans up the test environment.\nfunc (s *PectraForkSuite) TearDownTest() {\n\ts.Geth.CleanupTestWithLabel(s.T(), \"GETH\")\n\ts.Reth.CleanupTestWithLabel(s.T(), \"RETH\")\n}\n\n// TestTimestampFork_ELAndCLInSync_IsSuccessful tests that we can fork successfully if EL and CL have synced timestamps\n// The forks timestamp at Unix 0, as the genesis at Unix 0, Cancun is at 10 and Prague is at 20.\n// The Geth Node will be the block producer but the Reth node is treated as a full node, i.e. doesn't produce blocks.\nfunc (s *PectraForkSuite) TestTimestampFork_ELAndCLInSync_IsSuccessful() {\n\t// Initialize the geth chain state.\n\ts.Geth.InitializeChain(s.T(), 1)\n\t// Initialize the reth chain state.\n\ts.Reth.InitializeChain(s.T(), 1)\n\n\tnodeAddress, err := s.Geth.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.Geth.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\texpectedMessages := []string{\n\t\t\"Processing block with fork version service=blockchain\\u001B[0m block=1\\u001B[0m fork=0x04010000\\u001B[0m\",\n\t\t\"Processing block with fork version service=blockchain\\u001B[0m block=2\\u001B[0m fork=0x04010000\\u001B[0m\",\n\t\t\"Processing block with fork version service=blockchain\\u001B[0m block=3\\u001B[0m fork=0x04010000\\u001B[0m\",\n\t\t\"Processing block with fork version service=blockchain\\u001B[0m block=4\\u001B[0m fork=0x04010000\\u001B[0m\",\n\t\t\"Processing block with fork version service=blockchain\\u001B[0m block=5\\u001B[0m fork=0x04010000\\u001B[0m\",\n\t\t\"Processing block with fork version service=blockchain\\u001B[0m block=6\\u001B[0m fork=0x04010000\\u001B[0m\",\n\t\t\"Processing block with fork version service=blockchain\\u001B[0m block=7\\u001B[0m fork=0x04010000\\u001B[0m\",\n\t\t\"Processing block with fork version service=blockchain\\u001B[0m block=8\\u001B[0m fork=0x04010000\\u001B[0m\",\n\t\t\"Processing block with fork version service=blockchain\\u001B[0m block=9\\u001B[0m fork=0x05000000\\u001B[0m\",\n\t\t\"Processing block with fork version service=blockchain\\u001B[0m block=10\\u001B[0m fork=0x05000000\\u001B[0m\",\n\t\t\"Processing block with fork version service=blockchain\\u001B[0m block=11\\u001B[0m fork=0x05000000\\u001B[0m\",\n\t}\n\n\tvar (\n\t\tstartHeight         = int64(1)\n\t\titerations          = int64(len(expectedMessages))\n\t\texpectedMessagesIdx = 0\n\t\tsubmitTxNonce       = uint64(0)\n\t\tconsensusTime       = time.Unix(startHeight*2, 0)\n\t)\n\n\tfor currentHeight := startHeight; currentHeight < startHeight+iterations; currentHeight++ {\n\t\tsubmitTxNonce = s.submitTransactions(submitTxNonce, 100)\n\t\tproposal, err := s.Geth.SimComet.Comet.PrepareProposal(s.Geth.CtxComet, &types.PrepareProposalRequest{\n\t\t\tHeight:          currentHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: nodeAddress,\n\t\t})\n\t\ts.Require().NoError(err)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              currentHeight,\n\t\t\tProposerAddress:     nodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: nodeAddress,\n\t\t}\n\n\t\tfinalizeRequest := &types.FinalizeBlockRequest{\n\t\t\tTxs:             proposal.Txs,\n\t\t\tHeight:          currentHeight,\n\t\t\tProposerAddress: nodeAddress,\n\t\t\tTime:            consensusTime,\n\t\t}\n\t\texpectedMessage := expectedMessages[expectedMessagesIdx]\n\t\tprocessFinalizeCommit(s.T(), s.Geth, processRequest, finalizeRequest, expectedMessage)\n\t\tprocessFinalizeCommit(s.T(), s.Reth, processRequest, finalizeRequest, expectedMessage)\n\n\t\texpectedMessagesIdx++\n\n\t\t// set consensus time for the next block to match\n\t\t// the timestamp of the payload built optimistically.\n\t\tforkVersion := s.Geth.TestNode.ChainSpec.ActiveForkVersionForTimestamp(math.U64(consensusTime.Unix())) //#nosec: G115\n\t\tblk, _, err := encoding.ExtractBlobsAndBlockFromRequest(\n\t\t\tprocessRequest,\n\t\t\tblockchain.BeaconBlockTxIndex,\n\t\t\tblockchain.BlobSidecarsTxIndex,\n\t\t\tforkVersion,\n\t\t)\n\t\ts.Require().NoError(err)\n\t\tconsensusTime = time.Unix(\n\t\t\tint64(payloadtime.Next(blk.GetTimestamp(), blk.GetTimestamp(), true)),\n\t\t\t0,\n\t\t)\n\t}\n}\n\n// A user makes a consolidation request on our chain which isn't supported.\nfunc (s *PectraForkSuite) TestMaliciousUser_MakesConsolidationRequest_IsIgnored() {\n\t// Initialize the chain state.\n\ts.Geth.InitializeChain(s.T(), 1)\n\ts.Reth.InitializeChain(s.T(), 1)\n\n\t// Retrieve the BLS signer and proposer address.\n\tblsSigner := simulated.GetBlsSigner(s.Geth.HomeDir)\n\tpubkey, err := blsSigner.GetPubKey()\n\ts.Require().NoError(err)\n\tnodeAddress := pubkey.Address()\n\ts.Geth.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\tnextBlockHeight := int64(1)\n\t// We must first move the chain to the fork height, then an extra block\n\t// such that the consolidation contract has an updated `EXCESS_INHIBITOR`.\n\t// We set the timestamp such that the fork has occurred (i.e., time.Now)\n\t{\n\t\tfor i := 0; i < 2; i++ {\n\t\t\tconsensusTime := time.Now()\n\t\t\tproposal, err := s.Geth.SimComet.Comet.PrepareProposal(s.Geth.CtxComet, &types.PrepareProposalRequest{\n\t\t\t\tHeight:          nextBlockHeight,\n\t\t\t\tTime:            consensusTime,\n\t\t\t\tProposerAddress: nodeAddress,\n\t\t\t})\n\t\t\ts.Require().NoError(err)\n\t\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\t\tTxs:                 proposal.Txs,\n\t\t\t\tHeight:              nextBlockHeight,\n\t\t\t\tProposerAddress:     nodeAddress,\n\t\t\t\tTime:                consensusTime,\n\t\t\t\tNextProposerAddress: nodeAddress,\n\t\t\t}\n\n\t\t\tfinalizeRequest := &types.FinalizeBlockRequest{\n\t\t\t\tTxs:             proposal.Txs,\n\t\t\t\tHeight:          nextBlockHeight,\n\t\t\t\tProposerAddress: nodeAddress,\n\t\t\t\tTime:            consensusTime,\n\t\t\t}\n\t\t\texpectedMsg := \"fork=0x05000000\"\n\t\t\tprocessFinalizeCommit(s.T(), s.Geth, processRequest, finalizeRequest, expectedMsg)\n\t\t\tprocessFinalizeCommit(s.T(), s.Reth, processRequest, finalizeRequest, expectedMsg)\n\t\t\tnextBlockHeight++\n\t\t}\n\t}\n\t// Next we submit the Consolidation request transaction\n\t{\n\t\t// corresponds with the funded address in genesis\n\t\tsenderKey, err := crypto.HexToECDSA(\"fffdbb37105441e14b0ee6330d855d8504ff39e705c3afa8f859ac9865f99306\")\n\t\ts.Require().NoError(err)\n\n\t\telChainID := big.NewInt(int64(s.Geth.TestNode.ChainSpec.DepositEth1ChainID()))\n\t\tsigner := gethtypes.NewPragueSigner(elChainID)\n\n\t\tfee, feeErr := eip7251.GetConsolidationFee(s.Geth.CtxApp, s.Geth.TestNode.EngineClient)\n\t\ts.Require().NoError(feeErr)\n\n\t\t// The inputs to the request do not necessarily matter, as long as they pass EL validation\n\t\tconsolidationTxData, requestErr := eip7251.CreateConsolidationRequestData(blsSigner.PublicKey(), blsSigner.PublicKey())\n\t\ts.Require().NoError(requestErr)\n\n\t\tconsolidationTx := gethtypes.MustSignNewTx(senderKey, signer, &gethtypes.DynamicFeeTx{\n\t\t\tChainID:   elChainID,\n\t\t\tNonce:     0,\n\t\t\tTo:        &params.ConsolidationQueueAddress,\n\t\t\tGas:       500_000,\n\t\t\tGasFeeCap: big.NewInt(1000000000),\n\t\t\tGasTipCap: big.NewInt(1000000000),\n\t\t\tValue:     fee,\n\t\t\tData:      consolidationTxData,\n\t\t})\n\t\ttxBytes, marshalErr := consolidationTx.MarshalBinary()\n\t\ts.Require().NoError(marshalErr)\n\t\tvar result interface{}\n\t\terr = s.Geth.TestNode.EngineClient.Call(s.Geth.CtxApp, &result, \"eth_sendRawTransaction\", hexutil.Encode(txBytes))\n\t\ts.Require().NoError(err)\n\t\ttime.Sleep(time.Second) // give it time to allow the tx to be included in the next block\n\t}\n\t// Move the chain so that tx is included and progresses correctly afterward.\n\t{\n\t\tfor i := 0; i < 5; i++ {\n\t\t\tconsensusTime := time.Now()\n\t\t\tproposal, err := s.Geth.SimComet.Comet.PrepareProposal(s.Geth.CtxComet, &types.PrepareProposalRequest{\n\t\t\t\tHeight:          nextBlockHeight,\n\t\t\t\tTime:            consensusTime,\n\t\t\t\tProposerAddress: nodeAddress,\n\t\t\t})\n\t\t\ts.Require().NoError(err)\n\t\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\t\tTxs:                 proposal.Txs,\n\t\t\t\tHeight:              nextBlockHeight,\n\t\t\t\tProposerAddress:     nodeAddress,\n\t\t\t\tTime:                consensusTime,\n\t\t\t\tNextProposerAddress: nodeAddress,\n\t\t\t}\n\n\t\t\tfinalizeRequest := &types.FinalizeBlockRequest{\n\t\t\t\tTxs:             proposal.Txs,\n\t\t\t\tHeight:          nextBlockHeight,\n\t\t\t\tProposerAddress: nodeAddress,\n\t\t\t\tTime:            consensusTime,\n\t\t\t}\n\t\t\tvar expectedMsg string\n\t\t\tif i == 0 {\n\t\t\t\t// The first block since tx submission will have the consolidation propagated to the CL.\n\t\t\t\texpectedMsg = \"consolidations=1\"\n\t\t\t}\n\t\t\tprocessFinalizeCommit(s.T(), s.Geth, processRequest, finalizeRequest, expectedMsg)\n\t\t\tprocessFinalizeCommit(s.T(), s.Reth, processRequest, finalizeRequest, expectedMsg)\n\t\t\tnextBlockHeight++\n\t\t}\n\t}\n}\n\n// This test will have a proposer propose a valid post-fork block, but one that is not finalized.\n// The next round will propose a valid pre-fork block that gets finalized due to deviance in the consensus timestamp.\n// The proposer will then propose a valid post-fork block that is correctly finalized.\nfunc (s *PectraForkSuite) TestValidProposer_ProposesPostForkBlockIsNotFinalized_IsSuccessful() {\n\tclient := s.Geth\n\thelper := s.Reth\n\n\t// Initialize the chain state.\n\tclient.InitializeChain(s.T(), 1)\n\thelper.InitializeChain(s.T(), 1) // helper to build \"invalid\" blocks\n\n\tnodeAddress, err := client.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\tclient.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\tnextBlockHeight := int64(1)\n\tvar proposal *types.PrepareProposalResponse\n\n\t// 1 - Build a block whose consensus and payloadTimestamp are both post-fork.\n\t//     Check that it verifies, but do not finalize it\n\t{\n\t\tconsensusTime := time.Unix(int64(client.TestNode.ChainSpec.ElectraForkTime()), 0)\n\t\tprepareReq := &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: nodeAddress,\n\t\t}\n\t\tproposal, err = helper.SimComet.Comet.PrepareProposal(helper.CtxComet, prepareReq)\n\t\ts.Require().NoError(err)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     nodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: nodeAddress,\n\t\t}\n\n\t\t// Process the proposal\n\t\tclient.LogBuffer.Reset()\n\t\tprocessResp, respErr := client.SimComet.Comet.ProcessProposal(client.CtxComet, processRequest)\n\t\ts.Require().NoError(respErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT.String(), processResp.Status.String())\n\t}\n\n\t// 2 - Build a block whose consensus timestamp is pre-fork, while the payload is post fork.\n\t//     Check that it does not verifies.\n\t// Note: to build the invalid block we reuse the beaconBlock from point 1 and just change CometBFT timestamp\n\t{\n\t\tmaliciouConsensusTime := time.Unix(int64(client.TestNode.ChainSpec.ElectraForkTime())-2, 0)\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     nodeAddress,\n\t\t\tTime:                maliciouConsensusTime,\n\t\t\tNextProposerAddress: nodeAddress,\n\t\t}\n\n\t\t// Process the proposal\n\t\tclient.LogBuffer.Reset()\n\t\tprocessResp, processErr := client.SimComet.Comet.ProcessProposal(client.CtxComet, processRequest)\n\t\ts.Require().NoError(processErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_REJECT.String(), processResp.Status.String())\n\t\ts.Require().Contains(\n\t\t\tclient.LogBuffer.String(),\n\t\t\t\"failed decoding *types.SignedBeaconBlock: ssz: offset smaller than previous\",\n\t\t)\n\t}\n\n\t// 3 - Build a block whose consensus and payload timestamp are pre-fork.\n\t//     Check that it does verify (even if we already validated a post fork block).\n\t// Note: to build the block we reuse the beaconBlock from point 1 and just change CometBFT timestamp\n\t{\n\t\tconsensusTime := time.Unix(int64(client.TestNode.ChainSpec.ElectraForkTime())-2, 0)\n\t\tprepareReq := &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: nodeAddress,\n\t\t}\n\t\tproposal, prepareErr := helper.SimComet.Comet.PrepareProposal(helper.CtxComet, prepareReq)\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     nodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: nodeAddress,\n\t\t}\n\n\t\t// Process the proposal\n\t\tclient.LogBuffer.Reset()\n\t\tprocessResp, processErr := client.SimComet.Comet.ProcessProposal(client.CtxComet, processRequest)\n\t\ts.Require().NoError(processErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT.String(), processResp.Status.String())\n\t}\n\n\t// The next block the proposer proposes with a pre-fork timestamp will actually have a pre-fork time\n\t// Since the previous payload in cache has been evicted and a new payload is retrieved.\n\t{\n\t\tconsensusTime := time.Unix(int64(client.TestNode.ChainSpec.ElectraForkTime())-2, 0)\n\t\tprepareReq := &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: nodeAddress,\n\t\t}\n\t\tproposal, prepareErr := helper.SimComet.Comet.PrepareProposal(helper.CtxComet, prepareReq)\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     nodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: nodeAddress,\n\t\t}\n\n\t\t// Process the proposal\n\t\tclient.LogBuffer.Reset()\n\t\tprocessResp, processErr := client.SimComet.Comet.ProcessProposal(client.CtxComet, processRequest)\n\t\ts.Require().NoError(processErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT.String(), processResp.Status.String())\n\n\t\t// Finalize the block\n\t\tfinalizeRequest := &types.FinalizeBlockRequest{\n\t\t\tTxs:             proposal.Txs,\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tProposerAddress: nodeAddress,\n\t\t\tTime:            consensusTime,\n\t\t}\n\t\t_, finalizeErr := client.SimComet.Comet.FinalizeBlock(client.CtxComet, finalizeRequest)\n\t\ts.Require().NoError(finalizeErr)\n\n\t\t// Commit the block.\n\t\t_, err = client.SimComet.Comet.Commit(client.CtxComet, &types.CommitRequest{})\n\t\ts.Require().NoError(err)\n\n\t\tnextBlockHeight++\n\t}\n\t// Finally, we cross the fork and show no issues\n\t{\n\t\tconsensusTime := time.Unix(int64(client.TestNode.ChainSpec.ElectraForkTime())+2, 0)\n\t\tprepareReq := &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: nodeAddress,\n\t\t}\n\t\tproposal, prepareErr := client.SimComet.Comet.PrepareProposal(client.CtxComet, prepareReq)\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     nodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: nodeAddress,\n\t\t}\n\t\t// Process the proposal\n\t\tclient.LogBuffer.Reset()\n\t\tprocessResp, processErr := client.SimComet.Comet.ProcessProposal(client.CtxComet, processRequest)\n\t\ts.Require().NoError(processErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT.String(), processResp.Status.String())\n\t\ts.Require().Contains(client.LogBuffer.String(), \"Processing execution requests\")\n\t}\n}\n\n// The proposer prepares a proposal with a pre-fork timestamp, but a post-fork process proposal consensus time.\n// This will be rejected and is expected to occur around the fork for 1 or 2 rounds.\nfunc (s *PectraForkSuite) TestValidProposer_ProposesPreForkBlockWithPostForkConsensusTimestamp_IsRejected() {\n\t// Initialize the chain state.\n\ts.Geth.InitializeChain(s.T(), 1)\n\tnodeAddress, err := s.Geth.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.Geth.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\tnextBlockHeight := int64(1)\n\t// The proposer prepares a proposal with a pre-fork timestamp, but a post-fork process proposal consensus time.\n\t{\n\t\t// a pre-fork time.\n\t\tconsensusTime := time.Unix(2, 0)\n\t\tproposal, prepareErr := s.Geth.SimComet.Comet.PrepareProposal(s.Geth.CtxComet, &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: nodeAddress,\n\t\t})\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              nextBlockHeight,\n\t\t\tProposerAddress:     nodeAddress,\n\t\t\tTime:                time.Now(),\n\t\t\tNextProposerAddress: nodeAddress,\n\t\t}\n\n\t\t// Process the proposal, expect a reject\n\t\t{\n\t\t\ts.Geth.LogBuffer.Reset()\n\t\t\tprocessResp, err := s.Geth.SimComet.Comet.ProcessProposal(s.Geth.CtxComet, processRequest)\n\t\t\ts.Require().NoError(err)\n\t\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_REJECT, processResp.Status)\n\t\t\ts.Require().Contains(\n\t\t\t\ts.Geth.LogBuffer.String(),\n\t\t\t\t\"failed decoding *types.SignedBeaconBlock: ssz: offset smaller than previous: decoded 392, previous was 396\",\n\t\t\t)\n\t\t}\n\t}\n}\n\n// This test will show that an optimistically building a payload across the fork boundary\n// correctly invokes `ProcessFork` on the state processor.\nfunc (s *PectraForkSuite) Test_OptimisticBuildAtFork_IsSuccessful() {\n\t// Initialize the chain state.\n\tclient := s.Geth\n\tclient.InitializeChain(s.T(), 1) // init the validator\n\n\t// Retrieve the BLS signer and proposer address.\n\tblsSigner := simulated.GetBlsSigner(client.HomeDir)\n\tpubkey, err := blsSigner.GetPubKey()\n\ts.Require().NoError(err)\n\n\t// setup first payload and consensus timestamps so that\n\t// - it would be pre Electra fork\n\t// - the second block, built optimistically would be at the electra fork.\n\tspecs := client.TestNode.ChainSpec\n\tfirstBlkConsensusTime := specs.ElectraForkTime() - 1 // before fork\n\tfirstBlkPayloadTime := firstBlkConsensusTime\n\tsecondBlkConsensusTime := specs.ElectraForkTime()\n\tsecondBlkPayloadTime := payloadtime.Next(\n\t\tmath.U64(secondBlkConsensusTime),\n\t\tmath.U64(firstBlkPayloadTime),\n\t\ttrue, // this is the formula used while setting second block timestamp optimistically\n\t)\n\ts.Require().GreaterOrEqual(secondBlkPayloadTime, math.U64(specs.ElectraForkTime())) // post fork\n\n\tnextBlockHeight := int64(1)\n\t{\n\t\t// 1- Build pre-fork block\n\t\tprepareRequest := &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            time.Unix(int64(firstBlkConsensusTime), 0),\n\t\t\tProposerAddress: pubkey.Address(),\n\t\t}\n\t\tproposal, prepareErr := client.SimComet.Comet.PrepareProposal(client.CtxComet, prepareRequest)\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\t// 2- Process the proposal. This will trigger am optimistic payload build for block height 2.\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:             proposal.Txs,\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tProposerAddress: pubkey.Address(),\n\t\t\tTime:            time.Unix(int64(firstBlkConsensusTime), 0),\n\t\t}\n\t\tprocessResp, respErr := client.SimComet.Comet.ProcessProposal(client.CtxComet, processRequest)\n\t\ts.Require().NoError(respErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT.String(), processResp.Status.String())\n\n\t\t// 3- finalize and commit the first block\n\t\tfinalizeRequest := &types.FinalizeBlockRequest{\n\t\t\tTxs:             proposal.Txs,\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tProposerAddress: pubkey.Address(),\n\t\t\tTime:            time.Unix(int64(firstBlkConsensusTime), 0),\n\t\t}\n\t\t_, finalizeErr := client.SimComet.Comet.FinalizeBlock(client.CtxComet, finalizeRequest)\n\t\ts.Require().NoError(finalizeErr)\n\t\t_, commitErr := client.SimComet.Comet.Commit(client.CtxComet, &types.CommitRequest{})\n\t\ts.Require().NoError(commitErr)\n\t}\n\n\t// Now build the next block\n\tnextBlockHeight++\n\t{\n\t\t// 4- Build post-fork block. Make sure that the fork transition happens\n\t\tprepareRequest := &types.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            time.Unix(int64(secondBlkConsensusTime), 0),\n\t\t\tProposerAddress: pubkey.Address(),\n\t\t}\n\t\tproposal, prepareErr := client.SimComet.Comet.PrepareProposal(client.CtxComet, prepareRequest)\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\t\ts.Require().Contains(client.LogBuffer.String(), \"✅  welcome to the\")\n\n\t\t// 5- Process the proposal.\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:             proposal.Txs,\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tProposerAddress: pubkey.Address(),\n\t\t\tTime:            time.Unix(int64(secondBlkConsensusTime), 0),\n\t\t}\n\t\tprocessResp, respErr := client.SimComet.Comet.ProcessProposal(client.CtxComet, processRequest)\n\t\ts.Require().NoError(respErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT.String(), processResp.Status.String())\n\n\t\t// 6- finalize and commit the second block\n\t\tfinalizeRequest := &types.FinalizeBlockRequest{\n\t\t\tTxs:             proposal.Txs,\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tProposerAddress: pubkey.Address(),\n\t\t\tTime:            time.Unix(int64(secondBlkConsensusTime), 0),\n\t\t}\n\t\t_, finalizeErr := client.SimComet.Comet.FinalizeBlock(client.CtxComet, finalizeRequest)\n\t\ts.Require().NoError(finalizeErr)\n\t\t_, commitErr := client.SimComet.Comet.Commit(client.CtxComet, &types.CommitRequest{})\n\t\ts.Require().NoError(commitErr)\n\t}\n}\n\n// Test a scenario where reth must rebuild a payload for a failed state transition.\nfunc (s *PectraForkSuite) TestReth_MustRebuildForFailedStateTransition_IsSuccessful() {\n\t// Initialize the chain state.\n\ttestEL := s.Reth\n\thelpBuilder := s.Geth\n\ttestEL.InitializeChain(s.T(), 1)\n\thelpBuilder.InitializeChain(s.T(), 1)\n\n\t// Retrieve the BLS signer and proposer address.\n\tblsSigner := simulated.GetBlsSigner(testEL.HomeDir)\n\tpubkey, err := blsSigner.GetPubKey()\n\ts.Require().NoError(err)\n\tnodeAddress := pubkey.Address()\n\ttestEL.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\tconst blkHeight = int64(1)\n\tvar (\n\t\tspecs         = testEL.TestNode.ChainSpec\n\t\tconsensusTime = time.Unix(int64(specs.ElectraForkTime()), 0)\n\n\t\tvalidTxsHeight1 [][]byte\n\t)\n\n\t{\n\t\t// 1- Build a valid block at height 1, via the helpBuilder\n\t\tprepareRequest := &types.PrepareProposalRequest{\n\t\t\tHeight:          blkHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: nodeAddress,\n\t\t}\n\t\tproposal, prepareErr := helpBuilder.SimComet.Comet.PrepareProposal(helpBuilder.CtxComet, prepareRequest)\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\t\tvalidTxsHeight1 = proposal.Txs\n\n\t\t// 2- Process the block via testEL node. The proposal is expected\n\t\t// to pass and start building payload for height 2, optimistically.\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              blkHeight,\n\t\t\tProposerAddress:     nodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: nodeAddress,\n\t\t}\n\t\tprocessResp, respErr := testEL.SimComet.Comet.ProcessProposal(testEL.CtxComet, processRequest)\n\t\ts.Require().NoError(respErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT.String(), processResp.Status.String())\n\t}\n\n\t// For some reason, the supermajority does not finalize the block.\n\t// Another block comes, still at height 1, this time *invalid*. This would force\n\t// the node to rebuild height 1, which the EL cannot do since it has already received\n\t// an FCU(head == block_at_height_2)\n\t{\n\t\tinvalidTxs := testBuildInvalidBlock(\n\t\t\ts.Require(),\n\t\t\thelpBuilder,\n\t\t\t&types.PrepareProposalRequest{\n\t\t\t\tTxs:             validTxsHeight1,\n\t\t\t\tHeight:          blkHeight,\n\t\t\t\tTime:            consensusTime,\n\t\t\t\tProposerAddress: pubkey.Address(),\n\t\t\t},\n\t\t\tfunc(sbb *ctypes.SignedBeaconBlock) {\n\t\t\t\tsbb.Body.RandaoReveal = [96]byte{'t', 'e', 's', 't'} // this makes the block invalid\n\t\t\t},\n\t\t)\n\n\t\t// 3- Process the invalid proposal proposal. It will be rejected\n\t\t// and attempt to build optimistically a block at height 1.\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 invalidTxs,\n\t\t\tHeight:              blkHeight,\n\t\t\tProposerAddress:     nodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: nodeAddress,\n\t\t}\n\t\tprocessResp, processErr := testEL.SimComet.Comet.ProcessProposal(testEL.CtxComet, processRequest)\n\t\ts.Require().NoError(processErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_REJECT.String(), processResp.Status.String())\n\t}\n\n\t{\n\t\t// 4- Finally let reth node build block at height 1, process and finalize it\n\t\tprepareRequest := &types.PrepareProposalRequest{\n\t\t\tHeight:          blkHeight,\n\t\t\tTime:            consensusTime,\n\t\t\tProposerAddress: pubkey.Address(),\n\t\t}\n\t\tproposal, prepareErr := testEL.SimComet.Comet.PrepareProposal(testEL.CtxComet, prepareRequest)\n\t\ts.Require().NoError(prepareErr)\n\t\ts.Require().Len(proposal.Txs, 2)\n\n\t\t// Process the proposal via testEL node. The proposal is expected\n\t\t// to pass and start building payload for height 2, optimistically.\n\t\tprocessRequest := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              blkHeight,\n\t\t\tProposerAddress:     nodeAddress,\n\t\t\tTime:                consensusTime,\n\t\t\tNextProposerAddress: nodeAddress,\n\t\t}\n\t\tprocessResp, respErr := testEL.SimComet.Comet.ProcessProposal(testEL.CtxComet, processRequest)\n\t\ts.Require().NoError(respErr)\n\t\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT.String(), processResp.Status.String())\n\n\t\tfinalizeRequest := &types.FinalizeBlockRequest{\n\t\t\tTxs:             proposal.Txs,\n\t\t\tHeight:          blkHeight,\n\t\t\tProposerAddress: pubkey.Address(),\n\t\t\tTime:            consensusTime,\n\t\t}\n\t\t_, finalizeErr := testEL.SimComet.Comet.FinalizeBlock(testEL.CtxComet, finalizeRequest)\n\t\ts.Require().NoError(finalizeErr)\n\t\t_, commitErr := testEL.SimComet.Comet.Commit(testEL.CtxComet, &types.CommitRequest{})\n\t\ts.Require().NoError(commitErr)\n\t}\n}\n\nfunc processFinalizeCommit(\n\tt *testing.T,\n\tnode simulated.SharedAccessors,\n\tprocessRequest *types.ProcessProposalRequest,\n\tfinalizeRequest *types.FinalizeBlockRequest,\n\texpectedMessage string,\n) {\n\t// Process the proposal\n\tnode.LogBuffer.Reset()\n\tprocessResp, err := node.SimComet.Comet.ProcessProposal(node.CtxComet, processRequest)\n\trequire.NoError(t, err)\n\trequire.Equal(t, types.PROCESS_PROPOSAL_STATUS_ACCEPT, processResp.Status)\n\trequire.Contains(t, node.LogBuffer.String(), expectedMessage)\n\n\t// Finalize the block\n\tfinalizeResp, err := node.SimComet.Comet.FinalizeBlock(node.CtxComet, finalizeRequest)\n\trequire.NoError(t, err)\n\trequire.NotEmpty(t, finalizeResp)\n\n\t// Commit the block.\n\t_, err = node.SimComet.Comet.Commit(node.CtxComet, &types.CommitRequest{})\n\trequire.NoError(t, err)\n}\n\nfunc (s *PectraForkSuite) submitTransactions(startNonce uint64, numTransactions uint64) uint64 {\n\t// corresponds with funded address in genesis 0x20f33ce90a13a4b5e7697e3544c3083b8f8a51d4\n\tsenderKey, err := crypto.HexToECDSA(\"fffdbb37105441e14b0ee6330d855d8504ff39e705c3afa8f859ac9865f99306\")\n\ts.Require().NoError(err)\n\telChainID := big.NewInt(int64(s.Geth.TestNode.ChainSpec.DepositEth1ChainID()))\n\tsigner := gethtypes.NewPragueSigner(elChainID)\n\n\tfor i := startNonce; i < startNonce+numTransactions; i++ {\n\t\ttransaction := gethtypes.MustSignNewTx(senderKey, signer, &gethtypes.DynamicFeeTx{\n\t\t\tChainID:   elChainID,\n\t\t\tNonce:     i,\n\t\t\tTo:        &params.BeaconRootsAddress, // any address\n\t\t\tGas:       500_000,\n\t\t\tGasFeeCap: big.NewInt(1000000000),\n\t\t\tGasTipCap: big.NewInt(1000000000),\n\t\t\tValue:     big.NewInt(0),\n\t\t\tData:      nil,\n\t\t})\n\n\t\ttxBytes, marshalErr := transaction.MarshalBinary()\n\t\ts.Require().NoError(marshalErr)\n\n\t\tvar result interface{}\n\t\terr = s.Geth.TestNode.EngineClient.Call(s.Geth.CtxApp, &result, \"eth_sendRawTransaction\", hexutil.Encode(txBytes))\n\t\ts.Require().NoError(err)\n\t}\n\treturn startNonce + numTransactions\n}\n"
  },
  {
    "path": "testing/simulated/pectra_genesis_test.go",
    "content": "//go:build simulated\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage simulated_test\n\nimport (\n\t\"context\"\n\t\"math/big\"\n\t\"path\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/beacon/blockchain\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/encoding\"\n\t\"github.com/berachain/beacon-kit/engine-primitives/errors\"\n\t\"github.com/berachain/beacon-kit/execution/requests/eip7002\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/primitives/encoding/hex\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/testing/simulated\"\n\t\"github.com/berachain/beacon-kit/testing/simulated/execution\"\n\tv1 \"github.com/cometbft/cometbft/api/cometbft/abci/v1\"\n\t\"github.com/ethereum/go-ethereum/common/hexutil\"\n\t\"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/ethereum/go-ethereum/crypto\"\n\t\"github.com/ethereum/go-ethereum/params\"\n\t\"github.com/spf13/viper\"\n\t\"github.com/stretchr/testify/suite\"\n)\n\n// PectraGenesisSuite defines our test suite for Pectra related work using simulated Comet component.\ntype PectraGenesisSuite struct {\n\tsuite.Suite\n\t// Embedded shared accessors for convenience.\n\tsimulated.SharedAccessors\n}\n\n// TestPectraSuite runs the test suite.\nfunc TestPectraSuite(t *testing.T) {\n\tsuite.Run(t, new(PectraGenesisSuite))\n}\n\n// SetupTest initializes the test environment.\nfunc (s *PectraGenesisSuite) SetupTest() {\n\t// Create a cancellable context for the duration of the test.\n\ts.CtxApp, s.CtxAppCancelFn = context.WithCancel(context.Background())\n\n\t// CometBFT uses context.TODO() for all ABCI calls, so we replicate that.\n\ts.CtxComet = context.TODO()\n\n\ts.HomeDir = s.T().TempDir()\n\n\t// Initialize the home directory, Comet configuration, and genesis info.\n\tconst elGenesisPath = \"./el-genesis-files/pectra-eth-genesis.json\"\n\tchainSpecFunc := simulated.ProvideElectraGenesisChainSpec\n\t// Create the chainSpec.\n\tchainSpec, err := chainSpecFunc()\n\ts.Require().NoError(err)\n\tconfigs, genesisValidatorsRoot := simulated.InitializeHomeDirs(s.T(), chainSpec, elGenesisPath, s.HomeDir)\n\tcometConfig := configs[0]\n\ts.GenesisValidatorsRoot = genesisValidatorsRoot\n\n\t// Start the EL (execution layer) Geth node.\n\telNode := execution.NewGethNode(s.HomeDir, execution.ValidGethImage())\n\telHandle, authRPC, elRPC := elNode.Start(s.T(), path.Base(elGenesisPath))\n\ts.ElHandle = elHandle\n\n\t// Prepare a logger backed by a buffer to capture logs for assertions.\n\ts.LogBuffer = &simulated.SyncBuffer{}\n\tlogger := phuslu.NewLogger(s.LogBuffer, nil)\n\n\t// Build the Beacon node with the simulated Comet component and electra genesis chain spec\n\tcomponents := simulated.FixedComponents(s.T())\n\tcomponents = append(components, simulated.ProvideSimComet)\n\tcomponents = append(components, chainSpecFunc)\n\n\ts.TestNode = simulated.NewTestNode(s.T(), simulated.TestNodeInput{\n\t\tTempHomeDir: s.HomeDir,\n\t\tCometConfig: cometConfig,\n\t\tAuthRPC:     authRPC,\n\t\tClientRPC:   elRPC,\n\t\tLogger:      logger,\n\t\tAppOpts:     viper.New(),\n\t\tComponents:  components,\n\t})\n\n\ts.SimComet = s.TestNode.SimComet\n\n\t// Start the Beacon node in a separate goroutine.\n\tgo func() {\n\t\t_ = s.TestNode.Start(s.CtxApp)\n\t}()\n\n\ts.SimulationClient = execution.NewSimulationClient(s.TestNode.EngineClient)\n\ttimeOut := 10 * time.Second\n\tinterval := 50 * time.Millisecond\n\terr = simulated.WaitTillServicesStarted(s.LogBuffer, timeOut, interval)\n\ts.Require().NoError(err)\n}\n\n// TearDownTest cleans up the test environment.\nfunc (s *PectraGenesisSuite) TearDownTest() {\n\ts.CleanupTest(s.T())\n}\n\nfunc (s *PectraGenesisSuite) TestFullLifecycle_WithoutRequests_IsSuccessful() {\n\tconst blockHeight = 1\n\tconst coreLoopIterations = 10\n\n\t// Initialize the chain state.\n\ts.InitializeChain(s.T(), 1)\n\tnodeAddress, err := s.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\t// Test happens post Electra fork.\n\tstartTime := time.Now()\n\n\t// Go through iterations of the core loop.\n\tproposals, _, _ := s.MoveChainToHeight(s.T(), blockHeight, coreLoopIterations, nodeAddress, startTime)\n\ts.Require().Len(proposals, coreLoopIterations)\n}\n\nfunc (s *PectraGenesisSuite) TestFullLifecycle_WithPartialWithdrawalRequests_IsSuccessful() {\n\t// Initialize the chain state.\n\ts.InitializeChain(s.T(), 1)\n\n\t// Retrieve the BLS signer and proposer address.\n\tblsSigner := simulated.GetBlsSigner(s.HomeDir)\n\tpubkey, err := blsSigner.GetPubKey()\n\ts.Require().NoError(err)\n\tnodeAddress := pubkey.Address()\n\ts.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\tnextBlockHeight := int64(1)\n\t// We must first move the chain by 1 height such that the withdrawal contract has an updated `EXCESS_INHIBITOR`.\n\t{\n\t\tproposals, _, _ := s.MoveChainToHeight(s.T(), nextBlockHeight, 1, nodeAddress, time.Now())\n\t\ts.Require().Len(proposals, 1)\n\t\tnextBlockHeight++\n\t}\n\n\t// create and submit the withdrawal request\n\ttotalWithdrawalAmount := 3456\n\t{\n\t\t// corresponds with the funded address in genesis `simulated.WithdrawalExecutionAddress`\n\t\tsenderKey, err := crypto.HexToECDSA(\"fffdbb37105441e14b0ee6330d855d8504ff39e705c3afa8f859ac9865f99306\")\n\t\ts.Require().NoError(err)\n\n\t\telChainID := big.NewInt(int64(s.TestNode.ChainSpec.DepositEth1ChainID()))\n\t\tsigner := types.NewPragueSigner(elChainID)\n\n\t\tfee, err := eip7002.GetWithdrawalFee(s.CtxApp, s.TestNode.EngineClient)\n\t\ts.Require().NoError(err)\n\n\t\ttotalTxs := 2\n\t\tamountPerTx := totalWithdrawalAmount / totalTxs\n\t\twithdrawalTxData, err := eip7002.CreateWithdrawalRequestData(blsSigner.PublicKey(), math.Gwei(amountPerTx))\n\t\ts.Require().NoError(err)\n\n\t\t// submit 2 txs\n\t\tfor i := 0; i < totalTxs; i++ {\n\t\t\twithdrawalTx := types.MustSignNewTx(senderKey, signer, &types.DynamicFeeTx{\n\t\t\t\tChainID:   elChainID,\n\t\t\t\tNonce:     uint64(i),\n\t\t\t\tTo:        &params.WithdrawalQueueAddress,\n\t\t\t\tGas:       500_000,\n\t\t\t\tGasFeeCap: big.NewInt(1000000000),\n\t\t\t\tGasTipCap: big.NewInt(1000000000),\n\t\t\t\tValue:     fee,\n\t\t\t\tData:      withdrawalTxData,\n\t\t\t})\n\n\t\t\tvar balance hexutil.Big\n\t\t\terr = s.TestNode.EngineClient.Call(s.CtxApp, &balance, \"eth_getBalance\", simulated.WithdrawalExecutionAddress, \"latest\")\n\t\t\ts.T().Logf(\"Balance before withdrawal request sent: %s\", balance.ToInt().String())\n\n\t\t\tvar txBytes []byte\n\t\t\ttxBytes, err = withdrawalTx.MarshalBinary()\n\t\t\ts.Require().NoError(err)\n\n\t\t\tvar result interface{}\n\t\t\terr = s.TestNode.EngineClient.Call(s.CtxApp, &result, \"eth_sendRawTransaction\", hexutil.Encode(txBytes))\n\t\t\ts.Require().NoError(err)\n\t\t\ttime.Sleep(time.Second) // give it time to allow the tx to be included in the next block\n\t\t}\n\t}\n\n\t// Go through 1 iteration of the core loop so that both withdrawal txs is included\n\tvar afterRequestBalance hexutil.Big\n\t{\n\t\ts.LogBuffer.Reset()\n\t\tproposals, _, _ := s.MoveChainToHeight(s.T(), nextBlockHeight, 1, nodeAddress, time.Now())\n\t\ts.Require().Len(proposals, 1)\n\t\t// Log contains 2 withdrawals\n\t\ts.Require().Contains(s.LogBuffer.String(), \"Processing execution requests service=state-processor\\u001B[0m deposits=0\\u001B[0m withdrawals=2\\u001B[0m consolidations=0\\u001B[0m\")\n\n\t\ts.LogBuffer.Reset()\n\t\terr := s.TestNode.EngineClient.Call(s.CtxApp, &afterRequestBalance, \"eth_getBalance\", simulated.WithdrawalExecutionAddress, \"latest\")\n\t\ts.Require().NoError(err)\n\t\ts.T().Logf(\"Balance after withdrawal request included in block: %s\", afterRequestBalance.ToInt().String())\n\t\tnextBlockHeight++\n\t}\n\n\t// We must progress to Epoch `nextEpoch + MinValidatorWithdrawabilityDelay` before the balance will be removed.\n\t// IterationsToTurn will get us to the slot before the turn of the target\n\tvar beforeWithdrawalBalance hexutil.Big\n\t{\n\t\tprevBlockHeight := nextBlockHeight - 1\n\t\tepochOfWithdrawalRequest := s.TestNode.ChainSpec.SlotToEpoch(math.Slot(prevBlockHeight))\n\t\tnextEpoch := epochOfWithdrawalRequest + 1\n\t\ttargetEpoch := nextEpoch + s.TestNode.ChainSpec.MinValidatorWithdrawabilityDelay()\n\t\titerationsToTurn := (s.TestNode.ChainSpec.SlotsPerEpoch() * uint64(targetEpoch)) - uint64(prevBlockHeight) - 1\n\n\t\ts.MoveChainToHeight(s.T(), nextBlockHeight, int64(iterationsToTurn), nodeAddress, time.Now())\n\n\t\ts.LogBuffer.Reset()\n\t\terr := s.TestNode.EngineClient.Call(s.CtxApp, &beforeWithdrawalBalance, \"eth_getBalance\", simulated.WithdrawalExecutionAddress, \"latest\")\n\t\ts.Require().NoError(err)\n\t\ts.T().Logf(\"Balance before withdrawal processed: %s\", beforeWithdrawalBalance.ToInt().String())\n\n\t\t// Balance should not have changed yet\n\t\ts.Require().Equal(afterRequestBalance.ToInt().String(), beforeWithdrawalBalance.ToInt().String())\n\t\tnextBlockHeight = nextBlockHeight + int64(iterationsToTurn)\n\t}\n\n\t// The next block will be the turn of the Epoch, and the balance will change\n\t{\n\t\ts.MoveChainToHeight(s.T(), nextBlockHeight, 1, nodeAddress, time.Now())\n\n\t\tvar afterWithdrawalBalance hexutil.Big\n\t\terr := s.TestNode.EngineClient.Call(s.CtxApp, &afterWithdrawalBalance, \"eth_getBalance\", simulated.WithdrawalExecutionAddress, \"latest\")\n\t\ts.Require().NoError(err)\n\t\ts.T().Logf(\"Balance after withdrawal processed: %s\", afterWithdrawalBalance.ToInt().String())\n\n\t\twithdrawalAmountWei := new(big.Int).Mul(big.NewInt(int64(totalWithdrawalAmount)), big.NewInt(params.GWei))\n\n\t\t// Expected balance is balance before withdrawal + totalWithdrawalAmount\n\t\texpectedBalance := new(big.Int).Add(beforeWithdrawalBalance.ToInt(), withdrawalAmountWei)\n\n\t\t// The new balance of the validator is updated\n\t\ts.Require().Equal(expectedBalance.String(), afterWithdrawalBalance.ToInt().String())\n\t}\n}\n\nfunc (s *PectraGenesisSuite) TestFullLifecycle_WithFullWithdrawalRequest_IsSuccessful() {\n\t// Initialize the chain state.\n\ts.InitializeChain(s.T(), 1)\n\n\t// Retrieve the BLS signer and proposer address.\n\tblsSigner := simulated.GetBlsSigner(s.HomeDir)\n\tpubkey, err := blsSigner.GetPubKey()\n\ts.Require().NoError(err)\n\tnodeAddress := pubkey.Address()\n\n\tnextBlockHeight := int64(1)\n\t// We must first move the chain by 1 height such that the withdrawal contract has an updated `EXCESS_INHIBITOR`.\n\t{\n\t\tproposals, _, _ := s.MoveChainToHeight(s.T(), nextBlockHeight, 1, nodeAddress, time.Now())\n\t\ts.Require().Len(proposals, 1)\n\t\tnextBlockHeight = nextBlockHeight + 1\n\t}\n\n\t// create a withdrawal request and submit\n\t{\n\t\t// corresponds with the funded address in genesis `simulated.WithdrawalExecutionAddress`\n\t\tsenderKey, err := crypto.HexToECDSA(\"fffdbb37105441e14b0ee6330d855d8504ff39e705c3afa8f859ac9865f99306\")\n\t\ts.Require().NoError(err)\n\n\t\telChainID := big.NewInt(int64(s.TestNode.ChainSpec.DepositEth1ChainID()))\n\t\tsigner := types.NewPragueSigner(elChainID)\n\n\t\tfee, err := eip7002.GetWithdrawalFee(s.CtxApp, s.TestNode.EngineClient)\n\t\ts.Require().NoError(err)\n\n\t\t// 0 amount will correspond with a full withdrawal request.\n\t\twithdrawalAmount := 0\n\t\twithdrawalTxData, err := eip7002.CreateWithdrawalRequestData(blsSigner.PublicKey(), math.Gwei(withdrawalAmount))\n\t\ts.Require().NoError(err)\n\n\t\twithdrawalTx := types.MustSignNewTx(senderKey, signer, &types.DynamicFeeTx{\n\t\t\tChainID:   elChainID,\n\t\t\tNonce:     0,\n\t\t\tTo:        &params.WithdrawalQueueAddress,\n\t\t\tGas:       500_000,\n\t\t\tGasFeeCap: big.NewInt(1000000000),\n\t\t\tGasTipCap: big.NewInt(1000000000),\n\t\t\tValue:     fee,\n\t\t\tData:      withdrawalTxData,\n\t\t})\n\n\t\tvar balance hexutil.Big\n\t\terr = s.TestNode.EngineClient.Call(s.CtxApp, &balance, \"eth_getBalance\", simulated.WithdrawalExecutionAddress, \"latest\")\n\t\ts.T().Logf(\"Balance before withdrawal request sent: %s\", balance.ToInt().String())\n\n\t\ttxBytes, err := withdrawalTx.MarshalBinary()\n\t\ts.Require().NoError(err)\n\n\t\tvar result interface{}\n\t\terr = s.TestNode.EngineClient.Call(s.CtxApp, &result, \"eth_sendRawTransaction\", hexutil.Encode(txBytes))\n\t\ts.Require().NoError(err)\n\t\ttime.Sleep(time.Second) // give it time to allow the tx to be included in the next block\n\t}\n\n\t// Go through 1 iteration of the core loop so that the withdrawal tx is included\n\tvar afterRequestBalance hexutil.Big\n\t{\n\t\tproposals, finalizeBlockResponses, _ := s.MoveChainToHeight(s.T(), nextBlockHeight, 1, nodeAddress, time.Now())\n\t\ts.Require().Len(proposals, 1)\n\t\t// Log contains 1 withdrawal\n\t\ts.Require().Contains(s.LogBuffer.String(), \"Processing execution requests service=state-processor\\u001B[0m deposits=0\\u001B[0m withdrawals=1\\u001B[0m consolidations=0\\u001B[0m\")\n\t\ts.Require().Len(finalizeBlockResponses, 1)\n\t\t// No validator updates yet\n\t\ts.Require().Len(finalizeBlockResponses[0].GetValidatorUpdates(), 0)\n\n\t\terr := s.TestNode.EngineClient.Call(s.CtxApp, &afterRequestBalance, \"eth_getBalance\", simulated.WithdrawalExecutionAddress, \"latest\")\n\t\ts.Require().NoError(err)\n\t\ts.T().Logf(\"Balance after withdrawal request included in block: %s\", afterRequestBalance.ToInt().String())\n\t\tnextBlockHeight++\n\t}\n\n\t// Once a validator's full withdrawal request has been included in a block, it's exit epoch will be set to the next epoch.\n\t// We enforce that it is exited by checking that FinalizeBlock returns the updated validator set without the validator.\n\tvar exitEpoch math.Epoch\n\t{\n\t\ts.LogBuffer.Reset()\n\t\tprevBlockHeight := nextBlockHeight - 1\n\t\tepochOfWithdrawalRequest := s.TestNode.ChainSpec.SlotToEpoch(math.Slot(prevBlockHeight))\n\t\tnextEpoch := epochOfWithdrawalRequest + 1\n\t\texitEpoch = nextEpoch\n\t\titerationsToExitEpoch := (s.TestNode.ChainSpec.SlotsPerEpoch() * uint64(exitEpoch)) - uint64(prevBlockHeight)\n\n\t\t_, finalizeBlockResponses, _ := s.MoveChainToHeight(s.T(), nextBlockHeight, int64(iterationsToExitEpoch), nodeAddress, time.Now())\n\t\ts.Require().Len(finalizeBlockResponses, int(iterationsToExitEpoch))\n\t\tlastBlockIdx := len(finalizeBlockResponses) - 1\n\t\t// We expect the validator to be kicked out now, with power 0\n\t\ts.Require().Len(finalizeBlockResponses[lastBlockIdx].GetValidatorUpdates(), 1)\n\t\tejectedValidator := finalizeBlockResponses[lastBlockIdx].GetValidatorUpdates()[0]\n\t\ts.Require().Equal(int64(0), ejectedValidator.GetPower())\n\t\ts.Require().Equal(blsSigner.PublicKey().String(), hex.EncodeBytes(ejectedValidator.GetPubKeyBytes()))\n\n\t\tnextBlockHeight = nextBlockHeight + int64(iterationsToExitEpoch)\n\t}\n\n\t// We must progress to Epoch `exitEpoch + MinValidatorWithdrawabilityDelay` before the balance will be removed.\n\t// We progress to the slot before the turn of the target epoch to enforce the balance has not changed.\n\tvar beforeWithdrawalBalance hexutil.Big\n\t{\n\t\t// IterationsToTurn will get us to the slot before the turn of the target\n\t\ttargetEpoch := exitEpoch + s.TestNode.ChainSpec.MinValidatorWithdrawabilityDelay()\n\t\titerationsToTurn := (s.TestNode.ChainSpec.SlotsPerEpoch() * uint64(targetEpoch)) - uint64(nextBlockHeight)\n\t\ts.MoveChainToHeight(s.T(), nextBlockHeight, int64(iterationsToTurn), nodeAddress, time.Now())\n\n\t\ts.LogBuffer.Reset()\n\t\terr := s.TestNode.EngineClient.Call(s.CtxApp, &beforeWithdrawalBalance, \"eth_getBalance\", simulated.WithdrawalExecutionAddress, \"latest\")\n\t\ts.Require().NoError(err)\n\t\ts.T().Logf(\"Balance before withdrawal processed: %s\", beforeWithdrawalBalance.ToInt().String())\n\n\t\t// Balance should not have changed yet\n\t\ts.Require().Equal(afterRequestBalance.ToInt().String(), beforeWithdrawalBalance.ToInt().String())\n\t\tnextBlockHeight = nextBlockHeight + int64(iterationsToTurn)\n\t}\n\n\t// The next block will be the turn of the Epoch, and the balance will change\n\t{\n\t\ts.MoveChainToHeight(s.T(), nextBlockHeight, 1, nodeAddress, time.Now())\n\t\tvar afterWithdrawalBalance hexutil.Big\n\t\terr := s.TestNode.EngineClient.Call(s.CtxApp, &afterWithdrawalBalance, \"eth_getBalance\", simulated.WithdrawalExecutionAddress, \"latest\")\n\t\ts.Require().NoError(err)\n\t\ts.T().Logf(\"Balance after withdrawal processed: %s\", afterWithdrawalBalance.ToInt().String())\n\n\t\t// Since this is a full withdrawal, the full balance will be withdrawn.\n\t\t// The validator started with a balance equal to math.Gwei(chainSpec.MaxEffectiveBalance())\n\t\twithdrawalAmountWei := new(big.Int).Mul(big.NewInt(int64(s.TestNode.ChainSpec.MaxEffectiveBalance())), big.NewInt(params.GWei))\n\n\t\t// Expected balance is balance before withdrawal + withdrawalAmount\n\t\texpectedBalance := new(big.Int).Add(beforeWithdrawalBalance.ToInt(), withdrawalAmountWei)\n\n\t\t// The new balance of the validator is updated\n\t\ts.Require().Equal(expectedBalance.String(), afterWithdrawalBalance.ToInt().String())\n\t}\n}\n\n// TestMaliciousProposer_AddInvalidExecutionRequests_IsRejected a malicious proposer adds execution requests\n// that were not actually requested.\nfunc (s *PectraGenesisSuite) TestMaliciousProposer_AddInvalidExecutionRequests_IsRejected() {\n\t// Initialize the chain state.\n\ts.InitializeChain(s.T(), 1)\n\n\t// Retrieve the BLS signer and proposer address.\n\tblsSigner := simulated.GetBlsSigner(s.HomeDir)\n\tpubkey, err := blsSigner.GetPubKey()\n\ts.Require().NoError(err)\n\tnodeAddress := pubkey.Address()\n\ts.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\tnextBlockHeight := int64(1)\n\t// We must first move the chain by 1 height such that the withdrawal contract has an updated `EXCESS_INHIBITOR`.\n\t{\n\t\tproposals, _, _ := s.MoveChainToHeight(s.T(), nextBlockHeight, 1, nodeAddress, time.Now())\n\t\ts.Require().Len(proposals, 1)\n\t\tnextBlockHeight++\n\t}\n\n\t// Create a signed block with invalid execution requests.\n\tvar maliciousSignedBlock *ctypes.SignedBeaconBlock\n\tvar proposal *v1.PrepareProposalResponse\n\tproposalTime := time.Now()\n\t{\n\t\ts.LogBuffer.Reset()\n\t\tproposal, err = s.SimComet.Comet.PrepareProposal(s.CtxComet, &v1.PrepareProposalRequest{\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tTime:            time.Now(),\n\t\t\tProposerAddress: nodeAddress,\n\t\t})\n\t\ts.Require().NoError(err)\n\t\ts.Require().Len(proposal.Txs, 2)\n\t\t// Unmarshal the proposal block.\n\t\tproposedBlock, unmarshalErr := encoding.UnmarshalBeaconBlockFromABCIRequest(\n\t\t\tproposal.Txs,\n\t\t\tblockchain.BeaconBlockTxIndex,\n\t\t\ts.TestNode.ChainSpec.ActiveForkVersionForTimestamp(math.U64(proposalTime.Unix())),\n\t\t)\n\t\ts.Require().NoError(unmarshalErr)\n\n\t\t// Invalid Execution Request\n\t\tinvalidExecutionRequests := &ctypes.ExecutionRequests{\n\t\t\tDeposits: []*ctypes.DepositRequest{\n\t\t\t\t{\n\t\t\t\t\tPubkey:      [48]byte{0, 1, 2},\n\t\t\t\t\tCredentials: [32]byte{0, 3, 2},\n\t\t\t\t\tAmount:      10000000,\n\t\t\t\t\tSignature:   [96]byte{5, 6, 7},\n\t\t\t\t\tIndex:       5,\n\t\t\t\t},\n\t\t\t},\n\t\t\tWithdrawals:    nil,\n\t\t\tConsolidations: nil,\n\t\t}\n\n\t\t// Create a malicious block by injecting an invalid Execution Request.\n\t\tmaliciousBlock := simulated.ComputeAndSetInvalidExecutionBlock(\n\t\t\ts.T(), proposedBlock.GetBeaconBlock(), s.TestNode.ChainSpec, nil, invalidExecutionRequests,\n\t\t)\n\t\t// Re-sign the block\n\t\tmaliciousSignedBlock, err = ctypes.NewSignedBeaconBlock(\n\t\t\tmaliciousBlock,\n\t\t\t&ctypes.ForkData{\n\t\t\t\tCurrentVersion:        s.TestNode.ChainSpec.ActiveForkVersionForTimestamp(maliciousBlock.GetTimestamp()),\n\t\t\t\tGenesisValidatorsRoot: s.GenesisValidatorsRoot,\n\t\t\t},\n\t\t\ts.TestNode.ChainSpec,\n\t\t\tblsSigner,\n\t\t)\n\t\ts.Require().NoError(err)\n\n\t\t// Check that the block contains the invalid execution request.\n\t\trequests, getErr := maliciousSignedBlock.GetBeaconBlock().GetBody().GetExecutionRequests()\n\t\ts.Require().NoError(getErr)\n\t\ts.Require().Len(requests.Deposits, 1)\n\n\t}\n\t// Propose the invalid block\n\t{\n\t\tmaliciousBlockBytes, sszErr := maliciousSignedBlock.MarshalSSZ()\n\t\ts.Require().NoError(sszErr)\n\n\t\t// Replace the valid block with the malicious block in the proposal.\n\t\tproposal.Txs[0] = maliciousBlockBytes\n\n\t\t// Reset the log buffer to discard old logs we don't care about\n\t\ts.LogBuffer.Reset()\n\t\t// Process the proposal containing the malicious block.\n\t\tprocessResp, err := s.SimComet.Comet.ProcessProposal(s.CtxComet, &v1.ProcessProposalRequest{\n\t\t\tTxs:             proposal.Txs,\n\t\t\tHeight:          nextBlockHeight,\n\t\t\tProposerAddress: nodeAddress,\n\t\t\tTime:            proposalTime,\n\t\t})\n\t\ts.Require().NoError(err)\n\t\ts.Require().Equal(v1.PROCESS_PROPOSAL_STATUS_REJECT, processResp.Status)\n\n\t\t// Verify that the log contains the expected error message.\n\t\ts.Require().Contains(s.LogBuffer.String(), errors.ErrInvalidPayloadStatus.Error())\n\t\ts.Require().Contains(s.LogBuffer.String(), \"invalid requests hash (remote: 33ba74e937423115e3abf4250db02588388b4b3a7918950ed44a28e4bf3428d2 local: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855)\")\n\t}\n}\n"
  },
  {
    "path": "testing/simulated/pectra_withdrawal_test.go",
    "content": "//go:build simulated\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage simulated_test\n\nimport (\n\t\"context\"\n\t\"math/big\"\n\t\"path\"\n\t\"testing\"\n\t\"time\"\n\n\tdepositcli \"github.com/berachain/beacon-kit/cli/commands/deposit\"\n\tconsensustypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/execution/requests/eip7002\"\n\t\"github.com/berachain/beacon-kit/gethlib/deposit\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/node-core/components/signer\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\tbeaconmath \"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/testing/simulated\"\n\t\"github.com/berachain/beacon-kit/testing/simulated/execution\"\n\t\"github.com/cometbft/cometbft/crypto/bls12381\"\n\t\"github.com/cometbft/cometbft/types\"\n\t\"github.com/ethereum/go-ethereum/accounts/abi/bind\"\n\tgethcommon \"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-ethereum/common/hexutil\"\n\tgethcore \"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/ethereum/go-ethereum/crypto\"\n\t\"github.com/ethereum/go-ethereum/params\"\n\t\"github.com/prysmaticlabs/prysm/v5/consensus-types/validator\"\n\t\"github.com/spf13/viper\"\n\t\"github.com/stretchr/testify/suite\"\n)\n\n// testPkey corresponds to address 0x56898d1aFb10cad584961eb96AcD476C6826e41E which is prefunded in genesis\nconst testPkey2 = \"9b9bc88a144fff869ae2f4ea8e252f2494d9b52ea1008d0b3537dad27ab489d5\"\n\n// PectraWithdrawalSuite defines our test suite for Pectra related work using simulated Comet component.\ntype PectraWithdrawalSuite struct {\n\tsuite.Suite\n\t// Embedded shared accessors for convenience.\n\tsimulated.SharedAccessors\n}\n\n// TestPectraWithdrawalSuite runs the test suite.\nfunc TestPectraWithdrawalSuite(t *testing.T) {\n\tsuite.Run(t, new(PectraWithdrawalSuite))\n}\n\n// SetupTest initializes the test environment.\nfunc (s *PectraWithdrawalSuite) SetupTest() {\n\t// Create a cancellable context for the duration of the test.\n\ts.CtxApp, s.CtxAppCancelFn = context.WithCancel(context.Background())\n\n\t// CometBFT uses context.TODO() for all ABCI calls, so we replicate that.\n\ts.CtxComet = context.TODO()\n\n\ts.HomeDir = s.T().TempDir()\n\n\t// Initialize the home directory, Comet configuration, and genesis info.\n\tconst elGenesisPath = \"./el-genesis-files/pectra-fork-genesis.json\"\n\tchainSpecFunc := simulated.ProvidePectraWithdrawalTestChainSpec\n\t// Create the chainSpec.\n\tchainSpec, err := chainSpecFunc()\n\ts.Require().NoError(err)\n\tconfigs, genesisValidatorsRoot := simulated.InitializeHomeDirs(s.T(), chainSpec, elGenesisPath, s.HomeDir)\n\tcometConfig := configs[0]\n\ts.GenesisValidatorsRoot = genesisValidatorsRoot\n\n\t// Start the EL (execution layer) Geth node.\n\telNode := execution.NewGethNode(s.HomeDir, execution.ValidGethImage())\n\telHandle, authRPC, elRPC := elNode.Start(s.T(), path.Base(elGenesisPath))\n\ts.ElHandle = elHandle\n\n\t// Prepare a logger backed by a buffer to capture logs for assertions.\n\ts.LogBuffer = &simulated.SyncBuffer{}\n\tlogger := phuslu.NewLogger(s.LogBuffer, nil)\n\n\t// Build the Beacon node with the simulated Comet component and electra genesis chain spec\n\tcomponents := simulated.FixedComponents(s.T())\n\tcomponents = append(components, simulated.ProvideSimComet)\n\tcomponents = append(components, chainSpecFunc)\n\n\ts.TestNode = simulated.NewTestNode(s.T(), simulated.TestNodeInput{\n\t\tTempHomeDir: s.HomeDir,\n\t\tCometConfig: cometConfig,\n\t\tAuthRPC:     authRPC,\n\t\tClientRPC:   elRPC,\n\t\tLogger:      logger,\n\t\tAppOpts:     viper.New(),\n\t\tComponents:  components,\n\t})\n\n\ts.SimComet = s.TestNode.SimComet\n\n\t// Start the Beacon node in a separate goroutine.\n\tgo func() {\n\t\t_ = s.TestNode.Start(s.CtxApp)\n\t}()\n\n\ts.SimulationClient = execution.NewSimulationClient(s.TestNode.EngineClient)\n\ttimeOut := 10 * time.Second\n\tinterval := 50 * time.Millisecond\n\terr = simulated.WaitTillServicesStarted(s.LogBuffer, timeOut, interval)\n\ts.Require().NoError(err)\n}\n\n// TearDownTest cleans up the test environment.\nfunc (s *PectraWithdrawalSuite) TearDownTest() {\n\ts.CleanupTest(s.T())\n}\n\n// TestExcessValidatorBeforeFork_CorrectlyEvicted verifies that when a validator’s deposit\n// exceeds the validator set cap before the Electra fork, it is evicted correctly. The set\n// cap is 1.\n//\n// Scenario timeline:\n//   Epoch 1: Move chain by 1 block to include the deposit (deposit store len == 1).\n//   Epoch 2: Move chain by 1 block to enqueue the deposit (deposit store len == 2).\n//   Epoch 3: Move chain by 1 block → validator status becomes PendingInitialized.\n//   Epoch 4: Move chain by 1 block → validator status becomes PendingQueued.\n//   Epoch 5: Move chain by 1 block → validator status becomes ExitedUnslashed; withdrawableEpoch is set to 6.\n//   —— Electra fork ——\n//   Epoch 6: Move chain by 1 block → status is WithdrawalPossible and EL balance is returned immediately.\n//   Epoch 7: Move chain by 1 block → status is WithdrawalDone (effective balance = 0).\n\nfunc (s *PectraWithdrawalSuite) TestExcessValidatorBeforeFork_CorrectlyEvicted() {\n\t// Initialize the chain state.\n\ts.InitializeChain(s.T(), 1)\n\tnodeAddress, err := s.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\t// Send the Deposit\n\tvar senderAddress gethcommon.Address\n\tdepositAmount := beaconmath.Gwei(500_000 * 1e9) // 500K Bera\n\t{\n\t\tdepositContractAddress := gethcommon.Address(s.TestNode.ChainSpec.DepositContractAddress())\n\t\tdepositClient, err := deposit.NewDepositContract(depositContractAddress, s.TestNode.ContractBackend)\n\t\ts.Require().NoError(err)\n\t\tdepositCount, err := depositClient.DepositCount(&bind.CallOpts{\n\t\t\tBlockNumber: big.NewInt(0),\n\t\t})\n\t\ts.Require().NoError(err)\n\t\ts.Require().Equal(uint64(1), depositCount)\n\n\t\tvar credAddress common.ExecutionAddress\n\t\tcredAddress, err = common.NewExecutionAddressFromHex(\"0x56898d1aFb10cad584961eb96AcD476C6826e41E\")\n\t\ts.Require().NoError(err)\n\t\tcreds := consensustypes.NewCredentialsFromExecutionAddress(credAddress)\n\t\tnewDepositor := &signer.BLSSigner{PrivValidator: types.NewMockPVWithKeyType(bls12381.KeyType)}\n\t\tdepositMsg, blsSig, err := depositcli.CreateDepositMessage(\n\t\t\ts.TestNode.ChainSpec,\n\t\t\tnewDepositor,\n\t\t\ts.GenesisValidatorsRoot,\n\t\t\tcreds,\n\t\t\tdepositAmount,\n\t\t)\n\t\ts.Require().NoError(err)\n\t\terr = depositcli.ValidateDeposit(\n\t\t\ts.TestNode.ChainSpec,\n\t\t\tdepositMsg.Pubkey,\n\t\t\tdepositMsg.Credentials,\n\t\t\tdepositMsg.Amount,\n\t\t\ts.GenesisValidatorsRoot,\n\t\t\tblsSig,\n\t\t)\n\t\ts.Require().NoError(err)\n\n\t\telChainID := big.NewInt(int64(s.TestNode.ChainSpec.DepositEth1ChainID()))\n\t\tsenderKey, err := crypto.HexToECDSA(testPkey2)\n\t\tsenderAddress = gethcommon.HexToAddress(credAddress.String())\n\t\ts.Require().NoError(err)\n\t\t_, err = depositClient.Deposit(&bind.TransactOpts{\n\t\t\tFrom: senderAddress,\n\t\t\tSigner: func(_ gethcommon.Address, tx *gethcore.Transaction) (*gethcore.Transaction, error) {\n\t\t\t\treturn gethcore.SignTx(\n\t\t\t\t\ttx, gethcore.LatestSignerForChainID(elChainID), senderKey,\n\t\t\t\t)\n\t\t\t},\n\t\t\tValue: big.NewInt(0).Mul(big.NewInt(int64(depositAmount)), big.NewInt(1e9)),\n\t\t}, depositMsg.Pubkey[:], depositMsg.Credentials[:], blsSig[:], senderAddress)\n\t\ts.Require().NoError(err)\n\t}\n\n\t// Hard fork occurs at t=10, so we start at t=5\n\t// This accounts for optimistic block building pushing payloadTime\n\t// ahead of 1 second per block\n\tnextBlockTime := time.Unix(5, 0)\n\tnextBlockHeight := int64(1)\n\n\t// [Slot/Epoch 1] Move the chain by 1 block to include the deposit\n\t{\n\t\ts.LogBuffer.Reset()\n\t\t_, _, nextBlockTime = s.MoveChainToHeight(s.T(), nextBlockHeight, 1, nodeAddress, nextBlockTime)\n\t\ts.Require().Equal(time.Unix(6, 0), nextBlockTime)\n\n\t\tds := s.TestNode.StorageBackend.DepositStore()\n\t\tdeposits, _, err := ds.GetDepositsByIndex(s.CtxApp, 0, uint64(nextBlockHeight)*s.TestNode.ChainSpec.MaxDepositsPerBlock())\n\t\ts.Require().NoError(err)\n\t\t// There should only be 1 deposit in the deposit store from genesis\n\t\ts.Require().Len(deposits, 1)\n\t\tnextBlockHeight++\n\t}\n\t// [Slot/Epoch 2] Move the chain by 1 block to Enqueue the deposit\n\t{\n\t\ts.LogBuffer.Reset()\n\t\t_, _, nextBlockTime = s.MoveChainToHeight(s.T(), nextBlockHeight, 1, nodeAddress, nextBlockTime)\n\t\ts.Require().Equal(time.Unix(7, 0), nextBlockTime)\n\n\t\tds := s.TestNode.StorageBackend.DepositStore()\n\t\tdeposits, _, err := ds.GetDepositsByIndex(s.CtxApp, 0, uint64(nextBlockHeight)*s.TestNode.ChainSpec.MaxDepositsPerBlock())\n\t\ts.Require().NoError(err)\n\t\t// There should be 2 deposits in the deposit store\n\t\ts.Require().Len(deposits, 2)\n\t\tvalidators, err := s.TestNode.APIBackend.FilterValidators(nextBlockHeight, nil, nil)\n\t\ts.Require().NoError(err)\n\t\ts.Require().Len(validators, 1)\n\t\tnextBlockHeight++\n\t}\n\t// [Slot/Epoch 3] Move the chain by 1 block make the validator pending initialized\n\t{\n\t\ts.LogBuffer.Reset()\n\t\t_, _, nextBlockTime = s.MoveChainToHeight(s.T(), nextBlockHeight, 1, nodeAddress, nextBlockTime)\n\t\ts.Require().Equal(time.Unix(8, 0), nextBlockTime)\n\n\t\tvalidators, err := s.TestNode.APIBackend.FilterValidators(nextBlockHeight, nil, nil)\n\t\ts.Require().NoError(err)\n\t\ts.Require().Len(validators, 2)\n\t\ts.Require().Equal(validator.PendingInitialized.String(), validators[1].Status)\n\t\tnextBlockHeight++\n\t}\n\t// [Slot/Epoch 4] Move the chain by 1 block make the validator pending queued\n\t{\n\t\ts.LogBuffer.Reset()\n\t\t_, _, nextBlockTime = s.MoveChainToHeight(s.T(), nextBlockHeight, 1, nodeAddress, nextBlockTime)\n\t\ts.Require().Equal(time.Unix(9, 0), nextBlockTime)\n\n\t\tvalidators, err := s.TestNode.APIBackend.FilterValidators(nextBlockHeight, nil, nil)\n\t\ts.Require().NoError(err)\n\t\ts.Require().Len(validators, 2)\n\t\ts.Require().Equal(validator.PendingQueued.String(), validators[1].Status)\n\t\tnextBlockHeight++\n\t}\n\n\t// [Slot/Epoch 5] Move the chain by 1 block mark the validator as exited\n\t{\n\t\ts.LogBuffer.Reset()\n\t\t_, _, nextBlockTime = s.MoveChainToHeight(s.T(), nextBlockHeight, 1, nodeAddress, nextBlockTime)\n\t\ts.Require().Equal(time.Unix(10, 0), nextBlockTime)\n\n\t\tvalidators, err := s.TestNode.APIBackend.FilterValidators(nextBlockHeight, nil, nil)\n\t\ts.Require().NoError(err)\n\t\ts.Require().Len(validators, 2)\n\t\ts.Require().Equal(validator.ExitedUnslashed.String(), validators[1].Status)\n\n\t\t// The validator should withdrawable at Epoch 6 since hard fork has not occurred.\n\t\ts.Require().Equal(\"6\", validators[1].Validator.WithdrawableEpoch)\n\t\tnextBlockHeight++\n\t}\n\t// [Slot/Epoch 6] Move the chain by 1. This block activates the hard fork. No withdrawal delay is expected.\n\t{\n\t\ts.LogBuffer.Reset()\n\n\t\t_, _, nextBlockTime = s.MoveChainToHeight(s.T(), nextBlockHeight, 1, nodeAddress, nextBlockTime)\n\t\ts.Require().Equal(time.Unix(11, 0), nextBlockTime)\n\n\t\tvalidators, err := s.TestNode.APIBackend.FilterValidators(nextBlockHeight, nil, nil)\n\t\ts.Require().NoError(err)\n\t\ts.Require().Len(validators, 2)\n\t\ts.Require().Equal(validator.WithdrawalPossible.String(), validators[1].Status)\n\n\t\t// The validator should withdrawable at Epoch 6 since hard fork has not occurred.\n\t\ts.Require().Equal(\"6\", validators[1].Validator.WithdrawableEpoch)\n\n\t\t// Confirm the fork was activated\n\t\ts.Require().Contains(s.LogBuffer.String(), \"✅  welcome to the electra (0x05000000) fork! 🎉\")\n\n\t\t// Confirm the balance change on EL\n\t\tpreviousBlockBalance, err := s.TestNode.ContractBackend.BalanceAt(s.CtxApp, senderAddress, big.NewInt(nextBlockHeight-1))\n\t\ts.Require().NoError(err)\n\t\tcurrentBalance, err := s.TestNode.ContractBackend.BalanceAt(s.CtxApp, senderAddress, big.NewInt(nextBlockHeight))\n\t\ts.Require().NoError(err)\n\t\tdepositAmountWei := big.NewInt(0).Mul(big.NewInt(int64(depositAmount)), big.NewInt(1e9))\n\t\texpectedBalance := big.NewInt(0).Add(previousBlockBalance, depositAmountWei)\n\t\ts.Require().Equal(expectedBalance, currentBalance)\n\t\tnextBlockHeight++\n\t}\n\t// [Slot/Epoch 7] Move the chain by 1. The effective balance is now 0 and the withdrawal is complete\n\t{\n\t\ts.LogBuffer.Reset()\n\n\t\t_, _, nextBlockTime = s.MoveChainToHeight(s.T(), nextBlockHeight, 1, nodeAddress, nextBlockTime)\n\t\ts.Require().Equal(time.Unix(12, 0), nextBlockTime)\n\n\t\tvalidators, err := s.TestNode.APIBackend.FilterValidators(nextBlockHeight, nil, nil)\n\t\ts.Require().NoError(err)\n\t\ts.Require().Len(validators, 2)\n\t\ts.Require().Equal(validator.WithdrawalDone.String(), validators[1].Status)\n\t\tnextBlockHeight++\n\t}\n}\n\n// Verifies that excess balance is not withdrawn accidentally if a validator has multiple sources of withdrawals.\n// Both the partial withdrawal and the excess balance withdrawal will occur simultaneously in a block.\n// Multiple deposits are sent so that Consensus Layer has a higher balance when the withdrawal request is processed.\n// This also served as a PoC for a now patched bug (see https://github.com/berachain/beacon-kit/pull/2723).\nfunc (s *PectraWithdrawalSuite) TestWithdrawalFromExcessStake_WithPartialWithdrawal_CorrectAmountWithdrawn() {\n\t// Initialize the chain state.\n\ts.InitializeChain(s.T(), 1)\n\n\t// Retrieve the BLS signer and proposer address.\n\tblsSigner := simulated.GetBlsSigner(s.HomeDir)\n\tpubkey, err := blsSigner.GetPubKey()\n\ts.Require().NoError(err)\n\tnodeAddress := pubkey.Address()\n\ts.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\tcredAddress, err := common.NewExecutionAddressFromHex(simulated.WithdrawalExecutionAddress)\n\ts.Require().NoError(err)\n\tcreds := consensustypes.NewCredentialsFromExecutionAddress(credAddress)\n\tsenderAddress := gethcommon.HexToAddress(credAddress.String())\n\t// Hard fork occurs at t=10, so we move passed the pectra hard fork\n\tnextBlockHeight := int64(1)\n\t{\n\t\ts.LogBuffer.Reset()\n\t\ts.MoveChainToHeight(s.T(), nextBlockHeight, 1, nodeAddress, time.Now())\n\t\tnextBlockHeight++\n\t}\n\t// 10 million bera on EL at the start.\n\texpectedStartBalance, isValid := big.NewInt(0).SetString(\"10000000000000000000000000\", 10)\n\ts.Require().True(isValid)\n\t// Confirm the validator's expected start balance in Wei\n\t{\n\t\tstartBalance, err := s.TestNode.ContractBackend.BalanceAt(s.CtxApp, senderAddress, big.NewInt(nextBlockHeight-1))\n\t\ts.Require().NoError(err)\n\t\ts.Require().Equal(expectedStartBalance, startBalance)\n\t\ts.T().Logf(\"balance at start: %s wei\", startBalance.String())\n\n\t\tvalidators, err := s.TestNode.APIBackend.FilterValidators(nextBlockHeight-1, nil, nil)\n\t\ts.Require().NoError(err)\n\t\ts.Require().Len(validators, 1)\n\t\ts.T().Logf(\"staked validator balance at start: %v gwei\", validators[0].Validator.EffectiveBalance)\n\t\t// Starts with 10000000000000000 gwei / 10 million BERA staked.\n\t\ts.Require().Equal(\"10000000000000000\", validators[0].Validator.EffectiveBalance)\n\t}\n\n\t// Send the Deposit and progress 1 block so that the deposit is included in the next block\n\tdepositAmount := beaconmath.Gwei(1_000_000 * 1e9) // 1 million Bera\n\t{\n\t\t// Send Deposit Request\n\t\titerations := int64(2)\n\t\ts.defaultDeposit(blsSigner, creds, depositAmount, true)\n\t\ttime.Sleep(time.Second) // give it time to allow the tx to be included in the next block\n\t\ts.MoveChainToHeight(s.T(), nextBlockHeight, iterations, nodeAddress, time.Now())\n\t\tnextBlockHeight += iterations\n\t}\n\n\t// Create the Partial Withdrawal Request for a large amount above the MaxEffectiveBalance.\n\t// It will be reduced to the maximum possible amount above the MinActivationBalance as part of the processing logic.\n\ttotalWithdrawalAmount := beaconmath.Gwei(15_000_000 * 1e9)\n\t{\n\t\t// corresponds with the funded address in genesis `simulated.WithdrawalExecutionAddress`\n\t\tsenderKey := simulated.GetTestKey(s.T())\n\n\t\telChainID := big.NewInt(int64(s.TestNode.ChainSpec.DepositEth1ChainID()))\n\t\tpragueSigner := gethcore.NewPragueSigner(elChainID)\n\n\t\tfee, err := eip7002.GetWithdrawalFee(s.CtxApp, s.TestNode.EngineClient)\n\t\ts.Require().NoError(err)\n\n\t\twithdrawalTxData, err := eip7002.CreateWithdrawalRequestData(blsSigner.PublicKey(), totalWithdrawalAmount)\n\t\ts.Require().NoError(err)\n\n\t\twithdrawalTx := gethcore.MustSignNewTx(senderKey, pragueSigner, &gethcore.DynamicFeeTx{\n\t\t\tChainID:   elChainID,\n\t\t\tNonce:     1,\n\t\t\tTo:        &params.WithdrawalQueueAddress,\n\t\t\tGas:       500_000,\n\t\t\tGasFeeCap: big.NewInt(1000000000),\n\t\t\tGasTipCap: big.NewInt(1000000000),\n\t\t\tValue:     fee,\n\t\t\tData:      withdrawalTxData,\n\t\t})\n\n\t\tvar balance hexutil.Big\n\t\terr = s.TestNode.EngineClient.Call(s.CtxApp, &balance, \"eth_getBalance\", simulated.WithdrawalExecutionAddress, \"latest\")\n\t\ts.T().Logf(\"Balance before withdrawal request sent: %s\", balance.ToInt().String())\n\n\t\tvar txBytes []byte\n\t\ttxBytes, err = withdrawalTx.MarshalBinary()\n\t\ts.Require().NoError(err)\n\n\t\tvar result interface{}\n\t\terr = s.TestNode.EngineClient.Call(s.CtxApp, &result, \"eth_sendRawTransaction\", hexutil.Encode(txBytes))\n\t\ts.Require().NoError(err)\n\t\ttime.Sleep(time.Second) // give it time to allow the tx to be included in the next block\n\t}\n\t// Move forward two blocks to include in the chain\n\t{\n\t\ts.LogBuffer.Reset()\n\t\ts.MoveChainToHeight(s.T(), nextBlockHeight, 2, nodeAddress, time.Now())\n\t\tnextBlockHeight += 2\n\t}\n\n\t// Send another deposit\n\t{\n\t\ts.defaultDeposit(blsSigner, creds, depositAmount, false)\n\t\ttime.Sleep(time.Second) // give it time to allow the tx to be included in the next block\n\t}\n\n\t// Move the chain by 1 block to include the deposit\n\tvar balanceAfterDepositTxIncluded *big.Int\n\t{\n\t\ts.LogBuffer.Reset()\n\t\ts.MoveChainToHeight(s.T(), nextBlockHeight, 1, nodeAddress, time.Now())\n\n\t\tds := s.TestNode.StorageBackend.DepositStore()\n\t\tdeposits, _, err := ds.GetDepositsByIndex(s.CtxApp, 0, uint64(nextBlockHeight)*s.TestNode.ChainSpec.MaxDepositsPerBlock())\n\t\ts.Require().NoError(err)\n\t\t// There should be 2 deposits in the store\n\t\ts.Require().Len(deposits, 2)\n\n\t\tbalanceAfterDepositTxIncluded, err = s.TestNode.ContractBackend.BalanceAt(s.CtxApp, senderAddress, big.NewInt(nextBlockHeight))\n\t\ts.Require().NoError(err)\n\t\tnextBlockHeight++\n\t}\n\t// Move the chain by 1 block to Enqueue the deposit\n\t{\n\t\ts.LogBuffer.Reset()\n\t\ts.MoveChainToHeight(s.T(), nextBlockHeight, 1, nodeAddress, time.Now())\n\n\t\tds := s.TestNode.StorageBackend.DepositStore()\n\t\tdeposits, _, err := ds.GetDepositsByIndex(s.CtxApp, 0, uint64(nextBlockHeight)*s.TestNode.ChainSpec.MaxDepositsPerBlock())\n\t\ts.Require().NoError(err)\n\t\t// There should be 3 deposits in the deposit store\n\t\ts.Require().Len(deposits, 3)\n\t\t// Only 1 active validator\n\t\tvalidators, err := s.TestNode.APIBackend.FilterValidators(nextBlockHeight, nil, nil)\n\t\ts.Require().NoError(err)\n\t\ts.Require().Len(validators, 1)\n\t\ts.T().Logf(\"staked validator balance: %v gwei\", validators[0].Validator.EffectiveBalance)\n\t\tnextBlockHeight++\n\t}\n\t// Move the chain by 1 block trigger the withdrawal.\n\t{\n\t\ts.LogBuffer.Reset()\n\t\ts.MoveChainToHeight(s.T(), nextBlockHeight, 1, nodeAddress, time.Now())\n\n\t\tbalance, err := s.TestNode.ContractBackend.BalanceAt(s.CtxApp, senderAddress, big.NewInt(nextBlockHeight))\n\t\ts.Require().NoError(err)\n\t\ts.Require().Equal(balanceAfterDepositTxIncluded, balance)\n\t\t// The validator's balance should not have changed yet\n\t\tnextBlockHeight++\n\t}\n\t// The next block will have the partial withdrawal, but not the excess balance withdrawal and increase the validator's EL balance\n\t// Before the fix, it would also have the excess balance withdrawal.\n\t{\n\t\ts.MoveChainToHeight(s.T(), nextBlockHeight, 1, nodeAddress, time.Now())\n\t\tnextBlockHeight++\n\t}\n\t{\n\t\titerations := int64(4)\n\t\ts.MoveChainToHeight(s.T(), nextBlockHeight, iterations, nodeAddress, time.Now())\n\t\tnextBlockHeight += iterations\n\n\t\tfinalBalance, err := s.TestNode.ContractBackend.BalanceAt(s.CtxApp, senderAddress, big.NewInt(nextBlockHeight-1))\n\t\ts.Require().NoError(err)\n\t\ts.T().Logf(\"balance at end: %s wei\", finalBalance.String())\n\t\tfinalBalanceGwei, convertErr := beaconmath.GweiFromWei(finalBalance)\n\t\ts.Require().NoError(convertErr)\n\t\texpectedStartBalanceGwei, convertErr := beaconmath.GweiFromWei(expectedStartBalance)\n\t\ts.Require().NoError(convertErr)\n\t\ts.Require().InDelta(\n\t\t\tuint64(expectedStartBalanceGwei)+\n\t\t\t\tuint64(\n\t\t\t\t\ts.TestNode.ChainSpec.MaxEffectiveBalance()-\n\t\t\t\t\t\ts.TestNode.ChainSpec.MinActivationBalance(),\n\t\t\t\t),\n\t\t\tuint64(finalBalanceGwei),\n\t\t\t500_000, // maximum 0.0005 BERA or 500000 Gwei delta\n\t\t)\n\n\t\tvalidators, err := s.TestNode.APIBackend.FilterValidators(nextBlockHeight-1, nil, nil)\n\t\ts.Require().NoError(err)\n\t\ts.Require().Len(validators, 1)\n\t\ts.T().Logf(\"staked validator balance at end: %v gwei\", validators[0].Validator.EffectiveBalance)\n\t\ts.Require().Equal(s.TestNode.ChainSpec.MinActivationBalance().Base10(), validators[0].Validator.EffectiveBalance)\n\t}\n}\n\nfunc (s *PectraWithdrawalSuite) TestWithdrawalFromExcessStake_HasCorrectWithdrawalAmount() {\n\t// Initialize the chain state.\n\ts.InitializeChain(s.T(), 1)\n\n\t// Retrieve the BLS signer and proposer address.\n\tblsSigner := simulated.GetBlsSigner(s.HomeDir)\n\tpubkey, err := blsSigner.GetPubKey()\n\ts.Require().NoError(err)\n\tnodeAddress := pubkey.Address()\n\ts.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\tcredAddress, err := common.NewExecutionAddressFromHex(simulated.WithdrawalExecutionAddress)\n\ts.Require().NoError(err)\n\tcreds := consensustypes.NewCredentialsFromExecutionAddress(credAddress)\n\tsenderAddress := gethcommon.HexToAddress(credAddress.String())\n\t// Hard fork occurs at t=10, so we move passed the pectra hard fork\n\tnextBlockHeight := int64(1)\n\t{\n\t\ts.LogBuffer.Reset()\n\t\ts.MoveChainToHeight(s.T(), nextBlockHeight, 1, nodeAddress, time.Now())\n\t\tnextBlockHeight++\n\t}\n\t// 10 million bera on EL at the start.\n\texpectedStartBalance, isValid := big.NewInt(0).SetString(\"10000000000000000000000000\", 10)\n\ts.Require().True(isValid)\n\t// Confirm the validator's expected start balance in Wei\n\t{\n\t\tstartBalance, err := s.TestNode.ContractBackend.BalanceAt(s.CtxApp, senderAddress, big.NewInt(nextBlockHeight-1))\n\t\ts.Require().NoError(err)\n\t\ts.Require().Equal(expectedStartBalance, startBalance)\n\n\t\tvalidators, err := s.TestNode.APIBackend.FilterValidators(nextBlockHeight-1, nil, nil)\n\t\ts.Require().NoError(err)\n\t\ts.Require().Len(validators, 1)\n\t\t// Starts with 10000000000000000 gwei / 10 million BERA staked.\n\t\ts.Require().Equal(\"10000000000000000\", validators[0].Validator.EffectiveBalance)\n\t}\n\n\t// Send the Deposit and progress 1 block so that the deposit is included in the next block\n\tdepositAmount := beaconmath.Gwei(10_000 * 1e9) // 10K BERA\n\t{\n\t\t// Send Deposit Requests\n\t\titerations := int64(10)\n\t\ts.defaultDepositWithNonce(blsSigner, creds, depositAmount, true, big.NewInt(0))\n\t\tfor i := 1; i < 30; i++ {\n\t\t\ts.defaultDepositWithNonce(blsSigner, creds, depositAmount, false, big.NewInt(int64(i)))\n\t\t}\n\n\t\ts.LogBuffer.Reset()\n\t\ts.MoveChainToHeight(s.T(), nextBlockHeight, iterations, nodeAddress, time.Now())\n\t\tnextBlockHeight += iterations\n\t\t// We expect that withdrawals due to excess balance were created\n\t\ts.Require().Contains(s.LogBuffer.String(), \"expectedWithdrawals: validator withdrawal due to excess balance\")\n\n\t\tdeposits, _, err := s.TestNode.StorageBackend.DepositStore().GetDepositsByIndex(\n\t\t\ts.CtxApp, 0, uint64(nextBlockHeight)*s.TestNode.ChainSpec.MaxDepositsPerBlock(),\n\t\t)\n\t\ts.Require().Len(deposits, 31)\n\t\ts.Require().NoError(err)\n\t}\n\t// Confirm the validator's end balance on EL is similar to the start balance on EL\n\t// Confirm the validator's end balance on CL is still at the cap, i.e., 10 Mil BERA.\n\t{\n\t\tendBalance, err := s.TestNode.ContractBackend.BalanceAt(s.CtxApp, senderAddress, big.NewInt(nextBlockHeight-1))\n\t\ts.Require().NoError(err)\n\t\tfinalBalanceGwei, convertErr := beaconmath.GweiFromWei(endBalance)\n\t\ts.Require().NoError(convertErr)\n\t\texpectedStartBalanceGwei, convertErr := beaconmath.GweiFromWei(expectedStartBalance)\n\t\ts.Require().NoError(convertErr)\n\t\ts.Require().InDelta(finalBalanceGwei.Unwrap(), expectedStartBalanceGwei.Unwrap(), 2_000_000) // maximum 2_000_000 Gwei delta\n\n\t\tvalidators, err := s.TestNode.APIBackend.FilterValidators(nextBlockHeight-1, nil, nil)\n\t\ts.Require().NoError(err)\n\t\ts.Require().Len(validators, 1)\n\t\t// Ends with 10000000000000000 gwei / 10 million BERA staked.\n\t\ts.Require().Equal(\"10000000000000000\", validators[0].Validator.EffectiveBalance)\n\t}\n}\n\nfunc (s *PectraWithdrawalSuite) defaultDepositWithNonce(\n\tblsSigner *signer.BLSSigner, creds consensustypes.WithdrawalCredentials, depositAmount beaconmath.Gwei, setOperator bool, nonce *big.Int) {\n\tdepositContractAddress := gethcommon.Address(s.TestNode.ChainSpec.DepositContractAddress())\n\tdepositClient, err := deposit.NewDepositContract(depositContractAddress, s.TestNode.ContractBackend)\n\ts.Require().NoError(err)\n\n\tdepositMsg, blsSig, err := depositcli.CreateDepositMessage(\n\t\ts.TestNode.ChainSpec,\n\t\tblsSigner,\n\t\ts.GenesisValidatorsRoot,\n\t\tcreds,\n\t\tdepositAmount,\n\t)\n\ts.Require().NoError(err)\n\terr = depositcli.ValidateDeposit(\n\t\ts.TestNode.ChainSpec,\n\t\tdepositMsg.Pubkey,\n\t\tdepositMsg.Credentials,\n\t\tdepositMsg.Amount,\n\t\ts.GenesisValidatorsRoot,\n\t\tblsSig,\n\t)\n\ts.Require().NoError(err)\n\n\telChainID := big.NewInt(int64(s.TestNode.ChainSpec.DepositEth1ChainID()))\n\tsenderKey := simulated.GetTestKey(s.T())\n\tsenderAddress := gethcommon.HexToAddress(creds.String())\n\ts.Require().NoError(err)\n\toperator := senderAddress\n\tif !setOperator {\n\t\toperator = gethcommon.HexToAddress(\"0x0000000000000000000000000000000000000000\")\n\t}\n\n\ttxOpts := &bind.TransactOpts{\n\t\tFrom: senderAddress,\n\t\tSigner: func(_ gethcommon.Address, tx *gethcore.Transaction) (*gethcore.Transaction, error) {\n\t\t\treturn gethcore.SignTx(\n\t\t\t\ttx, gethcore.LatestSignerForChainID(elChainID), senderKey,\n\t\t\t)\n\t\t},\n\t\tGasLimit: 200_000,\n\t\tValue:    big.NewInt(0).Mul(big.NewInt(int64(depositAmount)), big.NewInt(1e9)),\n\t}\n\n\tif nonce != nil {\n\t\ttxOpts.Nonce = nonce\n\t}\n\n\t_, err = depositClient.Deposit(txOpts, depositMsg.Pubkey[:], depositMsg.Credentials[:], blsSig[:], operator)\n\ts.Require().NoError(err)\n}\n\nfunc (s *PectraWithdrawalSuite) defaultDeposit(blsSigner *signer.BLSSigner, creds consensustypes.WithdrawalCredentials, depositAmount beaconmath.Gwei, setOperator bool) {\n\ts.defaultDepositWithNonce(blsSigner, creds, depositAmount, setOperator, nil)\n}\n"
  },
  {
    "path": "testing/simulated/rpc_errors_test.go",
    "content": "//go:build simulated\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage simulated_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"path\"\n\t\"sync/atomic\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/execution/client/ethclient\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\tjsonrpc \"github.com/berachain/beacon-kit/primitives/net/json-rpc\"\n\t\"github.com/berachain/beacon-kit/primitives/net/url\"\n\t\"github.com/berachain/beacon-kit/testing/simulated\"\n\t\"github.com/berachain/beacon-kit/testing/simulated/execution\"\n\t\"github.com/cometbft/cometbft/abci/types\"\n\t\"github.com/spf13/viper\"\n\t\"github.com/stretchr/testify/suite\"\n)\n\n// HTTP proxy in between beacon node and execution client. When active,\n// replaces responses with specified JSON-RPC error.\ntype rpcErrorProxy struct {\n\ttargetURL  string\n\tactive     atomic.Bool\n\terrorCode  int\n\terrorMsg   string\n\thttpClient *http.Client\n}\n\nfunc newRPCErrorProxy(targetURL string) *rpcErrorProxy {\n\treturn &rpcErrorProxy{\n\t\ttargetURL:  targetURL,\n\t\thttpClient: &http.Client{Timeout: 30 * time.Second},\n\t}\n}\n\nfunc (p *rpcErrorProxy) activate(code int, msg string) {\n\tp.errorCode = code\n\tp.errorMsg = msg\n\tp.active.Store(true)\n}\n\nfunc (p *rpcErrorProxy) deactivate() {\n\tp.active.Store(false)\n}\n\nfunc (p *rpcErrorProxy) getErr(reqId json.RawMessage) string {\n\treturn fmt.Sprintf(\n\t\t`{\"jsonrpc\":\"2.0\",\"id\":%s,\"error\":{\"code\":%d,\"message\":\"%s\"}}`,\n\t\tstring(reqId), p.errorCode, p.errorMsg,\n\t)\n}\n\nfunc (p *rpcErrorProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tbodyBytes, err := io.ReadAll(r.Body)\n\tif err != nil {\n\t\thttp.Error(w, \"proxy read error\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\tdefer r.Body.Close()\n\n\t// Check if need interceptor.\n\tif p.active.Load() {\n\t\tvar req struct {\n\t\t\tID     json.RawMessage `json:\"id\"`\n\t\t\tMethod string          `json:\"method\"`\n\t\t}\n\t\tif json.Unmarshal(bodyBytes, &req) == nil {\n\t\t\t// Intercept targeted methods.\n\t\t\tif isTargetedEngineMethod(req.Method) {\n\t\t\t\tw.Header().Set(\"Content-Type\", \"application/json\")\n\t\t\t\tw.WriteHeader(http.StatusOK)\n\t\t\t\t_, _ = w.Write([]byte(p.getErr(req.ID)))\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\t// Forward original request.\n\tproxyReq, err := http.NewRequestWithContext(\n\t\tr.Context(), r.Method, p.targetURL,\n\t\tbytes.NewReader(bodyBytes),\n\t)\n\tif err != nil {\n\t\thttp.Error(w, \"proxy forward error\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\tproxyReq.Header = r.Header.Clone()\n\n\tresp, err := p.httpClient.Do(proxyReq)\n\tif err != nil {\n\t\thttp.Error(w, \"proxy upstream error\", http.StatusBadGateway)\n\t\treturn\n\t}\n\tdefer resp.Body.Close()\n\n\tfor k, vv := range resp.Header {\n\t\tfor _, v := range vv {\n\t\t\tw.Header().Add(k, v)\n\t\t}\n\t}\n\tw.WriteHeader(resp.StatusCode)\n\t_, _ = io.Copy(w, resp.Body)\n}\n\nfunc isTargetedEngineMethod(method string) bool {\n\tswitch method {\n\tcase ethclient.NewPayloadMethodV3,\n\t\tethclient.NewPayloadMethodV4,\n\t\tethclient.NewPayloadMethodV4P11,\n\t\tethclient.ForkchoiceUpdatedMethodV3,\n\t\tethclient.ForkchoiceUpdatedMethodV3P11:\n\t\treturn true\n\t}\n\treturn false\n}\n\ntype RPCErrorProxySuite struct {\n\tsuite.Suite\n\tsimulated.SharedAccessors\n\terrProxy       *rpcErrorProxy\n\terrProxyServer *httptest.Server\n}\n\nfunc TestRPCErrorProxySuite(t *testing.T) {\n\tsuite.Run(t, new(RPCErrorProxySuite))\n}\n\n// SetupTest inserts a proxy in between the node and execution client,\n// to enable injection and testing of JSON-RPC errors.\nfunc (s *RPCErrorProxySuite) SetupTest() {\n\ts.CtxApp, s.CtxAppCancelFn = context.WithCancel(context.Background())\n\ts.CtxComet = context.TODO()\n\ts.HomeDir = s.T().TempDir()\n\n\tconst elGenesisPath = \"./el-genesis-files/eth-genesis.json\"\n\tchainSpecFunc := simulated.ProvideSimulationChainSpec\n\tchainSpec, err := chainSpecFunc()\n\ts.Require().NoError(err)\n\tconfigs, genesisValidatorsRoot := simulated.InitializeHomeDirs(s.T(), chainSpec, elGenesisPath, s.HomeDir)\n\tcometConfig := configs[0]\n\ts.GenesisValidatorsRoot = genesisValidatorsRoot\n\n\t// Start Geth.\n\telNode := execution.NewGethNode(s.HomeDir, execution.ValidGethImage())\n\telHandle, authRPC, elRPC := elNode.Start(s.T(), path.Base(elGenesisPath))\n\ts.ElHandle = elHandle\n\n\t// Create the error proxy for AuthRPC.\n\ts.errProxy = newRPCErrorProxy(authRPC.String())\n\ts.errProxyServer = httptest.NewServer(s.errProxy)\n\n\t// Create a ConnectionURL pointing to the proxy instead of Geth.\n\tproxyURL, err := url.NewFromRaw(s.errProxyServer.URL)\n\ts.Require().NoError(err)\n\n\ts.LogBuffer = &simulated.SyncBuffer{}\n\tlogger := phuslu.NewLogger(s.LogBuffer, nil)\n\n\tcomponents := simulated.FixedComponents(s.T())\n\tcomponents = append(components, simulated.ProvideSimComet)\n\tcomponents = append(components, chainSpecFunc)\n\n\t// Use proxy connection URL as AuthRPC\n\ts.TestNode = simulated.NewTestNode(s.T(), simulated.TestNodeInput{\n\t\tTempHomeDir: s.HomeDir,\n\t\tCometConfig: cometConfig,\n\t\tAuthRPC:     proxyURL,\n\t\tClientRPC:   elRPC,\n\t\tLogger:      logger,\n\t\tAppOpts:     viper.New(),\n\t\tComponents:  components,\n\t})\n\n\ts.SimComet = s.TestNode.SimComet\n\n\tgo func() {\n\t\t_ = s.TestNode.Start(s.CtxApp)\n\t}()\n\n\ts.SimulationClient = execution.NewSimulationClient(s.TestNode.EngineClient)\n\ttimeOut := 10 * time.Second\n\tinterval := 50 * time.Millisecond\n\terr = simulated.WaitTillServicesStarted(s.LogBuffer, timeOut, interval)\n\ts.Require().NoError(err)\n}\n\nfunc (s *RPCErrorProxySuite) TearDownTest() {\n\ts.errProxyServer.Close()\n\ts.CleanupTest(s.T())\n}\n\n// preparedProposal holds the state needed to call FinalizeBlock.\ntype preparedProposal struct {\n\ttxs             [][]byte\n\theight          int64\n\tproposerAddress []byte\n\tproposalTime    time.Time\n}\n\n// prepareForFinalize advances the chain and prepares a proposal, returning\n// the data needed to call FinalizeBlock.\nfunc (s *RPCErrorProxySuite) prepareForFinalize() preparedProposal {\n\ts.T().Helper()\n\n\tconst blockHeight = 1\n\tconst coreLoopIterations = 1\n\n\ts.InitializeChain(s.T(), 1)\n\tnodeAddress, err := s.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\tstartTime := time.Now()\n\n\tproposals, _, proposalTime := s.MoveChainToHeight(s.T(), blockHeight, coreLoopIterations, nodeAddress, startTime)\n\ts.Require().Len(proposals, coreLoopIterations)\n\n\tcurrentHeight := int64(blockHeight + coreLoopIterations)\n\n\tproposal, err := s.SimComet.Comet.PrepareProposal(s.CtxComet, &types.PrepareProposalRequest{\n\t\tHeight:          currentHeight,\n\t\tTime:            proposalTime,\n\t\tProposerAddress: nodeAddress,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotEmpty(proposal)\n\n\ts.LogBuffer.Reset()\n\n\treturn preparedProposal{\n\t\ttxs:             proposal.Txs,\n\t\theight:          currentHeight,\n\t\tproposerAddress: nodeAddress,\n\t\tproposalTime:    proposalTime,\n\t}\n}\n\n// TestFinalizeBlock_FatalRPCError shows that when exec client returns a\n// JSON-RPC error (e.g. -32700 parse error) during FinalizeBlock, the error is\n// correctly identified and returned.\nfunc (s *RPCErrorProxySuite) TestFinalizeBlock_HandleRPCError() {\n\tpp := s.prepareForFinalize()\n\n\t// Activate the error proxy with an RPC error code (-32700 parse error).\n\ts.errProxy.activate(-32700, \"Parse Error\")\n\n\tfinalizeResp, err := s.SimComet.Comet.FinalizeBlock(s.CtxComet, &types.FinalizeBlockRequest{\n\t\tTxs:             pp.txs,\n\t\tHeight:          pp.height,\n\t\tProposerAddress: pp.proposerAddress,\n\t\tTime:            pp.proposalTime,\n\t})\n\n\ts.Require().Error(err, \"FinalizeBlock should fail on fatal RPC error\")\n\ts.Require().Nil(finalizeResp)\n\ts.Require().ErrorIs(err, jsonrpc.ErrParse, \"Error should be correctly classified\")\n}\n"
  },
  {
    "path": "testing/simulated/simcomet.go",
    "content": "//go:build simulated\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage simulated\n\nimport (\n\t\"context\"\n\n\t\"github.com/berachain/beacon-kit/beacon/blockchain\"\n\t\"github.com/berachain/beacon-kit/beacon/validator\"\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/config\"\n\tcometbft \"github.com/berachain/beacon-kit/consensus/cometbft/service\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/node-core/builder\"\n\t\"github.com/berachain/beacon-kit/node-core/components/metrics\"\n\t\"github.com/berachain/beacon-kit/node-core/types\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\tcmtcrypto \"github.com/cometbft/cometbft/crypto\"\n\tpvm \"github.com/cometbft/cometbft/privval\"\n\tcmttypes \"github.com/cometbft/cometbft/types\"\n\tdbm \"github.com/cosmos/cosmos-db\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n)\n\nvar _ types.ConsensusService = (*SimComet)(nil)\n\n// SimComet is normal Comet under the hood, but we override the Start method to avoid starting the actual\n// CometBFT core loop so that we can orchestrate it ourselves.\ntype SimComet struct {\n\t// We are forced to stutter here as we want to override the implementations of the original comet service.\n\tComet *cometbft.Service\n\t// Used to initialize the node address.\n\tcmtCfg *cmtcfg.Config\n}\n\nfunc ProvideSimComet(\n\tlogger *phuslu.Logger,\n\tblockchain blockchain.BlockchainI,\n\tblockBuilder validator.BlockBuilderI,\n\tdb dbm.DB,\n\tcs chain.Spec,\n\tcmtCfg *cmtcfg.Config,\n\tappOpts config.AppOptions,\n\ttelemetrySink *metrics.TelemetrySink) *SimComet {\n\treturn &SimComet{\n\t\tComet: cometbft.NewService(\n\t\t\tlogger,\n\t\t\tdb,\n\t\t\tblockchain,\n\t\t\tblockBuilder,\n\t\t\tcs,\n\t\t\tcmtCfg,\n\t\t\ttelemetrySink,\n\t\t\tbuilder.DefaultServiceOptions(appOpts)...,\n\t\t),\n\t\tcmtCfg: cmtCfg,\n\t}\n}\n\n// Start sets the ctx and the node address for the SimComet service.\nfunc (s *SimComet) Start(ctx context.Context) error {\n\ts.Comet.ResetAppCtx(ctx)\n\treturn nil\n}\n\n// GetNodeAddress returns the node address for the SimComet service.\nfunc (s *SimComet) GetNodeAddress() (cmtcrypto.Address, error) {\n\tprivVal, err := pvm.LoadOrGenFilePV(\n\t\ts.cmtCfg.PrivValidatorKeyFile(),\n\t\ts.cmtCfg.PrivValidatorStateFile(),\n\t\tnil,\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpubKey, err := privVal.GetPubKey()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn pubKey.Address(), nil\n}\n\nfunc (s *SimComet) Stop() error {\n\treturn nil\n}\n\nfunc (s *SimComet) Name() string {\n\treturn s.Comet.Name()\n}\n\nfunc (s *SimComet) IsAppReady() error {\n\treturn s.Comet.IsAppReady()\n}\n\nfunc (s *SimComet) CreateQueryContext(height int64, prove bool) (sdk.Context, error) {\n\treturn s.Comet.CreateQueryContext(height, prove)\n}\n\nfunc (s *SimComet) GetSyncData() (int64, int64) {\n\tpanic(\"unimplemented\")\n}\n\nfunc (s *SimComet) GetBlock(height int64) *cmttypes.Block {\n\treturn s.Comet.GetBlock(height)\n}\n\nfunc (s *SimComet) GetSignedHeader(height int64) *cmttypes.SignedHeader {\n\treturn s.Comet.GetSignedHeader(height)\n}\n"
  },
  {
    "path": "testing/simulated/simulated_test.go",
    "content": "//go:build simulated\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage simulated_test\n\nimport (\n\t\"context\"\n\t\"path\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/testing/simulated\"\n\t\"github.com/berachain/beacon-kit/testing/simulated/execution\"\n\t\"github.com/spf13/viper\"\n\t\"github.com/stretchr/testify/suite\"\n)\n\n// SimulatedSuite defines our test suite for the simulated Comet component.\ntype SimulatedSuite struct {\n\tsuite.Suite\n\t// Embedded shared accessors for convenience.\n\tsimulated.SharedAccessors\n}\n\n// TestSimulatedCometComponent runs the test suite.\nfunc TestSimulatedCometComponent(t *testing.T) {\n\tsuite.Run(t, new(SimulatedSuite))\n}\n\n// SetupTest initializes the test environment.\nfunc (s *SimulatedSuite) SetupTest() {\n\t// Create a cancellable context for the duration of the test.\n\ts.CtxApp, s.CtxAppCancelFn = context.WithCancel(context.Background())\n\n\t// CometBFT uses context.TODO() for all ABCI calls, so we replicate that.\n\ts.CtxComet = context.TODO()\n\n\ts.HomeDir = s.T().TempDir()\n\n\t// Initialize the home directory, Comet configuration, and genesis info.\n\tconst elGenesisPath = \"./el-genesis-files/eth-genesis.json\"\n\tchainSpecFunc := simulated.ProvideSimulationChainSpec\n\t// Create the chainSpec.\n\tchainSpec, err := chainSpecFunc()\n\ts.Require().NoError(err)\n\tconfigs, genesisValidatorsRoot := simulated.InitializeHomeDirs(s.T(), chainSpec, elGenesisPath, s.HomeDir)\n\tcometConfig := configs[0]\n\ts.GenesisValidatorsRoot = genesisValidatorsRoot\n\n\t// Start the EL (execution layer) Geth node.\n\telNode := execution.NewGethNode(s.HomeDir, execution.ValidGethImage())\n\telHandle, authRPC, elRPC := elNode.Start(s.T(), path.Base(elGenesisPath))\n\ts.ElHandle = elHandle\n\n\t// Prepare a logger backed by a buffer to capture logs for assertions.\n\ts.LogBuffer = &simulated.SyncBuffer{}\n\tlogger := phuslu.NewLogger(s.LogBuffer, nil)\n\n\t// Build the Beacon node with the simulated Comet component.\n\tcomponents := simulated.FixedComponents(s.T())\n\tcomponents = append(components, simulated.ProvideSimComet)\n\tcomponents = append(components, chainSpecFunc)\n\ts.TestNode = simulated.NewTestNode(s.T(), simulated.TestNodeInput{\n\t\tTempHomeDir: s.HomeDir,\n\t\tCometConfig: cometConfig,\n\t\tAuthRPC:     authRPC,\n\t\tClientRPC:   elRPC,\n\t\tLogger:      logger,\n\t\tAppOpts:     viper.New(),\n\t\tComponents:  components,\n\t})\n\n\ts.SimComet = s.TestNode.SimComet\n\n\t// Start the Beacon node in a separate goroutine.\n\tgo func() {\n\t\t_ = s.TestNode.Start(s.CtxApp)\n\t}()\n\n\ts.SimulationClient = execution.NewSimulationClient(s.TestNode.EngineClient)\n\ttimeOut := 10 * time.Second\n\tinterval := 50 * time.Millisecond\n\terr = simulated.WaitTillServicesStarted(s.LogBuffer, timeOut, interval)\n\ts.Require().NoError(err)\n}\n\n// TearDownTest cleans up the test environment.\nfunc (s *SimulatedSuite) TearDownTest() {\n\ts.CleanupTest(s.T())\n}\n"
  },
  {
    "path": "testing/simulated/testnode.go",
    "content": "//go:build simulated\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage simulated\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"cosmossdk.io/depinject\"\n\t\"github.com/berachain/beacon-kit/beacon/blockchain\"\n\t\"github.com/berachain/beacon-kit/chain\"\n\tservertypes \"github.com/berachain/beacon-kit/cli/commands/server/types\"\n\t\"github.com/berachain/beacon-kit/cli/flags\"\n\t\"github.com/berachain/beacon-kit/config\"\n\t\"github.com/berachain/beacon-kit/da/kzg\"\n\t\"github.com/berachain/beacon-kit/execution/client\"\n\t\"github.com/berachain/beacon-kit/log/phuslu\"\n\t\"github.com/berachain/beacon-kit/node-api/handlers/beacon/types\"\n\t\"github.com/berachain/beacon-kit/node-api/server\"\n\tservice \"github.com/berachain/beacon-kit/node-core/services/registry\"\n\tnodetypes \"github.com/berachain/beacon-kit/node-core/types\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/net/url\"\n\t\"github.com/berachain/beacon-kit/state-transition/core\"\n\t\"github.com/berachain/beacon-kit/storage/db\"\n\tcmtcfg \"github.com/cometbft/cometbft/config\"\n\tdbm \"github.com/cosmos/cosmos-db\"\n\t\"github.com/ethereum/go-ethereum/ethclient\"\n\t\"github.com/spf13/viper\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// TestNodeInput takes the input for building and starting a node\ntype TestNodeInput struct {\n\tTempHomeDir string\n\tCometConfig *cmtcfg.Config\n\tAuthRPC     *url.ConnectionURL\n\tClientRPC   *url.ConnectionURL\n\tLogger      *phuslu.Logger\n\tAppOpts     *viper.Viper\n\tComponents  []any\n}\n\ntype ValidatorAPI interface {\n\tFilterValidators(height int64, ids []string, statuses []string) ([]*types.ValidatorData, error)\n}\n\ntype TestNode struct {\n\tnodetypes.Node\n\tStorageBackend  blockchain.StorageBackend\n\tBlockchain      *blockchain.Service\n\tChainSpec       chain.Spec\n\tAPIBackend      ValidatorAPI\n\tSimComet        *SimComet\n\tEngineClient    *client.EngineClient\n\tStateProcessor  *core.StateProcessor\n\tServiceRegistry *service.Registry\n\tKZGVerifier     kzg.BlobProofVerifier\n\tContractBackend *ethclient.Client\n}\n\n// NewTestNode Uses the testnet chainspec.\nfunc NewTestNode(\n\tt *testing.T,\n\tinput TestNodeInput,\n) TestNode {\n\tt.Helper()\n\trequire.NotNil(t, input.AuthRPC)\n\trequire.NotNil(t, input.ClientRPC)\n\n\tbeaconKitConfig := createBeaconKitConfig(t)\n\tbeaconKitConfig.Engine.RPCDialURL = input.AuthRPC\n\tappOpts := getAppOptions(t, input.AppOpts, beaconKitConfig, input.TempHomeDir)\n\n\t// Create a database\n\tdatabase, err := db.OpenDB(input.TempHomeDir, dbm.PebbleDBBackend)\n\trequire.NoError(t, err)\n\n\t// Build a node\n\tnode := buildNode(\n\t\tinput.Logger,\n\t\tdatabase,\n\t\tos.Stdout, // or some other writer\n\t\tinput.CometConfig,\n\t\tappOpts,\n\t\tinput.Components,\n\t)\n\tcontractBackend, err := ethclient.Dial(input.ClientRPC.String())\n\trequire.NoError(t, err)\n\tnode.ContractBackend = contractBackend\n\treturn node\n}\n\n// buildNode run the same logic as primary build, but it returns the components allowing us to query them.\nfunc buildNode(\n\tlogger *phuslu.Logger,\n\tdb dbm.DB,\n\t_ io.Writer,\n\tcmtCfg *cmtcfg.Config,\n\tappOpts servertypes.AppOptions,\n\tcomponents []any,\n) TestNode {\n\t// variables to hold the components needed to set up BeaconApp\n\tvar (\n\t\tapiServer       *server.Server\n\t\tbeaconNode      nodetypes.Node\n\t\tsimComet        *SimComet\n\t\tconfig          *config.Config\n\t\tstorageBackend  blockchain.StorageBackend\n\t\tblockchain      *blockchain.Service\n\t\tchainSpec       chain.Spec\n\t\tengineClient    *client.EngineClient\n\t\tstateProcessor  *core.StateProcessor\n\t\tserviceRegistry *service.Registry\n\t\tkzgVerifier     kzg.BlobProofVerifier\n\t)\n\n\t// build all node components using depinject\n\tif err := depinject.Inject(\n\t\tdepinject.Configs(\n\t\t\tdepinject.Provide(\n\t\t\t\tcomponents...,\n\t\t\t),\n\t\t\tdepinject.Supply(\n\t\t\t\tappOpts,\n\t\t\t\tlogger,\n\t\t\t\tdb,\n\t\t\t\tcmtCfg,\n\t\t\t),\n\t\t),\n\t\t&apiServer,\n\t\t&beaconNode,\n\t\t&simComet,\n\t\t&config,\n\t\t&storageBackend,\n\t\t&blockchain,\n\t\t&chainSpec,\n\t\t&engineClient,\n\t\t&stateProcessor,\n\t\t&serviceRegistry,\n\t\t&kzgVerifier,\n\t); err != nil {\n\t\tpanic(err)\n\t}\n\tif config == nil {\n\t\tpanic(\"config is nil\")\n\t}\n\tif apiServer == nil {\n\t\tpanic(\"api server is nil\")\n\t}\n\n\tlogger.WithConfig(config.GetLogger())\n\treturn TestNode{\n\t\tNode:            beaconNode,\n\t\tStorageBackend:  storageBackend,\n\t\tBlockchain:      blockchain,\n\t\tChainSpec:       chainSpec,\n\t\tAPIBackend:      apiServer.GetBeaconHandler(),\n\t\tSimComet:        simComet,\n\t\tEngineClient:    engineClient,\n\t\tStateProcessor:  stateProcessor,\n\t\tServiceRegistry: serviceRegistry,\n\t\tKZGVerifier:     kzgVerifier,\n\t}\n}\n\n// getAppOptions returns the Application Options we need to set for the Node Builder.\n// Ideally we can avoid having to set the flags like this and just directly modify a config type.\nfunc getAppOptions(t *testing.T, appOpts *viper.Viper, beaconKitConfig *config.Config, tempHomeDir string) *viper.Viper {\n\tt.Helper()\n\t// Execution Client Config\n\trelativePathJwt := \"../files/jwt.hex\"\n\tjwtPath, err := filepath.Abs(relativePathJwt)\n\trequire.NoError(t, err)\n\tappOpts.Set(flags.JWTSecretPath, jwtPath)\n\tappOpts.Set(flags.RPCJWTRefreshInterval, beaconKitConfig.GetEngine().RPCJWTRefreshInterval.String())\n\tappOpts.Set(flags.RPCStartupCheckInterval, beaconKitConfig.GetEngine().RPCStartupCheckInterval.String())\n\tappOpts.Set(flags.RPCDialURL, beaconKitConfig.GetEngine().RPCDialURL.String())\n\tappOpts.Set(flags.RPCTimeout, beaconKitConfig.GetEngine().RPCTimeout.String())\n\n\tappOpts.Set(flags.LogLevel, \"debug\")\n\n\t// BLS Config\n\tappOpts.Set(flags.PrivValidatorKeyFile, \"./config/priv_validator_key.json\")\n\tappOpts.Set(flags.PrivValidatorStateFile, \"./data/priv_validator_state.json\")\n\n\t// Beacon Config\n\tappOpts.Set(flags.BlockStoreServiceAvailabilityWindow, beaconKitConfig.GetBlockStoreService().AvailabilityWindow)\n\tappOpts.Set(flags.KZGTrustedSetupPath, \"../files/kzg-trusted-setup.json\")\n\tappOpts.Set(flags.KZGImplementation, kzg.DefaultConfig().Implementation)\n\n\t// Payload Builder Config\n\tbeaconKitConfig.GetPayloadBuilder().SuggestedFeeRecipient, err = common.NewExecutionAddressFromHex(\n\t\t\"0x981114102592310C347E61368342DDA67017bf84\",\n\t)\n\trequire.NoError(t, err, \"failed to create suggested fee recipient\")\n\tappOpts.Set(flags.BuilderEnabled, beaconKitConfig.GetPayloadBuilder().Enabled)\n\tappOpts.Set(flags.BuildPayloadTimeout, beaconKitConfig.GetPayloadBuilder().PayloadTimeout)\n\tappOpts.Set(flags.SuggestedFeeRecipient, beaconKitConfig.GetPayloadBuilder().SuggestedFeeRecipient)\n\n\t// TODO: Cleanup this Set\n\tappOpts.Set(\"pruning\", \"default\")\n\tappOpts.Set(\"home\", tempHomeDir)\n\treturn appOpts\n}\n\nfunc createBeaconKitConfig(_ *testing.T) *config.Config {\n\treturn config.DefaultConfig()\n}\n"
  },
  {
    "path": "testing/simulated/transformers.go",
    "content": "//go:build simulated\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage simulated\n\nimport (\n\t\"fmt\"\n\t\"math/big\"\n\t\"unsafe\"\n\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/berachain/beacon-kit/testing/simulated/execution\"\n\tgethengine \"github.com/ethereum/go-ethereum/beacon/engine\"\n\tgethcommon \"github.com/ethereum/go-ethereum/common\"\n\tcoretypes \"github.com/ethereum/go-ethereum/core/types\"\n\tgethtypes \"github.com/ethereum/go-ethereum/core/types\"\n\tgethtrie \"github.com/ethereum/go-ethereum/trie\"\n)\n\n// transformSimulatedBlockToGethBlock converts a simulated execution block into a Geth-style block.\n// It uses the provided transactions and parent beacon root to construct a new execution block header.\nfunc transformSimulatedBlockToGethBlock(\n\tsimBlock *execution.SimulatedBlock,\n\ttxs []*gethtypes.Transaction,\n\tparentBeaconRoot common.Root,\n) *gethtypes.Block {\n\t// Convert numeric fields.\n\texcessBlobGas := simBlock.ExcessBlobGas.ToInt().Uint64()\n\tblobGasUsed := simBlock.BlobGasUsed.ToInt().Uint64()\n\tbaseFeePerGas := simBlock.BaseFeePerGas.ToInt()\n\n\t// Compute the withdrawals hash from the simulated block's withdrawals.\n\twithdrawalsHash := gethtypes.DeriveSha(simBlock.Withdrawals, gethtrie.NewStackTrie(nil))\n\n\t// Create a new header using values from the simulated block.\n\theader := &gethtypes.Header{\n\t\tParentHash: simBlock.ParentHash,\n\t\tUncleHash:  gethtypes.EmptyUncleHash,\n\t\tCoinbase:   simBlock.Miner,\n\t\tRoot:       simBlock.StateRoot,\n\t\t// TxHash is computed from the provided transactions since simulation does not have signatures\n\t\t// which is required for correct hash calculation.\n\t\tTxHash:           gethtypes.DeriveSha(gethtypes.Transactions(txs), gethtrie.NewStackTrie(nil)),\n\t\tReceiptHash:      simBlock.ReceiptsRoot,\n\t\tBloom:            gethtypes.Bloom(simBlock.LogsBloom),\n\t\tDifficulty:       big.NewInt(0),\n\t\tNumber:           (*big.Int)(simBlock.Number),\n\t\tGasLimit:         (uint64)(*simBlock.GasLimit),\n\t\tGasUsed:          (uint64)(*simBlock.GasUsed),\n\t\tTime:             (uint64)(*simBlock.Timestamp),\n\t\tBaseFee:          baseFeePerGas,\n\t\tExtra:            simBlock.ExtraData,\n\t\tMixDigest:        simBlock.MixHash,\n\t\tWithdrawalsHash:  &withdrawalsHash,\n\t\tExcessBlobGas:    &excessBlobGas,\n\t\tBlobGasUsed:      &blobGasUsed,\n\t\tParentBeaconRoot: (*gethcommon.Hash)(&parentBeaconRoot),\n\t}\n\n\t// Create the block body using the transactions and withdrawals from the simulation.\n\tbody := gethtypes.Body{\n\t\tTransactions: txs,\n\t\tUncles:       nil,\n\t\tWithdrawals:  simBlock.Withdrawals,\n\t}\n\n\treturn gethtypes.NewBlockWithHeader(header).WithBody(body)\n}\n\n// transformExecutableDataToExecutionPayload converts Ethereum executable data into a beacon execution payload.\n// This function supports fork versions prior to Deneb1. For unsupported fork versions, it returns an error.\nfunc transformExecutableDataToExecutionPayload(\n\tforkVersion common.Version,\n\tdata *gethengine.ExecutableData,\n) (*ctypes.ExecutionPayload, error) {\n\t// Check that the fork version is supported\n\tif version.IsAfter(forkVersion, version.Electra()) {\n\t\treturn nil, ctypes.ErrForkVersionNotSupported\n\t}\n\n\t// Convert withdrawals\n\twithdrawals := *(*engineprimitives.Withdrawals)(unsafe.Pointer(&data.Withdrawals))\n\n\t// Truncate ExtraData if it exceeds the allowed length.\n\tif len(data.ExtraData) > constants.ExtraDataLength {\n\t\tdata.ExtraData = data.ExtraData[:constants.ExtraDataLength]\n\t}\n\n\t// Safely dereference optional fields.\n\tvar blobGasUsed, excessBlobGas uint64\n\tif data.BlobGasUsed != nil {\n\t\tblobGasUsed = *data.BlobGasUsed\n\t}\n\tif data.ExcessBlobGas != nil {\n\t\texcessBlobGas = *data.ExcessBlobGas\n\t}\n\n\t// Convert BaseFeePerGas into a U256 value.\n\tbaseFeePerGas, err := math.NewU256FromBigInt(data.BaseFeePerGas)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed baseFeePerGas conversion: %w\", err)\n\t}\n\n\t// Construct the execution payload.\n\texecutionPayload := &ctypes.ExecutionPayload{\n\t\tVersionable:   ctypes.NewVersionable(forkVersion),\n\t\tParentHash:    common.ExecutionHash(data.ParentHash),\n\t\tFeeRecipient:  common.ExecutionAddress(data.FeeRecipient),\n\t\tStateRoot:     common.Bytes32(data.StateRoot),\n\t\tReceiptsRoot:  common.Bytes32(data.ReceiptsRoot),\n\t\tLogsBloom:     [256]byte(data.LogsBloom),\n\t\tRandom:        common.Bytes32(data.Random),\n\t\tNumber:        math.U64(data.Number),\n\t\tGasLimit:      math.U64(data.GasLimit),\n\t\tGasUsed:       math.U64(data.GasUsed),\n\t\tTimestamp:     math.U64(data.Timestamp),\n\t\tWithdrawals:   withdrawals,\n\t\tExtraData:     data.ExtraData,\n\t\tBaseFeePerGas: baseFeePerGas,\n\t\tBlockHash:     common.ExecutionHash(data.BlockHash),\n\t\tTransactions:  data.Transactions,\n\t\tBlobGasUsed:   math.U64(blobGasUsed),\n\t\tExcessBlobGas: math.U64(excessBlobGas),\n\t}\n\treturn executionPayload, nil\n}\n\n// splitTxs separates transactions into two slices:\n// 1. Transactions with blob sidecars removed.\n// 2. The extracted blob sidecars, if any.\nfunc splitTxs(txs []*coretypes.Transaction) (txsWithoutSidecars []*coretypes.Transaction, txSidecars []*coretypes.BlobTxSidecar) {\n\ttxsWithoutSidecars = make([]*coretypes.Transaction, 0, len(txs))\n\ttxSidecars = make([]*coretypes.BlobTxSidecar, 0, len(txs))\n\n\tfor _, tx := range txs {\n\t\t// Append the transaction with its blob sidecar removed.\n\t\ttxsWithoutSidecars = append(txsWithoutSidecars, tx.WithoutBlobTxSidecar())\n\t\t// If a blob sidecar exists, collect it.\n\t\tif sidecar := tx.BlobTxSidecar(); sidecar != nil {\n\t\t\ttxSidecars = append(txSidecars, sidecar)\n\t\t}\n\t}\n\treturn\n}\n"
  },
  {
    "path": "testing/simulated/utils.go",
    "content": "//go:build simulated\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage simulated\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/ecdsa\"\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\t\"unsafe\"\n\n\t\"github.com/berachain/beacon-kit/beacon/blockchain\"\n\tpayloadtime \"github.com/berachain/beacon-kit/beacon/payload-time\"\n\t\"github.com/berachain/beacon-kit/chain\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/encoding\"\n\t\"github.com/berachain/beacon-kit/da/kzg\"\n\t\"github.com/berachain/beacon-kit/da/kzg/gokzg\"\n\t\"github.com/berachain/beacon-kit/errors\"\n\tgethtypes \"github.com/berachain/beacon-kit/gethlib/types\"\n\t\"github.com/berachain/beacon-kit/node-core/components/signer\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/constants\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/berachain/beacon-kit/state-transition/core\"\n\t\"github.com/berachain/beacon-kit/testing/simulated/execution\"\n\t\"github.com/cometbft/cometbft/abci/types\"\n\tcmtcrypto \"github.com/cometbft/cometbft/crypto\"\n\tgenutiltypes \"github.com/cosmos/cosmos-sdk/x/genutil/types\"\n\tgokzg4844 \"github.com/crate-crypto/go-kzg-4844\"\n\t\"github.com/ethereum/go-ethereum/beacon/engine\"\n\tgethcommon \"github.com/ethereum/go-ethereum/common\"\n\t\"github.com/ethereum/go-ethereum/common/hexutil\"\n\tcoretypes \"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/ethereum/go-ethereum/crypto\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// testPkey corresponds to address 0x20f33ce90a13a4b5e7697e3544c3083b8f8a51d4 which is prefunded in genesis\nconst testPkey = \"fffdbb37105441e14b0ee6330d855d8504ff39e705c3afa8f859ac9865f99306\"\n\n// SyncBuffer is a thread-safe wrapper around bytes.Buffer.\ntype SyncBuffer struct {\n\tmu  sync.RWMutex\n\tbuf bytes.Buffer\n}\n\nfunc (sb *SyncBuffer) Write(p []byte) (int, error) {\n\tsb.mu.Lock()\n\tdefer sb.mu.Unlock()\n\treturn sb.buf.Write(p)\n}\n\nfunc (sb *SyncBuffer) String() string {\n\tsb.mu.RLock()\n\tdefer sb.mu.RUnlock()\n\treturn sb.buf.String()\n}\n\nfunc (sb *SyncBuffer) Reset() {\n\tsb.mu.Lock()\n\tdefer sb.mu.Unlock()\n\tsb.buf.Reset()\n}\n\nfunc (sb *SyncBuffer) Contains(substr []byte) bool {\n\tsb.mu.RLock()\n\tdefer sb.mu.RUnlock()\n\treturn bytes.Contains(sb.buf.Bytes(), substr)\n}\n\n// SharedAccessors holds references to common utilities required in tests.\ntype SharedAccessors struct {\n\tCtxApp                context.Context\n\tCtxAppCancelFn        context.CancelFunc\n\tCtxComet              context.Context\n\tHomeDir               string\n\tTestNode              TestNode\n\tSimComet              *SimComet\n\tLogBuffer             *SyncBuffer\n\tGenesisValidatorsRoot common.Root\n\tSimulationClient      *execution.SimulationClient\n\n\t// ElHandle is a dockertest resource handle that should be closed in teardown.\n\tElHandle *execution.Resource\n}\n\n// CleanupTest performs common cleanup operations for test suites.\n// Call this from TearDownTest to ensure proper cleanup even when setup fails.\nfunc (s *SharedAccessors) CleanupTest(t *testing.T) {\n\ts.CleanupTestWithLabel(t, \"\")\n}\n\n// CleanupTestWithLabel performs common cleanup operations with an optional label for logs.\n// Use this when managing multiple execution clients (e.g., \"GETH\", \"RETH\").\nfunc (s *SharedAccessors) CleanupTestWithLabel(t *testing.T, label string) {\n\tt.Helper()\n\n\t// If the test has failed, log additional information.\n\tif t.Failed() && s.LogBuffer != nil {\n\t\tif label != \"\" {\n\t\t\tt.Logf(\"%s CL LOGS:\", label)\n\t\t}\n\t\tt.Log(s.LogBuffer.String())\n\t}\n\n\t// Close execution layer handle if it exists.\n\tif s.ElHandle != nil {\n\t\tif err := s.ElHandle.Close(); err != nil {\n\t\t\tif label != \"\" {\n\t\t\t\tt.Errorf(\"Error closing %s EL handle: %v\", label, err)\n\t\t\t} else {\n\t\t\t\tt.Errorf(\"Error closing EL handle: %v\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Cancel the application context if it exists.\n\tif s.CtxAppCancelFn != nil {\n\t\ts.CtxAppCancelFn()\n\t}\n\n\t// Stop all services if the service registry exists.\n\tif s.TestNode.ServiceRegistry != nil {\n\t\ts.TestNode.ServiceRegistry.StopAll()\n\t}\n}\n\n// InitializeChain sets up the chain using the genesis file and verifies the\n// expected number of validators and deposits are present.\nfunc (s *SharedAccessors) InitializeChain(t *testing.T, numValidators int) {\n\tt.Helper()\n\tappGenesis, err := genutiltypes.AppGenesisFromFile(s.HomeDir + \"/config/genesis.json\")\n\trequire.NoError(t, err)\n\n\tinitResp, err := s.SimComet.Comet.InitChain(s.CtxComet, &types.InitChainRequest{\n\t\tChainId:       TestnetBeaconChainID,\n\t\tAppStateBytes: appGenesis.AppState,\n\t})\n\trequire.NoError(t, err)\n\trequire.Len(t, initResp.Validators, numValidators, fmt.Sprintf(\"Expected %d validator(s)\", numValidators))\n\n\tdeposits, _, err := s.TestNode.StorageBackend.DepositStore().GetDepositsByIndex(\n\t\ts.CtxApp,\n\t\tconstants.FirstDepositIndex,\n\t\tconstants.FirstDepositIndex+s.TestNode.ChainSpec.MaxDepositsPerBlock(),\n\t)\n\trequire.NoError(t, err)\n\trequire.Len(t, deposits, numValidators, fmt.Sprintf(\"Expected %d deposit(s)\", numValidators))\n}\n\n// MoveChainToHeight will iterate through the core loop `iterations` times, i.e. Propose, Process, Finalize and Commit.\n// Returns the list of proposed comet blocks.\nfunc (s *SharedAccessors) MoveChainToHeight(\n\tt *testing.T,\n\tstartHeight,\n\titerations int64,\n\tnodeAddress cmtcrypto.Address,\n\tstartTime time.Time,\n) ([]*types.PrepareProposalResponse, []*types.FinalizeBlockResponse, time.Time) {\n\t// Prepare a block proposal.\n\tvar proposedCometBlocks []*types.PrepareProposalResponse\n\tvar finalizedResponses []*types.FinalizeBlockResponse\n\n\tproposalTime := startTime\n\tfor currentHeight := startHeight; currentHeight < startHeight+iterations; currentHeight++ {\n\t\tproposal, err := s.SimComet.Comet.PrepareProposal(s.CtxComet, &types.PrepareProposalRequest{\n\t\t\tHeight:          currentHeight,\n\t\t\tTime:            proposalTime,\n\t\t\tProposerAddress: nodeAddress,\n\t\t})\n\t\trequire.NoError(t, err)\n\t\trequire.Len(t, proposal.Txs, 2)\n\n\t\t// Process the proposal.\n\t\tprocessReq := &types.ProcessProposalRequest{\n\t\t\tTxs:                 proposal.Txs,\n\t\t\tHeight:              currentHeight,\n\t\t\tProposerAddress:     nodeAddress,\n\t\t\tTime:                proposalTime,\n\t\t\tNextProposerAddress: nodeAddress, // Trigger an optimistic build for the next height.\n\t\t}\n\t\tprocessResp, err := s.SimComet.Comet.ProcessProposal(s.CtxComet, processReq)\n\t\trequire.NoError(t, err)\n\t\trequire.Equal(t, types.PROCESS_PROPOSAL_STATUS_ACCEPT.String(), processResp.Status.String())\n\n\t\t// Finalize the block.\n\t\tfinalizeResp, err := s.SimComet.Comet.FinalizeBlock(s.CtxComet, &types.FinalizeBlockRequest{\n\t\t\tTxs:             proposal.Txs,\n\t\t\tHeight:          currentHeight,\n\t\t\tProposerAddress: nodeAddress,\n\t\t\tTime:            proposalTime,\n\t\t})\n\t\trequire.NoError(t, err)\n\t\trequire.NotEmpty(t, finalizeResp)\n\n\t\t// Commit the block.\n\t\t_, err = s.SimComet.Comet.Commit(s.CtxComet, &types.CommitRequest{})\n\t\trequire.NoError(t, err)\n\n\t\t// Record the Commit Block\n\t\tproposedCometBlocks = append(proposedCometBlocks, proposal)\n\t\tfinalizedResponses = append(finalizedResponses, finalizeResp)\n\n\t\t// set consensus time for the next block to match\n\t\t// the timestamp of the payload built optimistically.\n\t\tforkVersion := s.TestNode.ChainSpec.ActiveForkVersionForTimestamp(math.U64(proposalTime.Unix())) //#nosec: G115\n\t\tblk, _, err := encoding.ExtractBlobsAndBlockFromRequest(\n\t\t\tprocessReq,\n\t\t\tblockchain.BeaconBlockTxIndex,\n\t\t\tblockchain.BlobSidecarsTxIndex,\n\t\t\tforkVersion,\n\t\t)\n\t\trequire.NoError(t, err)\n\t\tproposalTime = time.Unix(\n\t\t\tint64(payloadtime.Next(blk.GetTimestamp(), blk.GetTimestamp(), true)),\n\t\t\t0,\n\t\t)\n\t}\n\treturn proposedCometBlocks, finalizedResponses, proposalTime\n}\n\n// WaitTillServicesStarted waits until the log buffer contains \"All services started\".\n// It checks periodically with a timeout to prevent indefinite waiting.\n// If there is a better way to determine the services have started, e.g. readiness probe, replace this.\nfunc WaitTillServicesStarted(logBuffer *SyncBuffer, timeout, interval time.Duration) error {\n\tdeadline := time.After(timeout)\n\tticker := time.NewTicker(interval)\n\tdefer ticker.Stop()\n\tfor {\n\t\tselect {\n\t\tcase <-deadline:\n\t\t\treturn errors.New(\"timeout waiting for services to start\")\n\t\tcase <-ticker.C:\n\t\t\tif logBuffer.Contains([]byte(\"All services started\")) {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc GetTestKey(t *testing.T) *ecdsa.PrivateKey {\n\tt.Helper()\n\t// Create a test key - copied from go-ethereum.\n\ttestKey, err := crypto.HexToECDSA(testPkey)\n\trequire.NoError(t, err, \"failed to create test key for malicious transaction\")\n\treturn testKey\n}\n\n// GetBlsSigner returns a new BLSSigner using the configuration files in the provided home directory.\nfunc GetBlsSigner(tempHomeDir string) *signer.BLSSigner {\n\tprivValKeyFile := filepath.Join(tempHomeDir, \"config\", \"priv_validator_key.json\")\n\tprivValStateFile := filepath.Join(tempHomeDir, \"data\", \"priv_validator_state.json\")\n\treturn signer.NewBLSSigner(privValKeyFile, privValStateFile)\n}\n\nfunc DefaultSimulationInput(\n\tt *testing.T,\n\tchainSpec chain.Spec,\n\torigBlock *ctypes.BeaconBlock,\n\ttxs []*coretypes.Transaction,\n) *execution.SimOpts {\n\tt.Helper()\n\toverrideTime := hexutil.Uint64(origBlock.GetTimestamp().Unwrap())\n\toverrideGasLimit := hexutil.Uint64(30000000)\n\toverrideFeeRecipient := origBlock.GetBody().GetExecutionPayload().GetFeeRecipient()\n\toverridePrevRandao := gethcommon.Hash(origBlock.GetBody().GetExecutionPayload().GetPrevRandao())\n\toverrideBaseFeePerGas := origBlock.GetBody().GetExecutionPayload().GetBaseFeePerGas().ToBig()\n\toverrideBeaconRoot := gethcommon.HexToHash(origBlock.GetParentBlockRoot().Hex())\n\torigWithdrawls := origBlock.GetBody().GetExecutionPayload().GetWithdrawals()\n\toverrideWithdrawals := *(*coretypes.Withdrawals)(unsafe.Pointer(&origWithdrawls))\n\n\tcalls, err := execution.TxsToTransactionArgs(chainSpec.DepositEth1ChainID(), txs)\n\trequire.NoError(t, err)\n\tsimulationInput := &execution.SimOpts{\n\t\tBlockStateCalls: []*execution.SimBlock{\n\t\t\t{\n\t\t\t\tCalls: calls,\n\t\t\t\tBlockOverrides: &execution.BlockOverrides{\n\t\t\t\t\tTime:          &overrideTime,\n\t\t\t\t\tGasLimit:      &overrideGasLimit,\n\t\t\t\t\tFeeRecipient:  (*gethcommon.Address)(&overrideFeeRecipient),\n\t\t\t\t\tPrevRandao:    &overridePrevRandao,\n\t\t\t\t\tBaseFeePerGas: (*hexutil.Big)(overrideBaseFeePerGas),\n\t\t\t\t\tBeaconRoot:    &overrideBeaconRoot,\n\t\t\t\t\tWithdrawals:   overrideWithdrawals,\n\t\t\t\t\t// TODO: Do we need to override blob base fee?\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tValidation:     true,\n\t\tTraceTransfers: false,\n\t}\n\treturn simulationInput\n}\n\n// ComputeAndSetInvalidExecutionBlock transforms the current execution payload of latestBlock\n// into a new payload (using the invalid transformation) and updates latestBlock with it.\n// This will make sure all the fields validated by the CL, i.e. Execution Block Hash, are valid, but does not set\n// correct values for fields like the Execution Block StateRoot and ReceiptsRoot as that requires simulation and\n// is not validated in the CL.\nfunc ComputeAndSetInvalidExecutionBlock(\n\tt *testing.T,\n\tlatestBlock *ctypes.BeaconBlock,\n\tchainSpec chain.Spec,\n\ttxs []*coretypes.Transaction,\n\texecutionRequests *ctypes.ExecutionRequests,\n) *ctypes.BeaconBlock {\n\tt.Helper()\n\tforkVersion := chainSpec.ActiveForkVersionForTimestamp(latestBlock.GetTimestamp())\n\t_, sidecars := splitTxs(txs)\n\t// Use the current execution payload (e.g. for an invalid block, no simulation is done).\n\texecutionPayload := latestBlock.GetBody().GetExecutionPayload()\n\t// Transform the payload into a Geth block.\n\ttxsBytesArray := make([][]byte, len(txs))\n\tfor i, tx := range txs {\n\t\ttxBytes, err := tx.MarshalBinary()\n\t\trequire.NoError(t, err)\n\t\ttxsBytesArray[i] = txBytes\n\t}\n\texecutionPayload.Transactions = txsBytesArray\n\tparentBlockRoot := latestBlock.GetParentBlockRoot()\n\n\tvar (\n\t\texecBlock           *gethtypes.Block\n\t\tencodedExecRequests []ctypes.EncodedExecutionRequest\n\t\terr                 error\n\t)\n\tif version.EqualsOrIsAfter(forkVersion, version.Electra()) {\n\t\tencodedExecRequests, err = ctypes.GetExecutionRequestsList(executionRequests)\n\t\trequire.NoError(t, err)\n\t}\n\texecBlock, _, err = ctypes.MakeEthBlock(executionPayload, parentBlockRoot, encodedExecRequests, nil)\n\trequire.NoError(t, err)\n\n\treturn updateBeaconBlockBody(t, latestBlock, forkVersion, execBlock, sidecars, executionRequests)\n}\n\n// ComputeAndSetValidExecutionBlock simulates a new execution payload based on the provided transactions,\n// transforms the simulated block into a Geth-style execution block, and updates the given beacon block\n// with the new execution payload. This will correctly set the Execution Block State and Receipts Root using simulation.\n// Note: The returned block's state root is not finalized and must be updated via a state transition (see ComputeAndSetStateRoot).\nfunc ComputeAndSetValidExecutionBlock(\n\tt *testing.T,\n\tlatestBlock *ctypes.BeaconBlock,\n\tsimClient *execution.SimulationClient,\n\tchainSpec chain.Spec,\n\ttxs []*coretypes.Transaction,\n) *ctypes.BeaconBlock {\n\tt.Helper()\n\t// Check that the fork version is supported\n\tif version.IsAfter(latestBlock.GetForkVersion(), version.Deneb1()) {\n\t\tt.Fatalf(\"fork version %s is not supported by this function\", latestBlock.GetForkVersion())\n\t}\n\t// Run simulation to get a simulated block.\n\tbaseHeight := int64(latestBlock.GetSlot().Unwrap()) - 1\n\tsimInput := DefaultSimulationInput(t, chainSpec, latestBlock, txs)\n\tsimulatedBlocks, err := simClient.Simulate(context.TODO(), baseHeight, simInput)\n\trequire.NoError(t, err)\n\trequire.Len(t, simulatedBlocks, 1)\n\tsimBlock := simulatedBlocks[0]\n\n\tforkVersion := chainSpec.ActiveForkVersionForTimestamp(latestBlock.GetTimestamp())\n\ttxsNoSidecar, sidecars := splitTxs(txs)\n\torigParent := latestBlock.GetParentBlockRoot()\n\n\t// Transform the simulated block into a Geth block.\n\texecBlock := transformSimulatedBlockToGethBlock(simBlock, txsNoSidecar, origParent)\n\t// TODO: Add support for execution requests before allowing electra\n\treturn updateBeaconBlockBody(t, latestBlock, forkVersion, execBlock, sidecars, nil)\n}\n\n// ComputeAndSetStateRoot applies a state transition to the given beacon block.\n// It creates a copy of the current state (from the provided storage backend and query context),\n// constructs a transition context using the consensus time and proposer address,\n// runs the state transition, and then updates the block’s state root based on the new state.\n// Returns the updated block or an error.\n// This should only be used if you know the block is valid. Otherwise use ComputeAndSetInvalidExecutionBlock.\n// TODO: Can we use a mocked execution client for the StateProcessor to avoid doing an unnecessary NewPayload?\nfunc ComputeAndSetStateRoot(\n\tqueryCtx context.Context,\n\tconsensusTime time.Time,\n\tproposerAddress []byte,\n\tstateProcessor *core.StateProcessor,\n\tstorageBackend blockchain.StorageBackend,\n\tblock *ctypes.BeaconBlock,\n) (*ctypes.BeaconBlock, error) {\n\n\t// Copy the current state from the storage backend.\n\tstateDBCopy := storageBackend.StateFromContext(queryCtx).Protect(queryCtx)\n\n\t// Create a transition context with the provided consensus time and proposer address.\n\ttxCtx := transition.NewTransitionCtx(\n\t\tqueryCtx,\n\t\tmath.U64(consensusTime.Unix()),\n\t\tproposerAddress,\n\t).WithVerifyPayload(false).\n\t\tWithVerifyRandao(false).\n\t\tWithVerifyResult(false).\n\t\tWithMeterGas(false)\n\n\t// Run the state transition.\n\t_, err := stateProcessor.Transition(txCtx, stateDBCopy, block)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"state transition failed: %w\", err)\n\t}\n\n\t// Compute the new state root from the updated state.\n\tnewStateRoot := stateDBCopy.HashTreeRoot()\n\tblock.SetStateRoot(newStateRoot)\n\treturn block, nil\n}\n\n// GetProofAndCommitmentsForBlobs will create a commitment and proof for each blob. Technically\nfunc GetProofAndCommitmentsForBlobs(\n\tt *require.Assertions,\n\tblobs []*eip4844.Blob,\n\tverifier kzg.BlobProofVerifier,\n) ([]eip4844.KZGProof, []eip4844.KZGCommitment) {\n\tif verifier.GetImplementation() != gokzg.Implementation {\n\t\tt.Fail(\"test expects gokzg implementation\")\n\t}\n\tgokzgVerifier, ok := verifier.(*gokzg.Verifier)\n\tif !ok {\n\t\tt.Fail(\"verifier is not of type *gokzg.Verifier\")\n\t}\n\tcommitments := make([]eip4844.KZGCommitment, len(blobs))\n\tproofs := make([]eip4844.KZGProof, len(blobs))\n\tfor i, blob := range blobs {\n\t\tkzgBlob := (*gokzg4844.Blob)(blob)\n\t\tcommitment, err := gokzgVerifier.BlobToKZGCommitment(kzgBlob, 1)\n\t\tt.NoError(err)\n\t\tproof, err := gokzgVerifier.ComputeBlobKZGProof(kzgBlob, commitment, 1)\n\t\tt.NoError(err)\n\t\tcommitments[i] = eip4844.KZGCommitment(commitment)\n\t\tproofs[i] = eip4844.KZGProof(proof)\n\t}\n\treturn proofs, commitments\n}\n\n// updateBeaconBlockBody converts executable data into an ExecutionPayload using\n// the given fork version, and then sets that payload into latestBlock. It\n// returns the updated block.\nfunc updateBeaconBlockBody(\n\tt *testing.T,\n\tlatestBlock *ctypes.BeaconBlock,\n\tforkVersion common.Version,\n\texecBlock any,\n\tsidecars []*coretypes.BlobTxSidecar, // adjust type as needed\n\texecutionRequests *ctypes.ExecutionRequests,\n) *ctypes.BeaconBlock {\n\tvar erBytes [][]byte\n\tif version.EqualsOrIsAfter(forkVersion, version.Electra()) {\n\t\tencodedExecRequests, err := ctypes.GetExecutionRequestsList(executionRequests)\n\t\trequire.NoError(t, err)\n\t\tfor _, er := range encodedExecRequests {\n\t\t\terBytes = append(erBytes, er)\n\t\t}\n\t}\n\n\tvar execData *engine.ExecutionPayloadEnvelope\n\tswitch execBlock := execBlock.(type) {\n\tcase *gethtypes.Block:\n\t\texecData = gethtypes.BlockToExecutableData(execBlock, nil, sidecars, erBytes)\n\tcase *coretypes.Block:\n\t\texecData = engine.BlockToExecutableData(execBlock, nil, sidecars, erBytes)\n\tdefault:\n\t\tt.Fatalf(\"unsupported block type: %T\", execBlock)\n\t\treturn nil\n\t}\n\n\t// Convert the ExecutableData into our internal ExecutionPayload type.\n\texecPayload, err := transformExecutableDataToExecutionPayload(forkVersion, execData.ExecutionPayload)\n\trequire.NoError(t, err, \"failed to convert executable data\")\n\t// Update the beacon block with the new execution payload.\n\tlatestBlock.GetBody().SetExecutionPayload(execPayload)\n\n\tif version.EqualsOrIsAfter(forkVersion, version.Electra()) {\n\t\terr = latestBlock.GetBody().SetExecutionRequests(executionRequests)\n\t\trequire.NoError(t, err)\n\t}\n\treturn latestBlock\n}\n"
  },
  {
    "path": "testing/simulated/valid_chain_test.go",
    "content": "//go:build simulated\n\n// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\npackage simulated_test\n\nimport (\n\t\"math/big\"\n\t\"time\"\n\n\t\"github.com/berachain/beacon-kit/beacon/blockchain\"\n\tctypes \"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/consensus/cometbft/service/encoding\"\n\tdablob \"github.com/berachain/beacon-kit/da/blob\"\n\tdatypes \"github.com/berachain/beacon-kit/da/types\"\n\t\"github.com/berachain/beacon-kit/node-core/components/metrics\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/testing/simulated\"\n\t\"github.com/cometbft/cometbft/abci/types\"\n\tgethcommon \"github.com/ethereum/go-ethereum/common\"\n\tgethtypes \"github.com/ethereum/go-ethereum/core/types\"\n\t\"github.com/ethereum/go-ethereum/crypto/kzg4844\"\n\t\"github.com/holiman/uint256\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// TestFullLifecycle_ValidBlock_IsSuccessful tests that a valid block proposal is processed, finalized, and committed.\n// It loops through this core process `coreLoopIterations` times.\nfunc (s *SimulatedSuite) TestFullLifecycle_ValidBlock_IsSuccessful() {\n\tconst blockHeight = 1\n\tconst coreLoopIterations = 10\n\n\t// Initialize the chain state.\n\ts.InitializeChain(s.T(), 1)\n\tnodeAddress, err := s.SimComet.GetNodeAddress()\n\ts.Require().NoError(err)\n\ts.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\t// Test happens post Deneb1 fork.\n\tstartTime := time.Now()\n\n\t// iterate through the core loop `coreLoopIterations` times, i.e. Propose, Process, Finalize and Commit.\n\tproposals, _, _ := s.MoveChainToHeight(s.T(), blockHeight, coreLoopIterations, nodeAddress, startTime)\n\n\t// We expect that the number of proposals that were finalized should be `coreLoopIterations`.\n\ts.Require().Len(proposals, coreLoopIterations)\n\n\tcurrentHeight := int64(blockHeight + coreLoopIterations)\n\t// Validate post-commit state.\n\tqueryCtx, err := s.SimComet.CreateQueryContext(currentHeight-1, false)\n\ts.Require().NoError(err)\n\n\tstateDB := s.TestNode.StorageBackend.StateFromContext(queryCtx)\n\tslot, err := stateDB.GetSlot()\n\ts.Require().NoError(err)\n\ts.Require().Equal(math.U64(currentHeight-1), slot)\n\n\tstateHeader, err := stateDB.GetLatestBlockHeader()\n\ts.Require().NoError(err)\n\n\tlph, err := stateDB.GetLatestExecutionPayloadHeader()\n\ts.Require().NoError(err)\n\n\t// Unmarshal the beacon block from the ABCI request.\n\tproposedBlock, err := encoding.UnmarshalBeaconBlockFromABCIRequest(\n\t\tproposals[len(proposals)-1].Txs,\n\t\tblockchain.BeaconBlockTxIndex,\n\t\ts.TestNode.ChainSpec.ActiveForkVersionForTimestamp(lph.GetTimestamp()),\n\t)\n\ts.Require().NoError(err)\n\ts.Require().Equal(proposedBlock.GetHeader().GetBodyRoot(), stateHeader.GetBodyRoot())\n}\n\n// TestFullLifecycle_ValidBlockWithInjectedTransaction_IsSuccessful effectively serves as a demonstration for how one can\n// inject custom transactions and state transitions into the core loop.\nfunc (s *SimulatedSuite) TestFullLifecycle_ValidBlockWithInjectedTransaction_IsSuccessful() {\n\tconst blockHeight = 1\n\tconst coreLoopIterations = 1\n\n\t// Initialize the chain state.\n\ts.InitializeChain(s.T(), 1)\n\n\t// Retrieve the BLS signer and proposer address.\n\tblsSigner := simulated.GetBlsSigner(s.HomeDir)\n\tpubkey, err := blsSigner.GetPubKey()\n\ts.Require().NoError(err)\n\tnodeAddress := pubkey.Address()\n\ts.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\t// Test happens on Deneb, pre Deneb1 fork.\n\tstartTime := time.Unix(0, 0)\n\n\t// Go through 1 iteration of the core loop to bypass any startup specific edge cases such as sync head on startup.\n\tproposals, _, consensusTime := s.MoveChainToHeight(s.T(), blockHeight, coreLoopIterations, nodeAddress, startTime)\n\ts.Require().Len(proposals, coreLoopIterations)\n\n\t// We expected this test to happen during Pre-Deneb1 fork.\n\tcurrentHeight := int64(blockHeight + coreLoopIterations)\n\n\t// Prepare a valid block proposal.\n\tproposal, err := s.SimComet.Comet.PrepareProposal(s.CtxComet, &types.PrepareProposalRequest{\n\t\tHeight:          currentHeight,\n\t\tTime:            consensusTime,\n\t\tProposerAddress: nodeAddress,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotEmpty(proposal)\n\n\t// Unmarshal the proposal block.\n\tproposedBlock, err := encoding.UnmarshalBeaconBlockFromABCIRequest(\n\t\tproposal.Txs,\n\t\tblockchain.BeaconBlockTxIndex,\n\t\ts.TestNode.ChainSpec.ActiveForkVersionForTimestamp(math.U64(consensusTime.Unix())),\n\t)\n\ts.Require().NoError(err)\n\n\t// Sign a valid transaction that is expected to pass\n\trecipientAddress := gethcommon.HexToAddress(\"0x56898d1aFb10cad584961eb96AcD476C6826e41E\")\n\tvalidTx, err := gethtypes.SignNewTx(\n\t\tsimulated.GetTestKey(s.T()),\n\t\tgethtypes.NewCancunSigner(big.NewInt(int64(s.TestNode.ChainSpec.DepositEth1ChainID()))),\n\t\t&gethtypes.DynamicFeeTx{\n\t\t\tNonce:     0,\n\t\t\tTo:        &recipientAddress,\n\t\t\tValue:     big.NewInt(0),\n\t\t\tGas:       21016,\n\t\t\tGasTipCap: big.NewInt(765625000),\n\t\t\tGasFeeCap: big.NewInt(765625000),\n\t\t\tData:      []byte{},\n\t\t},\n\t)\n\n\tvalidTxs := []*gethtypes.Transaction{validTx}\n\t// Create a new beacon block with the valid transaction.\n\t// Note: The beacon block returned here has an incorrect beacon state root, which is fixed in `ComputeAndSetStateRoot`.\n\tunsignedBlock := simulated.ComputeAndSetValidExecutionBlock(s.T(), proposedBlock.GetBeaconBlock(), s.SimulationClient, s.TestNode.ChainSpec, validTxs)\n\n\t// Finalize the block by applying the state transition to update its state root.\n\tqueryCtx, err := s.SimComet.CreateQueryContext(currentHeight-1, false)\n\ts.Require().NoError(err)\n\tfinalBlock, err := simulated.ComputeAndSetStateRoot(queryCtx, consensusTime, nodeAddress, s.TestNode.StateProcessor, s.TestNode.StorageBackend, unsignedBlock)\n\ts.Require().NoError(err)\n\n\tnewSignedBlock, err := ctypes.NewSignedBeaconBlock(\n\t\tfinalBlock,\n\t\t&ctypes.ForkData{\n\t\t\tCurrentVersion:        s.TestNode.ChainSpec.ActiveForkVersionForTimestamp(unsignedBlock.GetTimestamp()),\n\t\t\tGenesisValidatorsRoot: s.GenesisValidatorsRoot,\n\t\t},\n\t\ts.TestNode.ChainSpec,\n\t\tblsSigner,\n\t)\n\ts.Require().NoError(err)\n\n\tnewBlockBytes, err := newSignedBlock.MarshalSSZ()\n\ts.Require().NoError(err)\n\n\t// Replace the old block with the new block in the proposal.\n\tproposal.Txs[0] = newBlockBytes\n\n\t// Reset the log buffer to discard old logs we don't care about\n\ts.LogBuffer.Reset()\n\t// Process the proposal containing the valid block.\n\tprocessResp, err := s.SimComet.Comet.ProcessProposal(s.CtxComet, &types.ProcessProposalRequest{\n\t\tTxs:             proposal.Txs,\n\t\tHeight:          currentHeight,\n\t\tProposerAddress: nodeAddress,\n\t\tTime:            consensusTime,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT, processResp.Status)\n\n\t// Finalize the block.\n\tfinalizeResp, err := s.SimComet.Comet.FinalizeBlock(s.CtxComet, &types.FinalizeBlockRequest{\n\t\tTxs:             proposal.Txs,\n\t\tHeight:          currentHeight,\n\t\tProposerAddress: nodeAddress,\n\t\tTime:            consensusTime,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotEmpty(finalizeResp)\n\n\t// Commit the block.\n\t_, err = s.SimComet.Comet.Commit(s.CtxComet, &types.CommitRequest{})\n\ts.Require().NoError(err)\n}\n\n// TestFullLifecycle_ValidBlockAndInjectedBlob_IsSuccessful tests that a valid block and blob and proposal is processed, finalized, and committed.\nfunc (s *SimulatedSuite) TestFullLifecycle_ValidBlockAndInjectedBlob_IsSuccessful() {\n\tconst blockHeight = 1\n\tconst coreLoopIterations = 1\n\n\t// Initialize the chain state.\n\ts.InitializeChain(s.T(), 1)\n\n\t// Retrieve the BLS signer and proposer address.\n\tblsSigner := simulated.GetBlsSigner(s.HomeDir)\n\tpubkey, err := blsSigner.GetPubKey()\n\ts.Require().NoError(err)\n\tnodeAddress := pubkey.Address()\n\ts.SimComet.Comet.SetNodeAddress(nodeAddress)\n\n\t// Test happens on Deneb, pre Deneb1 fork.\n\tstartTime := time.Unix(0, 0)\n\n\t// Go through 1 iteration of the core loop to bypass any startup specific edge cases such as sync head on startup.\n\tproposals, _, consensusTime := s.MoveChainToHeight(s.T(), blockHeight, coreLoopIterations, nodeAddress, startTime)\n\ts.Require().Len(proposals, coreLoopIterations)\n\n\t// We expected this test to happen during Pre-Deneb1 fork.\n\tcurrentHeight := int64(blockHeight + coreLoopIterations)\n\n\t// Prepare a valid block proposal.\n\tproposal, err := s.SimComet.Comet.PrepareProposal(s.CtxComet, &types.PrepareProposalRequest{\n\t\tHeight:          currentHeight,\n\t\tTime:            consensusTime,\n\t\tProposerAddress: nodeAddress,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotEmpty(proposal)\n\n\t// Unmarshal the proposal block.\n\tproposedBlock, err := encoding.UnmarshalBeaconBlockFromABCIRequest(\n\t\tproposal.Txs,\n\t\tblockchain.BeaconBlockTxIndex,\n\t\ts.TestNode.ChainSpec.ActiveForkVersionForTimestamp(math.U64(consensusTime.Unix())),\n\t)\n\ts.Require().NoError(err)\n\n\t// Create the Blobs, with proofs and commitments\n\t// Each blob will go into 1 transaction.\n\tblobs := []*eip4844.Blob{{1, 2, 3}, {4, 5, 6}}\n\tproofs, commitments := simulated.GetProofAndCommitmentsForBlobs(require.New(s.T()), blobs, s.TestNode.KZGVerifier)\n\ts.Require().Len(proofs, len(blobs))\n\ts.Require().Len(commitments, len(blobs))\n\n\t// Sign blob transactions\n\tblobTxs := make([]*gethtypes.Transaction, len(blobs))\n\tfor i := range blobs {\n\t\tblobCommitment := commitments[i]\n\t\tblobHash := blobCommitment.ToVersionedHash()\n\t\ttxSidecar := &gethtypes.BlobTxSidecar{\n\t\t\tBlobs:       []kzg4844.Blob{kzg4844.Blob(blobs[i][:])},\n\t\t\tCommitments: []kzg4844.Commitment{kzg4844.Commitment(blobCommitment)},\n\t\t\tProofs:      []kzg4844.Proof{kzg4844.Proof(proofs[i])},\n\t\t}\n\t\tblobTx, err := gethtypes.SignNewTx(\n\t\t\tsimulated.GetTestKey(s.T()),\n\t\t\tgethtypes.NewCancunSigner(big.NewInt(int64(s.TestNode.ChainSpec.DepositEth1ChainID()))),\n\t\t\t&gethtypes.BlobTx{\n\t\t\t\tNonce: uint64(i),\n\t\t\t\t// Set to 875000000 as that is the tx base fee\n\t\t\t\tGasTipCap: uint256.NewInt(875000000),\n\t\t\t\tGasFeeCap: uint256.NewInt(875000000),\n\t\t\t\t// Set to 21000 for minimum intrinsic gas\n\t\t\t\tGas:        210000,\n\t\t\t\tValue:      uint256.NewInt(0),\n\t\t\t\tData:       []byte{},\n\t\t\t\tAccessList: nil,\n\t\t\t\tBlobFeeCap: uint256.NewInt(10),\n\t\t\t\t// If we have 1 tx with multiple blobs, we must add the blob hashes here.\n\t\t\t\tBlobHashes: []gethcommon.Hash{blobHash},\n\t\t\t\t// Sidecar must be set to nil here or Geth will error with \"unexpected blob sidecar in transaction\"\n\t\t\t\tSidecar: nil,\n\t\t\t},\n\t\t)\n\t\ts.Require().NoError(err)\n\t\t// Once we've signed the Tx, we tag the blob with the tx purely for association between tx and sidecars.\n\t\t// In this case, each 1 tx has a sidecar with 1 blob, even though 1 tx could have more than 1 blob.\n\t\tblobTx = blobTx.WithBlobTxSidecar(txSidecar)\n\t\tblobTxs[i] = blobTx\n\t}\n\n\tproposedBlockMessage := simulated.ComputeAndSetValidExecutionBlock(\n\t\ts.T(),\n\t\tproposedBlock.GetBeaconBlock(),\n\t\ts.SimulationClient,\n\t\ts.TestNode.ChainSpec,\n\t\tblobTxs,\n\t)\n\tproposedBlockMessage.GetBody().SetBlobKzgCommitments(commitments)\n\n\t// Finalize the block by applying the state transition to update its state root.\n\tqueryCtx, err := s.SimComet.CreateQueryContext(currentHeight-1, false)\n\ts.Require().NoError(err)\n\n\tproposedBlockMessage, err = simulated.ComputeAndSetStateRoot(queryCtx, consensusTime, nodeAddress, s.TestNode.StateProcessor, s.TestNode.StorageBackend, proposedBlockMessage)\n\ts.Require().NoError(err)\n\n\tnewSignedBlock, err := ctypes.NewSignedBeaconBlock(\n\t\tproposedBlockMessage,\n\t\t&ctypes.ForkData{\n\t\t\tCurrentVersion:        s.TestNode.ChainSpec.ActiveForkVersionForTimestamp(proposedBlockMessage.GetTimestamp()),\n\t\t\tGenesisValidatorsRoot: s.GenesisValidatorsRoot,\n\t\t},\n\t\ts.TestNode.ChainSpec,\n\t\tblsSigner,\n\t)\n\ts.Require().NoError(err)\n\n\t// Inject the new block\n\tnewSignedBlockBytes, err := newSignedBlock.MarshalSSZ()\n\ts.Require().NoError(err)\n\tproposal.Txs[0] = newSignedBlockBytes\n\n\t// Create the beaconBlock Header for the sidecar\n\tblockWithCommitmentsSignedHeader := ctypes.NewSignedBeaconBlockHeader(\n\t\tnewSignedBlock.GetHeader(),\n\t\tnewSignedBlock.GetSignature(),\n\t)\n\n\tsidecarsSlice := make([]*datypes.BlobSidecar, len(blobs))\n\t// Build Inclusion Proofs for Sidecars\n\tsidecarFactory := dablob.NewSidecarFactory(metrics.NewNoOpTelemetrySink())\n\tfor i := range blobs {\n\t\tinclusionProof, err := sidecarFactory.BuildKZGInclusionProof(proposedBlockMessage.GetBody(), math.U64(i))\n\t\ts.Require().NoError(err)\n\t\tsidecar := datypes.BuildBlobSidecar(\n\t\t\tmath.U64(i),\n\t\t\tblockWithCommitmentsSignedHeader,\n\t\t\tblobs[i],\n\t\t\tcommitments[i],\n\t\t\tproofs[i],\n\t\t\tinclusionProof,\n\t\t)\n\t\tsidecarsSlice[i] = sidecar\n\t}\n\tsidecars := datypes.BlobSidecars(sidecarsSlice)\n\t// Inject the valid sidecar\n\tsidecarBytes, err := sidecars.MarshalSSZ()\n\ts.Require().NoError(err)\n\n\tproposal.Txs[1] = sidecarBytes\n\n\t// Reset the log buffer to discard old logs we don't care about\n\ts.LogBuffer.Reset()\n\t// Process the proposal containing the valid block.\n\tprocessResp, err := s.SimComet.Comet.ProcessProposal(s.CtxComet, &types.ProcessProposalRequest{\n\t\tTxs:             proposal.Txs,\n\t\tHeight:          currentHeight,\n\t\tProposerAddress: nodeAddress,\n\t\tTime:            consensusTime,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().Equal(types.PROCESS_PROPOSAL_STATUS_ACCEPT, processResp.Status)\n\n\t// Finalize the block.\n\tfinalizeResp, err := s.SimComet.Comet.FinalizeBlock(s.CtxComet, &types.FinalizeBlockRequest{\n\t\tTxs:             proposal.Txs,\n\t\tHeight:          currentHeight,\n\t\tProposerAddress: nodeAddress,\n\t\tTime:            consensusTime,\n\t})\n\ts.Require().NoError(err)\n\ts.Require().NotEmpty(finalizeResp)\n\n\t// Commit the block.\n\t_, err = s.SimComet.Comet.Commit(s.CtxComet, &types.CommitRequest{})\n\ts.Require().NoError(err)\n}\n"
  },
  {
    "path": "testing/state-transition/README.md",
    "content": "# Testing state transitions\n\nThis package, `statetransition`, contains code which is helpful to test state transitions.\n\nSpecifically, it contains code to instantiate a test state processor with a mocked bls signer and its own state.\n\nThis code can be reused across tests in multiple packages but **should not be used in production code**."
  },
  {
    "path": "testing/state-transition/state-transition.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n//go:build test\n\npackage statetransition\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"testing\"\n\n\tcorestore \"cosmossdk.io/core/store\"\n\t\"cosmossdk.io/log\"\n\t\"cosmossdk.io/store\"\n\t\"cosmossdk.io/store/metrics\"\n\tstoretypes \"cosmossdk.io/store/types\"\n\t\"github.com/berachain/beacon-kit/chain\"\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\t\"github.com/berachain/beacon-kit/log/noop\"\n\tnodemetrics \"github.com/berachain/beacon-kit/node-core/components/metrics\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\tcryptomocks \"github.com/berachain/beacon-kit/primitives/crypto/mocks\"\n\t\"github.com/berachain/beacon-kit/primitives/transition\"\n\t\"github.com/berachain/beacon-kit/state-transition/core\"\n\t\"github.com/berachain/beacon-kit/state-transition/core/mocks\"\n\tstatedb \"github.com/berachain/beacon-kit/state-transition/core/state\"\n\t\"github.com/berachain/beacon-kit/storage\"\n\t\"github.com/berachain/beacon-kit/storage/beacondb\"\n\t\"github.com/berachain/beacon-kit/storage/db\"\n\t\"github.com/berachain/beacon-kit/storage/deposit\"\n\tdbm \"github.com/cosmos/cosmos-db\"\n\tsdk \"github.com/cosmos/cosmos-sdk/types\"\n\t\"github.com/stretchr/testify/mock\"\n\t\"github.com/stretchr/testify/require\"\n)\n\ntype (\n\tTestBeaconStateMarshallableT = types.BeaconState\n\tTestBeaconStateT             = statedb.StateDB\n\tTestStateProcessorT          = core.StateProcessor\n)\n\ntype testKVStoreService struct{}\n\nfunc (kvs *testKVStoreService) OpenKVStore(ctx context.Context) corestore.KVStore {\n\tstore := sdk.UnwrapSDKContext(ctx).KVStore(testStoreKey)\n\treturn storage.NewKVStore(store)\n}\n\nvar (\n\t//nolint:gochecknoglobals // unexported and used only in tests\n\ttestStoreKey = storetypes.NewKVStoreKey(\"state-transition-tests\")\n\n\t//nolint:gochecknoglobals // exported but used only in tests\n\tDummyProposerAddr = []byte{0xff}\n)\n\nfunc BuildTestStores() (\n\tstoretypes.CommitMultiStore,\n\t*beacondb.KVStore,\n\tdeposit.StoreManager,\n\terror,\n) {\n\tappDB, err := db.OpenDB(\"app\", dbm.MemDBBackend)\n\tif err != nil {\n\t\treturn nil, nil, nil, fmt.Errorf(\"failed opening mem app db: %w\", err)\n\t}\n\n\tdepositsDB, err := db.OpenDB(\"deposits\", dbm.MemDBBackend)\n\tif err != nil {\n\t\treturn nil, nil, nil, fmt.Errorf(\"failed opening mem deposits db: %w\", err)\n\t}\n\n\tvar (\n\t\tnopLog     = log.NewNopLogger()\n\t\tnopMetrics = metrics.NewNoOpMetrics()\n\t)\n\n\tcms := store.NewCommitMultiStore(\n\t\tappDB,\n\t\tnopLog,\n\t\tnopMetrics,\n\t)\n\n\tcms.MountStoreWithDB(testStoreKey, storetypes.StoreTypeIAVL, nil)\n\tif err = cms.LoadLatestVersion(); err != nil {\n\t\treturn nil, nil, nil, fmt.Errorf(\"failed to load latest version: %w\", err)\n\t}\n\n\tdepositStore := deposit.NewStore(depositsDB, nopLog)\n\treturn cms,\n\t\tbeacondb.New(&testKVStoreService{}),\n\t\tdepositStore,\n\t\tnil\n}\n\nfunc SetupTestState(t *testing.T, cs chain.Spec) (\n\t*TestStateProcessorT,\n\t*TestBeaconStateT,\n\tdeposit.StoreManager,\n\tcore.ReadOnlyContext,\n\tstoretypes.CommitMultiStore,\n\t*mocks.ExecutionEngine,\n) {\n\tt.Helper()\n\n\texecEngine := mocks.NewExecutionEngine(t)\n\n\tmocksSigner := &cryptomocks.Blssigner{}\n\tmocksSigner.On(\n\t\t\"VerifySignature\",\n\t\tmock.Anything, mock.Anything, mock.Anything,\n\t).Return(nil)\n\n\tcms, kvStore, depositStore, err := BuildTestStores()\n\trequire.NoError(t, err)\n\n\tsdkCtx := sdk.NewContext(cms.CacheMultiStore(), true, log.NewNopLogger())\n\tbeaconState := statedb.NewBeaconStateFromDB(\n\t\tkvStore.WithContext(sdkCtx), cs, sdkCtx.Logger(), nodemetrics.NewNoOpTelemetrySink(),\n\t)\n\n\tsp := core.NewStateProcessor(\n\t\tnoop.NewLogger[any](),\n\t\tcs,\n\t\texecEngine,\n\t\tdepositStore,\n\t\tmocksSigner,\n\t\tfunc(bytes.B48) ([]byte, error) {\n\t\t\treturn DummyProposerAddr, nil\n\t\t},\n\t\tnodemetrics.NewNoOpTelemetrySink(),\n\t)\n\n\t// by default we keep checks at minimum. It is up\n\t// to single tests to redefine the ctx along their needs.\n\tctx := transition.NewTransitionCtx(\n\t\tsdkCtx,\n\t\t0, // time\n\t\tDummyProposerAddr,\n\t).\n\t\tWithVerifyPayload(false).\n\t\tWithVerifyRandao(false).\n\t\tWithVerifyResult(false).\n\t\tWithMeterGas(false)\n\n\treturn sp, beaconState, depositStore, ctx, cms, execEngine\n}\n"
  },
  {
    "path": "testing/utils/.gitkeep",
    "content": "TODO: put general testing utilities in here. "
  },
  {
    "path": "testing/utils/generate.go",
    "content": "// SPDX-License-Identifier: BUSL-1.1\n//\n// Copyright (C) 2025, Berachain Foundation. All rights reserved.\n// Use of this software is governed by the Business Source License included\n// in the LICENSE file of this repository and at www.mariadb.com/bsl11.\n//\n// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY\n// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER\n// VERSIONS OF THE LICENSED WORK.\n//\n// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF\n// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF\n// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).\n//\n// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON\n// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,\n// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND\n// TITLE.\n\n//go:build test\n\npackage utils\n\nimport (\n\t\"testing\"\n\n\t\"github.com/berachain/beacon-kit/consensus-types/types\"\n\tengineprimitives \"github.com/berachain/beacon-kit/engine-primitives/engine-primitives\"\n\t\"github.com/berachain/beacon-kit/primitives/bytes\"\n\t\"github.com/berachain/beacon-kit/primitives/common\"\n\t\"github.com/berachain/beacon-kit/primitives/crypto\"\n\t\"github.com/berachain/beacon-kit/primitives/eip4844\"\n\t\"github.com/berachain/beacon-kit/primitives/math\"\n\t\"github.com/berachain/beacon-kit/primitives/version\"\n\t\"github.com/stretchr/testify/require\"\n)\n\n// GenerateValidBeaconBlock generates a valid beacon block for the Deneb.\nfunc GenerateValidBeaconBlock(t *testing.T, forkVersion common.Version) *types.BeaconBlock {\n\tt.Helper()\n\n\t// Initialize your block here\n\tbeaconBlock, err := types.NewBeaconBlockWithVersion(\n\t\tmath.Slot(10),              //nolint:mnd // dummy value\n\t\tmath.ValidatorIndex(5),     //nolint:mnd // dummy value\n\t\tcommon.Root{1, 2, 3, 4, 5}, // parent block root\n\t\tforkVersion,\n\t)\n\trequire.NoError(t, err)\n\n\tversionable := types.NewVersionable(forkVersion)\n\tbeaconBlock.StateRoot = common.Root{5, 4, 3, 2, 1}\n\tbeaconBlock.Body = &types.BeaconBlockBody{\n\t\tVersionable: versionable,\n\t\tExecutionPayload: &types.ExecutionPayload{\n\t\t\tVersionable: versionable,\n\t\t\tTimestamp:   10, //nolint:mnd // dummy value\n\t\t\tExtraData:   []byte(\"dummy extra data for testing\"),\n\t\t\tTransactions: [][]byte{\n\t\t\t\t[]byte(\"0x\"),\n\t\t\t\t[]byte(\"0x\"),\n\t\t\t\t[]byte(\"0x\"),\n\t\t\t},\n\t\t\tWithdrawals: engineprimitives.Withdrawals{\n\t\t\t\t{Index: 0, Amount: 100}, //nolint:mnd // dummy value\n\t\t\t\t{Index: 1, Amount: 200}, //nolint:mnd // dummy value\n\t\t\t},\n\t\t\tBaseFeePerGas: math.NewU256(0),\n\t\t},\n\t\tEth1Data: &types.Eth1Data{},\n\t\tDeposits: []*types.Deposit{\n\t\t\t{\n\t\t\t\tIndex: 1,\n\t\t\t},\n\t\t},\n\t\tBlobKzgCommitments: []eip4844.KZGCommitment{\n\t\t\t{1, 2, 3},\n\t\t},\n\t}\n\tbody := beaconBlock.GetBody()\n\tbody.SetProposerSlashings(types.ProposerSlashings{})\n\tbody.SetAttesterSlashings(types.AttesterSlashings{})\n\tbody.SetAttestations(types.Attestations{})\n\tbody.SetSyncAggregate(&types.SyncAggregate{})\n\tbody.SetVoluntaryExits(types.VoluntaryExits{})\n\tbody.SetBlsToExecutionChanges(types.BlsToExecutionChanges{})\n\tif version.EqualsOrIsAfter(forkVersion, version.Electra()) {\n\t\terr = body.SetExecutionRequests(&types.ExecutionRequests{\n\t\t\tDeposits: []*types.DepositRequest{\n\t\t\t\t{\n\t\t\t\t\tPubkey:      crypto.BLSPubkey{1, 2, 3},\n\t\t\t\t\tCredentials: types.WithdrawalCredentials(bytes.B32{4, 5, 6}),\n\t\t\t\t\tAmount:      100, //nolint:mnd // dummy value\n\t\t\t\t\tSignature:   crypto.BLSSignature{1, 2, 3},\n\t\t\t\t\tIndex:       1,\n\t\t\t\t},\n\t\t\t},\n\t\t\tWithdrawals: []*types.WithdrawalRequest{\n\t\t\t\t{\n\t\t\t\t\tSourceAddress:   common.ExecutionAddress{0, 1, 2, 3, 4, 5},\n\t\t\t\t\tValidatorPubKey: crypto.BLSPubkey{4, 2, 0}, //\t\t\tAmount:          1000, // nolint:mnd // dummy value\n\n\t\t\t\t},\n\t\t\t},\n\t\t\tConsolidations: []*types.ConsolidationRequest{},\n\t\t})\n\t\trequire.NoError(t, err)\n\t}\n\treturn beaconBlock\n}\n"
  }
]